window_util.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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/screen_util.h" 11#include "ash/shell.h" 12#include "ash/wm/window_properties.h" 13#include "ash/wm/window_state.h" 14#include "ui/aura/client/activation_client.h" 15#include "ui/aura/client/aura_constants.h" 16#include "ui/aura/window.h" 17#include "ui/aura/window_delegate.h" 18#include "ui/aura/window_event_dispatcher.h" 19#include "ui/gfx/display.h" 20#include "ui/gfx/rect.h" 21#include "ui/gfx/screen.h" 22#include "ui/gfx/size.h" 23#include "ui/views/view.h" 24#include "ui/views/widget/widget.h" 25#include "ui/wm/core/window_util.h" 26 27namespace ash { 28namespace wm { 29 30namespace { 31 32// Returns the default width of a snapped window. 33int GetDefaultSnappedWindowWidth(aura::Window* window) { 34 const float kSnappedWidthWorkspaceRatio = 0.5f; 35 36 int work_area_width = 37 ScreenUtil::GetDisplayWorkAreaBoundsInParent(window).width(); 38 int min_width = window->delegate() ? 39 window->delegate()->GetMinimumSize().width() : 0; 40 int ideal_width = 41 static_cast<int>(work_area_width * kSnappedWidthWorkspaceRatio); 42 return std::min(work_area_width, std::max(ideal_width, min_width)); 43} 44 45} // namespace 46 47// TODO(beng): replace many of these functions with the corewm versions. 48void ActivateWindow(aura::Window* window) { 49 ::wm::ActivateWindow(window); 50} 51 52void DeactivateWindow(aura::Window* window) { 53 ::wm::DeactivateWindow(window); 54} 55 56bool IsActiveWindow(aura::Window* window) { 57 return ::wm::IsActiveWindow(window); 58} 59 60aura::Window* GetActiveWindow() { 61 return aura::client::GetActivationClient(Shell::GetPrimaryRootWindow())-> 62 GetActiveWindow(); 63} 64 65aura::Window* GetActivatableWindow(aura::Window* window) { 66 return ::wm::GetActivatableWindow(window); 67} 68 69bool CanActivateWindow(aura::Window* window) { 70 return ::wm::CanActivateWindow(window); 71} 72 73bool IsWindowMinimized(aura::Window* window) { 74 return ash::wm::GetWindowState(window)->IsMinimized(); 75} 76 77void CenterWindow(aura::Window* window) { 78 wm::WindowState* window_state = wm::GetWindowState(window); 79 if (!window_state->IsNormalOrSnapped()) 80 return; 81 const gfx::Display display = 82 Shell::GetScreen()->GetDisplayNearestWindow(window); 83 gfx::Rect center = display.work_area(); 84 gfx::Size size = window->bounds().size(); 85 if (window_state->IsSnapped()) { 86 if (window_state->HasRestoreBounds()) 87 size = window_state->GetRestoreBoundsInScreen().size(); 88 center.ClampToCenteredSize(size); 89 window_state->SetRestoreBoundsInScreen(center); 90 window_state->Restore(); 91 } else { 92 center = ScreenUtil::ConvertRectFromScreen(window->parent(), 93 center); 94 center.ClampToCenteredSize(size); 95 window->SetBounds(center); 96 } 97} 98 99 100gfx::Rect GetDefaultLeftSnappedWindowBoundsInParent(aura::Window* window) { 101 gfx::Rect work_area_in_parent(ScreenUtil::GetDisplayWorkAreaBoundsInParent( 102 window)); 103 return gfx::Rect(work_area_in_parent.x(), 104 work_area_in_parent.y(), 105 GetDefaultSnappedWindowWidth(window), 106 work_area_in_parent.height()); 107} 108 109gfx::Rect GetDefaultRightSnappedWindowBoundsInParent(aura::Window* window) { 110 gfx::Rect work_area_in_parent(ScreenUtil::GetDisplayWorkAreaBoundsInParent( 111 window)); 112 int width = GetDefaultSnappedWindowWidth(window); 113 return gfx::Rect(work_area_in_parent.right() - width, 114 work_area_in_parent.y(), 115 width, 116 work_area_in_parent.height()); 117} 118 119void AdjustBoundsSmallerThan(const gfx::Size& max_size, gfx::Rect* bounds) { 120 bounds->set_width(std::min(bounds->width(), max_size.width())); 121 bounds->set_height(std::min(bounds->height(), max_size.height())); 122} 123 124void AdjustBoundsToEnsureMinimumWindowVisibility(const gfx::Rect& visible_area, 125 gfx::Rect* bounds) { 126 AdjustBoundsToEnsureWindowVisibility( 127 visible_area, kMinimumOnScreenArea, kMinimumOnScreenArea, bounds); 128} 129 130void AdjustBoundsToEnsureWindowVisibility(const gfx::Rect& visible_area, 131 int min_width, 132 int min_height, 133 gfx::Rect* bounds) { 134 AdjustBoundsSmallerThan(visible_area.size(), bounds); 135 136 min_width = std::min(min_width, visible_area.width()); 137 min_height = std::min(min_height, visible_area.height()); 138 139 if (bounds->right() < visible_area.x() + min_width) { 140 bounds->set_x(visible_area.x() + min_width - bounds->width()); 141 } else if (bounds->x() > visible_area.right() - min_width) { 142 bounds->set_x(visible_area.right() - min_width); 143 } 144 if (bounds->bottom() < visible_area.y() + min_height) { 145 bounds->set_y(visible_area.y() + min_height - bounds->height()); 146 } else if (bounds->y() > visible_area.bottom() - min_height) { 147 bounds->set_y(visible_area.bottom() - min_height); 148 } 149 if (bounds->y() < visible_area.y()) 150 bounds->set_y(visible_area.y()); 151} 152 153bool MoveWindowToEventRoot(aura::Window* window, const ui::Event& event) { 154 views::View* target = static_cast<views::View*>(event.target()); 155 if (!target) 156 return false; 157 aura::Window* target_root = 158 target->GetWidget()->GetNativeView()->GetRootWindow(); 159 if (!target_root || target_root == window->GetRootWindow()) 160 return false; 161 aura::Window* window_container = 162 ash::Shell::GetContainer(target_root, window->parent()->id()); 163 // Move the window to the target launcher. 164 window_container->AddChild(window); 165 return true; 166} 167 168void ReparentChildWithTransientChildren(aura::Window* child, 169 aura::Window* old_parent, 170 aura::Window* new_parent) { 171 if (child->parent() == old_parent) 172 new_parent->AddChild(child); 173 ReparentTransientChildrenOfChild(child, old_parent, new_parent); 174} 175 176void ReparentTransientChildrenOfChild(aura::Window* child, 177 aura::Window* old_parent, 178 aura::Window* new_parent) { 179 for (size_t i = 0; 180 i < ::wm::GetTransientChildren(child).size(); 181 ++i) { 182 ReparentChildWithTransientChildren( 183 ::wm::GetTransientChildren(child)[i], 184 old_parent, 185 new_parent); 186 } 187} 188 189} // namespace wm 190} // namespace ash 191