| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef COMPONENTS_MUS_WS_EVENT_DISPATCHER_H_ | |
| 6 #define COMPONENTS_MUS_WS_EVENT_DISPATCHER_H_ | |
| 7 | |
| 8 #include <stdint.h> | |
| 9 | |
| 10 #include <map> | |
| 11 #include <memory> | |
| 12 #include <utility> | |
| 13 | |
| 14 #include "base/macros.h" | |
| 15 #include "components/mus/common/types.h" | |
| 16 #include "components/mus/public/interfaces/event_matcher.mojom.h" | |
| 17 #include "components/mus/ws/modal_window_controller.h" | |
| 18 #include "components/mus/ws/server_window_observer.h" | |
| 19 #include "ui/gfx/geometry/rect_f.h" | |
| 20 | |
| 21 namespace ui { | |
| 22 class Event; | |
| 23 class KeyEvent; | |
| 24 class LocatedEvent; | |
| 25 } | |
| 26 | |
| 27 namespace mus { | |
| 28 namespace ws { | |
| 29 | |
| 30 class Accelerator; | |
| 31 class EventDispatcherDelegate; | |
| 32 class ServerWindow; | |
| 33 | |
| 34 namespace test { | |
| 35 class EventDispatcherTestApi; | |
| 36 } | |
| 37 | |
| 38 // Handles dispatching events to the right location as well as updating focus. | |
| 39 class EventDispatcher : public ServerWindowObserver { | |
| 40 public: | |
| 41 explicit EventDispatcher(EventDispatcherDelegate* delegate); | |
| 42 ~EventDispatcher() override; | |
| 43 | |
| 44 // Cancels capture and stops tracking any pointer events. This does not send | |
| 45 // any events to the delegate. | |
| 46 void Reset(); | |
| 47 | |
| 48 void SetMousePointerScreenLocation(const gfx::Point& screen_location); | |
| 49 const gfx::Point& mouse_pointer_last_location() const { | |
| 50 return mouse_pointer_last_location_; | |
| 51 } | |
| 52 | |
| 53 // If we still have the window of the last mouse move, returns true and sets | |
| 54 // the current cursor to use to |cursor_out|. | |
| 55 bool GetCurrentMouseCursor(int32_t* cursor_out); | |
| 56 | |
| 57 // |capture_window_| will receive all input. See window_tree.mojom for | |
| 58 // details. | |
| 59 ServerWindow* capture_window() { return capture_window_; } | |
| 60 const ServerWindow* capture_window() const { return capture_window_; } | |
| 61 // Setting capture can fail if the window is blocked by a modal window | |
| 62 // (indicated by returning |false|). | |
| 63 bool SetCaptureWindow(ServerWindow* capture_window, | |
| 64 ClientSpecificId client_id); | |
| 65 | |
| 66 // Id of the client that capture events are sent to. | |
| 67 ClientSpecificId capture_window_client_id() const { | |
| 68 return capture_window_client_id_; | |
| 69 } | |
| 70 | |
| 71 // Adds a system modal window. The window remains modal to system until it is | |
| 72 // destroyed. There can exist multiple system modal windows, in which case the | |
| 73 // one that is visible and added most recently or shown most recently would be | |
| 74 // the active one. | |
| 75 void AddSystemModalWindow(ServerWindow* window); | |
| 76 | |
| 77 // Checks if |modal_window| is a visible modal window that blocks current | |
| 78 // capture window and if that's the case, releases the capture. | |
| 79 void ReleaseCaptureBlockedByModalWindow(const ServerWindow* modal_window); | |
| 80 | |
| 81 // Checks if the current capture window is blocked by any visible modal window | |
| 82 // and if that's the case, releases the capture. | |
| 83 void ReleaseCaptureBlockedByAnyModalWindow(); | |
| 84 | |
| 85 // Retrieves the ServerWindow of the last mouse move. | |
| 86 ServerWindow* mouse_cursor_source_window() const { | |
| 87 return mouse_cursor_source_window_; | |
| 88 } | |
| 89 | |
| 90 // If the mouse cursor is still over |mouse_cursor_source_window_|, updates | |
| 91 // whether we are in the non-client area. Used when | |
| 92 // |mouse_cursor_source_window_| has changed its properties. | |
| 93 void UpdateNonClientAreaForCurrentWindow(); | |
| 94 | |
| 95 // Possibly updates the cursor. If we aren't in an implicit capture, we take | |
| 96 // the last known location of the mouse pointer, and look for the | |
| 97 // ServerWindow* under it. | |
| 98 void UpdateCursorProviderByLastKnownLocation(); | |
| 99 | |
| 100 // Adds an accelerator with the given id and event-matcher. If an accelerator | |
| 101 // already exists with the same id or the same matcher, then the accelerator | |
| 102 // is not added. Returns whether adding the accelerator was successful or not. | |
| 103 bool AddAccelerator(uint32_t id, mojom::EventMatcherPtr event_matcher); | |
| 104 void RemoveAccelerator(uint32_t id); | |
| 105 | |
| 106 // Processes the supplied event, informing the delegate as approriate. This | |
| 107 // may result in generating any number of events. | |
| 108 void ProcessEvent(const ui::Event& event); | |
| 109 | |
| 110 private: | |
| 111 friend class test::EventDispatcherTestApi; | |
| 112 | |
| 113 // Keeps track of state associated with an active pointer. | |
| 114 struct PointerTarget { | |
| 115 PointerTarget() | |
| 116 : window(nullptr), | |
| 117 is_mouse_event(false), | |
| 118 in_nonclient_area(false), | |
| 119 is_pointer_down(false) {} | |
| 120 | |
| 121 // NOTE: this is set to null if the window is destroyed before a | |
| 122 // corresponding release/cancel. | |
| 123 ServerWindow* window; | |
| 124 | |
| 125 bool is_mouse_event; | |
| 126 | |
| 127 // Did the pointer event start in the non-client area. | |
| 128 bool in_nonclient_area; | |
| 129 | |
| 130 bool is_pointer_down; | |
| 131 }; | |
| 132 | |
| 133 void ProcessKeyEvent(const ui::KeyEvent& event); | |
| 134 | |
| 135 bool IsTrackingPointer(int32_t pointer_id) const { | |
| 136 return pointer_targets_.count(pointer_id) > 0; | |
| 137 } | |
| 138 | |
| 139 // EventDispatcher provides the following logic for pointer events: | |
| 140 // . wheel events go to the current target of the associated pointer. If | |
| 141 // there is no target, they go to the deepest window. | |
| 142 // . move (not drag) events go to the deepest window. | |
| 143 // . when a pointer goes down all events until the corresponding up or | |
| 144 // cancel go to the deepest target. For mouse events the up only occurs | |
| 145 // when no buttons on the mouse are down. | |
| 146 // This also generates exit events as appropriate. For example, if the mouse | |
| 147 // moves between one window to another an exit is generated on the first. | |
| 148 void ProcessLocatedEvent(const ui::LocatedEvent& event); | |
| 149 | |
| 150 // Adds |pointer_target| to |pointer_targets_|. | |
| 151 void StartTrackingPointer(int32_t pointer_id, | |
| 152 const PointerTarget& pointer_target); | |
| 153 | |
| 154 // Removes a PointerTarget from |pointer_targets_|. | |
| 155 void StopTrackingPointer(int32_t pointer_id); | |
| 156 | |
| 157 // Starts tracking the pointer for |event|, or if already tracking the | |
| 158 // pointer sends the appropriate event to the delegate and updates the | |
| 159 // currently tracked PointerTarget appropriately. | |
| 160 void UpdateTargetForPointer(int32_t pointer_id, | |
| 161 const ui::LocatedEvent& event); | |
| 162 | |
| 163 // Returns a PointerTarget from the supplied event. | |
| 164 PointerTarget PointerTargetForEvent(const ui::LocatedEvent& event); | |
| 165 | |
| 166 // Returns true if any pointers are in the pressed/down state. | |
| 167 bool AreAnyPointersDown() const; | |
| 168 | |
| 169 // If |target->window| is valid, then passes the event to the delegate. | |
| 170 void DispatchToPointerTarget(const PointerTarget& target, | |
| 171 const ui::LocatedEvent& event); | |
| 172 | |
| 173 // Dispatch |event| to the delegate. | |
| 174 void DispatchToClient(ServerWindow* window, | |
| 175 ClientSpecificId client_id, | |
| 176 const ui::LocatedEvent& event); | |
| 177 | |
| 178 // Stops sending pointer events to |window|. This does not remove the entry | |
| 179 // for |window| from |pointer_targets_|, rather it nulls out the window. This | |
| 180 // way we continue to eat events until the up/cancel is received. | |
| 181 void CancelPointerEventsToTarget(ServerWindow* window); | |
| 182 | |
| 183 // Used to observe a window. Can be called multiple times on a window. To | |
| 184 // unobserve a window, UnobserveWindow() should be called the same number of | |
| 185 // times. | |
| 186 void ObserveWindow(ServerWindow* winodw); | |
| 187 void UnobserveWindow(ServerWindow* winodw); | |
| 188 | |
| 189 // Returns an Accelerator bound to the specified code/flags, and of the | |
| 190 // matching |phase|. Otherwise returns null. | |
| 191 Accelerator* FindAccelerator(const ui::KeyEvent& event, | |
| 192 const ui::mojom::AcceleratorPhase phase); | |
| 193 | |
| 194 ServerWindow* FindDeepestVisibleWindowForEvents(gfx::Point* location); | |
| 195 | |
| 196 // ServerWindowObserver: | |
| 197 void OnWillChangeWindowHierarchy(ServerWindow* window, | |
| 198 ServerWindow* new_parent, | |
| 199 ServerWindow* old_parent) override; | |
| 200 void OnWindowVisibilityChanged(ServerWindow* window) override; | |
| 201 void OnWindowDestroyed(ServerWindow* window) override; | |
| 202 | |
| 203 EventDispatcherDelegate* delegate_; | |
| 204 | |
| 205 ServerWindow* capture_window_; | |
| 206 ClientSpecificId capture_window_client_id_; | |
| 207 | |
| 208 ModalWindowController modal_window_controller_; | |
| 209 | |
| 210 bool mouse_button_down_; | |
| 211 ServerWindow* mouse_cursor_source_window_; | |
| 212 bool mouse_cursor_in_non_client_area_; | |
| 213 | |
| 214 // The on screen location of the mouse pointer. This can be outside the | |
| 215 // bounds of |mouse_cursor_source_window_|, which can capture the cursor. | |
| 216 gfx::Point mouse_pointer_last_location_; | |
| 217 | |
| 218 std::map<uint32_t, std::unique_ptr<Accelerator>> accelerators_; | |
| 219 | |
| 220 using PointerIdToTargetMap = std::map<int32_t, PointerTarget>; | |
| 221 // |pointer_targets_| contains the active pointers. For a mouse based pointer | |
| 222 // a PointerTarget is always active (and present in |pointer_targets_|). For | |
| 223 // touch based pointers the pointer is active while down and removed on | |
| 224 // cancel or up. | |
| 225 PointerIdToTargetMap pointer_targets_; | |
| 226 | |
| 227 // Keeps track of number of observe requests for each observed window. | |
| 228 std::map<const ServerWindow*, uint8_t> observed_windows_; | |
| 229 | |
| 230 DISALLOW_COPY_AND_ASSIGN(EventDispatcher); | |
| 231 }; | |
| 232 | |
| 233 } // namespace ws | |
| 234 } // namespace mus | |
| 235 | |
| 236 #endif // COMPONENTS_MUS_WS_EVENT_DISPATCHER_H_ | |
| OLD | NEW |