default_state.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/default_state.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/display/display_controller.h" 86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ash/screen_util.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shell.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shell_window_ids.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/coordinate_conversion.h" 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ash/wm/window_animations.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/wm/window_state.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/wm/window_state_delegate.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/window_util.h" 16a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "ash/wm/wm_event.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/workspace/workspace_window_resizer.h" 181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/aura/client/aura_constants.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/aura/window.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/aura/window_delegate.h" 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/gfx/display.h" 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/gfx/rect.h" 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash { 25b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)namespace wm { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// This specifies how much percent (30%) of a window rect 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// must be visible when the window is added to the workspace. 30a3f7b4e666c476898878fa745f637129375cd889Ben Murdochconst float kMinimumPercentOnScreenArea = 0.3f; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsPanel(aura::Window* window) { 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return window->parent() && 34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) window->parent()->id() == internal::kShellWindowId_DockedContainer; 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void MoveToDisplayForRestore(WindowState* window_state) { 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!window_state->HasRestoreBounds()) 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const gfx::Rect& restore_bounds = window_state->GetRestoreBoundsInScreen(); 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Move only if the restore bounds is outside of 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // the display. There is no information about in which 44b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // display it should be restored, so this is best guess. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(oshima): Restore information should contain the 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // work area information like WindowResizer does for the 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // last window location. 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gfx::Rect display_area = Shell::GetScreen()->GetDisplayNearestWindow( 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_state->window()).bounds(); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!display_area.Intersects(restore_bounds)) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::Display& display = 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetScreen()->GetDisplayMatching(restore_bounds); 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DisplayController* display_controller = 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetInstance()->display_controller(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::Window* new_root = 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci display_controller->GetRootWindowForDisplayId(display.id()); 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (new_root != window_state->window()->GetRootWindow()) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aura::Window* new_container = 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shell::GetContainer(new_root, window_state->window()->parent()->id()); 61a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch new_container->AddChild(window_state->window()); 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace; 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 68116680a4aac90f2aa7413d9095a592090648e557Ben MurdochDefaultState::DefaultState(WindowStateType initial_state_type) 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : state_type_(initial_state_type) {} 706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)DefaultState::~DefaultState() {} 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void DefaultState::OnWMEvent(WindowState* window_state, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const WMEvent* event) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ProcessWorkspaceEvents(window_state, event)) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (ProcessCompoundEvents(window_state, event)) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WindowStateType next_state_type = WINDOW_STATE_TYPE_NORMAL; 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) switch (event->type()) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WM_EVENT_NORMAL: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_type = WINDOW_STATE_TYPE_NORMAL; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WM_EVENT_MAXIMIZE: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_type = WINDOW_STATE_TYPE_MAXIMIZED; 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_EVENT_MINIMIZE: 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_state_type = WINDOW_STATE_TYPE_MINIMIZED; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_EVENT_FULLSCREEN: 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_state_type = WINDOW_STATE_TYPE_FULLSCREEN; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_EVENT_SNAP_LEFT: 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_state_type = WINDOW_STATE_TYPE_LEFT_SNAPPED; 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_EVENT_SNAP_RIGHT: 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_state_type = WINDOW_STATE_TYPE_RIGHT_SNAPPED; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 100a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch case WM_EVENT_SET_BOUNDS: 101a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch SetBounds(window_state, static_cast<const SetBoundsEvent*>(event)); 102a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return; 103a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch case WM_EVENT_SHOW_INACTIVE: 104a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch next_state_type = WINDOW_STATE_TYPE_INACTIVE; 105a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch break; 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case WM_EVENT_TOGGLE_MAXIMIZE_CAPTION: 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case WM_EVENT_TOGGLE_MAXIMIZE: 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE: 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE: 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case WM_EVENT_TOGGLE_FULLSCREEN: 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTREACHED() << "Compound event should not reach here:" << event; 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case WM_EVENT_ADDED_TO_WORKSPACE: 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case WM_EVENT_WORKAREA_BOUNDS_CHANGED: 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case WM_EVENT_DISPLAY_BOUNDS_CHANGED: 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) NOTREACHED() << "Workspace event should not reach here:" << event; 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WindowStateType current = window_state->GetStateType(); 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (next_state_type == current && window_state->IsSnapped()) { 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::Rect snapped_bounds = event->type() == WM_EVENT_SNAP_LEFT ? 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) GetDefaultLeftSnappedWindowBoundsInParent(window_state->window()) : 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetDefaultRightSnappedWindowBoundsInParent(window_state->window()); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_state->SetBoundsDirectAnimated(snapped_bounds); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current != next_state_type) { 131a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) state_type_ = next_state_type; 132a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) window_state->UpdateWindowShowStateFromStateType(); 133a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) window_state->NotifyPreStateTypeChange(current); 134a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // TODO(oshima): Make docked window a state. 135a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (window_state->IsSnapped() || 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (!window_state->IsDocked() && !IsPanel(window_state->window()))) { 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UpdateBounds(window_state, current, event); 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_state->NotifyPostStateTypeChange(current); 140a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 141a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)WindowStateType DefaultState::GetType() const { 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return state_type_; 145ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 146ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 148a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)bool DefaultState::ProcessCompoundEvents(WindowState* window_state, 149ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const WMEvent* event) { 150ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch aura::Window* window = window_state->window(); 151ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 152ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch switch (event->type()) { 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_EVENT_TOGGLE_MAXIMIZE_CAPTION: 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (window_state->IsFullscreen()) { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_state->OnWMEvent(&event); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (window_state->IsMaximized()) { 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_state->Restore(); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (window_state->IsNormalOrSnapped()) { 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (window_state->CanMaximize()) 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window_state->Maximize(); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case WM_EVENT_TOGGLE_MAXIMIZE: 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (window_state->IsFullscreen()) { 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const wm::WMEvent event(wm::WM_EVENT_TOGGLE_FULLSCREEN); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_state->OnWMEvent(&event); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (window_state->IsMaximized()) { 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) window_state->Restore(); 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else if (window_state->CanMaximize()) { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_state->Maximize(); 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE: { 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gfx::Rect work_area = 176a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch ScreenUtil::GetDisplayWorkAreaBoundsInParent(window); 177a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Maximize vertically if: 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // - The window does not have a max height defined. 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // - The window has the normal state type. Snapped windows are excluded 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // because they are already maximized vertically and reverting to the 182a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch // restored bounds looks weird. 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (window->delegate()->GetMaximumSize().height() != 0 || 184a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch !window_state->IsNormalStateType()) { 185a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return true; 186a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (window_state->HasRestoreBounds() && 188a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch (window->bounds().height() == work_area.height() && 189a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch window->bounds().y() == work_area.y())) { 190a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch window_state->SetAndClearRestoreBounds(); 191a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } else { 192a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch window_state->SaveCurrentBoundsForRestore(); 193a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch window->SetBounds(gfx::Rect(window->bounds().x(), 194a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch work_area.y(), 195a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch window->bounds().width(), 196a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch work_area.height())); 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 199a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch } 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE: { 201a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch // Maximize horizontally if: 202a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch // - The window does not have a max width defined. 203a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch // - The window is snapped or has the normal state type. 2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (window->delegate()->GetMaximumSize().width() != 0) 205a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return true; 206a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (!window_state->IsNormalOrSnapped()) 207a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch return true; 208a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch gfx::Rect work_area = 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScreenUtil::GetDisplayWorkAreaBoundsInParent(window); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_state->IsNormalStateType() && 211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state->HasRestoreBounds() && 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (window->bounds().width() == work_area.width() && 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window->bounds().x() == work_area.x())) { 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state->SetAndClearRestoreBounds(); 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect new_bounds(work_area.x(), 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window->bounds().y(), 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) work_area.width(), 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window->bounds().height()); 220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect restore_bounds = window->bounds(); 222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (window_state->IsSnapped()) { 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state->SetRestoreBoundsInParent(new_bounds); 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state->Restore(); 225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The restore logic prevents a window from being restored to bounds 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // which match the workspace bounds exactly so it is necessary to set 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // the bounds again below. 229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_state->SetRestoreBoundsInParent(restore_bounds); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window->SetBounds(new_bounds); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case WM_EVENT_TOGGLE_FULLSCREEN: { 237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Window which cannot be maximized should not be fullscreened. 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It can, however, be restored if it was fullscreened. 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_fullscreen = window_state->IsFullscreen(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_fullscreen && !window_state->CanMaximize()) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_state->delegate() && 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_state->delegate()->ToggleFullscreen(window_state)) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (is_fullscreen) { 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_state->Restore(); 248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } else { 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_state->window()->SetProperty(aura::client::kShowStateKey, 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui::SHOW_STATE_FULLSCREEN); 2521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return true; 254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 255cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case WM_EVENT_NORMAL: 25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WM_EVENT_MAXIMIZE: 2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case WM_EVENT_MINIMIZE: 25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WM_EVENT_FULLSCREEN: 2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case WM_EVENT_SNAP_LEFT: 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_EVENT_SNAP_RIGHT: 261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) case WM_EVENT_SET_BOUNDS: 262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case WM_EVENT_SHOW_INACTIVE: 263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WM_EVENT_ADDED_TO_WORKSPACE: 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_EVENT_WORKAREA_BOUNDS_CHANGED: 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case WM_EVENT_DISPLAY_BOUNDS_CHANGED: 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED() << "Workspace event should not reach here:" << event; 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool DefaultState::ProcessWorkspaceEvents(WindowState* window_state, 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const WMEvent* event) { 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) switch (event->type()) { 276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) case WM_EVENT_ADDED_TO_WORKSPACE: { 277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // When a window is dragged and dropped onto a different 278f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // root window, the bounds will be updated after they are added 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // to the root window. 2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If a window is opened as maximized or fullscreen, its bounds may be 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // empty, so update the bounds now before checking empty. 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (window_state->is_dragged() || 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetMaximizedOrFullscreenBounds(window_state)) { 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) aura::Window* window = window_state->window(); 2886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) gfx::Rect bounds = window->bounds(); 2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Don't adjust window bounds if the bounds are empty as this 2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // happens when a new views::Widget is created. 2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (bounds.IsEmpty()) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use entire display instead of workarea because the workarea can 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // be further shrunk by the docked area. The logic ensures 30% 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // visibility which should be enough to see where the window gets 2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // moved. 299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) gfx::Rect display_area = ScreenUtil::GetDisplayBoundsInParent(window); 300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int min_width = bounds.width() * kMinimumPercentOnScreenArea; 301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int min_height = bounds.height() * kMinimumPercentOnScreenArea; 302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) AdjustBoundsToEnsureWindowVisibility( 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) display_area, min_width, min_height, &bounds); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_state->AdjustSnappedBounds(&bounds); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window->bounds() != bounds) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_state->SetBoundsConstrained(bounds); 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case WM_EVENT_DISPLAY_BOUNDS_CHANGED: { 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (window_state->is_dragged() || 311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SetMaximizedOrFullscreenBounds(window_state)) { 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect work_area_in_parent = 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_state->window()); 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect bounds = window_state->window()->bounds(); 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // When display bounds has changed, make sure the entire window is fully 318e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch // visible. 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bounds.AdjustToFit(work_area_in_parent); 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window_state->AdjustSnappedBounds(&bounds); 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (window_state->window()->bounds() != bounds) 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window_state->SetBoundsDirectAnimated(bounds); 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case WM_EVENT_WORKAREA_BOUNDS_CHANGED: { 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (window_state->is_dragged() || 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SetMaximizedOrFullscreenBounds(window_state)) { 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect work_area_in_parent = 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_state->window()); 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect bounds = window_state->window()->bounds(); 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AdjustBoundsToEnsureMinimumWindowVisibility(work_area_in_parent, &bounds); 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window_state->AdjustSnappedBounds(&bounds); 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (window_state->window()->bounds() != bounds) 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window_state->SetBoundsDirectAnimated(bounds); 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case WM_EVENT_TOGGLE_MAXIMIZE_CAPTION: 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case WM_EVENT_TOGGLE_MAXIMIZE: 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case WM_EVENT_TOGGLE_VERTICAL_MAXIMIZE: 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case WM_EVENT_TOGGLE_HORIZONTAL_MAXIMIZE: 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case WM_EVENT_TOGGLE_FULLSCREEN: 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case WM_EVENT_NORMAL: 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case WM_EVENT_MAXIMIZE: 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case WM_EVENT_MINIMIZE: 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case WM_EVENT_FULLSCREEN: 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case WM_EVENT_SNAP_LEFT: 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) case WM_EVENT_SNAP_RIGHT: 350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) case WM_EVENT_SET_BOUNDS: 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WM_EVENT_SHOW_INACTIVE: 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void DefaultState::UpdateBounds(WindowState* window_state, 359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) WindowStateType old_state_type, 360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const WMEvent* event) { 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) aura::Window* window = window_state->window(); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Do nothing If this is not yet added to the container. 363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!window->parent()) 364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (old_state_type != WINDOW_STATE_TYPE_MINIMIZED && 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !window_state->HasRestoreBounds() && 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window_state->IsMaximizedOrFullscreen() && 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !IsMaximizedOrFullscreenWindowStateType(old_state_type)) { 370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window_state->SaveCurrentBoundsForRestore(); 371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // When restoring from a minimized state, we want to restore to the previous 374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // bounds. However, we want to maintain the restore bounds. (The restore 375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // bounds are set if a user maximized the window in one axis by double 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // clicking the window border for example). 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) gfx::Rect restore_bounds_in_screen; 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (old_state_type == WINDOW_STATE_TYPE_MINIMIZED && 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window_state->IsNormalOrSnapped() && 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window_state->HasRestoreBounds() && 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !window_state->unminimize_to_restore_bounds()) { 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) restore_bounds_in_screen = window_state->GetRestoreBoundsInScreen(); 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) window_state->SaveCurrentBoundsForRestore(); 3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (window_state->IsMaximizedOrFullscreen()) 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MoveToDisplayForRestore(window_state); 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) WindowStateType state_type = window_state->GetStateType(); 3905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gfx::Rect bounds_in_parent; 39146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 39246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) switch (state_type) { 39346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WINDOW_STATE_TYPE_LEFT_SNAPPED: 39446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) case WINDOW_STATE_TYPE_RIGHT_SNAPPED: { 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // There is no transition from minimized to snapped state. 396a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) SnapWindow(window_state, event, old_state_type); 397a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case WINDOW_STATE_TYPE_DEFAULT: 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case WINDOW_STATE_TYPE_NORMAL: { 401d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) gfx::Rect work_area_in_parent = 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_state->window()); 403d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (window_state->HasRestoreBounds()) 404d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bounds_in_parent = window_state->GetRestoreBoundsInParent(); 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bounds_in_parent = window->bounds(); 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Make sure that part of the window is always visible. 408d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) AdjustBoundsToEnsureMinimumWindowVisibility( 409effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch work_area_in_parent, &bounds_in_parent); 410effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch break; 411010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 412010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) case WINDOW_STATE_TYPE_MAXIMIZED: 413effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bounds_in_parent = ScreenUtil::GetMaximizedWindowBoundsInParent(window); 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 415868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WINDOW_STATE_TYPE_FULLSCREEN: 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_in_parent = ScreenUtil::GetDisplayBoundsInParent(window); 418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WINDOW_STATE_TYPE_MINIMIZED: 421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case WINDOW_STATE_TYPE_INACTIVE: 4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case WINDOW_STATE_TYPE_DETACHED: 4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case WINDOW_STATE_TYPE_END: 4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case WINDOW_STATE_TYPE_AUTO_POSITIONED: 4266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return; 4276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (state_type != WINDOW_STATE_TYPE_MINIMIZED) { 4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (old_state_type == WINDOW_STATE_TYPE_MINIMIZED || 4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) window_state->IsFullscreen()) { 4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) window_state->SetBoundsDirect(bounds_in_parent); 4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (window_state->IsMaximizedOrFullscreen() || 434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) IsMaximizedOrFullscreenWindowStateType(old_state_type)) { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_state->SetBoundsDirectCrossFade(bounds_in_parent); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_state->SetBoundsDirectAnimated(bounds_in_parent); 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_state->IsMinimized()) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save the previous show state so that we can correctly restore it. 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_state->window()->SetProperty(aura::client::kRestoreShowStateKey, 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ToWindowShowState(old_state_type)); 445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ::wm::SetWindowVisibilityAnimationType( 446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_state->window(), WINDOW_VISIBILITY_ANIMATION_TYPE_MINIMIZE); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hide the window. 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_state->window()->Hide(); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Activate another window. 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (window_state->IsActive()) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_state->Deactivate(); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((window_state->window()->TargetVisibility() || 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_state_type == WINDOW_STATE_TYPE_MINIMIZED) && 455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch !window_state->window()->layer()->visible()) { 45646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // The layer may be hidden if the window was previously minimized. Make 45746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // sure it's visible. 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_state->window()->Show(); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (old_state_type == WINDOW_STATE_TYPE_MINIMIZED && 460ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch !window_state->IsMaximizedOrFullscreen()) { 461ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch window_state->set_unminimize_to_restore_bounds(false); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (window_state->IsNormalOrSnapped()) 4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci window_state->ClearRestoreBounds(); 4671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Set the restore rectangle to the previously set restore rectangle. 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!restore_bounds_in_screen.IsEmpty()) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_state->SetRestoreBoundsInScreen(restore_bounds_in_screen); 471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static 474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool DefaultState::SetMaximizedOrFullscreenBounds(WindowState* window_state) { 475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!window_state->is_dragged()); 476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (window_state->IsMaximized()) { 4771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci window_state->SetBoundsDirect( 4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScreenUtil::GetMaximizedWindowBoundsInParent(window_state->window())); 4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (window_state->IsFullscreen()) { 4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci window_state->SetBoundsDirect( 4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScreenUtil::GetDisplayBoundsInParent(window_state->window())); 4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 4855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 48746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static 490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void DefaultState::SnapWindow(WindowState* window_state, 49146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const WMEvent* event, 492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) WindowStateType old_state_type) { 493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Compute the bounds that the window will restore to. If the window does not 494a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // already have restore bounds, it will be restored (when un-snapped) to the 495a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // last bounds that it had before getting snapped. 496a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch gfx::Rect restore_bounds_in_screen = window_state->HasRestoreBounds() ? 497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) window_state->GetRestoreBoundsInScreen() : 4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) window_state->window()->GetBoundsInScreen(); 499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gfx::Rect snapped_bounds = event->type() == WM_EVENT_SNAP_LEFT ? 500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetDefaultLeftSnappedWindowBoundsInParent(window_state->window()) : 501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetDefaultRightSnappedWindowBoundsInParent(window_state->window()); 502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (IsMaximizedOrFullscreenWindowStateType(old_state_type)) { 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_state->SetBoundsDirectCrossFade(snapped_bounds); 5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (window_state->is_dragged()) { 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // SetBoundsDirectAnimated does not work when the window gets reparented. 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(oshima): Consider fixing it and reenable the animation. 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_state->SetBoundsDirect(snapped_bounds); 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_state->SetBoundsDirectAnimated(snapped_bounds); 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_state->SetRestoreBoundsInScreen(restore_bounds_in_screen); 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DefaultState::SetBounds(WindowState* window_state, 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const SetBoundsEvent* event) { 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (window_state->is_dragged()) { 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) window_state->SetBoundsDirect(event->requested_bounds()); 5216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } else if (window_state->IsSnapped()) { 5226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) gfx::Rect work_area_in_parent = 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScreenUtil::GetDisplayWorkAreaBoundsInParent(window_state->window()); 524a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) gfx::Rect child_bounds(event->requested_bounds()); 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AdjustBoundsSmallerThan(work_area_in_parent.size(), &child_bounds); 526a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) window_state->AdjustSnappedBounds(&child_bounds); 527a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) window_state->SetBoundsDirect(child_bounds); 528a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } else if (!SetMaximizedOrFullscreenBounds(window_state)) { 529a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) window_state->SetBoundsConstrained(event->requested_bounds()); 530a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 531a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 532a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 533a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} // namespace wm 534a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} // namespace ash 535ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch