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

Unified 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 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/mus/ws/event_dispatcher.cc
diff --git a/components/mus/ws/event_dispatcher.cc b/components/mus/ws/event_dispatcher.cc
index 69d7fa155ecaf903264d89c6736a20eb9dd75b5a..6e49d6630c7ea49b37a15902271d73e0db760382 100644
--- a/components/mus/ws/event_dispatcher.cc
+++ b/components/mus/ws/event_dispatcher.cc
@@ -4,8 +4,6 @@
#include "components/mus/ws/event_dispatcher.h"
-#include <set>
-
#include "base/time/time.h"
#include "cc/surfaces/surface_hittest.h"
#include "components/mus/surfaces/surfaces_state.h"
@@ -76,17 +74,18 @@ EventDispatcher::EventDispatcher(EventDispatcherDelegate* delegate)
mouse_cursor_source_window_(nullptr) {}
EventDispatcher::~EventDispatcher() {
- std::set<ServerWindow*> pointer_targets;
if (capture_window_) {
- pointer_targets.insert(capture_window_);
- capture_window_->RemoveObserver(this);
+ UnobserveWindow(capture_window_);
capture_window_ = nullptr;
}
+ for (auto it = system_modal_windows_.begin();
+ it != system_modal_windows_.end();) {
+ auto remove_it = it++;
+ RemoveSystemModalWindow(remove_it);
+ }
for (const auto& pair : pointer_targets_) {
- if (pair.second.window &&
- pointer_targets.insert(pair.second.window).second) {
- pair.second.window->RemoveObserver(this);
- }
+ if (pair.second.window)
+ UnobserveWindow(pair.second.window);
}
pointer_targets_.clear();
}
@@ -116,23 +115,23 @@ bool EventDispatcher::SetCaptureWindow(ServerWindow* window,
return true;
// A window that is blocked by a modal window cannot gain capture.
- if (window && window->IsBlockedByModalWindow())
+ if (window &&
+ (GetActiveSystemModalWindow() || window->IsBlockedByModalWindow())) {
return false;
+ }
if (capture_window_) {
// Stop observing old capture window. |pointer_targets_| are cleared on
// initial setting of a capture window.
delegate_->OnServerWindowCaptureLost(capture_window_);
- capture_window_->RemoveObserver(this);
+ UnobserveWindow(capture_window_);
} else {
// Cancel implicit capture to all other windows.
- std::set<ServerWindow*> unobserved_windows;
for (const auto& pair : pointer_targets_) {
ServerWindow* target = pair.second.window;
if (!target)
continue;
- if (unobserved_windows.insert(target).second)
- target->RemoveObserver(this);
+ UnobserveWindow(target);
if (target == window)
continue;
@@ -154,7 +153,7 @@ bool EventDispatcher::SetCaptureWindow(ServerWindow* window,
// Begin tracking the capture window if it is not yet being observed.
if (window) {
- window->AddObserver(this);
+ ObserveWindow(window);
if (!capture_window_)
delegate_->SetNativeCapture();
} else {
@@ -168,6 +167,45 @@ bool EventDispatcher::SetCaptureWindow(ServerWindow* window,
return true;
}
+void EventDispatcher::AddSystemModalWindow(ServerWindow* window) {
+ DCHECK(window);
+ DCHECK(std::find(system_modal_windows_.begin(), system_modal_windows_.end(),
+ window) == system_modal_windows_.end());
+
+ window->SetModal();
+ system_modal_windows_.push_front(window);
+ ObserveWindow(window);
sky 2016/04/25 23:36:08 It's confusing and error prone to have this class
mohsen 2016/04/26 20:24:05 I agree. Even before adding modal windows, it was
+
+ ReleaseCaptureBlockedByModalWindow(window);
+}
+
+void EventDispatcher::ReleaseCaptureBlockedByModalWindow(
+ const ServerWindow* modal_window) {
+ if (!capture_window_ || !modal_window->is_modal() ||
+ !modal_window->IsDrawn()) {
+ return;
+ }
+
+ if (modal_window->transient_parent() &&
+ !modal_window->transient_parent()->Contains(capture_window_)) {
+ return;
+ }
+
+ SetCaptureWindow(nullptr, false);
+}
+
+void EventDispatcher::ReleaseCaptureBlockedByAnyModalWindow() {
+ if (!capture_window_)
+ return;
+
+ if (!GetActiveSystemModalWindow() &&
+ !capture_window_->IsBlockedByModalWindow()) {
+ return;
+ }
+
+ SetCaptureWindow(nullptr, false);
+}
+
void EventDispatcher::UpdateCursorProviderByLastKnownLocation() {
if (!mouse_button_down_) {
gfx::Point location = mouse_pointer_last_location_;
@@ -311,8 +349,7 @@ void EventDispatcher::StartTrackingPointer(
int32_t pointer_id,
const PointerTarget& pointer_target) {
DCHECK(!IsTrackingPointer(pointer_id));
- if (!IsObservingWindow(pointer_target.window))
- pointer_target.window->AddObserver(this);
+ ObserveWindow(pointer_target.window);
pointer_targets_[pointer_id] = pointer_target;
}
@@ -320,8 +357,8 @@ void EventDispatcher::StopTrackingPointer(int32_t pointer_id) {
DCHECK(IsTrackingPointer(pointer_id));
ServerWindow* window = pointer_targets_[pointer_id].window;
pointer_targets_.erase(pointer_id);
- if (window && !IsObservingWindow(window))
- window->RemoveObserver(this);
+ if (window)
+ UnobserveWindow(window);
}
void EventDispatcher::UpdateTargetForPointer(int32_t pointer_id,
@@ -363,7 +400,9 @@ EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent(
gfx::Point location(event.location());
ServerWindow* target_window =
FindDeepestVisibleWindowForEvents(root_, surface_id_, &location);
- pointer_target.window = target_window->GetModalTarget();
+ ServerWindow* system_modal_window = GetActiveSystemModalWindow();
+ pointer_target.window = system_modal_window ? system_modal_window
+ : target_window->GetModalTarget();
pointer_target.is_mouse_event = event.IsMousePointerEvent();
pointer_target.in_nonclient_area =
target_window != pointer_target.window ||
@@ -399,9 +438,8 @@ void EventDispatcher::DispatchToPointerTarget(const PointerTarget& target,
}
void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) {
- window->RemoveObserver(this);
-
if (capture_window_ == window) {
+ UnobserveWindow(window);
capture_window_ = nullptr;
mouse_button_down_ = false;
// A window only cares to be informed that it lost capture if it explicitly
@@ -414,17 +452,29 @@ void EventDispatcher::CancelPointerEventsToTarget(ServerWindow* window) {
}
for (auto& pair : pointer_targets_) {
- if (pair.second.window == window)
+ if (pair.second.window == window) {
+ UnobserveWindow(window);
pair.second.window = nullptr;
+ }
}
}
-bool EventDispatcher::IsObservingWindow(ServerWindow* window) {
- for (const auto& pair : pointer_targets_) {
- if (pair.second.window == window)
- return true;
+void EventDispatcher::ObserveWindow(ServerWindow* window) {
+ auto res = observed_windows_.insert(std::make_pair(window, 0u));
+ res.first->second++;
+ if (res.second)
+ window->AddObserver(this);
+}
+
+void EventDispatcher::UnobserveWindow(ServerWindow* window) {
+ auto it = observed_windows_.find(window);
+ DCHECK(it != observed_windows_.end());
+ DCHECK_LT(0u, it->second);
+ it->second--;
+ if (!it->second) {
+ window->RemoveObserver(this);
+ observed_windows_.erase(it);
}
- return false;
}
Accelerator* EventDispatcher::FindAccelerator(
@@ -438,6 +488,20 @@ Accelerator* EventDispatcher::FindAccelerator(
return nullptr;
}
+ServerWindow* EventDispatcher::GetActiveSystemModalWindow() const {
+ for (auto modal : system_modal_windows_) {
+ if (modal->IsDrawn())
+ return modal;
+ }
+ return nullptr;
+}
+
+void EventDispatcher::RemoveSystemModalWindow(ServerWindowList::iterator it) {
+ DCHECK(it != system_modal_windows_.end());
+ UnobserveWindow(*it);
+ system_modal_windows_.erase(it);
+}
+
void EventDispatcher::OnWillChangeWindowHierarchy(ServerWindow* window,
ServerWindow* new_parent,
ServerWindow* old_parent) {
@@ -445,12 +509,29 @@ void EventDispatcher::OnWillChangeWindowHierarchy(ServerWindow* window,
}
void EventDispatcher::OnWindowVisibilityChanged(ServerWindow* window) {
+ if (window->is_modal() && window->IsDrawn()) {
+ auto it = std::find(system_modal_windows_.begin(),
+ system_modal_windows_.end(), window);
+ DCHECK(window->transient_parent() || it != system_modal_windows_.end());
+
+ if (it != system_modal_windows_.end()) {
+ system_modal_windows_.splice(system_modal_windows_.begin(),
+ system_modal_windows_, it);
+ }
+ return;
+ }
+
CancelPointerEventsToTarget(window);
}
void EventDispatcher::OnWindowDestroyed(ServerWindow* window) {
CancelPointerEventsToTarget(window);
+ auto it = std::find(system_modal_windows_.begin(),
+ system_modal_windows_.end(), window);
+ if (it != system_modal_windows_.end())
+ RemoveSystemModalWindow(it);
+
if (mouse_cursor_source_window_ == window)
mouse_cursor_source_window_ = nullptr;
}
« 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