OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "components/mus/ws/modal_window_controller.h" | |
6 | |
7 #include "base/stl_util.h" | |
8 #include "components/mus/ws/event_dispatcher.h" | |
9 #include "components/mus/ws/server_window.h" | |
10 #include "components/mus/ws/server_window_drawn_tracker.h" | |
11 | |
12 namespace mus { | |
13 namespace ws { | |
14 namespace { | |
15 | |
16 const ServerWindow* GetModalChildForWindowAncestor(const ServerWindow* window) { | |
17 for (const ServerWindow* ancestor = window; ancestor; | |
18 ancestor = ancestor->parent()) { | |
19 for (const auto& transient_child : ancestor->transient_children()) { | |
20 if (transient_child->is_modal() && transient_child->IsDrawn()) | |
21 return transient_child; | |
22 } | |
23 } | |
24 return nullptr; | |
25 } | |
26 | |
27 const ServerWindow* GetWindowModalTargetForWindow(const ServerWindow* window) { | |
28 const ServerWindow* modal_window = GetModalChildForWindowAncestor(window); | |
29 if (!modal_window) | |
30 return window; | |
31 return GetWindowModalTargetForWindow(modal_window); | |
32 } | |
33 | |
34 } // namespace | |
35 | |
36 ModalWindowController::ModalWindowController(EventDispatcher* event_dispatcher) | |
37 : event_dispatcher_(event_dispatcher) {} | |
38 | |
39 ModalWindowController::~ModalWindowController() { | |
40 for (auto it = system_modal_windows_.begin(); | |
41 it != system_modal_windows_.end(); it++) { | |
42 (*it)->RemoveObserver(this); | |
43 } | |
44 } | |
45 | |
46 void ModalWindowController::AddSystemModalWindow(ServerWindow* window) { | |
47 DCHECK(window); | |
48 DCHECK(!ContainsValue(system_modal_windows_, window)); | |
49 | |
50 window->SetModal(); | |
51 system_modal_windows_.push_back(window); | |
52 window_drawn_trackers_.insert(make_pair( | |
53 window, base::WrapUnique(new ServerWindowDrawnTracker(window, this)))); | |
54 window->AddObserver(this); | |
55 | |
56 event_dispatcher_->ReleaseCaptureBlockedByModalWindow(window); | |
57 } | |
58 | |
59 bool ModalWindowController::IsWindowBlockedBy( | |
60 const ServerWindow* window, | |
61 const ServerWindow* modal_window) const { | |
62 DCHECK(window); | |
63 DCHECK(modal_window); | |
64 if (!modal_window->is_modal() || !modal_window->IsDrawn()) | |
65 return false; | |
66 | |
67 if (modal_window->transient_parent() && | |
68 !modal_window->transient_parent()->Contains(window)) { | |
69 return false; | |
70 } | |
71 | |
72 return true; | |
73 } | |
74 | |
75 bool ModalWindowController::IsWindowBlocked(const ServerWindow* window) const { | |
76 DCHECK(window); | |
77 return GetActiveSystemModalWindow() || GetModalChildForWindowAncestor(window); | |
78 } | |
79 | |
80 const ServerWindow* ModalWindowController::GetTargetForWindow( | |
81 const ServerWindow* window) const { | |
82 ServerWindow* system_modal_window = GetActiveSystemModalWindow(); | |
83 return system_modal_window ? system_modal_window | |
84 : GetWindowModalTargetForWindow(window); | |
85 } | |
86 | |
87 ServerWindow* ModalWindowController::GetActiveSystemModalWindow() const { | |
88 for (auto it = system_modal_windows_.rbegin(); | |
89 it != system_modal_windows_.rend(); it++) { | |
90 ServerWindow* modal = *it; | |
91 if (modal->IsDrawn()) | |
92 return modal; | |
93 } | |
94 return nullptr; | |
95 } | |
96 | |
97 void ModalWindowController::OnWindowDestroyed(ServerWindow* window) { | |
98 window->RemoveObserver(this); | |
99 auto it = std::find(system_modal_windows_.begin(), | |
100 system_modal_windows_.end(), window); | |
101 DCHECK(it != system_modal_windows_.end()); | |
102 system_modal_windows_.erase(it); | |
103 window_drawn_trackers_.erase(window); | |
104 } | |
105 | |
106 void ModalWindowController::OnDrawnStateChanged(ServerWindow* ancestor, | |
107 ServerWindow* window, | |
108 bool is_drawn) { | |
109 if (!is_drawn) | |
110 return; | |
111 | |
112 // Move the most recently shown window to the end of the list. | |
113 auto it = std::find(system_modal_windows_.begin(), | |
114 system_modal_windows_.end(), window); | |
115 DCHECK(it != system_modal_windows_.end()); | |
116 system_modal_windows_.splice(system_modal_windows_.end(), | |
117 system_modal_windows_, it); | |
118 } | |
119 | |
120 } // namespace ws | |
121 } // namespace mus | |
OLD | NEW |