| // 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_ |