window_util.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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"
10#include "ash/root_window_controller.h"
11#include "ash/shell.h"
12#include "ash/shell_window_ids.h"
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"
19#include "ui/aura/window_delegate.h"
20#include "ui/compositor/layer.h"
21#include "ui/gfx/display.h"
22#include "ui/gfx/rect.h"
23#include "ui/gfx/screen.h"
24#include "ui/views/corewm/window_util.h"
25
26namespace ash {
27namespace wm {
28
29// TODO(beng): replace many of these functions with the corewm versions.
30void ActivateWindow(aura::Window* window) {
31  views::corewm::ActivateWindow(window);
32}
33
34void DeactivateWindow(aura::Window* window) {
35  views::corewm::DeactivateWindow(window);
36}
37
38bool IsActiveWindow(aura::Window* window) {
39  return views::corewm::IsActiveWindow(window);
40}
41
42aura::Window* GetActiveWindow() {
43  return aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
44      GetActiveWindow();
45}
46
47aura::Window* GetActivatableWindow(aura::Window* window) {
48  return views::corewm::GetActivatableWindow(window);
49}
50
51bool IsActiveWindowFullscreen() {
52  aura::Window* window = GetActiveWindow();
53  while (window) {
54    if (window->GetProperty(aura::client::kShowStateKey) ==
55        ui::SHOW_STATE_FULLSCREEN) {
56      return true;
57    }
58    window = window->parent();
59  }
60  return false;
61}
62
63bool CanActivateWindow(aura::Window* window) {
64  return views::corewm::CanActivateWindow(window);
65}
66
67bool CanMaximizeWindow(const aura::Window* window) {
68  return window->GetProperty(aura::client::kCanMaximizeKey);
69}
70
71bool CanMinimizeWindow(const aura::Window* window) {
72  internal::RootWindowController* controller =
73      internal::RootWindowController::ForWindow(window);
74  if (!controller)
75    return false;
76  aura::Window* lockscreen = controller->GetContainer(
77      internal::kShellWindowId_LockScreenContainersContainer);
78  if (lockscreen->Contains(window))
79    return false;
80
81  return true;
82}
83
84bool CanResizeWindow(const aura::Window* window) {
85  return window->GetProperty(aura::client::kCanResizeKey);
86}
87
88bool CanSnapWindow(aura::Window* window) {
89  if (!CanResizeWindow(window))
90    return false;
91  // If a window has a maximum size defined, snapping may make it too big.
92  return window->delegate() ? window->delegate()->GetMaximumSize().IsEmpty() :
93                              true;
94}
95
96bool IsWindowNormal(const aura::Window* window) {
97  return IsWindowStateNormal(window->GetProperty(aura::client::kShowStateKey));
98}
99
100bool IsWindowStateNormal(ui::WindowShowState state) {
101  return state == ui::SHOW_STATE_NORMAL || state == ui::SHOW_STATE_DEFAULT;
102}
103
104bool IsWindowMaximized(const aura::Window* window) {
105  return window->GetProperty(aura::client::kShowStateKey) ==
106      ui::SHOW_STATE_MAXIMIZED;
107}
108
109bool IsWindowMinimized(const aura::Window* window) {
110  return window->GetProperty(aura::client::kShowStateKey) ==
111      ui::SHOW_STATE_MINIMIZED;
112}
113
114bool IsWindowFullscreen(const aura::Window* window) {
115  return window->GetProperty(aura::client::kShowStateKey) ==
116      ui::SHOW_STATE_FULLSCREEN;
117}
118
119void MaximizeWindow(aura::Window* window) {
120  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
121}
122
123void MinimizeWindow(aura::Window* window) {
124  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED);
125}
126
127void RestoreWindow(aura::Window* window) {
128  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_NORMAL);
129}
130
131void ToggleMaximizedWindow(aura::Window* window) {
132  if (ash::wm::IsWindowMaximized(window))
133    ash::wm::RestoreWindow(window);
134  else if (ash::wm::CanMaximizeWindow(window))
135    ash::wm::MaximizeWindow(window);
136}
137
138void CenterWindow(aura::Window* window) {
139  const gfx::Display display =
140      Shell::GetScreen()->GetDisplayNearestWindow(window);
141  gfx::Rect center = display.work_area();
142  center.ClampToCenteredSize(window->bounds().size());
143  window->SetBounds(center);
144}
145
146bool IsWindowPositionManaged(const aura::Window* window) {
147  return window->GetProperty(ash::internal::kWindowPositionManagedKey);
148}
149
150void SetWindowPositionManaged(aura::Window* window, bool managed) {
151  window->SetProperty(ash::internal::kWindowPositionManagedKey, managed);
152}
153
154bool HasUserChangedWindowPositionOrSize(const aura::Window* window) {
155  return window->GetProperty(
156      ash::internal::kUserChangedWindowPositionOrSizeKey);
157}
158
159void SetUserHasChangedWindowPositionOrSize(aura::Window* window, bool changed) {
160  window->SetProperty(ash::internal::kUserChangedWindowPositionOrSizeKey,
161                      changed);
162}
163
164const gfx::Rect* GetPreAutoManageWindowBounds(const aura::Window* window) {
165  return window->GetProperty(ash::internal::kPreAutoManagedWindowBoundsKey);
166}
167
168void SetPreAutoManageWindowBounds(aura::Window* window,
169                                const gfx::Rect& bounds) {
170  window->SetProperty(ash::internal::kPreAutoManagedWindowBoundsKey,
171                      new gfx::Rect(bounds));
172}
173
174void AdjustBoundsToEnsureMinimumWindowVisibility(const gfx::Rect& work_area,
175                                                 gfx::Rect* bounds) {
176  AdjustBoundsToEnsureWindowVisibility(
177      work_area, kMinimumOnScreenArea, kMinimumOnScreenArea, bounds);
178}
179
180void AdjustBoundsToEnsureWindowVisibility(const gfx::Rect& work_area,
181                                          int min_width,
182                                          int min_height,
183                                          gfx::Rect* bounds) {
184  bounds->set_width(std::min(bounds->width(), work_area.width()));
185  bounds->set_height(std::min(bounds->height(), work_area.height()));
186  if (!work_area.Intersects(*bounds)) {
187    int y_offset = 0;
188    if (work_area.bottom() < bounds->y()) {
189      y_offset = work_area.bottom() - bounds->y() - min_height;
190    } else if (bounds->bottom() < work_area.y()) {
191      y_offset = work_area.y() - bounds->bottom() + min_height;
192    }
193
194    int x_offset = 0;
195    if (work_area.right() < bounds->x()) {
196      x_offset = work_area.right() - bounds->x() - min_width;
197    } else if (bounds->right() < work_area.x()) {
198      x_offset = work_area.x() - bounds->right() + min_width;
199    }
200    bounds->Offset(x_offset, y_offset);
201  }
202}
203
204}  // namespace wm
205}  // namespace ash
206