Home | History | Annotate | Download | only in wm
      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 #include "ui/views/view.h"
     26 #include "ui/views/widget/widget.h"
     27 
     28 namespace ash {
     29 namespace wm {
     30 
     31 // TODO(beng): replace many of these functions with the corewm versions.
     32 void ActivateWindow(aura::Window* window) {
     33   views::corewm::ActivateWindow(window);
     34 }
     35 
     36 void DeactivateWindow(aura::Window* window) {
     37   views::corewm::DeactivateWindow(window);
     38 }
     39 
     40 bool IsActiveWindow(aura::Window* window) {
     41   return views::corewm::IsActiveWindow(window);
     42 }
     43 
     44 aura::Window* GetActiveWindow() {
     45   return aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())->
     46       GetActiveWindow();
     47 }
     48 
     49 aura::Window* GetActivatableWindow(aura::Window* window) {
     50   return views::corewm::GetActivatableWindow(window);
     51 }
     52 
     53 bool CanActivateWindow(aura::Window* window) {
     54   return views::corewm::CanActivateWindow(window);
     55 }
     56 
     57 bool CanMaximizeWindow(const aura::Window* window) {
     58   return window->GetProperty(aura::client::kCanMaximizeKey);
     59 }
     60 
     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 
     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());
    133   window->SetBoundsInScreen(center, display);
    134 }
    135 
    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 
    164 void AdjustBoundsToEnsureMinimumWindowVisibility(const gfx::Rect& visible_area,
    165                                                  gfx::Rect* bounds) {
    166   AdjustBoundsToEnsureWindowVisibility(
    167       visible_area, kMinimumOnScreenArea, kMinimumOnScreenArea, bounds);
    168 }
    169 
    170 void AdjustBoundsToEnsureWindowVisibility(const gfx::Rect& visible_area,
    171                                           int min_width,
    172                                           int min_height,
    173                                           gfx::Rect* bounds) {
    174   bounds->set_width(std::min(bounds->width(), visible_area.width()));
    175   bounds->set_height(std::min(bounds->height(), visible_area.height()));
    176 
    177   min_width = std::min(min_width, visible_area.width());
    178   min_height = std::min(min_height, visible_area.height());
    179 
    180   if (bounds->x() + min_width > visible_area.right()) {
    181     bounds->set_x(visible_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 > visible_area.bottom()) {
    186     bounds->set_y(visible_area.bottom() - min_height);
    187   } else if (bounds->bottom() - min_height < 0) {
    188     bounds->set_y(min_height - bounds->height());
    189   }
    190 }
    191 
    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 
    207 }  // namespace wm
    208 }  // namespace ash
    209