| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/mus/ws/event_dispatcher.h" | 5 #include "components/mus/ws/event_dispatcher.h" |
| 6 | 6 |
| 7 #include "cc/surfaces/surface_hittest.h" | 7 #include "cc/surfaces/surface_hittest.h" |
| 8 #include "components/mus/surfaces/surfaces_state.h" | 8 #include "components/mus/surfaces/surfaces_state.h" |
| 9 #include "components/mus/ws/event_dispatcher_delegate.h" | 9 #include "components/mus/ws/event_dispatcher_delegate.h" |
| 10 #include "components/mus/ws/move_loop.h" | |
| 11 #include "components/mus/ws/server_window.h" | 10 #include "components/mus/ws/server_window.h" |
| 12 #include "components/mus/ws/server_window_delegate.h" | 11 #include "components/mus/ws/server_window_delegate.h" |
| 13 #include "components/mus/ws/window_coordinate_conversions.h" | 12 #include "components/mus/ws/window_coordinate_conversions.h" |
| 14 #include "components/mus/ws/window_finder.h" | 13 #include "components/mus/ws/window_finder.h" |
| 15 #include "components/mus/ws/window_tree_host_impl.h" | 14 #include "components/mus/ws/window_tree_host_impl.h" |
| 16 #include "mojo/converters/geometry/geometry_type_converters.h" | 15 #include "mojo/converters/geometry/geometry_type_converters.h" |
| 17 #include "ui/gfx/geometry/point.h" | 16 #include "ui/gfx/geometry/point.h" |
| 17 #include "ui/gfx/geometry/point_conversions.h" |
| 18 | 18 |
| 19 namespace mus { | 19 namespace mus { |
| 20 namespace ws { | 20 namespace ws { |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 bool IsPointerEvent(const mojo::Event& event) { | |
| 24 return event.action == mojo::EVENT_TYPE_POINTER_CANCEL || | |
| 25 event.action == mojo::EVENT_TYPE_POINTER_DOWN || | |
| 26 event.action == mojo::EVENT_TYPE_POINTER_MOVE || | |
| 27 event.action == mojo::EVENT_TYPE_POINTER_UP; | |
| 28 } | |
| 29 | |
| 30 } // namespace | |
| 31 | |
| 32 namespace { | |
| 33 | |
| 34 bool IsMouseEventFlag(int32_t event_flags) { | 23 bool IsMouseEventFlag(int32_t event_flags) { |
| 35 return !!(event_flags & (mojo::EVENT_FLAGS_LEFT_MOUSE_BUTTON | | 24 return !!(event_flags & (mojo::EVENT_FLAGS_LEFT_MOUSE_BUTTON | |
| 36 mojo::EVENT_FLAGS_MIDDLE_MOUSE_BUTTON | | 25 mojo::EVENT_FLAGS_MIDDLE_MOUSE_BUTTON | |
| 37 mojo::EVENT_FLAGS_RIGHT_MOUSE_BUTTON)); | 26 mojo::EVENT_FLAGS_RIGHT_MOUSE_BUTTON)); |
| 38 } | 27 } |
| 39 | 28 |
| 40 bool IsOnlyOneMouseButtonDown(mojo::EventFlags flags) { | 29 bool IsOnlyOneMouseButtonDown(mojo::EventFlags flags) { |
| 41 const uint32_t mouse_only_flags = | 30 const uint32_t mouse_only_flags = |
| 42 flags & (mojo::EVENT_FLAGS_LEFT_MOUSE_BUTTON | | 31 flags & (mojo::EVENT_FLAGS_LEFT_MOUSE_BUTTON | |
| 43 mojo::EVENT_FLAGS_MIDDLE_MOUSE_BUTTON | | 32 mojo::EVENT_FLAGS_MIDDLE_MOUSE_BUTTON | |
| 44 mojo::EVENT_FLAGS_RIGHT_MOUSE_BUTTON); | 33 mojo::EVENT_FLAGS_RIGHT_MOUSE_BUTTON); |
| 45 return mouse_only_flags == mojo::EVENT_FLAGS_LEFT_MOUSE_BUTTON || | 34 return mouse_only_flags == mojo::EVENT_FLAGS_LEFT_MOUSE_BUTTON || |
| 46 mouse_only_flags == mojo::EVENT_FLAGS_MIDDLE_MOUSE_BUTTON || | 35 mouse_only_flags == mojo::EVENT_FLAGS_MIDDLE_MOUSE_BUTTON || |
| 47 mouse_only_flags == mojo::EVENT_FLAGS_RIGHT_MOUSE_BUTTON; | 36 mouse_only_flags == mojo::EVENT_FLAGS_RIGHT_MOUSE_BUTTON; |
| 48 } | 37 } |
| 49 | 38 |
| 39 bool IsLocationInNonclientArea(const ServerWindow* target, |
| 40 const gfx::Point& location) { |
| 41 return target->parent() && |
| 42 !target->client_area().Contains(location); |
| 43 } |
| 44 |
| 45 gfx::Point EventLocationToPoint(const mojo::Event& event) { |
| 46 return gfx::ToFlooredPoint(gfx::PointF(event.pointer_data->location->x, |
| 47 event.pointer_data->location->y)); |
| 48 } |
| 49 |
| 50 } // namespace | 50 } // namespace |
| 51 | 51 |
| 52 class EventMatcher { | 52 class EventMatcher { |
| 53 public: | 53 public: |
| 54 explicit EventMatcher(const mojo::EventMatcher& matcher) | 54 explicit EventMatcher(const mojo::EventMatcher& matcher) |
| 55 : fields_to_match_(NONE), | 55 : fields_to_match_(NONE), |
| 56 event_type_(mojo::EVENT_TYPE_UNKNOWN), | 56 event_type_(mojo::EVENT_TYPE_UNKNOWN), |
| 57 event_flags_(mojo::EVENT_FLAGS_NONE), | 57 event_flags_(mojo::EVENT_FLAGS_NONE), |
| 58 keyboard_code_(mojo::KEYBOARD_CODE_UNKNOWN), | 58 keyboard_code_(mojo::KEYBOARD_CODE_UNKNOWN), |
| 59 pointer_kind_(mojo::POINTER_KIND_MOUSE) { | 59 pointer_kind_(mojo::POINTER_KIND_MOUSE) { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 mojo::EventType event_type_; | 134 mojo::EventType event_type_; |
| 135 mojo::EventFlags event_flags_; | 135 mojo::EventFlags event_flags_; |
| 136 mojo::KeyboardCode keyboard_code_; | 136 mojo::KeyboardCode keyboard_code_; |
| 137 mojo::PointerKind pointer_kind_; | 137 mojo::PointerKind pointer_kind_; |
| 138 gfx::RectF pointer_region_; | 138 gfx::RectF pointer_region_; |
| 139 }; | 139 }; |
| 140 | 140 |
| 141 //////////////////////////////////////////////////////////////////////////////// | 141 //////////////////////////////////////////////////////////////////////////////// |
| 142 | 142 |
| 143 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) | 143 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) |
| 144 : delegate_(delegate), root_(nullptr), capture_window_(nullptr) {} | 144 : delegate_(delegate), |
| 145 root_(nullptr), |
| 146 capture_window_(nullptr), |
| 147 capture_in_nonclient_area_(false) {} |
| 145 | 148 |
| 146 EventDispatcher::~EventDispatcher() {} | 149 EventDispatcher::~EventDispatcher() {} |
| 147 | 150 |
| 148 void EventDispatcher::AddAccelerator(uint32_t id, | 151 void EventDispatcher::AddAccelerator(uint32_t id, |
| 149 mojo::EventMatcherPtr event_matcher) { | 152 mojo::EventMatcherPtr event_matcher) { |
| 150 EventMatcher matcher(*event_matcher); | 153 EventMatcher matcher(*event_matcher); |
| 151 #if !defined(NDEBUG) | 154 #if !defined(NDEBUG) |
| 152 for (const auto& pair : accelerators_) { | 155 for (const auto& pair : accelerators_) { |
| 153 DCHECK_NE(pair.first, id); | 156 DCHECK_NE(pair.first, id); |
| 154 DCHECK(!matcher.Equals(pair.second)); | 157 DCHECK(!matcher.Equals(pair.second)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 169 | 172 |
| 170 if (event->action == mojo::EVENT_TYPE_KEY_PRESSED && | 173 if (event->action == mojo::EVENT_TYPE_KEY_PRESSED && |
| 171 !event->key_data->is_char) { | 174 !event->key_data->is_char) { |
| 172 uint32_t accelerator = 0u; | 175 uint32_t accelerator = 0u; |
| 173 if (FindAccelerator(*event, &accelerator)) { | 176 if (FindAccelerator(*event, &accelerator)) { |
| 174 delegate_->OnAccelerator(accelerator, event.Pass()); | 177 delegate_->OnAccelerator(accelerator, event.Pass()); |
| 175 return; | 178 return; |
| 176 } | 179 } |
| 177 } | 180 } |
| 178 | 181 |
| 179 // If there is a MoveLoop all pointer events are forwarded to it. | |
| 180 if (move_loop_ && IsPointerEvent(*event)) { | |
| 181 if (move_loop_->Move(*event) == MoveLoop::DONE) { | |
| 182 move_loop_.reset(); | |
| 183 ResetCaptureWindowIfPointerUp(*event); | |
| 184 } | |
| 185 | |
| 186 return; | |
| 187 } | |
| 188 | |
| 189 ServerWindow* target = FindEventTarget(event.get()); | 182 ServerWindow* target = FindEventTarget(event.get()); |
| 183 bool in_nonclient_area = false; |
| 190 | 184 |
| 191 if (IsMouseEventFlag(event->flags)) { | 185 if (IsMouseEventFlag(event->flags)) { |
| 192 if (!capture_window_ && (event->action == mojo::EVENT_TYPE_POINTER_DOWN)) | 186 if (!capture_window_ && target && |
| 187 (event->action == mojo::EVENT_TYPE_POINTER_DOWN)) { |
| 188 // TODO(sky): |capture_window_| needs to be reset when window removed |
| 189 // from hierarchy. |
| 193 capture_window_ = target; | 190 capture_window_ = target; |
| 194 else | 191 // TODO(sky): this needs to happen for pointer down events too. |
| 195 ResetCaptureWindowIfPointerUp(*event); | 192 capture_in_nonclient_area_ = |
| 193 IsLocationInNonclientArea(target, EventLocationToPoint(*event)); |
| 194 in_nonclient_area = capture_in_nonclient_area_; |
| 195 } else if (event->action == mojo::EVENT_TYPE_POINTER_UP && |
| 196 IsOnlyOneMouseButtonDown(event->flags)) { |
| 197 capture_window_ = nullptr; |
| 198 } |
| 199 in_nonclient_area = capture_in_nonclient_area_; |
| 196 } | 200 } |
| 197 | 201 |
| 198 if (target) { | 202 if (target) { |
| 199 if (event->action == mojo::EVENT_TYPE_POINTER_DOWN) { | 203 if (event->action == mojo::EVENT_TYPE_POINTER_DOWN) |
| 200 delegate_->SetFocusedWindowFromEventDispatcher(target); | 204 delegate_->SetFocusedWindowFromEventDispatcher(target); |
| 201 | 205 |
| 202 if (!move_loop_) { | 206 delegate_->DispatchInputEventToWindow(target, in_nonclient_area, |
| 203 move_loop_ = MoveLoop::Create(target, *event); | 207 event.Pass()); |
| 204 if (move_loop_) | |
| 205 return; | |
| 206 } | |
| 207 } | |
| 208 | |
| 209 delegate_->DispatchInputEventToWindow(target, event.Pass()); | |
| 210 } | 208 } |
| 211 } | 209 } |
| 212 | 210 |
| 213 bool EventDispatcher::FindAccelerator(const mojo::Event& event, | 211 bool EventDispatcher::FindAccelerator(const mojo::Event& event, |
| 214 uint32_t* accelerator_id) { | 212 uint32_t* accelerator_id) { |
| 215 DCHECK(event.key_data); | 213 DCHECK(event.key_data); |
| 216 for (const auto& pair : accelerators_) { | 214 for (const auto& pair : accelerators_) { |
| 217 if (pair.second.MatchesEvent(event)) { | 215 if (pair.second.MatchesEvent(event)) { |
| 218 *accelerator_id = pair.first; | 216 *accelerator_id = pair.first; |
| 219 return true; | 217 return true; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 244 | 242 |
| 245 if (!target) { | 243 if (!target) { |
| 246 target = FindDeepestVisibleWindow(root_, surface_id_, &location); | 244 target = FindDeepestVisibleWindow(root_, surface_id_, &location); |
| 247 } else { | 245 } else { |
| 248 gfx::Transform transform(GetTransformToWindow(surface_id_, target)); | 246 gfx::Transform transform(GetTransformToWindow(surface_id_, target)); |
| 249 transform.TransformPoint(&location); | 247 transform.TransformPoint(&location); |
| 250 } | 248 } |
| 251 | 249 |
| 252 event_location->x = location.x(); | 250 event_location->x = location.x(); |
| 253 event_location->y = location.y(); | 251 event_location->y = location.y(); |
| 252 |
| 254 return target; | 253 return target; |
| 255 } | 254 } |
| 256 | 255 |
| 257 void EventDispatcher::ResetCaptureWindowIfPointerUp(const mojo::Event& event) { | |
| 258 if (event.action == mojo::EVENT_TYPE_POINTER_UP && | |
| 259 IsOnlyOneMouseButtonDown(event.flags)) { | |
| 260 capture_window_ = nullptr; | |
| 261 } | |
| 262 } | |
| 263 | |
| 264 } // namespace ws | 256 } // namespace ws |
| 265 } // namespace mus | 257 } // namespace mus |
| OLD | NEW |