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

Side by Side Diff: ash/common/wm/window_state.cc

Issue 2734653002: chromeos: Move files in //ash/common to //ash (Closed)
Patch Set: fix a11y tests, fix docs Created 3 years, 9 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
« no previous file with comments | « ash/common/wm/window_state.h ('k') | ash/common/wm/window_state_delegate.h » ('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/common/wm/window_state.h"
6
7 #include <utility>
8
9 #include "ash/common/wm/default_state.h"
10 #include "ash/common/wm/window_positioning_utils.h"
11 #include "ash/common/wm/window_state_delegate.h"
12 #include "ash/common/wm/window_state_observer.h"
13 #include "ash/common/wm/wm_event.h"
14 #include "ash/common/wm/wm_screen_util.h"
15 #include "ash/common/wm_window.h"
16 #include "base/auto_reset.h"
17
18 namespace ash {
19 namespace wm {
20
21 namespace {
22
23 WMEventType WMEventTypeFromShowState(ui::WindowShowState requested_show_state) {
24 switch (requested_show_state) {
25 case ui::SHOW_STATE_DEFAULT:
26 case ui::SHOW_STATE_NORMAL:
27 return WM_EVENT_NORMAL;
28 case ui::SHOW_STATE_MINIMIZED:
29 return WM_EVENT_MINIMIZE;
30 case ui::SHOW_STATE_MAXIMIZED:
31 return WM_EVENT_MAXIMIZE;
32 case ui::SHOW_STATE_FULLSCREEN:
33 return WM_EVENT_FULLSCREEN;
34 case ui::SHOW_STATE_INACTIVE:
35 return WM_EVENT_SHOW_INACTIVE;
36
37 // TODO(afakhry): Remove Docked Windows in M58.
38 case ui::SHOW_STATE_DOCKED:
39 return WM_EVENT_DOCK;
40 case ui::SHOW_STATE_END:
41 NOTREACHED() << "No WMEvent defined for the show state:"
42 << requested_show_state;
43 }
44 return WM_EVENT_NORMAL;
45 }
46
47 } // namespace
48
49 WindowState::~WindowState() {}
50
51 bool WindowState::HasDelegate() const {
52 return !!delegate_;
53 }
54
55 void WindowState::SetDelegate(std::unique_ptr<WindowStateDelegate> delegate) {
56 DCHECK(!delegate_.get());
57 delegate_ = std::move(delegate);
58 }
59
60 WindowStateType WindowState::GetStateType() const {
61 return current_state_->GetType();
62 }
63
64 bool WindowState::IsMinimized() const {
65 return GetStateType() == WINDOW_STATE_TYPE_MINIMIZED ||
66 GetStateType() == WINDOW_STATE_TYPE_DOCKED_MINIMIZED;
67 }
68
69 bool WindowState::IsMaximized() const {
70 return GetStateType() == WINDOW_STATE_TYPE_MAXIMIZED;
71 }
72
73 bool WindowState::IsFullscreen() const {
74 return GetStateType() == WINDOW_STATE_TYPE_FULLSCREEN;
75 }
76
77 bool WindowState::IsMaximizedOrFullscreenOrPinned() const {
78 return GetStateType() == WINDOW_STATE_TYPE_MAXIMIZED ||
79 GetStateType() == WINDOW_STATE_TYPE_FULLSCREEN || IsPinned();
80 }
81
82 bool WindowState::IsSnapped() const {
83 return GetStateType() == WINDOW_STATE_TYPE_LEFT_SNAPPED ||
84 GetStateType() == WINDOW_STATE_TYPE_RIGHT_SNAPPED;
85 }
86
87 bool WindowState::IsPinned() const {
88 return GetStateType() == WINDOW_STATE_TYPE_PINNED ||
89 GetStateType() == WINDOW_STATE_TYPE_TRUSTED_PINNED;
90 }
91
92 bool WindowState::IsTrustedPinned() const {
93 return GetStateType() == WINDOW_STATE_TYPE_TRUSTED_PINNED;
94 }
95
96 bool WindowState::IsNormalStateType() const {
97 return GetStateType() == WINDOW_STATE_TYPE_NORMAL ||
98 GetStateType() == WINDOW_STATE_TYPE_DEFAULT;
99 }
100
101 bool WindowState::IsNormalOrSnapped() const {
102 return IsNormalStateType() || IsSnapped();
103 }
104
105 bool WindowState::IsActive() const {
106 return window_->IsActive();
107 }
108
109 bool WindowState::IsDocked() const {
110 return GetStateType() == WINDOW_STATE_TYPE_DOCKED ||
111 GetStateType() == WINDOW_STATE_TYPE_DOCKED_MINIMIZED;
112 }
113
114 bool WindowState::IsUserPositionable() const {
115 return (window_->GetType() == ui::wm::WINDOW_TYPE_NORMAL ||
116 window_->GetType() == ui::wm::WINDOW_TYPE_PANEL);
117 }
118
119 bool WindowState::CanMaximize() const {
120 // Window must allow maximization and have no maximum width or height.
121 if (!window_->CanMaximize())
122 return false;
123
124 if (!window_->HasNonClientArea())
125 return true;
126
127 gfx::Size max_size = window_->GetMaximumSize();
128 return !max_size.width() && !max_size.height();
129 }
130
131 bool WindowState::CanMinimize() const {
132 return window_->CanMinimize();
133 }
134
135 bool WindowState::CanResize() const {
136 return window_->CanResize();
137 }
138
139 bool WindowState::CanActivate() const {
140 return window_->CanActivate();
141 }
142
143 bool WindowState::CanSnap() const {
144 if (!CanResize() || window_->GetType() == ui::wm::WINDOW_TYPE_PANEL ||
145 window_->GetTransientParent()) {
146 return false;
147 }
148 // If a window cannot be maximized, assume it cannot snap either.
149 // TODO(oshima): We should probably snap if the maximum size is greater than
150 // the snapped size.
151 return CanMaximize();
152 }
153
154 bool WindowState::HasRestoreBounds() const {
155 return window_->HasRestoreBounds();
156 }
157
158 void WindowState::Maximize() {
159 window_->Maximize();
160 }
161
162 void WindowState::Minimize() {
163 window_->Minimize();
164 }
165
166 void WindowState::Unminimize() {
167 window_->Unminimize();
168 }
169
170 void WindowState::Activate() {
171 window_->Activate();
172 }
173
174 void WindowState::Deactivate() {
175 window_->Deactivate();
176 }
177
178 void WindowState::Restore() {
179 if (!IsNormalStateType()) {
180 const WMEvent event(WM_EVENT_NORMAL);
181 OnWMEvent(&event);
182 }
183 }
184
185 void WindowState::DisableAlwaysOnTop(WmWindow* window_on_top) {
186 if (GetAlwaysOnTop()) {
187 // |window_| is hidden first to avoid canceling fullscreen mode when it is
188 // no longer always on top and gets added to default container. This avoids
189 // sending redundant OnFullscreenStateChanged to the layout manager. The
190 // |window_| visibility is restored after it no longer obscures the
191 // |window_on_top|.
192 bool visible = window_->IsVisible();
193 if (visible)
194 window_->Hide();
195 window_->SetAlwaysOnTop(false);
196 // Technically it is possible that a |window_| could make itself
197 // always_on_top really quickly. This is probably not a realistic case but
198 // check if the two windows are in the same container just in case.
199 if (window_on_top && window_on_top->GetParent() == window_->GetParent())
200 window_->GetParent()->StackChildAbove(window_on_top, window_);
201 if (visible)
202 window_->Show();
203 cached_always_on_top_ = true;
204 }
205 }
206
207 void WindowState::RestoreAlwaysOnTop() {
208 if (delegate() && delegate()->RestoreAlwaysOnTop(this))
209 return;
210 if (cached_always_on_top_) {
211 cached_always_on_top_ = false;
212 window_->SetAlwaysOnTop(true);
213 }
214 }
215
216 void WindowState::OnWMEvent(const WMEvent* event) {
217 current_state_->OnWMEvent(this, event);
218 }
219
220 void WindowState::SaveCurrentBoundsForRestore() {
221 gfx::Rect bounds_in_screen =
222 window_->GetParent()->ConvertRectToScreen(window_->GetBounds());
223 SetRestoreBoundsInScreen(bounds_in_screen);
224 }
225
226 gfx::Rect WindowState::GetRestoreBoundsInScreen() const {
227 return window_->GetRestoreBoundsInScreen();
228 }
229
230 gfx::Rect WindowState::GetRestoreBoundsInParent() const {
231 return window_->GetParent()->ConvertRectFromScreen(
232 GetRestoreBoundsInScreen());
233 }
234
235 void WindowState::SetRestoreBoundsInScreen(const gfx::Rect& bounds) {
236 window_->SetRestoreBoundsInScreen(bounds);
237 }
238
239 void WindowState::SetRestoreBoundsInParent(const gfx::Rect& bounds) {
240 SetRestoreBoundsInScreen(window_->GetParent()->ConvertRectToScreen(bounds));
241 }
242
243 void WindowState::ClearRestoreBounds() {
244 window_->ClearRestoreBounds();
245 }
246
247 std::unique_ptr<WindowState::State> WindowState::SetStateObject(
248 std::unique_ptr<WindowState::State> new_state) {
249 current_state_->DetachState(this);
250 std::unique_ptr<WindowState::State> old_object = std::move(current_state_);
251 current_state_ = std::move(new_state);
252 current_state_->AttachState(this, old_object.get());
253 return old_object;
254 }
255
256 void WindowState::SetPreAutoManageWindowBounds(const gfx::Rect& bounds) {
257 pre_auto_manage_window_bounds_.reset(new gfx::Rect(bounds));
258 }
259
260 void WindowState::AddObserver(WindowStateObserver* observer) {
261 observer_list_.AddObserver(observer);
262 }
263
264 void WindowState::RemoveObserver(WindowStateObserver* observer) {
265 observer_list_.RemoveObserver(observer);
266 }
267
268 void WindowState::set_bounds_changed_by_user(bool bounds_changed_by_user) {
269 bounds_changed_by_user_ = bounds_changed_by_user;
270 if (bounds_changed_by_user)
271 pre_auto_manage_window_bounds_.reset();
272 }
273
274 void WindowState::CreateDragDetails(const gfx::Point& point_in_parent,
275 int window_component,
276 aura::client::WindowMoveSource source) {
277 drag_details_.reset(
278 new DragDetails(window_, point_in_parent, window_component, source));
279 }
280
281 void WindowState::DeleteDragDetails() {
282 drag_details_.reset();
283 }
284
285 void WindowState::SetAndClearRestoreBounds() {
286 DCHECK(HasRestoreBounds());
287 SetBoundsInScreen(GetRestoreBoundsInScreen());
288 ClearRestoreBounds();
289 }
290
291 void WindowState::OnWindowShowStateChanged() {
292 if (!ignore_property_change_) {
293 WMEvent event(WMEventTypeFromShowState(GetShowState()));
294 OnWMEvent(&event);
295 }
296 }
297
298 WindowState::WindowState(WmWindow* window)
299 : window_(window),
300 window_position_managed_(false),
301 bounds_changed_by_user_(false),
302 ignored_by_shelf_(false),
303 can_consume_system_keys_(false),
304 unminimize_to_restore_bounds_(false),
305 in_immersive_fullscreen_(false),
306 hide_shelf_when_fullscreen_(true),
307 minimum_visibility_(false),
308 can_be_dragged_(true),
309 cached_always_on_top_(false),
310 ignore_property_change_(false),
311 current_state_(new DefaultState(ToWindowStateType(GetShowState()))) {}
312
313 bool WindowState::GetAlwaysOnTop() const {
314 return window_->IsAlwaysOnTop();
315 }
316
317 ui::WindowShowState WindowState::GetShowState() const {
318 return window_->GetShowState();
319 }
320
321 void WindowState::SetBoundsInScreen(const gfx::Rect& bounds_in_screen) {
322 gfx::Rect bounds_in_parent =
323 window_->GetParent()->ConvertRectFromScreen(bounds_in_screen);
324 window_->SetBounds(bounds_in_parent);
325 }
326
327 void WindowState::AdjustSnappedBounds(gfx::Rect* bounds) {
328 if (is_dragged() || !IsSnapped())
329 return;
330 gfx::Rect maximized_bounds = GetMaximizedWindowBoundsInParent(window_);
331 if (GetStateType() == WINDOW_STATE_TYPE_LEFT_SNAPPED)
332 bounds->set_x(maximized_bounds.x());
333 else if (GetStateType() == WINDOW_STATE_TYPE_RIGHT_SNAPPED)
334 bounds->set_x(maximized_bounds.right() - bounds->width());
335 bounds->set_y(maximized_bounds.y());
336 bounds->set_height(maximized_bounds.height());
337 }
338
339 void WindowState::UpdateWindowShowStateFromStateType() {
340 ui::WindowShowState new_window_state =
341 ToWindowShowState(current_state_->GetType());
342 if (new_window_state != GetShowState()) {
343 base::AutoReset<bool> resetter(&ignore_property_change_, true);
344 window_->SetShowState(new_window_state);
345 }
346 }
347
348 void WindowState::NotifyPreStateTypeChange(
349 WindowStateType old_window_state_type) {
350 for (auto& observer : observer_list_)
351 observer.OnPreWindowStateTypeChange(this, old_window_state_type);
352 }
353
354 void WindowState::NotifyPostStateTypeChange(
355 WindowStateType old_window_state_type) {
356 for (auto& observer : observer_list_)
357 observer.OnPostWindowStateTypeChange(this, old_window_state_type);
358 }
359
360 void WindowState::SetBoundsDirect(const gfx::Rect& bounds) {
361 gfx::Rect actual_new_bounds(bounds);
362 // Ensure we don't go smaller than our minimum bounds in "normal" window
363 // modes
364 if (window_->HasNonClientArea() && !IsMaximized() && !IsFullscreen()) {
365 // Get the minimum usable size of the minimum size and the screen size.
366 gfx::Size min_size = window_->GetMinimumSize();
367 min_size.SetToMin(window_->GetDisplayNearestWindow().work_area().size());
368
369 actual_new_bounds.set_width(
370 std::max(min_size.width(), actual_new_bounds.width()));
371 actual_new_bounds.set_height(
372 std::max(min_size.height(), actual_new_bounds.height()));
373 }
374 window_->SetBoundsDirect(actual_new_bounds);
375 }
376
377 void WindowState::SetBoundsConstrained(const gfx::Rect& bounds) {
378 gfx::Rect work_area_in_parent = GetDisplayWorkAreaBoundsInParent(window_);
379 gfx::Rect child_bounds(bounds);
380 AdjustBoundsSmallerThan(work_area_in_parent.size(), &child_bounds);
381 SetBoundsDirect(child_bounds);
382 }
383
384 void WindowState::SetBoundsDirectAnimated(const gfx::Rect& bounds) {
385 window_->SetBoundsDirectAnimated(bounds);
386 }
387
388 void WindowState::SetBoundsDirectCrossFade(const gfx::Rect& new_bounds) {
389 // Some test results in invoking CrossFadeToBounds when window is not visible.
390 // No animation is necessary in that case, thus just change the bounds and
391 // quit.
392 if (!window_->GetTargetVisibility()) {
393 SetBoundsConstrained(new_bounds);
394 return;
395 }
396
397 window_->SetBoundsDirectCrossFade(new_bounds);
398 }
399
400 } // namespace wm
401 } // namespace ash
OLDNEW
« no previous file with comments | « ash/common/wm/window_state.h ('k') | ash/common/wm/window_state_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698