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

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: Rebased after fixing the crash 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
« no previous file with comments | « components/mus/ws/event_dispatcher.h ('k') | components/mus/ws/event_dispatcher_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
(...skipping 13 matching lines...) Expand all
113 // process any events in views during window construction. 108 // process any events in views during window construction.
114 delegate_->OnMouseCursorLocationChanged(screen_location); 109 delegate_->OnMouseCursorLocationChanged(screen_location);
115 } 110 }
116 111
117 bool EventDispatcher::SetCaptureWindow(ServerWindow* window, 112 bool EventDispatcher::SetCaptureWindow(ServerWindow* window,
118 bool in_nonclient_area) { 113 bool in_nonclient_area) {
119 if (window == capture_window_) 114 if (window == capture_window_)
120 return true; 115 return true;
121 116
122 // A window that is blocked by a modal window cannot gain capture. 117 // A window that is blocked by a modal window cannot gain capture.
123 if (window && window->IsBlockedByModalWindow()) 118 if (window && modal_window_controller_.IsWindowBlocked(window))
124 return false; 119 return false;
125 120
126 if (capture_window_) { 121 if (capture_window_) {
127 // Stop observing old capture window. |pointer_targets_| are cleared on 122 // Stop observing old capture window. |pointer_targets_| are cleared on
128 // initial setting of a capture window. 123 // initial setting of a capture window.
129 delegate_->OnServerWindowCaptureLost(capture_window_); 124 delegate_->OnServerWindowCaptureLost(capture_window_);
130 capture_window_->RemoveObserver(this); 125 UnobserveWindow(capture_window_);
131 } else { 126 } else {
132 // Cancel implicit capture to all other windows. 127 // Cancel implicit capture to all other windows.
133 std::set<ServerWindow*> unobserved_windows;
134 for (const auto& pair : pointer_targets_) { 128 for (const auto& pair : pointer_targets_) {
135 ServerWindow* target = pair.second.window; 129 ServerWindow* target = pair.second.window;
136 if (!target) 130 if (!target)
137 continue; 131 continue;
138 if (unobserved_windows.insert(target).second) 132 UnobserveWindow(target);
139 target->RemoveObserver(this);
140 if (target == window) 133 if (target == window)
141 continue; 134 continue;
142 135
143 ui::EventType event_type = pair.second.is_mouse_event 136 ui::EventType event_type = pair.second.is_mouse_event
144 ? ui::ET_POINTER_EXITED 137 ? ui::ET_POINTER_EXITED
145 : ui::ET_POINTER_CANCELLED; 138 : ui::ET_POINTER_CANCELLED;
146 ui::EventPointerType pointer_type = 139 ui::EventPointerType pointer_type =
147 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE 140 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE
148 : ui::EventPointerType::POINTER_TYPE_TOUCH; 141 : ui::EventPointerType::POINTER_TYPE_TOUCH;
149 // TODO(jonross): Track previous location in PointerTarget for sending 142 // TODO(jonross): Track previous location in PointerTarget for sending
150 // cancels. 143 // cancels.
151 ui::PointerEvent event(event_type, pointer_type, gfx::Point(), 144 ui::PointerEvent event(event_type, pointer_type, gfx::Point(),
152 gfx::Point(), ui::EF_NONE, pair.first, 145 gfx::Point(), ui::EF_NONE, pair.first,
153 ui::EventTimeForNow()); 146 ui::EventTimeForNow());
154 DispatchToPointerTarget(pair.second, event); 147 DispatchToPointerTarget(pair.second, event);
155 } 148 }
156 pointer_targets_.clear(); 149 pointer_targets_.clear();
157 } 150 }
158 151
159 // Set the capture before changing native capture; otherwise, the callback 152 // Set the capture before changing native capture; otherwise, the callback
160 // from native platform might try to set the capture again. 153 // from native platform might try to set the capture again.
161 bool had_capture_window = capture_window_ != nullptr; 154 bool had_capture_window = capture_window_ != nullptr;
162 capture_window_ = window; 155 capture_window_ = window;
163 capture_window_in_nonclient_area_ = in_nonclient_area; 156 capture_window_in_nonclient_area_ = in_nonclient_area;
164 157
165 // Begin tracking the capture window if it is not yet being observed. 158 // Begin tracking the capture window if it is not yet being observed.
166 if (window) { 159 if (window) {
167 window->AddObserver(this); 160 ObserveWindow(window);
168 if (!had_capture_window) 161 if (!had_capture_window)
169 delegate_->SetNativeCapture(); 162 delegate_->SetNativeCapture();
170 } else { 163 } else {
171 delegate_->ReleaseNativeCapture(); 164 delegate_->ReleaseNativeCapture();
172 if (!mouse_button_down_) 165 if (!mouse_button_down_)
173 UpdateCursorProviderByLastKnownLocation(); 166 UpdateCursorProviderByLastKnownLocation();
174 } 167 }
175 168
176 return true; 169 return true;
177 } 170 }
178 171
172 void EventDispatcher::AddSystemModalWindow(ServerWindow* window) {
173 modal_window_controller_.AddSystemModalWindow(window);
174 }
175
176 void EventDispatcher::ReleaseCaptureBlockedByModalWindow(
177 const ServerWindow* modal_window) {
178 if (!capture_window_)
179 return;
180
181 if (modal_window_controller_.IsWindowBlockedBy(capture_window_,
182 modal_window)) {
183 SetCaptureWindow(nullptr, false);
184 }
185 }
186
187 void EventDispatcher::ReleaseCaptureBlockedByAnyModalWindow() {
188 if (!capture_window_)
189 return;
190
191 if (modal_window_controller_.IsWindowBlocked(capture_window_))
192 SetCaptureWindow(nullptr, false);
193 }
194
179 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { 195 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() {
180 if (!mouse_button_down_) { 196 if (!mouse_button_down_) {
181 gfx::Point location = mouse_pointer_last_location_; 197 gfx::Point location = mouse_pointer_last_location_;
182 mouse_cursor_source_window_ = 198 mouse_cursor_source_window_ =
183 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); 199 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
184 } 200 }
185 } 201 }
186 202
187 bool EventDispatcher::AddAccelerator(uint32_t id, 203 bool EventDispatcher::AddAccelerator(uint32_t id,
188 mojom::EventMatcherPtr event_matcher) { 204 mojom::EventMatcherPtr event_matcher) {
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 StopTrackingPointer(pointer_id); 330 StopTrackingPointer(pointer_id);
315 if (!AreAnyPointersDown()) 331 if (!AreAnyPointersDown())
316 delegate_->ReleaseNativeCapture(); 332 delegate_->ReleaseNativeCapture();
317 } 333 }
318 } 334 }
319 335
320 void EventDispatcher::StartTrackingPointer( 336 void EventDispatcher::StartTrackingPointer(
321 int32_t pointer_id, 337 int32_t pointer_id,
322 const PointerTarget& pointer_target) { 338 const PointerTarget& pointer_target) {
323 DCHECK(!IsTrackingPointer(pointer_id)); 339 DCHECK(!IsTrackingPointer(pointer_id));
324 if (!IsObservingWindow(pointer_target.window)) 340 ObserveWindow(pointer_target.window);
325 pointer_target.window->AddObserver(this);
326 pointer_targets_[pointer_id] = pointer_target; 341 pointer_targets_[pointer_id] = pointer_target;
327 } 342 }
328 343
329 void EventDispatcher::StopTrackingPointer(int32_t pointer_id) { 344 void EventDispatcher::StopTrackingPointer(int32_t pointer_id) {
330 DCHECK(IsTrackingPointer(pointer_id)); 345 DCHECK(IsTrackingPointer(pointer_id));
331 ServerWindow* window = pointer_targets_[pointer_id].window; 346 ServerWindow* window = pointer_targets_[pointer_id].window;
332 pointer_targets_.erase(pointer_id); 347 pointer_targets_.erase(pointer_id);
333 if (window && !IsObservingWindow(window)) 348 if (window)
334 window->RemoveObserver(this); 349 UnobserveWindow(window);
335 } 350 }
336 351
337 void EventDispatcher::UpdateTargetForPointer(int32_t pointer_id, 352 void EventDispatcher::UpdateTargetForPointer(int32_t pointer_id,
338 const ui::LocatedEvent& event) { 353 const ui::LocatedEvent& event) {
339 if (!IsTrackingPointer(pointer_id)) { 354 if (!IsTrackingPointer(pointer_id)) {
340 StartTrackingPointer(pointer_id, PointerTargetForEvent(event)); 355 StartTrackingPointer(pointer_id, PointerTargetForEvent(event));
341 return; 356 return;
342 } 357 }
343 358
344 const PointerTarget pointer_target = PointerTargetForEvent(event); 359 const PointerTarget pointer_target = PointerTargetForEvent(event);
(...skipping 21 matching lines...) Expand all
366 StopTrackingPointer(pointer_id); 381 StopTrackingPointer(pointer_id);
367 StartTrackingPointer(pointer_id, pointer_target); 382 StartTrackingPointer(pointer_id, pointer_target);
368 } 383 }
369 384
370 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent( 385 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent(
371 const ui::LocatedEvent& event) const { 386 const ui::LocatedEvent& event) const {
372 PointerTarget pointer_target; 387 PointerTarget pointer_target;
373 gfx::Point location(event.location()); 388 gfx::Point location(event.location());
374 ServerWindow* target_window = 389 ServerWindow* target_window =
375 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); 390 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
376 pointer_target.window = target_window->GetModalTarget(); 391 pointer_target.window =
392 modal_window_controller_.GetTargetForWindow(target_window);
377 pointer_target.is_mouse_event = event.IsMousePointerEvent(); 393 pointer_target.is_mouse_event = event.IsMousePointerEvent();
378 pointer_target.in_nonclient_area = 394 pointer_target.in_nonclient_area =
379 target_window != pointer_target.window || 395 target_window != pointer_target.window ||
380 IsLocationInNonclientArea(pointer_target.window, location); 396 IsLocationInNonclientArea(pointer_target.window, location);
381 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; 397 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN;
382 return pointer_target; 398 return pointer_target;
383 } 399 }
384 400
385 bool EventDispatcher::AreAnyPointersDown() const { 401 bool EventDispatcher::AreAnyPointersDown() const {
386 for (const auto& pair : pointer_targets_) { 402 for (const auto& pair : pointer_targets_) {
(...skipping 15 matching lines...) Expand all
402 transform.TransformPoint(&location); 418 transform.TransformPoint(&location);
403 std::unique_ptr<ui::Event> clone = ui::Event::Clone(event); 419 std::unique_ptr<ui::Event> clone = ui::Event::Clone(event);
404 clone->AsLocatedEvent()->set_location(location); 420 clone->AsLocatedEvent()->set_location(location);
405 // TODO(jonross): add post-target accelerator support once accelerators 421 // TODO(jonross): add post-target accelerator support once accelerators
406 // support pointer events. 422 // support pointer events.
407 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area, 423 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area,
408 *clone, nullptr); 424 *clone, nullptr);
409 } 425 }
410 426
411 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) { 427 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) {
412 window->RemoveObserver(this);
413
414 if (capture_window_ == window) { 428 if (capture_window_ == window) {
429 UnobserveWindow(window);
415 capture_window_ = nullptr; 430 capture_window_ = nullptr;
416 mouse_button_down_ = false; 431 mouse_button_down_ = false;
417 // A window only cares to be informed that it lost capture if it explicitly 432 // A window only cares to be informed that it lost capture if it explicitly
418 // requested capture. A window can lose capture if another window gains 433 // requested capture. A window can lose capture if another window gains
419 // explicit capture. 434 // explicit capture.
420 delegate_->OnServerWindowCaptureLost(window); 435 delegate_->OnServerWindowCaptureLost(window);
421 delegate_->ReleaseNativeCapture(); 436 delegate_->ReleaseNativeCapture();
422 UpdateCursorProviderByLastKnownLocation(); 437 UpdateCursorProviderByLastKnownLocation();
423 return; 438 return;
424 } 439 }
425 440
426 for (auto& pair : pointer_targets_) { 441 for (auto& pair : pointer_targets_) {
427 if (pair.second.window == window) 442 if (pair.second.window == window) {
443 UnobserveWindow(window);
428 pair.second.window = nullptr; 444 pair.second.window = nullptr;
445 }
429 } 446 }
430 } 447 }
431 448
432 bool EventDispatcher::IsObservingWindow(ServerWindow* window) { 449 void EventDispatcher::ObserveWindow(ServerWindow* window) {
433 for (const auto& pair : pointer_targets_) { 450 auto res = observed_windows_.insert(std::make_pair(window, 0u));
434 if (pair.second.window == window) 451 res.first->second++;
435 return true; 452 if (res.second)
453 window->AddObserver(this);
454 }
455
456 void EventDispatcher::UnobserveWindow(ServerWindow* window) {
457 auto it = observed_windows_.find(window);
458 DCHECK(it != observed_windows_.end());
459 DCHECK_LT(0u, it->second);
460 it->second--;
461 if (!it->second) {
462 window->RemoveObserver(this);
463 observed_windows_.erase(it);
436 } 464 }
437 return false;
438 } 465 }
439 466
440 Accelerator* EventDispatcher::FindAccelerator( 467 Accelerator* EventDispatcher::FindAccelerator(
441 const ui::KeyEvent& event, 468 const ui::KeyEvent& event,
442 const mojom::AcceleratorPhase phase) { 469 const mojom::AcceleratorPhase phase) {
443 for (const auto& pair : accelerators_) { 470 for (const auto& pair : accelerators_) {
444 if (pair.second->MatchesEvent(event, phase)) { 471 if (pair.second->MatchesEvent(event, phase)) {
445 return pair.second.get(); 472 return pair.second.get();
446 } 473 }
447 } 474 }
(...skipping 12 matching lines...) Expand all
460 487
461 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { 488 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) {
462 CancelPointerEventsToTarget(window); 489 CancelPointerEventsToTarget(window);
463 490
464 if (mouse_cursor_source_window_ == window) 491 if (mouse_cursor_source_window_ == window)
465 mouse_cursor_source_window_ = nullptr; 492 mouse_cursor_source_window_ = nullptr;
466 } 493 }
467 494
468 } // namespace ws 495 } // namespace ws
469 } // namespace mus 496 } // namespace mus
OLDNEW
« no previous file with comments | « components/mus/ws/event_dispatcher.h ('k') | components/mus/ws/event_dispatcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698