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

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: Cleaned up comments Created 4 years, 8 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 system_modal_window_(nullptr),
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 }
82 if (system_modal_window_) {
83 UnobserveWindow(system_modal_window_);
84 system_modal_window_ = nullptr;
85 }
85 for (const auto& pair : pointer_targets_) { 86 for (const auto& pair : pointer_targets_) {
86 if (pair.second.window && 87 if (pair.second.window)
87 pointer_targets.insert(pair.second.window).second) { 88 UnobserveWindow(pair.second.window);
88 pair.second.window->RemoveObserver(this);
89 }
90 } 89 }
91 pointer_targets_.clear(); 90 pointer_targets_.clear();
92 } 91 }
93 92
94 void EventDispatcher::Reset() { 93 void EventDispatcher::Reset() {
95 if (capture_window_) { 94 if (capture_window_) {
96 CancelPointerEventsToTarget(capture_window_); 95 CancelPointerEventsToTarget(capture_window_);
97 DCHECK(capture_window_ == nullptr); 96 DCHECK(capture_window_ == nullptr);
98 } 97 }
99 98
100 while (!pointer_targets_.empty()) 99 while (!pointer_targets_.empty())
101 StopTrackingPointer(pointer_targets_.begin()->first); 100 StopTrackingPointer(pointer_targets_.begin()->first);
102 101
103 mouse_button_down_ = false; 102 mouse_button_down_ = false;
104 } 103 }
105 104
106 void EventDispatcher::SetMousePointerScreenLocation( 105 void EventDispatcher::SetMousePointerScreenLocation(
107 const gfx::Point& screen_location) { 106 const gfx::Point& screen_location) {
108 DCHECK(pointer_targets_.empty()); 107 DCHECK(pointer_targets_.empty());
109 mouse_pointer_last_location_ = screen_location; 108 mouse_pointer_last_location_ = screen_location;
110 UpdateCursorProviderByLastKnownLocation(); 109 UpdateCursorProviderByLastKnownLocation();
111 } 110 }
112 111
113 bool EventDispatcher::SetCaptureWindow(ServerWindow* window, 112 bool EventDispatcher::SetCaptureWindow(ServerWindow* window,
114 bool in_nonclient_area) { 113 bool in_nonclient_area) {
115 if (window == capture_window_) 114 if (window == capture_window_)
116 return true; 115 return true;
117 116
118 // 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.
119 if (window && window->IsBlockedByModalWindow()) 118 if (window && ((system_modal_window_ && system_modal_window_->IsDrawn()) ||
119 window->IsBlockedByModalWindow())) {
120 return false; 120 return false;
121 }
121 122
122 if (capture_window_) { 123 if (capture_window_) {
123 // Stop observing old capture window. |pointer_targets_| are cleared on 124 // Stop observing old capture window. |pointer_targets_| are cleared on
124 // initial setting of a capture window. 125 // initial setting of a capture window.
125 delegate_->OnServerWindowCaptureLost(capture_window_); 126 delegate_->OnServerWindowCaptureLost(capture_window_);
126 capture_window_->RemoveObserver(this); 127 UnobserveWindow(capture_window_);
127 } else { 128 } else {
128 // Cancel implicit capture to all other windows. 129 // Cancel implicit capture to all other windows.
129 std::set<ServerWindow*> unobserved_windows;
130 for (const auto& pair : pointer_targets_) { 130 for (const auto& pair : pointer_targets_) {
131 ServerWindow* target = pair.second.window; 131 ServerWindow* target = pair.second.window;
132 if (!target) 132 if (!target)
133 continue; 133 continue;
134 if (unobserved_windows.insert(target).second) 134 UnobserveWindow(target);
135 target->RemoveObserver(this);
136 if (target == window) 135 if (target == window)
137 continue; 136 continue;
138 137
139 ui::EventType event_type = pair.second.is_mouse_event 138 ui::EventType event_type = pair.second.is_mouse_event
140 ? ui::ET_POINTER_EXITED 139 ? ui::ET_POINTER_EXITED
141 : ui::ET_POINTER_CANCELLED; 140 : ui::ET_POINTER_CANCELLED;
142 ui::EventPointerType pointer_type = 141 ui::EventPointerType pointer_type =
143 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE 142 pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE
144 : ui::EventPointerType::POINTER_TYPE_TOUCH; 143 : ui::EventPointerType::POINTER_TYPE_TOUCH;
145 // TODO(jonross): Track previous location in PointerTarget for sending 144 // TODO(jonross): Track previous location in PointerTarget for sending
146 // cancels. 145 // cancels.
147 ui::PointerEvent event(event_type, pointer_type, gfx::Point(), 146 ui::PointerEvent event(event_type, pointer_type, gfx::Point(),
148 gfx::Point(), ui::EF_NONE, pair.first, 147 gfx::Point(), ui::EF_NONE, pair.first,
149 ui::EventTimeForNow()); 148 ui::EventTimeForNow());
150 DispatchToPointerTarget(pair.second, event); 149 DispatchToPointerTarget(pair.second, event);
151 } 150 }
152 pointer_targets_.clear(); 151 pointer_targets_.clear();
153 } 152 }
154 153
155 // Begin tracking the capture window if it is not yet being observed. 154 // Begin tracking the capture window if it is not yet being observed.
156 if (window) { 155 if (window) {
157 window->AddObserver(this); 156 ObserveWindow(window);
158 if (!capture_window_) 157 if (!capture_window_)
159 delegate_->SetNativeCapture(); 158 delegate_->SetNativeCapture();
160 } else { 159 } else {
161 delegate_->ReleaseNativeCapture(); 160 delegate_->ReleaseNativeCapture();
162 if (!mouse_button_down_) 161 if (!mouse_button_down_)
163 UpdateCursorProviderByLastKnownLocation(); 162 UpdateCursorProviderByLastKnownLocation();
164 } 163 }
165 164
166 capture_window_ = window; 165 capture_window_ = window;
167 capture_window_in_nonclient_area_ = in_nonclient_area; 166 capture_window_in_nonclient_area_ = in_nonclient_area;
168 return true; 167 return true;
169 } 168 }
170 169
170 bool EventDispatcher::SetSystemModalWindow(ServerWindow* window) {
171 DCHECK(window);
172
173 if (window == system_modal_window_)
174 return true;
175
176 if (system_modal_window_)
177 return false;
sky 2016/04/20 20:14:11 nit: spacing is off (run git cl format).
mohsen 2016/04/21 17:58:43 Done.
178
179 system_modal_window_ = window;
sky 2016/04/20 20:14:11 I think we should cancel capture here rather than
mohsen 2016/04/21 17:58:43 Done.
180 system_modal_window_->SetModal();
181 ObserveWindow(system_modal_window_);
182 return true;
183 }
184
171 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() { 185 void EventDispatcher::UpdateCursorProviderByLastKnownLocation() {
172 if (!mouse_button_down_) { 186 if (!mouse_button_down_) {
173 gfx::Point location = mouse_pointer_last_location_; 187 gfx::Point location = mouse_pointer_last_location_;
174 mouse_cursor_source_window_ = 188 mouse_cursor_source_window_ =
175 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); 189 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
176 } 190 }
177 } 191 }
178 192
179 bool EventDispatcher::AddAccelerator(uint32_t id, 193 bool EventDispatcher::AddAccelerator(uint32_t id,
180 mojom::EventMatcherPtr event_matcher) { 194 mojom::EventMatcherPtr event_matcher) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 StopTrackingPointer(pointer_id); 316 StopTrackingPointer(pointer_id);
303 if (!AreAnyPointersDown()) 317 if (!AreAnyPointersDown())
304 delegate_->ReleaseNativeCapture(); 318 delegate_->ReleaseNativeCapture();
305 } 319 }
306 } 320 }
307 321
308 void EventDispatcher::StartTrackingPointer( 322 void EventDispatcher::StartTrackingPointer(
309 int32_t pointer_id, 323 int32_t pointer_id,
310 const PointerTarget& pointer_target) { 324 const PointerTarget& pointer_target) {
311 DCHECK(!IsTrackingPointer(pointer_id)); 325 DCHECK(!IsTrackingPointer(pointer_id));
312 if (!IsObservingWindow(pointer_target.window)) 326 ObserveWindow(pointer_target.window);
313 pointer_target.window->AddObserver(this);
314 pointer_targets_[pointer_id] = pointer_target; 327 pointer_targets_[pointer_id] = pointer_target;
315 } 328 }
316 329
317 void EventDispatcher::StopTrackingPointer(int32_t pointer_id) { 330 void EventDispatcher::StopTrackingPointer(int32_t pointer_id) {
318 DCHECK(IsTrackingPointer(pointer_id)); 331 DCHECK(IsTrackingPointer(pointer_id));
319 ServerWindow* window = pointer_targets_[pointer_id].window; 332 ServerWindow* window = pointer_targets_[pointer_id].window;
320 pointer_targets_.erase(pointer_id); 333 pointer_targets_.erase(pointer_id);
321 if (window && !IsObservingWindow(window)) 334 if (window)
322 window->RemoveObserver(this); 335 UnobserveWindow(window);
323 } 336 }
324 337
325 void EventDispatcher::UpdateTargetForPointer(int32_t pointer_id, 338 void EventDispatcher::UpdateTargetForPointer(int32_t pointer_id,
326 const ui::LocatedEvent& event) { 339 const ui::LocatedEvent& event) {
327 if (!IsTrackingPointer(pointer_id)) { 340 if (!IsTrackingPointer(pointer_id)) {
328 StartTrackingPointer(pointer_id, PointerTargetForEvent(event)); 341 StartTrackingPointer(pointer_id, PointerTargetForEvent(event));
329 return; 342 return;
330 } 343 }
331 344
332 const PointerTarget pointer_target = PointerTargetForEvent(event); 345 const PointerTarget pointer_target = PointerTargetForEvent(event);
(...skipping 21 matching lines...) Expand all
354 StopTrackingPointer(pointer_id); 367 StopTrackingPointer(pointer_id);
355 StartTrackingPointer(pointer_id, pointer_target); 368 StartTrackingPointer(pointer_id, pointer_target);
356 } 369 }
357 370
358 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent( 371 EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent(
359 const ui::LocatedEvent& event) const { 372 const ui::LocatedEvent& event) const {
360 PointerTarget pointer_target; 373 PointerTarget pointer_target;
361 gfx::Point location(event.location()); 374 gfx::Point location(event.location());
362 ServerWindow* target_window = 375 ServerWindow* target_window =
363 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location); 376 FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
364 pointer_target.window = target_window->GetModalTarget(); 377 pointer_target.window =
378 system_modal_window_ && system_modal_window_->IsDrawn()
379 ? system_modal_window_
380 : target_window->GetModalTarget();
365 pointer_target.is_mouse_event = event.IsMousePointerEvent(); 381 pointer_target.is_mouse_event = event.IsMousePointerEvent();
366 pointer_target.in_nonclient_area = 382 pointer_target.in_nonclient_area =
367 target_window != pointer_target.window || 383 target_window != pointer_target.window ||
368 IsLocationInNonclientArea(pointer_target.window, location); 384 IsLocationInNonclientArea(pointer_target.window, location);
369 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN; 385 pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN;
370 return pointer_target; 386 return pointer_target;
371 } 387 }
372 388
373 bool EventDispatcher::AreAnyPointersDown() const { 389 bool EventDispatcher::AreAnyPointersDown() const {
374 for (const auto& pair : pointer_targets_) { 390 for (const auto& pair : pointer_targets_) {
(...skipping 13 matching lines...) Expand all
388 transform.TransformPoint(&location); 404 transform.TransformPoint(&location);
389 scoped_ptr<ui::Event> clone = ui::Event::Clone(event); 405 scoped_ptr<ui::Event> clone = ui::Event::Clone(event);
390 clone->AsLocatedEvent()->set_location(location); 406 clone->AsLocatedEvent()->set_location(location);
391 // TODO(jonross): add post-target accelerator support once accelerators 407 // TODO(jonross): add post-target accelerator support once accelerators
392 // support pointer events. 408 // support pointer events.
393 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area, 409 delegate_->DispatchInputEventToWindow(target.window, target.in_nonclient_area,
394 *clone, nullptr); 410 *clone, nullptr);
395 } 411 }
396 412
397 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) { 413 void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) {
398 window->RemoveObserver(this);
399
400 if (capture_window_ == window) { 414 if (capture_window_ == window) {
415 UnobserveWindow(window);
401 capture_window_ = nullptr; 416 capture_window_ = nullptr;
402 mouse_button_down_ = false; 417 mouse_button_down_ = false;
403 // A window only cares to be informed that it lost capture if it explicitly 418 // A window only cares to be informed that it lost capture if it explicitly
404 // requested capture. A window can lose capture if another window gains 419 // requested capture. A window can lose capture if another window gains
405 // explicit capture. 420 // explicit capture.
406 delegate_->OnServerWindowCaptureLost(window); 421 delegate_->OnServerWindowCaptureLost(window);
407 delegate_->ReleaseNativeCapture(); 422 delegate_->ReleaseNativeCapture();
408 UpdateCursorProviderByLastKnownLocation(); 423 UpdateCursorProviderByLastKnownLocation();
409 return; 424 return;
410 } 425 }
411 426
412 for (auto& pair : pointer_targets_) { 427 for (auto& pair : pointer_targets_) {
413 if (pair.second.window == window) 428 if (pair.second.window == window) {
429 UnobserveWindow(window);
414 pair.second.window = nullptr; 430 pair.second.window = nullptr;
431 }
415 } 432 }
416 } 433 }
417 434
418 bool EventDispatcher::IsObservingWindow(ServerWindow* window) { 435 void EventDispatcher::ObserveWindow(ServerWindow* window) {
419 for (const auto& pair : pointer_targets_) { 436 auto res = observed_windows_.insert(std::make_pair(window, 0u));
420 if (pair.second.window == window) 437 res.first->second++;
421 return true; 438 if (res.second)
439 window->AddObserver(this);
440 }
441
442 void EventDispatcher::UnobserveWindow(ServerWindow* window) {
443 auto it = observed_windows_.find(window);
444 DCHECK(it != observed_windows_.end());
445 DCHECK_LT(0u, it->second);
446 it->second--;
447 if (!it->second) {
448 window->RemoveObserver(this);
449 observed_windows_.erase(it);
422 } 450 }
423 return false;
424 } 451 }
425 452
426 Accelerator* EventDispatcher::FindAccelerator( 453 Accelerator* EventDispatcher::FindAccelerator(
427 const ui::KeyEvent& event, 454 const ui::KeyEvent& event,
428 const mojom::AcceleratorPhase phase) { 455 const mojom::AcceleratorPhase phase) {
429 for (const auto& pair : accelerators_) { 456 for (const auto& pair : accelerators_) {
430 if (pair.second->MatchesEvent(event, phase)) { 457 if (pair.second->MatchesEvent(event, phase)) {
431 return pair.second.get(); 458 return pair.second.get();
432 } 459 }
433 } 460 }
434 return nullptr; 461 return nullptr;
435 } 462 }
436 463
437 void EventDispatcher::OnWillChangeWindowHierarchy(ServerWindow* window, 464 void EventDispatcher::OnWillChangeWindowHierarchy(ServerWindow* window,
438 ServerWindow* new_parent, 465 ServerWindow* new_parent,
439 ServerWindow* old_parent) { 466 ServerWindow* old_parent) {
440 CancelPointerEventsToTarget(window); 467 CancelPointerEventsToTarget(window);
441 } 468 }
442 469
443 void EventDispatcher::OnWindowVisibilityChanged(ServerWindow* window) { 470 void EventDispatcher::OnWindowVisibilityChanged(ServerWindow* window) {
444 CancelPointerEventsToTarget(window); 471 CancelPointerEventsToTarget(window);
445 } 472 }
446 473
447 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) { 474 void EventDispatcher::OnWindowDestroyed(ServerWindow* window) {
448 CancelPointerEventsToTarget(window); 475 CancelPointerEventsToTarget(window);
449 476
477 if (system_modal_window_ == window) {
sky 2016/04/20 20:14:11 You have this in the destructor as well. Maybe Res
mohsen 2016/04/21 17:58:42 Done.
478 UnobserveWindow(window);
479 system_modal_window_ = nullptr;
480 }
481
450 if (mouse_cursor_source_window_ == window) 482 if (mouse_cursor_source_window_ == window)
451 mouse_cursor_source_window_ = nullptr; 483 mouse_cursor_source_window_ = nullptr;
452 } 484 }
453 485
454 } // namespace ws 486 } // namespace ws
455 } // namespace mus 487 } // namespace mus
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698