blob: 761c680a98eed403f5b6a189403c62cb92a50fc8 [file] [log] [blame]
// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WINDOW_MANAGER_POINTER_POSITION_WATCHER_H_
#define WINDOW_MANAGER_POINTER_POSITION_WATCHER_H_
#include "base/memory/scoped_ptr.h"
#include "window_manager/callback.h"
#include "window_manager/geometry.h"
namespace window_manager {
class EventLoop;
class XConnection;
// This class periodically queries the mouse pointer's position and invokes
// a callback once the pointer has moved into or out of a target rectangle.
//
// This is primarily useful for:
// a) avoiding race conditions in cases where we want to open a new window
// under the pointer and then do something when the pointer leaves the
// window -- it's possible that the pointer will have already been moved
// away by the time that window is created
// b) getting notified when the pointer enters or leaves a region without
// creating a window that will steal events from windows underneath it
//
// With that being said, repeatedly waking up to poll the X server over
// long periods of time is a bad idea from a power consumption perspective,
// so this should only be used in cases where the user is likely to
// enter/leave the target region soon.
class PointerPositionWatcher {
public:
// The constructor takes ownership of |cb|.
PointerPositionWatcher(
EventLoop* event_loop,
XConnection* xconn,
Closure* cb,
bool watch_for_entering_target, // as opposed to leaving it
const Rect& target_bounds);
~PointerPositionWatcher();
// Useful for testing.
int timeout_id() const { return timeout_id_; }
// Invoke RunCallbackIfConditionIsSatisfied() and remove the current
// timeout if needed.
void TriggerTimeout();
private:
// If |timeout_id_| is set, clear it and remove the timeout.
void CancelTimeoutIfActive();
// Check the pointer's position, running the callback and removing the
// timeout if the condition has been satisfied.
void HandleTimeout();
EventLoop* event_loop_; // not owned
XConnection* xconn_; // not owned
// Callback that gets invoked when the pointer enters/exits the target
// rectangle.
scoped_ptr<Closure> cb_;
// Should we watch for the pointer entering the target rectangle, as
// opposed to leaving it?
bool watch_for_entering_target_;
// Target rectangle.
Rect target_bounds_;
// Timeout ID, or EventLoop::kUnsetTimeoutId if the timeout isn't active.
int timeout_id_;
};
} // namespace window_manager
#endif // WINDOW_MANAGER_MOTION_POINTER_POSITION_WATCHER_H_