Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "ash/wm/window_util.h" |
| 6 | |
| 7 | #include <vector> |
| 8 | |
| 9 | #include "ash/ash_constants.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 10 | #include "ash/root_window_controller.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 11 | #include "ash/shell.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 12 | #include "ash/shell_window_ids.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 13 | #include "ash/wm/activation_controller.h" |
| 14 | #include "ash/wm/window_properties.h" |
| 15 | #include "ui/aura/client/activation_client.h" |
| 16 | #include "ui/aura/client/aura_constants.h" |
| 17 | #include "ui/aura/root_window.h" |
| 18 | #include "ui/aura/window.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 19 | #include "ui/aura/window_delegate.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 20 | #include "ui/compositor/layer.h" |
| 21 | #include "ui/gfx/display.h" |
| 22 | #include "ui/gfx/rect.h" |
| 23 | #include "ui/gfx/screen.h" |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 24 | #include "ui/views/corewm/window_util.h" |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 25 | #include "ui/views/view.h" |
| 26 | #include "ui/views/widget/widget.h" |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 27 | |
| 28 | namespace ash { |
| 29 | namespace wm { |
| 30 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 31 | // TODO(beng): replace many of these functions with the corewm versions. |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 32 | void ActivateWindow(aura::Window* window) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 33 | views::corewm::ActivateWindow(window); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 34 | } |
| 35 | |
| 36 | void DeactivateWindow(aura::Window* window) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 37 | views::corewm::DeactivateWindow(window); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 38 | } |
| 39 | |
| 40 | bool IsActiveWindow(aura::Window* window) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 41 | return views::corewm::IsActiveWindow(window); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 42 | } |
| 43 | |
| 44 | aura::Window* GetActiveWindow() { |
| 45 | return aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())-> |
| 46 | GetActiveWindow(); |
| 47 | } |
| 48 | |
| 49 | aura::Window* GetActivatableWindow(aura::Window* window) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 50 | return views::corewm::GetActivatableWindow(window); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 51 | } |
| 52 | |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 53 | bool CanActivateWindow(aura::Window* window) { |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 54 | return views::corewm::CanActivateWindow(window); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 55 | } |
| 56 | |
| 57 | bool CanMaximizeWindow(const aura::Window* window) { |
| 58 | return window->GetProperty(aura::client::kCanMaximizeKey); |
| 59 | } |
| 60 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 61 | bool CanMinimizeWindow(const aura::Window* window) { |
| 62 | internal::RootWindowController* controller = |
| 63 | internal::RootWindowController::ForWindow(window); |
| 64 | if (!controller) |
| 65 | return false; |
| 66 | aura::Window* lockscreen = controller->GetContainer( |
| 67 | internal::kShellWindowId_LockScreenContainersContainer); |
| 68 | if (lockscreen->Contains(window)) |
| 69 | return false; |
| 70 | |
| 71 | return true; |
| 72 | } |
| 73 | |
| 74 | bool CanResizeWindow(const aura::Window* window) { |
| 75 | return window->GetProperty(aura::client::kCanResizeKey); |
| 76 | } |
| 77 | |
| 78 | bool CanSnapWindow(aura::Window* window) { |
| 79 | if (!CanResizeWindow(window)) |
| 80 | return false; |
| 81 | // If a window has a maximum size defined, snapping may make it too big. |
| 82 | return window->delegate() ? window->delegate()->GetMaximumSize().IsEmpty() : |
| 83 | true; |
| 84 | } |
| 85 | |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 86 | bool IsWindowNormal(const aura::Window* window) { |
| 87 | return IsWindowStateNormal(window->GetProperty(aura::client::kShowStateKey)); |
| 88 | } |
| 89 | |
| 90 | bool IsWindowStateNormal(ui::WindowShowState state) { |
| 91 | return state == ui::SHOW_STATE_NORMAL || state == ui::SHOW_STATE_DEFAULT; |
| 92 | } |
| 93 | |
| 94 | bool IsWindowMaximized(const aura::Window* window) { |
| 95 | return window->GetProperty(aura::client::kShowStateKey) == |
| 96 | ui::SHOW_STATE_MAXIMIZED; |
| 97 | } |
| 98 | |
| 99 | bool IsWindowMinimized(const aura::Window* window) { |
| 100 | return window->GetProperty(aura::client::kShowStateKey) == |
| 101 | ui::SHOW_STATE_MINIMIZED; |
| 102 | } |
| 103 | |
| 104 | bool IsWindowFullscreen(const aura::Window* window) { |
| 105 | return window->GetProperty(aura::client::kShowStateKey) == |
| 106 | ui::SHOW_STATE_FULLSCREEN; |
| 107 | } |
| 108 | |
| 109 | void MaximizeWindow(aura::Window* window) { |
| 110 | window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); |
| 111 | } |
| 112 | |
| 113 | void MinimizeWindow(aura::Window* window) { |
| 114 | window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); |
| 115 | } |
| 116 | |
| 117 | void RestoreWindow(aura::Window* window) { |
| 118 | window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL); |
| 119 | } |
| 120 | |
| 121 | void ToggleMaximizedWindow(aura::Window* window) { |
| 122 | if (ash::wm::IsWindowMaximized(window)) |
| 123 | ash::wm::RestoreWindow(window); |
| 124 | else if (ash::wm::CanMaximizeWindow(window)) |
| 125 | ash::wm::MaximizeWindow(window); |
| 126 | } |
| 127 | |
| 128 | void CenterWindow(aura::Window* window) { |
| 129 | const gfx::Display display = |
| 130 | Shell::GetScreen()->GetDisplayNearestWindow(window); |
| 131 | gfx::Rect center = display.work_area(); |
| 132 | center.ClampToCenteredSize(window->bounds().size()); |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 133 | window->SetBoundsInScreen(center, display); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 134 | } |
| 135 | |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 136 | bool IsWindowPositionManaged(const aura::Window* window) { |
| 137 | return window->GetProperty(ash::internal::kWindowPositionManagedKey); |
| 138 | } |
| 139 | |
| 140 | void SetWindowPositionManaged(aura::Window* window, bool managed) { |
| 141 | window->SetProperty(ash::internal::kWindowPositionManagedKey, managed); |
| 142 | } |
| 143 | |
| 144 | bool HasUserChangedWindowPositionOrSize(const aura::Window* window) { |
| 145 | return window->GetProperty( |
| 146 | ash::internal::kUserChangedWindowPositionOrSizeKey); |
| 147 | } |
| 148 | |
| 149 | void SetUserHasChangedWindowPositionOrSize(aura::Window* window, bool changed) { |
| 150 | window->SetProperty(ash::internal::kUserChangedWindowPositionOrSizeKey, |
| 151 | changed); |
| 152 | } |
| 153 | |
| 154 | const gfx::Rect* GetPreAutoManageWindowBounds(const aura::Window* window) { |
| 155 | return window->GetProperty(ash::internal::kPreAutoManagedWindowBoundsKey); |
| 156 | } |
| 157 | |
| 158 | void SetPreAutoManageWindowBounds(aura::Window* window, |
| 159 | const gfx::Rect& bounds) { |
| 160 | window->SetProperty(ash::internal::kPreAutoManagedWindowBoundsKey, |
| 161 | new gfx::Rect(bounds)); |
| 162 | } |
| 163 | |
Torne (Richard Coles) | 2a99a7e | 2013-03-28 15:31:22 +0000 | [diff] [blame] | 164 | void AdjustBoundsToEnsureMinimumWindowVisibility(const gfx::Rect& work_area, |
| 165 | gfx::Rect* bounds) { |
| 166 | AdjustBoundsToEnsureWindowVisibility( |
| 167 | work_area, kMinimumOnScreenArea, kMinimumOnScreenArea, bounds); |
| 168 | } |
| 169 | |
| 170 | void AdjustBoundsToEnsureWindowVisibility(const gfx::Rect& work_area, |
| 171 | int min_width, |
| 172 | int min_height, |
| 173 | gfx::Rect* bounds) { |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 174 | bounds->set_width(std::min(bounds->width(), work_area.width())); |
| 175 | bounds->set_height(std::min(bounds->height(), work_area.height())); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 176 | |
Ben Murdoch | bb1529c | 2013-08-08 10:24:53 +0100 | [diff] [blame^] | 177 | min_width = std::min(min_width, work_area.width()); |
| 178 | min_height = std::min(min_height, work_area.height()); |
| 179 | |
| 180 | if (bounds->x() + min_width > work_area.right()) { |
| 181 | bounds->set_x(work_area.right() - min_width); |
| 182 | } else if (bounds->right() - min_width < 0) { |
| 183 | bounds->set_x(min_width - bounds->width()); |
| 184 | } |
| 185 | if (bounds->y() + min_height > work_area.bottom()) { |
| 186 | bounds->set_y(work_area.bottom() - min_height); |
| 187 | } else if (bounds->bottom() - min_height < 0) { |
| 188 | bounds->set_y(min_height - bounds->height()); |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 189 | } |
| 190 | } |
| 191 | |
Torne (Richard Coles) | c2e0dbd | 2013-05-09 18:35:53 +0100 | [diff] [blame] | 192 | bool MoveWindowToEventRoot(aura::Window* window, const ui::Event& event) { |
| 193 | views::View* target = static_cast<views::View*>(event.target()); |
| 194 | if (!target) |
| 195 | return false; |
| 196 | aura::RootWindow* target_root = |
| 197 | target->GetWidget()->GetNativeView()->GetRootWindow(); |
| 198 | if (!target_root || target_root == window->GetRootWindow()) |
| 199 | return false; |
| 200 | aura::Window* window_container = |
| 201 | ash::Shell::GetContainer(target_root, window->parent()->id()); |
| 202 | // Move the window to the target launcher. |
| 203 | window_container->AddChild(window); |
| 204 | return true; |
| 205 | } |
| 206 | |
Torne (Richard Coles) | 5821806 | 2012-11-14 11:43:16 +0000 | [diff] [blame] | 207 | } // namespace wm |
| 208 | } // namespace ash |