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

Unified Diff: components/mus/ws/event_dispatcher.cc

Issue 1759523002: mus: Server-side implementation of modal windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: More cleanup Created 4 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: components/mus/ws/event_dispatcher.cc
diff --git a/components/mus/ws/event_dispatcher.cc b/components/mus/ws/event_dispatcher.cc
index 71dea6063039e8877df57d356e8f2ba37b6b7f36..368567b2f9a091b58477d01ef74fa5f8cc3bc744 100644
--- a/components/mus/ws/event_dispatcher.cc
+++ b/components/mus/ws/event_dispatcher.cc
@@ -52,6 +52,23 @@ bool IsLocationInNonclientArea(const ServerWindow* target,
return true;
}
+ServerWindow* GetClosestModalTargetForWindow(ServerWindow* target) {
sky 2016/03/08 17:07:53 Add description as closest isn't clear in this con
mohsen 2016/03/09 08:26:48 Renamed to GetModalChildForWindowAncestor() (also
+ for (ServerWindow* window = target; window; window = window->parent()) {
+ for (const auto& transient_child : window->transient_children()) {
+ if (transient_child->is_modal() && transient_child->IsDrawn())
+ return transient_child;
+ }
+ }
+ return target;
+}
+
+ServerWindow* GetModalTargetForWindow(ServerWindow* target) {
+ ServerWindow* closest_target = GetClosestModalTargetForWindow(target);
+ if (closest_target == target)
+ return target;
+ return GetModalTargetForWindow(closest_target);
+}
+
} // namespace
class EventMatcher {
@@ -216,14 +233,18 @@ EventDispatcher::~EventDispatcher() {
pointer_targets_.clear();
}
-void EventDispatcher::SetCaptureWindow(ServerWindow* window,
+bool EventDispatcher::SetCaptureWindow(ServerWindow* window,
bool in_nonclient_area) {
if (window == capture_window_)
- return;
+ return true;
+
+ // A window that is blocked by a modal window cannot gain capture.
+ if (window && GetClosestModalTargetForWindow(window) != window)
+ return false;
if (capture_window_) {
// Stop observing old capture window. |pointer_targets_| are cleared on
- // intial setting of a capture window.
+ // initial setting of a capture window.
delegate_->OnServerWindowCaptureLost(capture_window_);
capture_window_->RemoveObserver(this);
} else {
@@ -245,7 +266,7 @@ void EventDispatcher::SetCaptureWindow(ServerWindow* window,
pair.second.is_mouse_event ? ui::EventPointerType::POINTER_TYPE_MOUSE
: ui::EventPointerType::POINTER_TYPE_TOUCH;
// TODO(jonross): Track previous location in PointerTarget for sending
- // cancels
+ // cancels.
ui::PointerEvent event(event_type, pointer_type, gfx::Point(),
gfx::Point(), ui::EF_NONE, pair.first,
ui::EventTimeForNow());
@@ -267,6 +288,7 @@ void EventDispatcher::SetCaptureWindow(ServerWindow* window,
capture_window_ = window;
capture_window_in_nonclient_area_ = in_nonclient_area;
+ return true;
}
void EventDispatcher::UpdateCursorProviderByLastKnownLocation() {
@@ -451,10 +473,12 @@ EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent(
const ui::PointerEvent& event) const {
PointerTarget pointer_target;
gfx::Point location(event.location());
- pointer_target.window =
+ ServerWindow* target_window =
FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
+ pointer_target.window = GetModalTargetForWindow(target_window);
pointer_target.is_mouse_event = event.IsMousePointerEvent();
pointer_target.in_nonclient_area =
+ target_window != pointer_target.window ||
IsLocationInNonclientArea(pointer_target.window, location);
pointer_target.is_pointer_down = event.type() == ui::ET_POINTER_DOWN;
return pointer_target;

Powered by Google App Engine
This is Rietveld 408576698