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

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

Issue 149303003: [Refactor] Move the logic to update bounds for show type from WorkspaceLayoutManager to DefaultState (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/wm/default_state.h" 5 #include "ash/wm/default_state.h"
6 6
7 #include "ash/display/display_controller.h"
7 #include "ash/screen_util.h" 8 #include "ash/screen_util.h"
8 #include "ash/shell.h" 9 #include "ash/shell.h"
9 #include "ash/wm/coordinate_conversion.h" 10 #include "ash/wm/coordinate_conversion.h"
11 #include "ash/wm/window_animations.h"
10 #include "ash/wm/window_state.h" 12 #include "ash/wm/window_state.h"
13 #include "ash/wm/window_state_delegate.h"
14 #include "ash/wm/window_util.h"
15 #include "ash/wm/workspace/workspace_window_resizer.h"
16 #include "ui/aura/client/aura_constants.h"
11 #include "ui/aura/window.h" 17 #include "ui/aura/window.h"
12 #include "ui/aura/window_delegate.h" 18 #include "ui/aura/window_delegate.h"
13 #include "ui/gfx/display.h" 19 #include "ui/gfx/display.h"
14 #include "ui/gfx/rect.h" 20 #include "ui/gfx/rect.h"
15 21
16 namespace ash { 22 namespace ash {
17 namespace wm { 23 namespace wm {
24 namespace {
25
26 gfx::Rect BoundsWithScreenEdgeVisible(
27 aura::Window* window,
28 const gfx::Rect& restore_bounds) {
29 gfx::Rect max_bounds =
30 ash::ScreenUtil::GetMaximizedWindowBoundsInParent(window);
31 // If the restore_bounds are more than 1 grid step away from the size the
32 // window would be when maximized, inset it.
33 max_bounds.Inset(ash::internal::WorkspaceWindowResizer::kScreenEdgeInset,
34 ash::internal::WorkspaceWindowResizer::kScreenEdgeInset);
35 if (restore_bounds.Contains(max_bounds))
36 return max_bounds;
37 return restore_bounds;
38 }
39
40 void MoveToDisplayForRestore(wm::WindowState* window_state) {
41 if (!window_state->HasRestoreBounds())
42 return;
43 const gfx::Rect& restore_bounds = window_state->GetRestoreBoundsInScreen();
44
45 // Move only if the restore bounds is outside of
46 // the display. There is no information about in which
47 // display it should be restored, so this is best guess.
48 // TODO(oshima): Restore information should contain the
49 // work area information like WindowResizer does for the
50 // last window location.
51 gfx::Rect display_area = Shell::GetScreen()->GetDisplayNearestWindow(
52 window_state->window()).bounds();
53
54 if (!display_area.Intersects(restore_bounds)) {
55 const gfx::Display& display =
56 Shell::GetScreen()->GetDisplayMatching(restore_bounds);
57 DisplayController* display_controller =
58 Shell::GetInstance()->display_controller();
59 aura::Window* new_root =
60 display_controller->GetRootWindowForDisplayId(display.id());
61 if (new_root != window_state->window()->GetRootWindow()) {
62 aura::Window* new_container =
63 Shell::GetContainer(new_root, window_state->window()->parent()->id());
64 new_container->AddChild(window_state->window());
65 }
66 }
67 }
68
69 } // namespace;
18 70
19 DefaultState::DefaultState() {} 71 DefaultState::DefaultState() {}
20 DefaultState::~DefaultState() {} 72 DefaultState::~DefaultState() {}
21 73
22 void DefaultState::OnWMEvent(WindowState* window_state, 74 void DefaultState::OnWMEvent(WindowState* window_state,
23 WMEvent event) { 75 WMEvent event) {
76 if (ProcessCompoundEvents(window_state, event))
77 return;
78
79 WindowShowType next_show_type = SHOW_TYPE_NORMAL;
80 switch (event) {
81 case NORMAL:
82 next_show_type = SHOW_TYPE_NORMAL;
83 break;
84 case MAXIMIZE:
85 next_show_type = SHOW_TYPE_MAXIMIZED;
86 break;
87 case MINIMIZE:
88 next_show_type = SHOW_TYPE_MINIMIZED;
89 break;
90 case FULLSCREEN:
91 next_show_type = SHOW_TYPE_FULLSCREEN;
92 break;
93 case SNAP_LEFT:
94 next_show_type = SHOW_TYPE_LEFT_SNAPPED;
95 break;
96 case SNAP_RIGHT:
97 next_show_type = SHOW_TYPE_RIGHT_SNAPPED;
98 break;
99 case TOGGLE_MAXIMIZE_CAPTION:
100 case TOGGLE_MAXIMIZE:
101 case TOGGLE_VERTICAL_MAXIMIZE:
102 case TOGGLE_HORIZONTAL_MAXIMIZE:
103 case TOGGLE_FULLSCREEN:
104 NOTREACHED() << "Compound event should not reach here:" << event;
105 return;
106 }
107
108 WindowShowType current = window_state->window_show_type();
109 if (current != next_show_type) {
110 window_state->UpdateWindowShowType(next_show_type);
111 window_state->NotifyPreShowTypeChange(current);
112 // TODO(oshima): Make docked window a state.
113 if (!window_state->IsDocked() && !window_state->IsPanel())
pkotwicz 2014/02/12 22:27:27 Can you move the implementation of IsPanel() to th
oshima 2014/02/13 14:52:34 sure done. Note that IsDocked is also wrong, and I
114 UpdateBoundsFromShowType(window_state, current);
115 window_state->NotifyPostShowTypeChange(current);
116 }
117 };
118
119 // static
120 bool DefaultState::ProcessCompoundEvents(WindowState* window_state,
121 WMEvent event) {
24 aura::Window* window = window_state->window(); 122 aura::Window* window = window_state->window();
25 123
26 switch (event) { 124 switch (event) {
27 case TOGGLE_MAXIMIZE_CAPTION: 125 case TOGGLE_MAXIMIZE_CAPTION:
28 if (window_state->IsFullscreen()) { 126 if (window_state->IsFullscreen()) {
29 window_state->ToggleFullscreen(); 127 window_state->ToggleFullscreen();
30 } else if (window_state->IsMaximized()) { 128 } else if (window_state->IsMaximized()) {
31 window_state->Restore(); 129 window_state->Restore();
32 } else if (window_state->IsNormalShowType() || 130 } else if (window_state->IsNormalShowType() ||
33 window_state->IsSnapped()) { 131 window_state->IsSnapped()) {
34 if (window_state->CanMaximize()) 132 if (window_state->CanMaximize())
35 window_state->Maximize(); 133 window_state->Maximize();
36 } 134 }
37 break; 135 return true;
38
39 case TOGGLE_MAXIMIZE: 136 case TOGGLE_MAXIMIZE:
40 if (window_state->IsFullscreen()) 137 if (window_state->IsFullscreen())
41 window_state->ToggleFullscreen(); 138 window_state->ToggleFullscreen();
42 else if (window_state->IsMaximized()) 139 else if (window_state->IsMaximized())
43 window_state->Restore(); 140 window_state->Restore();
44 else if (window_state->CanMaximize()) 141 else if (window_state->CanMaximize())
45 window_state->Maximize(); 142 window_state->Maximize();
46 break; 143 return true;
47
48 case TOGGLE_VERTICAL_MAXIMIZE: { 144 case TOGGLE_VERTICAL_MAXIMIZE: {
49 gfx::Rect work_area = 145 gfx::Rect work_area =
50 ScreenUtil::GetDisplayWorkAreaBoundsInParent(window); 146 ScreenUtil::GetDisplayWorkAreaBoundsInParent(window);
51 147
52 // Maximize vertically if: 148 // Maximize vertically if:
53 // - The window does not have a max height defined. 149 // - The window does not have a max height defined.
54 // - The window has the normal show type. Snapped windows are excluded 150 // - The window has the normal show type. Snapped windows are excluded
55 // because they are already maximized vertically and reverting to the 151 // because they are already maximized vertically and reverting to the
56 // restored bounds looks weird. 152 // restored bounds looks weird.
57 if (window->delegate()->GetMaximumSize().height() != 0 || 153 if (window->delegate()->GetMaximumSize().height() != 0 ||
58 !window_state->IsNormalShowType()) { 154 !window_state->IsNormalShowType()) {
59 return; 155 return true;
60 } 156 }
61 if (window_state->HasRestoreBounds() && 157 if (window_state->HasRestoreBounds() &&
62 (window->bounds().height() == work_area.height() && 158 (window->bounds().height() == work_area.height() &&
63 window->bounds().y() == work_area.y())) { 159 window->bounds().y() == work_area.y())) {
64 window_state->SetAndClearRestoreBounds(); 160 window_state->SetAndClearRestoreBounds();
65 } else { 161 } else {
66 window_state->SaveCurrentBoundsForRestore(); 162 window_state->SaveCurrentBoundsForRestore();
67 window->SetBounds(gfx::Rect(window->bounds().x(), 163 window->SetBounds(gfx::Rect(window->bounds().x(),
68 work_area.y(), 164 work_area.y(),
69 window->bounds().width(), 165 window->bounds().width(),
70 work_area.height())); 166 work_area.height()));
71 } 167 }
72 break; 168 return true;
73 } 169 }
74 case TOGGLE_HORIZONTAL_MAXIMIZE: { 170 case TOGGLE_HORIZONTAL_MAXIMIZE: {
75 // Maximize horizontally if: 171 // Maximize horizontally if:
76 // - The window does not have a max width defined. 172 // - The window does not have a max width defined.
77 // - The window is snapped or has the normal show type. 173 // - The window is snapped or has the normal show type.
78 if (window->delegate()->GetMaximumSize().width() != 0) 174 if (window->delegate()->GetMaximumSize().width() != 0)
79 return; 175 return true;
80 if (!window_state->IsNormalShowType() && !window_state->IsSnapped()) 176 if (!window_state->IsNormalShowType() && !window_state->IsSnapped())
81 return; 177 return true;
82
83 gfx::Rect work_area = 178 gfx::Rect work_area =
84 ScreenUtil::GetDisplayWorkAreaBoundsInParent(window); 179 ScreenUtil::GetDisplayWorkAreaBoundsInParent(window);
85
86 if (window_state->IsNormalShowType() && 180 if (window_state->IsNormalShowType() &&
87 window_state->HasRestoreBounds() && 181 window_state->HasRestoreBounds() &&
88 (window->bounds().width() == work_area.width() && 182 (window->bounds().width() == work_area.width() &&
89 window->bounds().x() == work_area.x())) { 183 window->bounds().x() == work_area.x())) {
90 window_state->SetAndClearRestoreBounds(); 184 window_state->SetAndClearRestoreBounds();
91 } else { 185 } else {
92 gfx::Rect new_bounds(work_area.x(), 186 gfx::Rect new_bounds(work_area.x(),
93 window->bounds().y(), 187 window->bounds().y(),
94 work_area.width(), 188 work_area.width(),
95 window->bounds().height()); 189 window->bounds().height());
96 190
97 gfx::Rect restore_bounds = window->bounds(); 191 gfx::Rect restore_bounds = window->bounds();
98 if (window_state->IsSnapped()) { 192 if (window_state->IsSnapped()) {
99 window_state->SetRestoreBoundsInParent(new_bounds); 193 window_state->SetRestoreBoundsInParent(new_bounds);
100 window_state->Restore(); 194 window_state->Restore();
101 195
102 // The restore logic prevents a window from being restored to bounds 196 // The restore logic prevents a window from being restored to bounds
103 // which match the workspace bounds exactly so it is necessary to set 197 // which match the workspace bounds exactly so it is necessary to set
104 // the bounds again below. 198 // the bounds again below.
105 } 199 }
106 200
107 window_state->SetRestoreBoundsInParent(restore_bounds); 201 window_state->SetRestoreBoundsInParent(restore_bounds);
108 window->SetBounds(new_bounds); 202 window->SetBounds(new_bounds);
109 } 203 }
204 return true;
205 }
206 case TOGGLE_FULLSCREEN: {
207 // Window which cannot be maximized should not be fullscreened.
208 // It can, however, be restored if it was fullscreened.
209 bool is_fullscreen = window_state->IsFullscreen();
210 if (!is_fullscreen && !window_state->CanMaximize())
211 return true;
212 if (window_state->delegate() &&
213 window_state->delegate()->ToggleFullscreen(window_state)) {
214 return true;
215 }
216 if (is_fullscreen) {
217 window_state->Restore();
218 } else {
219 //
220 window_state->window()->SetProperty(aura::client::kShowStateKey,
221 ui::SHOW_STATE_FULLSCREEN);
222 }
223 return true;
224 }
225 case NORMAL:
226 case MAXIMIZE:
227 case MINIMIZE:
228 case FULLSCREEN:
229 case SNAP_LEFT:
230 case SNAP_RIGHT:
231 break;
232 }
233 return false;
234 }
235
236 // static
237 void DefaultState::UpdateBoundsFromShowType(wm::WindowState* window_state,
pkotwicz 2014/02/12 22:27:27 Nit: You can remove the wm:: namespace prefixes
oshima 2014/02/13 14:52:34 removed all wm::. Thanks
238 wm::WindowShowType old_show_type) {
239 aura::Window* window = window_state->window();
240 // Do nothing If this is not yet added to the container.
241 if (!window->parent())
242 return;
243
244 if (old_show_type != wm::SHOW_TYPE_MINIMIZED &&
245 !window_state->HasRestoreBounds() &&
246 window_state->IsMaximizedOrFullscreen() &&
247 !wm::IsMaximizedOrFullscreenWindowShowType(old_show_type)) {
248 window_state->SaveCurrentBoundsForRestore();
249 }
250
251 // When restoring from a minimized state, we want to restore to the previous
252 // bounds. However, we want to maintain the restore bounds. (The restore
253 // bounds are set if a user maximized the window in one axis by double
254 // clicking the window border for example).
255 gfx::Rect restore;
256 if (old_show_type == wm::SHOW_TYPE_MINIMIZED &&
257 window_state->IsNormalShowState() &&
258 window_state->HasRestoreBounds() &&
259 !window_state->unminimize_to_restore_bounds()) {
260 restore = window_state->GetRestoreBoundsInScreen();
261 window_state->SaveCurrentBoundsForRestore();
262 }
263
264 if (window_state->IsMaximizedOrFullscreen())
265 MoveToDisplayForRestore(window_state);
266
267 wm::WindowShowType show_type = window_state->window_show_type();
268 gfx::Rect bounds_in_parent;
269 switch (show_type) {
270 case wm::SHOW_TYPE_DEFAULT:
271 case wm::SHOW_TYPE_NORMAL:
272 case wm::SHOW_TYPE_LEFT_SNAPPED:
273 case wm::SHOW_TYPE_RIGHT_SNAPPED: {
274 gfx::Rect work_area_in_parent =
275 ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_state->window());
276
277 if (window_state->HasRestoreBounds())
278 bounds_in_parent = window_state->GetRestoreBoundsInParent();
279 else
280 bounds_in_parent = window->bounds();
281 // Make sure that part of the window is always visible.
282 wm::AdjustBoundsToEnsureMinimumWindowVisibility(
283 work_area_in_parent, &bounds_in_parent);
284
285 if (show_type == wm::SHOW_TYPE_LEFT_SNAPPED ||
286 show_type == wm::SHOW_TYPE_RIGHT_SNAPPED) {
287 window_state->AdjustSnappedBounds(&bounds_in_parent);
288 } else {
289 bounds_in_parent = BoundsWithScreenEdgeVisible(
290 window,
291 bounds_in_parent);
292 }
293 break;
294 }
295 case wm::SHOW_TYPE_MAXIMIZED:
296 bounds_in_parent = ScreenUtil::GetMaximizedWindowBoundsInParent(window);
297 break;
298
299 case wm::SHOW_TYPE_FULLSCREEN:
300 bounds_in_parent = ScreenUtil::GetDisplayBoundsInParent(window);
301 break;
302
303 case wm::SHOW_TYPE_MINIMIZED:
304 break;
305 case wm::SHOW_TYPE_INACTIVE:
306 case wm::SHOW_TYPE_DETACHED:
307 case wm::SHOW_TYPE_END:
308 case wm::SHOW_TYPE_AUTO_POSITIONED:
309 return;
310 }
311
312 if (show_type != wm::SHOW_TYPE_MINIMIZED) {
313 if (old_show_type == wm::SHOW_TYPE_MINIMIZED ||
314 (window_state->IsFullscreen() &&
315 !window_state->animate_to_fullscreen())) {
316 window_state->SetBoundsDirect(bounds_in_parent);
317 } else if (window_state->IsMaximizedOrFullscreen() ||
318 IsMaximizedOrFullscreenWindowShowType(old_show_type)) {
319 CrossFadeToBounds(window, bounds_in_parent);
320 } else {
321 window_state->SetBoundsDirectAnimated(bounds_in_parent);
110 } 322 }
111 } 323 }
112 }; 324
325 if (window_state->IsMinimized()) {
326 if (old_show_type == wm::SHOW_TYPE_MINIMIZED)
pkotwicz 2014/02/12 22:27:27 Lines 326 and 327 should be gone
oshima 2014/02/13 14:52:34 Done.
327 return;
328
329 // Save the previous show state so that we can correctly restore it.
330 window_state->window()->SetProperty(aura::client::kRestoreShowStateKey,
331 wm::ToWindowShowState(old_show_type));
332 views::corewm::SetWindowVisibilityAnimationType(
333 window_state->window(), WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE);
334
335 // Hide the window.
336 window_state->window()->Hide();
337 // Activate another window.
338 if (window_state->IsActive())
339 window_state->Deactivate();
340 } else if ((window_state->window()->TargetVisibility() ||
341 old_show_type == wm::SHOW_TYPE_MINIMIZED) &&
342 !window_state->window()->layer()->visible()) {
343 // The layer may be hidden if the window was previously minimized. Make
344 // sure it's visible.
345 window_state->window()->Show();
346 if (old_show_type == wm::SHOW_TYPE_MINIMIZED &&
347 !window_state->IsMaximizedOrFullscreen()) {
348 window_state->set_unminimize_to_restore_bounds(false);
349 }
350 }
351
352 if (window_state->IsNormalShowState())
353 window_state->ClearRestoreBounds();
354
355 // Set the restore rectangle to the previously set restore rectangle.
356 if (!restore.IsEmpty())
357 window_state->SetRestoreBoundsInScreen(restore);
358 }
113 359
114 } // namespace wm 360 } // namespace wm
115 } // namespace ash 361 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698