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

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

Powered by Google App Engine
This is Rietveld 408576698