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

Side by Side Diff: ash/wm/solo_window_tracker.cc

Issue 123023002: Remove "solo window" feature (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ash/wm/solo_window_tracker.h ('k') | ash/wm/solo_window_tracker_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 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 "ash/wm/solo_window_tracker.h"
6
7 #include <algorithm>
8
9 #include "ash/ash_constants.h"
10 #include "ash/root_window_controller.h"
11 #include "ash/shell.h"
12 #include "ash/shell_window_ids.h"
13 #include "ash/wm/window_state.h"
14 #include "ash/wm/window_state_observer.h"
15 #include "ui/aura/client/aura_constants.h"
16 #include "ui/aura/root_window.h"
17 #include "ui/aura/window.h"
18
19 namespace ash {
20
21 namespace {
22
23 // A flag to enable/disable the solo window header across all root windows.
24 bool g_solo_header_enabled = true;
25
26 // Returns the containers from which a solo window is chosen.
27 std::vector<aura::Window*> GetContainers(aura::RootWindow* root_window) {
28 int kContainerIds[] = {
29 internal::kShellWindowId_DefaultContainer,
30 internal::kShellWindowId_AlwaysOnTopContainer,
31 // Docked windows never use the solo header, but regular windows move to the
32 // docked container when dragged.
33 internal::kShellWindowId_DockedContainer,
34 };
35 std::vector<aura::Window*> containers;
36 for (size_t i = 0; i < arraysize(kContainerIds); ++i) {
37 containers.push_back(
38 Shell::GetContainer(root_window->window(), kContainerIds[i]));
39 }
40 return containers;
41 }
42
43 // Returns true if |child| and all of its ancestors are visible and neither
44 // |child| nor any its ancestors is animating hidden.
45 bool GetTargetVisibility(aura::Window* child) {
46 for (aura::Window* window = child; window; window = window->parent()) {
47 if (!window->TargetVisibility())
48 return false;
49 }
50 return true;
51 }
52
53 // Returns true if |window| can use the solo window header. Returns false for
54 // windows that are:
55 // * Not drawn (for example, DragDropTracker uses one for mouse capture)
56 // * Modal alerts (it looks odd for headers to change when an alert opens)
57 // * Constrained windows (ditto)
58 bool IsValidCandidate(aura::Window* window) {
59 return window->type() == ui::wm::WINDOW_TYPE_NORMAL && window->layer() &&
60 window->layer()->type() != ui::LAYER_NOT_DRAWN &&
61 window->GetProperty(aura::client::kModalKey) == ui::MODAL_TYPE_NONE &&
62 !window->GetProperty(aura::client::kConstrainedWindowKey);
63 }
64
65 // Schedule's a paint of the window's entire bounds.
66 void SchedulePaint(aura::Window* window) {
67 window->SchedulePaintInRect(gfx::Rect(window->bounds().size()));
68 }
69
70 } // namespace
71
72
73 // Class which triggers a repaint of the window which is passed to the
74 // constructor whenever the window's show type changes. The window's non client
75 // view is responsible for updating whether it uses the solo header as part of
76 // the repaint by querying GetWindowWithSoloHeader().
77 class SoloWindowTracker::SoloWindowObserver
78 : public ash::wm::WindowStateObserver {
79 public:
80 explicit SoloWindowObserver(aura::Window* window) : window_(window) {
81 wm::GetWindowState(window_)->AddObserver(this);
82 }
83
84 virtual ~SoloWindowObserver() {
85 wm::GetWindowState(window_)->RemoveObserver(this);
86 }
87
88 private:
89 // ash::wm::WindowStateObserver override.
90 virtual void OnWindowShowTypeChanged(
91 ash::wm::WindowState* window_state,
92 ash::wm::WindowShowType old_type) OVERRIDE {
93 SchedulePaint(window_);
94 }
95
96 aura::Window* window_;
97
98 DISALLOW_COPY_AND_ASSIGN(SoloWindowObserver);
99 };
100
101 SoloWindowTracker::SoloWindowTracker(aura::RootWindow* root_window)
102 : containers_(GetContainers(root_window)),
103 solo_window_(NULL) {
104 for (size_t i = 0; i < containers_.size(); ++i)
105 containers_[i]->AddObserver(this);
106 }
107
108 SoloWindowTracker::~SoloWindowTracker() {
109 for (size_t i = 0; i < containers_.size(); ++i)
110 containers_[i]->RemoveObserver(this);
111 }
112
113 // static
114 void SoloWindowTracker::SetSoloHeaderEnabled(bool enabled) {
115 g_solo_header_enabled = enabled;
116 std::vector<aura::Window*> root_windows =
117 Shell::GetInstance()->GetAllRootWindows();
118 for (size_t i = 0; i < root_windows.size(); ++i) {
119 SoloWindowTracker* tracker =
120 internal::GetRootWindowController(root_windows[i])->
121 solo_window_tracker();
122 if (tracker)
123 tracker->UpdateSoloWindow(NULL);
124 }
125 }
126
127 aura::Window* SoloWindowTracker::GetWindowWithSoloHeader() {
128 bool use_solo_header = solo_window_ &&
129 !wm::GetWindowState(solo_window_)->IsMaximizedOrFullscreen();
130 return use_solo_header ? solo_window_ : NULL;
131 }
132
133 void SoloWindowTracker::UpdateSoloWindow(aura::Window* ignore_window) {
134 std::vector<aura::Window*> candidates;
135 // Avoid memory allocations for typical window counts.
136 candidates.reserve(16);
137 for (size_t i = 0; i < containers_.size(); ++i) {
138 candidates.insert(candidates.end(),
139 containers_[i]->children().begin(),
140 containers_[i]->children().end());
141 }
142
143 aura::Window* old_solo_window = solo_window_;
144 solo_window_ = NULL;
145 if (g_solo_header_enabled && !AnyVisibleWindowDocked()) {
146 for (size_t i = 0; i < candidates.size(); ++i) {
147 aura::Window* candidate = candidates[i];
148 // Various sorts of windows "don't count" for this computation.
149 if (candidate == ignore_window ||
150 !IsValidCandidate(candidate) ||
151 !GetTargetVisibility(candidate)) {
152 continue;
153 }
154
155 if (solo_window_) {
156 // A window can only use the solo header if it is the only visible valid
157 // candidate (and there are no visible docked windows).
158 solo_window_ = NULL;
159 break;
160 } else {
161 solo_window_ = candidate;
162 }
163 }
164 }
165
166 if (solo_window_ == old_solo_window)
167 return;
168
169 solo_window_observer_.reset(solo_window_ ?
170 new SoloWindowObserver(solo_window_) : NULL);
171 if (old_solo_window)
172 SchedulePaint(old_solo_window);
173 if (solo_window_)
174 SchedulePaint(solo_window_);
175 }
176
177 bool SoloWindowTracker::AnyVisibleWindowDocked() const {
178 // For the purpose of SoloWindowTracker, there is a visible docked window if
179 // it causes the dock to have non-empty bounds. This is intentionally
180 // different from:
181 // DockedWindowLayoutManager::IsAnyWindowDocked() and
182 // DockedWindowLayoutManager::is_dragged_window_docked().
183 return !dock_bounds_.IsEmpty();
184 }
185
186 void SoloWindowTracker::OnWindowAdded(aura::Window* new_window) {
187 UpdateSoloWindow(NULL);
188 }
189
190 void SoloWindowTracker::OnWillRemoveWindow(aura::Window* window) {
191 UpdateSoloWindow(window);
192 }
193
194 void SoloWindowTracker::OnWindowVisibilityChanged(aura::Window* window,
195 bool visible) {
196 // |window| may be a grandchild of |containers_|.
197 std::vector<aura::Window*>::const_iterator it = std::find(
198 containers_.begin(), containers_.end(), window->parent());
199 if (it != containers_.end())
200 UpdateSoloWindow(NULL);
201 }
202
203 void SoloWindowTracker::OnDockBoundsChanging(const gfx::Rect& new_bounds,
204 Reason reason) {
205 dock_bounds_ = new_bounds;
206 UpdateSoloWindow(NULL);
207 }
208
209 } // namespace ash
OLDNEW
« no previous file with comments | « ash/wm/solo_window_tracker.h ('k') | ash/wm/solo_window_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698