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..4c46dbb178a8d3949630154d46793efec2de0617 |
--- /dev/null |
+++ b/components/mus/ws/modal_window_controller.cc |
@@ -0,0 +1,119 @@ |
+// 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 "components/mus/ws/event_dispatcher.h" |
+#include "components/mus/ws/server_window.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();) { |
+ auto remove_it = it++; |
+ RemoveSystemModalWindow(remove_it); |
+ } |
+} |
+ |
+void ModalWindowController::AddSystemModalWindow(ServerWindow* window) { |
+ DCHECK(window); |
+ DCHECK(std::find(system_modal_windows_.begin(), system_modal_windows_.end(), |
sky
2016/04/26 23:40:08
!ContainsValue (in stl_util).
mohsen
2016/04/27 20:18:25
Done.
|
+ window) == system_modal_windows_.end()); |
+ |
+ window->SetModal(); |
+ system_modal_windows_.push_front(window); |
+ 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 modal : system_modal_windows_) { |
+ if (modal->IsDrawn()) |
+ return modal; |
+ } |
+ return nullptr; |
+} |
+ |
+void ModalWindowController::RemoveSystemModalWindow( |
+ ServerWindowList::iterator it) { |
+ DCHECK(it != system_modal_windows_.end()); |
+ (*it)->RemoveObserver(this); |
+ system_modal_windows_.erase(it); |
+} |
+ |
+void ModalWindowController::OnWindowVisibilityChanged(ServerWindow* window) { |
+ if (!window->IsDrawn()) |
sky
2016/04/26 23:40:08
You need to use a ServerWindowDrawnTracker as OnWi
mohsen
2016/04/27 20:18:25
Done. I've used similar approach in WindowServer t
|
+ return; |
+ |
+ 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_.begin(), |
sky
2016/04/26 23:40:08
Don't you need to tell EventDispatcher when the mo
mohsen
2016/04/27 20:18:25
This is already handled in WindowServer, for all (
|
+ system_modal_windows_, it); |
+} |
+ |
+void ModalWindowController::OnWindowDestroyed(ServerWindow* window) { |
+ auto it = std::find(system_modal_windows_.begin(), |
+ system_modal_windows_.end(), window); |
+ DCHECK(it != system_modal_windows_.end()); |
+ RemoveSystemModalWindow(it); |
+} |
+ |
+} // namespace ws |
+} // namespace mus |