Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Side by Side Diff: components/mus/ws/event_dispatcher.cc

Issue 1818333002: Reland: mus: Enable system modal windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed review comments Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
9 #include "base/time/time.h" 7 #include "base/time/time.h"
10 #include "cc/surfaces/surface_hittest.h" 8 #include "cc/surfaces/surface_hittest.h"
11 #include "components/mus/surfaces/surfaces_state.h" 9 #include "components/mus/surfaces/surfaces_state.h"
12 #include "components/mus/ws/accelerator.h" 10 #include "components/mus/ws/accelerator.h"
13 #include "components/mus/ws/display.h" 11 #include "components/mus/ws/display.h"
14 #include "components/mus/ws/event_dispatcher_delegate.h" 12 #include "components/mus/ws/event_dispatcher_delegate.h"
15 #include "components/mus/ws/server_window.h" 13 #include "components/mus/ws/server_window.h"
16 #include "components/mus/ws/server_window_delegate.h" 14 #include "components/mus/ws/server_window_delegate.h"
17 #include "components/mus/ws/window_coordinate_conversions.h" 15 #include "components/mus/ws/window_coordinate_conversions.h"
18 #include "components/mus/ws/window_finder.h" 16 #include "components/mus/ws/window_finder.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 63
66 } // namespace 64 } // namespace
67 65
68 //////////////////////////////////////////////////////////////////////////////// 66 ////////////////////////////////////////////////////////////////////////////////
69 67
70 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate) 68 EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate)
71 : delegate_(delegate), 69 : delegate_(delegate),
72 root_(nullptr), 70 root_(nullptr),
73 capture_window_(nullptr), 71 capture_window_(nullptr),
74 capture_window_in_nonclient_area_(false), 72 capture_window_in_nonclient_area_(false),
73 modal_window_controller_(this),
75 mouse_button_down_(false), 74 mouse_button_down_(false),
76 mouse_cursor_source_window_(nullptr) {} 75 mouse_cursor_source_window_(nullptr) {}
77 76
78 EventDispatcher::~EventDispatcher() { 77 EventDispatcher::~EventDispatcher() {
79 std::set<ServerWindow*> pointer_targets;
80 if (capture_window_) { 78 if (capture_window_) {
81 pointer_targets.insert(capture_window_); 79 UnobserveWindow(capture_window_);
82 capture_window_->RemoveObserver(this);
83 capture_window_ = nullptr; 80 capture_window_ = nullptr;
84 } 81 }
85 for (const auto& pair : pointer_targets_) { 82 for (const auto& pair : pointer_targets_) {
86 if (pair.second.window && 83 if (pair.second.window)
87 pointer_targets.insert(pair.second.window).second) { 84 UnobserveWindow(pair.second.window);
88 pair.second.window->RemoveObserver(this);
89 }
90 } 85 }
91 pointer_targets_.clear(); 86 pointer_targets_.clear();
92 } 87 }
93 88
94 void EventDispatcher::Reset() { 89 void EventDispatcher::Reset() {
95 if (capture_window_) { 90 if (capture_window_) {
96 CancelPointerEventsToTarget(capture_window_); 91 CancelPointerEventsToTarget(capture_window_);
97 DCHECK(capture_window_ == nullptr); 92 DCHECK(capture_window_ == nullptr);
98 } 93 }
99 94
100 while (!pointer_targets_.empty()) 95 while (!pointer_targets_.empty())
101 StopTrackingPointer(pointer_targets_.begin()->first); 96 StopTrackingPointer(pointer_targets_.begin()->first);
102 97
103 mouse_button_down_ = false; 98 mouse_button_down_ = false;
104 } 99 }
105 100
106 void EventDispatcher::SetMousePointerScreenLocation( 101 void EventDispatcher::SetMousePointerScreenLocation(
107 const gfx::Point& screen_location) { 102 const gfx::Point& screen_location) {
108 DCHECK(pointer_targets_.empty()); 103 DCHECK(pointer_targets_.empty());
109 mouse_pointer_last_location_ = screen_location; 104 mouse_pointer_last_location_ = screen_location;
110 UpdateCursorProviderByLastKnownLocation(); 105 UpdateCursorProviderByLastKnownLocation();
111 } 106 }
112 107
113 bool EventDispatcher::SetCaptureWindow(ServerWindow* window, 108 bool EventDispatcher::SetCaptureWindow(ServerWindow* window,
114 bool in_nonclient_area) { 109 bool in_nonclient_area) {
115 if (window == capture_window_) 110 if (window == capture_window_)
116 return true; 111 return true;
117 112
118 // A window that is blocked by a modal window cannot gain capture. 113 // A window that is blocked by a modal window cannot gain capture.
119 if (window && window->IsBlockedByModalWindow()) 114 if (window && modal_window_controller_.IsWindowBlocked(window))
120 return false; 115 return false;
121 116
122 if (capture_window_) { 117 if (capture_window_) {
123 // Stop observing old capture window. |pointer_targets_| are cleared on 118 // Stop observing old capture window. |pointer_targets_| are cleared on
124 // initial setting of a capture window. 119 // initial setting of a capture window.
125 delegate_->OnServerWindowCaptureLost(capture_window_); 120 delegate_->OnServerWindowCaptureLost(capture_window_);
126 capture_window_->RemoveObserver(this); 121 UnobserveWindow(capture_window_);
127 } else { 122 } else {
128 // Cancel implicit capture to all other windows. 123 // Cancel implicit capture to all other windows.
129 std::set<ServerWindow*> unobserved_windows;
130 for (const auto& pair : pointer_targets_) { 124 for (const auto& pair : pointer_targets_) {
131 ServerWindow* target = pair.second.window; 125 ServerWindow* target = pair.second.window;
132 if (!target) 126 if (!target)
133 continue; 127 continue;
134 if (unobserved_windows.insert(target).second) 128 UnobserveWindow(target);
135 target->RemoveObserver(this);
136 if (target == window) 129 if (target == window)
137 continue; 130 continue;
138 131
139 ui::EventType event_type = pair.second.is_mouse_event 132 ui::EventType event_type = pair.second.is_mouse_event
140 ? ui::ET_POINTER_EXITED 133 ? ui::ET_POINTER_EXITED
141 : ui::ET_POINTER_CANCELLED; 134 : ui::ET_POINTER_CANCELLED;
142 ui::EventPointerType pointer_type = 135 ui::EventPointerType pointer_type =
143 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE 136 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE
144 : ui::EventPointerType::POINTER_TYPE_TOUCH; 137 : ui::EventPointerType::POINTER_TYPE_TOUCH;
145 // TODO(jonross): Track previous location in PointerTarget for sending 138 // TODO(jonross): Track previous location in PointerTarget for sending
146 // cancels. 139 // cancels.
147 ui::PointerEvent event(event_type, pointer_type, gfx::Point(), 140 ui::PointerEvent event(event_type, pointer_type, gfx::Point(),
148 gfx::Point(), ui::EF_NONE, pair.first, 141 gfx::Point(), ui::EF_NONE, pair.first,
149 ui::EventTimeForNow()); 142 ui::EventTimeForNow());
150 DispatchToPointerTarget(pair.second, event); 143 DispatchToPointerTarget(pair.second, event);
151 } 144 }
152 pointer_targets_.clear(); 145 pointer_targets_.clear();
153 } 146 }
154 147
155 // Begin tracking the capture window if it is not yet being observed. 148 // Begin tracking the capture window if it is not yet being observed.
156 if (window) { 149 if (window) {
157 window->AddObserver(this); 150 ObserveWindow(window);
158 if (!capture_window_) 151 if (!capture_window_)
159 delegate_->SetNativeCapture(); 152 delegate_->SetNativeCapture();
160 } else { 153 } else {
161 delegate_->ReleaseNativeCapture(); 154 delegate_->ReleaseNativeCapture();
162 if (!mouse_button_down_) 155 if (!mouse_button_down_)
163 UpdateCursorProviderByLastKnownLocation(); 156 UpdateCursorProviderByLastKnownLocation();
164 } 157 }
165 158
166 capture_window_ = window; 159 capture_window_ = window;
167 capture_window_in_nonclient_area_ = in_nonclient_area; 160 capture_window_in_nonclient_area_ = in_nonclient_area;
168 return true; 161 return true;
169 } 162 }
170 163
164 void EventDispatcher::AddSystemModalWindow(ServerWindow* window) {
165 modal_window_controller_.AddSystemModalWindow(window);
166 }
167
168 void EventDispatcher::ReleaseCaptureBlockedByModalWindow(
169 const ServerWindow* modal_window) {
170 if (!capture_window_)
171 return;
172
173 if (modal_window_controller_.IsWindowBlockedBy(capture_window_,
174 modal_window)) {
175 SetCaptureWindow(nullptr, false);
176 }
177 }
178
179 void EventDispatcher::ReleaseCaptureBlockedByAnyModalWindow() {
180 if (!capture_window_)
181 return;
182
183 if (modal_window_controller_.IsWindowBlocked(capture_window_))
184 SetCaptureWindow(nullptr, false);
185 }
186
171 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { 187 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() {
172 if (!mouse_button_down_) { 188 if (!mouse_button_down_) {
173 gfx::Point location = mouse_pointer_last_location_; 189 gfx::Point location = mouse_pointer_last_location_;
174 mouse_cursor_source_window_ = 190 mouse_cursor_source_window_ =
175 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); 191 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
176 } 192 }
177 } 193 }
178 194
179 bool EventDispatcher::AddAccelerator(uint32_t id, 195 bool EventDispatcher::AddAccelerator(uint32_t id,
180 mojom::EventMatcherPtr event_matcher) { 196 mojom::EventMatcherPtr event_matcher) {
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 StopTrackingPointer(pointer_id); 320 StopTrackingPointer(pointer_id);
305 if (!AreAnyPointersDown()) 321 if (!AreAnyPointersDown())
306 delegate_->ReleaseNativeCapture(); 322 delegate_->ReleaseNativeCapture();
307 } 323 }
308 } 324 }
309 325
310 void EventDispatcher::StartTrackingPointer( 326 void EventDispatcher::StartTrackingPointer(
311 int32_t pointer_id, 327 int32_t pointer_id,
312 const PointerTarget& pointer_target) { 328 const PointerTarget& pointer_target) {
313 DCHECK(!IsTrackingPointer(pointer_id)); 329 DCHECK(!IsTrackingPointer(pointer_id));
314 if (!IsObservingWindow(pointer_target.window)) 330 ObserveWindow(pointer_target.window);
315 pointer_target.window->AddObserver(this);
316 pointer_targets_[pointer_id] = pointer_target; 331 pointer_targets_[pointer_id] = pointer_target;
317 } 332 }
318 333
319 void EventDispatcher::StopTrackingPointer(int32_t pointer_id) { 334 void EventDispatcher::StopTrackingPointer(int32_t pointer_id) {
320 DCHECK(IsTrackingPointer(pointer_id)); 335 DCHECK(IsTrackingPointer(pointer_id));
321 ServerWindow* window = pointer_targets_[pointer_id].window; 336 ServerWindow* window = pointer_targets_[pointer_id].window;
322 pointer_targets_.erase(pointer_id); 337 pointer_targets_.erase(pointer_id);
323 if (window && !IsObservingWindow(window)) 338 if (window)
324 window->RemoveObserver(this); 339 UnobserveWindow(window);
325 } 340 }
326 341
327 void EventDispatcher::UpdateTargetForPointer(int32_t pointer_id, 342 void EventDispatcher::UpdateTargetForPointer(int32_t pointer_id,
328 const ui::LocatedEvent& event) { 343 const ui::LocatedEvent& event) {
329 if (!IsTrackingPointer(pointer_id)) { 344 if (!IsTrackingPointer(pointer_id)) {
330 StartTrackingPointer(pointer_id, PointerTargetForEvent(event)); 345 StartTrackingPointer(pointer_id, PointerTargetForEvent(event));
331 return; 346 return;
332 } 347 }
333 348
334 const PointerTarget pointer_target = PointerTargetForEvent(event); 349 const PointerTarget pointer_target = PointerTargetForEvent(event);
(...skipping 21 matching lines...) Expand all
356 StopTrackingPointer(pointer_id); 371 StopTrackingPointer(pointer_id);
357 StartTrackingPointer(pointer_id, pointer_target); 372 StartTrackingPointer(pointer_id, pointer_target);
358 } 373 }
359 374
360 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent( 375 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent(
361 const ui::LocatedEvent& event) const { 376 const ui::LocatedEvent& event) const {
362 PointerTarget pointer_target; 377 PointerTarget pointer_target;
363 gfx::Point location(event.location()); 378 gfx::Point location(event.location());
364 ServerWindow* target_window = 379 ServerWindow* target_window =
365 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); 380 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
366 pointer_target.window = target_window->GetModalTarget(); 381 pointer_target.window =
382 modal_window_controller_.GetTargetForWindow(target_window);
367 pointer_target.is_mouse_event = event.IsMousePointerEvent(); 383 pointer_target.is_mouse_event = event.IsMousePointerEvent();
368 pointer_target.in_nonclient_area = 384 pointer_target.in_nonclient_area =
369 target_window != pointer_target.window || 385 target_window != pointer_target.window ||
370 IsLocationInNonclientArea(pointer_target.window, location); 386 IsLocationInNonclientArea(pointer_target.window, location);
371 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; 387 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN;
372 return pointer_target; 388 return pointer_target;
373 } 389 }
374 390
375 bool EventDispatcher::AreAnyPointersDown() const { 391 bool EventDispatcher::AreAnyPointersDown() const {
376 for (const auto& pair : pointer_targets_) { 392 for (const auto& pair : pointer_targets_) {
(...skipping 15 matching lines...) Expand all
392 transform.TransformPoint(&location); 408 transform.TransformPoint(&location);
393 std::unique_ptr<ui::Event> clone = ui::Event::Clone(event); 409 std::unique_ptr<ui::Event> clone = ui::Event::Clone(event);
394 clone->AsLocatedEvent()->set_location(location); 410 clone->AsLocatedEvent()->set_location(location);
395 // TODO(jonross): add post-target accelerator support once accelerators 411 // TODO(jonross): add post-target accelerator support once accelerators
396 // support pointer events. 412 // support pointer events.
397 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area, 413 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area,
398 *clone, nullptr); 414 *clone, nullptr);
399 } 415 }
400 416
401 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) { 417 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) {
402 window->RemoveObserver(this);
403
404 if (capture_window_ == window) { 418 if (capture_window_ == window) {
419 UnobserveWindow(window);
405 capture_window_ = nullptr; 420 capture_window_ = nullptr;
406 mouse_button_down_ = false; 421 mouse_button_down_ = false;
407 // A window only cares to be informed that it lost capture if it explicitly 422 // A window only cares to be informed that it lost capture if it explicitly
408 // requested capture. A window can lose capture if another window gains 423 // requested capture. A window can lose capture if another window gains
409 // explicit capture. 424 // explicit capture.
410 delegate_->OnServerWindowCaptureLost(window); 425 delegate_->OnServerWindowCaptureLost(window);
411 delegate_->ReleaseNativeCapture(); 426 delegate_->ReleaseNativeCapture();
412 UpdateCursorProviderByLastKnownLocation(); 427 UpdateCursorProviderByLastKnownLocation();
413 return; 428 return;
414 } 429 }
415 430
416 for (auto& pair : pointer_targets_) { 431 for (auto& pair : pointer_targets_) {
417 if (pair.second.window == window) 432 if (pair.second.window == window) {
433 UnobserveWindow(window);
418 pair.second.window = nullptr; 434 pair.second.window = nullptr;
435 }
419 } 436 }
420 } 437 }
421 438
422 bool EventDispatcher::IsObservingWindow(ServerWindow* window) { 439 void EventDispatcher::ObserveWindow(ServerWindow* window) {
423 for (const auto& pair : pointer_targets_) { 440 auto res = observed_windows_.insert(std::make_pair(window, 0u));
424 if (pair.second.window == window) 441 res.first->second++;
425 return true; 442 if (res.second)
443 window->AddObserver(this);
444 }
445
446 void EventDispatcher::UnobserveWindow(ServerWindow* window) {
447 auto it = observed_windows_.find(window);
448 DCHECK(it != observed_windows_.end());
449 DCHECK_LT(0u, it->second);
450 it->second--;
451 if (!it->second) {
452 window->RemoveObserver(this);
453 observed_windows_.erase(it);
426 } 454 }
427 return false;
428 } 455 }
429 456
430 Accelerator* EventDispatcher::FindAccelerator( 457 Accelerator* EventDispatcher::FindAccelerator(
431 const ui::KeyEvent& event, 458 const ui::KeyEvent& event,
432 const mojom::AcceleratorPhase phase) { 459 const mojom::AcceleratorPhase phase) {
433 for (const auto& pair : accelerators_) { 460 for (const auto& pair : accelerators_) {
434 if (pair.second->MatchesEvent(event, phase)) { 461 if (pair.second->MatchesEvent(event, phase)) {
435 return pair.second.get(); 462 return pair.second.get();
436 } 463 }
437 } 464 }
(...skipping 12 matching lines...) Expand all
450 477
451 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { 478 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) {
452 CancelPointerEventsToTarget(window); 479 CancelPointerEventsToTarget(window);
453 480
454 if (mouse_cursor_source_window_ == window) 481 if (mouse_cursor_source_window_ == window)
455 mouse_cursor_source_window_ = nullptr; 482 mouse_cursor_source_window_ = nullptr;
456 } 483 }
457 484
458 } // namespace ws 485 } // namespace ws
459 } // namespace mus 486 } // namespace mus
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698