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