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

Unified Diff: components/mus/ws/modal_window_controller.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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/mus/ws/modal_window_controller.h ('k') | components/mus/ws/server_window.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/mus/ws/modal_window_controller.cc
diff --git a/components/mus/ws/modal_window_controller.cc b/components/mus/ws/modal_window_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..89ec02e37207a52ab8aa194bfd78a035cb4fd6d1
--- /dev/null
+++ b/components/mus/ws/modal_window_controller.cc
@@ -0,0 +1,121 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/mus/ws/modal_window_controller.h"
+
+#include "base/stl_util.h"
+#include "components/mus/ws/event_dispatcher.h"
+#include "components/mus/ws/server_window.h"
+#include "components/mus/ws/server_window_drawn_tracker.h"
+
+namespace mus {
+namespace ws {
+namespace {
+
+const ServerWindow* GetModalChildForWindowAncestor(const ServerWindow* window) {
+ for (const ServerWindow* ancestor = window; ancestor;
+ ancestor = ancestor->parent()) {
+ for (const auto& transient_child : ancestor->transient_children()) {
+ if (transient_child->is_modal() && transient_child->IsDrawn())
+ return transient_child;
+ }
+ }
+ return nullptr;
+}
+
+const ServerWindow* GetWindowModalTargetForWindow(const ServerWindow* window) {
+ const ServerWindow* modal_window = GetModalChildForWindowAncestor(window);
+ if (!modal_window)
+ return window;
+ return GetWindowModalTargetForWindow(modal_window);
+}
+
+} // namespace
+
+ModalWindowController::ModalWindowController(EventDispatcher* event_dispatcher)
+ : event_dispatcher_(event_dispatcher) {}
+
+ModalWindowController::~ModalWindowController() {
+ for (auto it = system_modal_windows_.begin();
+ it != system_modal_windows_.end(); it++) {
+ (*it)->RemoveObserver(this);
+ }
+}
+
+void ModalWindowController::AddSystemModalWindow(ServerWindow* window) {
+ DCHECK(window);
+ DCHECK(!ContainsValue(system_modal_windows_, window));
+
+ window->SetModal();
+ system_modal_windows_.push_back(window);
+ window_drawn_trackers_.insert(make_pair(
+ window, base::WrapUnique(new ServerWindowDrawnTracker(window, this))));
+ window->AddObserver(this);
+
+ event_dispatcher_->ReleaseCaptureBlockedByModalWindow(window);
+}
+
+bool ModalWindowController::IsWindowBlockedBy(
+ const ServerWindow* window,
+ const ServerWindow* modal_window) const {
+ DCHECK(window);
+ DCHECK(modal_window);
+ if (!modal_window->is_modal() || !modal_window->IsDrawn())
+ return false;
+
+ if (modal_window->transient_parent() &&
+ !modal_window->transient_parent()->Contains(window)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool ModalWindowController::IsWindowBlocked(const ServerWindow* window) const {
+ DCHECK(window);
+ return GetActiveSystemModalWindow() || GetModalChildForWindowAncestor(window);
+}
+
+const ServerWindow* ModalWindowController::GetTargetForWindow(
+ const ServerWindow* window) const {
+ ServerWindow* system_modal_window = GetActiveSystemModalWindow();
+ return system_modal_window ? system_modal_window
+ : GetWindowModalTargetForWindow(window);
+}
+
+ServerWindow* ModalWindowController::GetActiveSystemModalWindow() const {
+ for (auto it = system_modal_windows_.rbegin();
+ it != system_modal_windows_.rend(); it++) {
+ ServerWindow* modal = *it;
+ if (modal->IsDrawn())
+ return modal;
+ }
+ return nullptr;
+}
+
+void ModalWindowController::OnWindowDestroyed(ServerWindow* window) {
+ window->RemoveObserver(this);
+ auto it = std::find(system_modal_windows_.begin(),
+ system_modal_windows_.end(), window);
+ DCHECK(it != system_modal_windows_.end());
+ system_modal_windows_.erase(it);
+ window_drawn_trackers_.erase(window);
+}
+
+void ModalWindowController::OnDrawnStateChanged(ServerWindow* ancestor,
+ ServerWindow* window,
+ bool is_drawn) {
+ if (!is_drawn)
+ return;
+
+ // Move the most recently shown window to the end of the list.
+ auto it = std::find(system_modal_windows_.begin(),
+ system_modal_windows_.end(), window);
+ DCHECK(it != system_modal_windows_.end());
+ system_modal_windows_.splice(system_modal_windows_.end(),
+ system_modal_windows_, it);
+}
+
+} // namespace ws
+} // namespace mus
« no previous file with comments | « components/mus/ws/modal_window_controller.h ('k') | components/mus/ws/server_window.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698