Chromium Code Reviews| 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 <set> | |
| 8 | |
| 7 #include "cc/surfaces/surface_hittest.h" | 9 #include "cc/surfaces/surface_hittest.h" |
| 8 #include "components/mus/surfaces/surfaces_state.h" | 10 #include "components/mus/surfaces/surfaces_state.h" |
| 9 #include "components/mus/ws/event_dispatcher_delegate.h" | 11 #include "components/mus/ws/event_dispatcher_delegate.h" |
| 10 #include "components/mus/ws/server_window.h" | 12 #include "components/mus/ws/server_window.h" |
| 11 #include "components/mus/ws/server_window_delegate.h" | 13 #include "components/mus/ws/server_window_delegate.h" |
| 12 #include "components/mus/ws/window_coordinate_conversions.h" | 14 #include "components/mus/ws/window_coordinate_conversions.h" |
| 13 #include "components/mus/ws/window_finder.h" | 15 #include "components/mus/ws/window_finder.h" |
| 14 #include "components/mus/ws/window_tree_host_impl.h" | 16 #include "components/mus/ws/window_tree_host_impl.h" |
| 15 #include "mojo/converters/geometry/geometry_type_converters.h" | 17 #include "mojo/converters/geometry/geometry_type_converters.h" |
| 16 #include "ui/gfx/geometry/point.h" | 18 #include "ui/gfx/geometry/point.h" |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 mojo::EventType event_type_; | 136 mojo::EventType event_type_; |
| 135 mojo::EventFlags event_flags_; | 137 mojo::EventFlags event_flags_; |
| 136 mojo::KeyboardCode keyboard_code_; | 138 mojo::KeyboardCode keyboard_code_; |
| 137 mojo::PointerKind pointer_kind_; | 139 mojo::PointerKind pointer_kind_; |
| 138 gfx::RectF pointer_region_; | 140 gfx::RectF pointer_region_; |
| 139 }; | 141 }; |
| 140 | 142 |
| 141 //////////////////////////////////////////////////////////////////////////////// | 143 //////////////////////////////////////////////////////////////////////////////// |
| 142 | 144 |
| 143 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) | 145 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) |
| 144 : delegate_(delegate), | 146 : delegate_(delegate), root_(nullptr) {} |
| 145 root_(nullptr), | |
| 146 capture_window_(nullptr), | |
| 147 capture_in_nonclient_area_(false) {} | |
| 148 | 147 |
| 149 EventDispatcher::~EventDispatcher() {} | 148 EventDispatcher::~EventDispatcher() { |
| 149 std::set<ServerWindow*> pointer_targets; | |
| 150 for (const auto& pair : pointer_targets_) { | |
| 151 if (pair.second.window && | |
| 152 pointer_targets.insert(pair.second.window).second) { | |
| 153 pair.second.window->RemoveObserver(this); | |
| 154 } | |
| 155 } | |
| 156 } | |
| 150 | 157 |
| 151 void EventDispatcher::AddAccelerator(uint32_t id, | 158 void EventDispatcher::AddAccelerator(uint32_t id, |
| 152 mojo::EventMatcherPtr event_matcher) { | 159 mojo::EventMatcherPtr event_matcher) { |
| 153 EventMatcher matcher(*event_matcher); | 160 EventMatcher matcher(*event_matcher); |
| 154 #if !defined(NDEBUG) | 161 #if !defined(NDEBUG) |
| 155 for (const auto& pair : accelerators_) { | 162 for (const auto& pair : accelerators_) { |
| 156 DCHECK_NE(pair.first, id); | 163 DCHECK_NE(pair.first, id); |
| 157 DCHECK(!matcher.Equals(pair.second)); | 164 DCHECK(!matcher.Equals(pair.second)); |
| 158 } | 165 } |
| 159 #endif | 166 #endif |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 172 | 179 |
| 173 if (event->action == mojo::EVENT_TYPE_KEY_PRESSED && | 180 if (event->action == mojo::EVENT_TYPE_KEY_PRESSED && |
| 174 !event->key_data->is_char) { | 181 !event->key_data->is_char) { |
| 175 uint32_t accelerator = 0u; | 182 uint32_t accelerator = 0u; |
| 176 if (FindAccelerator(*event, &accelerator)) { | 183 if (FindAccelerator(*event, &accelerator)) { |
| 177 delegate_->OnAccelerator(accelerator, event.Pass()); | 184 delegate_->OnAccelerator(accelerator, event.Pass()); |
| 178 return; | 185 return; |
| 179 } | 186 } |
| 180 } | 187 } |
| 181 | 188 |
| 182 ServerWindow* target = FindEventTarget(event.get()); | 189 if (event->key_data) { |
| 183 bool in_nonclient_area = false; | 190 ProcessKeyEvent(event.Pass()); |
| 184 | 191 return; |
| 185 if (IsMouseEventFlag(event->flags)) { | |
| 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. | |
| 190 capture_window_ = target; | |
| 191 // TODO(sky): this needs to happen for pointer down events too. | |
| 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_; | |
| 200 } | 192 } |
| 201 | 193 |
| 202 if (target) { | 194 if (event->pointer_data.get()) { |
| 203 if (event->action == mojo::EVENT_TYPE_POINTER_DOWN) | 195 ProcessPointerEvent(event.Pass()); |
| 196 return; | |
| 197 } | |
| 198 | |
| 199 NOTREACHED(); | |
| 200 } | |
| 201 | |
| 202 void EventDispatcher::ProcessKeyEvent(mojo::EventPtr event) { | |
| 203 ServerWindow* focused_window = | |
| 204 delegate_->GetFocusedWindowForEventDispatcher(); | |
| 205 if (focused_window) | |
| 206 delegate_->DispatchInputEventToWindow(focused_window, false, event.Pass()); | |
| 207 } | |
| 208 | |
| 209 void EventDispatcher::ProcessPointerEvent(mojo::EventPtr event) { | |
| 210 const int32_t pointer_id = event->pointer_data->pointer_id; | |
| 211 if (event->action == mojo::EVENT_TYPE_WHEEL || | |
| 212 (event->action == mojo::EVENT_TYPE_POINTER_MOVE && | |
| 213 pointer_targets_.count(pointer_id) == 0)) { | |
| 214 PointerTarget pointer_target; | |
| 215 if (pointer_targets_.count(pointer_id) != 0) { | |
| 216 pointer_target = pointer_targets_[pointer_id]; | |
| 217 } else { | |
| 218 gfx::Point location(EventLocationToPoint(*event)); | |
| 219 pointer_target.window = | |
| 220 FindDeepestVisibleWindow(root_, surface_id_, &location); | |
| 221 } | |
| 222 DispatchToPointerTarget(pointer_target, event.Pass()); | |
| 223 return; | |
| 224 } | |
| 225 | |
| 226 // Pointer down implicitly captures. | |
| 227 if (pointer_targets_.count(pointer_id) == 0) { | |
| 228 DCHECK(event->action == mojo::EVENT_TYPE_POINTER_DOWN); | |
| 229 const bool is_first_pointer_down = pointer_targets_.empty(); | |
| 230 gfx::Point location(EventLocationToPoint(*event)); | |
| 231 ServerWindow* target = | |
| 232 FindDeepestVisibleWindow(root_, surface_id_, &location); | |
| 233 DCHECK(target); | |
| 234 if (!IsSendingPointerEventsToTarget(target)) | |
| 235 target->AddObserver(this); | |
| 236 | |
| 237 pointer_targets_[pointer_id].window = target; | |
| 238 pointer_targets_[pointer_id].in_nonclient_area = | |
| 239 IsLocationInNonclientArea(target, location); | |
| 240 | |
| 241 if (is_first_pointer_down) | |
| 204 delegate_->SetFocusedWindowFromEventDispatcher(target); | 242 delegate_->SetFocusedWindowFromEventDispatcher(target); |
| 243 } | |
| 205 | 244 |
| 206 delegate_->DispatchInputEventToWindow(target, in_nonclient_area, | 245 // Release capture on pointer up. For mouse we only release if there are |
| 207 event.Pass()); | 246 // no buttons down. |
| 247 const bool should_reset_target = | |
| 248 (event->action == mojo::EVENT_TYPE_POINTER_UP || | |
| 249 event->action == mojo::EVENT_TYPE_POINTER_CANCEL) && | |
| 250 (event->pointer_data->kind != mojo::POINTER_KIND_MOUSE || | |
| 251 IsOnlyOneMouseButtonDown(event->flags)); | |
| 252 | |
| 253 DispatchToPointerTarget(pointer_targets_[pointer_id], event.Pass()); | |
| 254 | |
| 255 if (should_reset_target) { | |
| 256 ServerWindow* target = pointer_targets_[pointer_id].window; | |
| 257 pointer_targets_.erase(pointer_id); | |
| 258 if (target && !IsSendingPointerEventsToTarget(target)) | |
| 259 target->RemoveObserver(this); | |
| 208 } | 260 } |
| 209 } | 261 } |
| 210 | 262 |
| 263 void EventDispatcher::DispatchToPointerTarget(const PointerTarget& target, | |
| 264 mojo::EventPtr event) { | |
| 265 if (!target.window) | |
| 266 return; | |
| 267 | |
| 268 gfx::Point location(EventLocationToPoint(*event)); | |
| 269 gfx::Transform transform(GetTransformToWindow(surface_id_, target.window)); | |
| 270 transform.TransformPoint(&location); | |
| 271 event->pointer_data->location->x = location.x(); | |
| 272 event->pointer_data->location->y = location.y(); | |
| 273 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area, | |
| 274 event.Pass()); | |
| 275 } | |
| 276 | |
| 277 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) { | |
| 278 window->RemoveObserver(this); | |
| 279 | |
| 280 for (auto& pair : pointer_targets_) { | |
| 281 if (pair.second.window == window) | |
| 282 pair.second.window = nullptr; | |
| 283 } | |
| 284 } | |
| 285 | |
| 286 bool EventDispatcher::IsSendingPointerEventsToTarget(ServerWindow* window) { | |
|
sadrul
2015/10/29 00:48:25
Would IsObservingWindow() better explain what this
sky
2015/10/29 14:54:16
Done.
| |
| 287 for (const auto& pair : pointer_targets_) { | |
| 288 if (pair.second.window == window) | |
| 289 return true; | |
| 290 } | |
| 291 return false; | |
| 292 } | |
| 293 | |
| 211 bool EventDispatcher::FindAccelerator(const mojo::Event& event, | 294 bool EventDispatcher::FindAccelerator(const mojo::Event& event, |
| 212 uint32_t* accelerator_id) { | 295 uint32_t* accelerator_id) { |
| 213 DCHECK(event.key_data); | 296 DCHECK(event.key_data); |
| 214 for (const auto& pair : accelerators_) { | 297 for (const auto& pair : accelerators_) { |
| 215 if (pair.second.MatchesEvent(event)) { | 298 if (pair.second.MatchesEvent(event)) { |
| 216 *accelerator_id = pair.first; | 299 *accelerator_id = pair.first; |
| 217 return true; | 300 return true; |
| 218 } | 301 } |
| 219 } | 302 } |
| 220 return false; | 303 return false; |
| 221 } | 304 } |
| 222 | 305 |
| 223 ServerWindow* EventDispatcher::FindEventTarget(mojo::Event* event) { | 306 void EventDispatcher::OnWillChangeWindowHierarchy(ServerWindow* window, |
| 224 ServerWindow* focused_window = | 307 ServerWindow* new_parent, |
| 225 delegate_->GetFocusedWindowForEventDispatcher(); | 308 ServerWindow* old_parent) { |
| 226 if (event->key_data) | 309 CancelPointerEventsToTarget(window); |
| 227 return focused_window; | 310 } |
| 228 | 311 |
| 229 DCHECK(event->pointer_data) << "Unknown event type: " << event->action; | 312 void EventDispatcher::OnWindowVisibilityChanged(ServerWindow* window) { |
| 230 mojo::LocationData* event_location = event->pointer_data->location.get(); | 313 CancelPointerEventsToTarget(window); |
| 231 DCHECK(event_location); | 314 } |
| 232 gfx::Point location(static_cast<int>(event_location->x), | |
| 233 static_cast<int>(event_location->y)); | |
| 234 | 315 |
| 235 ServerWindow* target = capture_window_; | 316 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { |
| 236 | 317 CancelPointerEventsToTarget(window); |
| 237 if (!target) { | |
| 238 target = FindDeepestVisibleWindow(root_, surface_id_, &location); | |
| 239 } else { | |
| 240 gfx::Transform transform(GetTransformToWindow(surface_id_, target)); | |
| 241 transform.TransformPoint(&location); | |
| 242 } | |
| 243 | |
| 244 event_location->x = location.x(); | |
| 245 event_location->y = location.y(); | |
| 246 | |
| 247 return target; | |
| 248 } | 318 } |
| 249 | 319 |
| 250 } // namespace ws | 320 } // namespace ws |
| 251 } // namespace mus | 321 } // namespace mus |
| OLD | NEW |