| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 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/aura/wm_window_aura.h" |
| 6 |
| 7 #include "ash/screen_util.h" |
| 8 #include "ash/wm/aura/wm_root_window_controller_aura.h" |
| 9 #include "ash/wm/common/wm_window_observer.h" |
| 10 #include "ash/wm/common/wm_window_property.h" |
| 11 #include "ash/wm/window_animations.h" |
| 12 #include "ash/wm/window_properties.h" |
| 13 #include "ash/wm/window_state.h" |
| 14 #include "ash/wm/window_state_aura.h" |
| 15 #include "ash/wm/window_util.h" |
| 16 #include "ui/aura/client/aura_constants.h" |
| 17 #include "ui/aura/layout_manager.h" |
| 18 #include "ui/aura/window.h" |
| 19 #include "ui/aura/window_delegate.h" |
| 20 #include "ui/aura/window_property.h" |
| 21 #include "ui/base/hit_test.h" |
| 22 #include "ui/compositor/layer_tree_owner.h" |
| 23 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 24 #include "ui/gfx/screen.h" |
| 25 #include "ui/wm/core/coordinate_conversion.h" |
| 26 #include "ui/wm/core/window_util.h" |
| 27 |
| 28 DECLARE_WINDOW_PROPERTY_TYPE(ash::wm::WmWindowAura*); |
| 29 |
| 30 namespace ash { |
| 31 namespace wm { |
| 32 |
| 33 DEFINE_OWNED_WINDOW_PROPERTY_KEY(ash::wm::WmWindowAura, kWmWindowKey, nullptr); |
| 34 |
| 35 namespace { |
| 36 |
| 37 // A tentative class to set the bounds on the window. |
| 38 // TODO(oshima): Once all logic is cleaned up, move this to the real layout |
| 39 // manager with proper friendship. |
| 40 class BoundsSetter : public aura::LayoutManager { |
| 41 public: |
| 42 BoundsSetter() {} |
| 43 ~BoundsSetter() override {} |
| 44 |
| 45 // aura::LayoutManager overrides: |
| 46 void OnWindowResized() override {} |
| 47 void OnWindowAddedToLayout(aura::Window* child) override {} |
| 48 void OnWillRemoveWindowFromLayout(aura::Window* child) override {} |
| 49 void OnWindowRemovedFromLayout(aura::Window* child) override {} |
| 50 void OnChildWindowVisibilityChanged(aura::Window* child, |
| 51 bool visible) override {} |
| 52 void SetChildBounds(aura::Window* child, |
| 53 const gfx::Rect& requested_bounds) override {} |
| 54 |
| 55 void SetBounds(aura::Window* window, const gfx::Rect& bounds) { |
| 56 SetChildBoundsDirect(window, bounds); |
| 57 } |
| 58 |
| 59 private: |
| 60 DISALLOW_COPY_AND_ASSIGN(BoundsSetter); |
| 61 }; |
| 62 |
| 63 } // namespace |
| 64 |
| 65 WmWindowAura::WmWindowAura(aura::Window* window) : window_(window) { |
| 66 window_->AddObserver(this); |
| 67 window_->SetProperty(kWmWindowKey, this); |
| 68 } |
| 69 |
| 70 // static |
| 71 WmWindow* WmWindowAura::Get(aura::Window* window) { |
| 72 if (!window) |
| 73 return nullptr; |
| 74 |
| 75 WmWindow* wm_window = window->GetProperty(kWmWindowKey); |
| 76 if (wm_window) |
| 77 return wm_window; |
| 78 // WmWindowAura is owned by the aura::Window. |
| 79 return new WmWindowAura(window); |
| 80 } |
| 81 |
| 82 // static |
| 83 const aura::Window* WmWindowAura::GetAuraWindow(const WmWindow* wm_window) { |
| 84 return static_cast<const WmWindowAura*>(wm_window)->aura_window(); |
| 85 } |
| 86 |
| 87 const WmWindow* WmWindowAura::GetRootWindow() const { |
| 88 return Get(window_->GetRootWindow()); |
| 89 } |
| 90 |
| 91 WmRootWindowController* WmWindowAura::GetRootWindowController() { |
| 92 aura::Window* root = window_->GetRootWindow(); |
| 93 return root ? WmRootWindowControllerAura::Get(root) : nullptr; |
| 94 } |
| 95 |
| 96 int WmWindowAura::GetShellWindowId() { |
| 97 return window_->id(); |
| 98 } |
| 99 |
| 100 ui::wm::WindowType WmWindowAura::GetType() const { |
| 101 return window_->type(); |
| 102 } |
| 103 |
| 104 ui::Layer* WmWindowAura::GetLayer() { |
| 105 return window_->layer(); |
| 106 } |
| 107 |
| 108 gfx::Display WmWindowAura::GetDisplayNearestWindow() { |
| 109 return gfx::Screen::GetScreen()->GetDisplayNearestWindow(window_); |
| 110 } |
| 111 |
| 112 bool WmWindowAura::HasNonClientArea() { |
| 113 return window_->delegate() ? true : false; |
| 114 } |
| 115 |
| 116 int WmWindowAura::GetNonClientComponent(const gfx::Point& location) { |
| 117 return window_->delegate() |
| 118 ? window_->delegate()->GetNonClientComponent(location) |
| 119 : HTNOWHERE; |
| 120 } |
| 121 |
| 122 gfx::Point WmWindowAura::ConvertPointToTarget(const WmWindow* target, |
| 123 const gfx::Point& point) const { |
| 124 gfx::Point result(point); |
| 125 aura::Window::ConvertPointToTarget(window_, GetAuraWindow(target), &result); |
| 126 return result; |
| 127 } |
| 128 |
| 129 gfx::Point WmWindowAura::ConvertPointToScreen(const gfx::Point& point) const { |
| 130 gfx::Point result(point); |
| 131 ::wm::ConvertPointToScreen(window_, &result); |
| 132 return result; |
| 133 } |
| 134 |
| 135 gfx::Point WmWindowAura::ConvertPointFromScreen(const gfx::Point& point) const { |
| 136 gfx::Point result(point); |
| 137 ::wm::ConvertPointFromScreen(window_, &result); |
| 138 return result; |
| 139 } |
| 140 |
| 141 gfx::Rect WmWindowAura::ConvertRectToScreen(const gfx::Rect& rect) const { |
| 142 return ScreenUtil::ConvertRectToScreen(window_, rect); |
| 143 } |
| 144 |
| 145 gfx::Rect WmWindowAura::ConvertRectFromScreen(const gfx::Rect& rect) const { |
| 146 return ScreenUtil::ConvertRectFromScreen(window_, rect); |
| 147 } |
| 148 |
| 149 gfx::Size WmWindowAura::GetMinimumSize() { |
| 150 return window_->delegate() ? window_->delegate()->GetMinimumSize() |
| 151 : gfx::Size(); |
| 152 } |
| 153 |
| 154 gfx::Size WmWindowAura::GetMaximumSize() { |
| 155 return window_->delegate() ? window_->delegate()->GetMaximumSize() |
| 156 : gfx::Size(); |
| 157 } |
| 158 |
| 159 bool WmWindowAura::GetTargetVisibility() const { |
| 160 return window_->TargetVisibility(); |
| 161 } |
| 162 |
| 163 bool WmWindowAura::IsVisible() const { |
| 164 return window_->IsVisible(); |
| 165 } |
| 166 |
| 167 bool WmWindowAura::GetBoolProperty(WmWindowProperty key) { |
| 168 switch (key) { |
| 169 case WmWindowProperty::SNAP_CHILDREN_TO_PIXEL_BOUDARY: |
| 170 return window_->GetProperty(kSnapChildrenToPixelBoundary); |
| 171 |
| 172 case WmWindowProperty::ALWAYS_ON_TOP: |
| 173 return window_->GetProperty(aura::client::kAlwaysOnTopKey); |
| 174 } |
| 175 |
| 176 NOTREACHED(); |
| 177 return false; |
| 178 } |
| 179 |
| 180 WindowState* WmWindowAura::GetWindowState() { |
| 181 return ash::wm::GetWindowState(window_); |
| 182 } |
| 183 |
| 184 WmWindow* WmWindowAura::GetToplevelWindow() { |
| 185 return Get(window_->GetToplevelWindow()); |
| 186 } |
| 187 |
| 188 WmWindow* WmWindowAura::GetParent() { |
| 189 return Get(window_->parent()); |
| 190 } |
| 191 |
| 192 WmWindow* WmWindowAura::GetTransientParent() { |
| 193 return Get(::wm::GetTransientParent(window_)); |
| 194 } |
| 195 |
| 196 void WmWindowAura::SetBounds(const gfx::Rect& bounds) { |
| 197 window_->SetBounds(bounds); |
| 198 } |
| 199 |
| 200 void WmWindowAura::SetBoundsDirect(const gfx::Rect& bounds) { |
| 201 BoundsSetter().SetBounds(window_, bounds); |
| 202 SnapWindowToPixelBoundary(window_); |
| 203 } |
| 204 |
| 205 void WmWindowAura::SetBoundsDirectAnimated(const gfx::Rect& bounds) { |
| 206 const int kBoundsChangeSlideDurationMs = 120; |
| 207 |
| 208 ui::Layer* layer = window_->layer(); |
| 209 ui::ScopedLayerAnimationSettings slide_settings(layer->GetAnimator()); |
| 210 slide_settings.SetPreemptionStrategy( |
| 211 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); |
| 212 slide_settings.SetTransitionDuration( |
| 213 base::TimeDelta::FromMilliseconds(kBoundsChangeSlideDurationMs)); |
| 214 SetBoundsDirect(bounds); |
| 215 } |
| 216 |
| 217 void WmWindowAura::SetBoundsDirectCrossFade(const gfx::Rect& bounds) { |
| 218 const gfx::Rect old_bounds = window_->bounds(); |
| 219 |
| 220 // Create fresh layers for the window and all its children to paint into. |
| 221 // Takes ownership of the old layer and all its children, which will be |
| 222 // cleaned up after the animation completes. |
| 223 // Specify |set_bounds| to true here to keep the old bounds in the child |
| 224 // windows of |window|. |
| 225 std::unique_ptr<ui::LayerTreeOwner> old_layer_owner = |
| 226 ::wm::RecreateLayers(window_); |
| 227 ui::Layer* old_layer = old_layer_owner->root(); |
| 228 DCHECK(old_layer); |
| 229 ui::Layer* new_layer = window_->layer(); |
| 230 |
| 231 // Resize the window to the new size, which will force a layout and paint. |
| 232 SetBoundsDirect(bounds); |
| 233 |
| 234 // Ensure the higher-resolution layer is on top. |
| 235 bool old_on_top = (old_bounds.width() > bounds.width()); |
| 236 if (old_on_top) |
| 237 old_layer->parent()->StackBelow(new_layer, old_layer); |
| 238 else |
| 239 old_layer->parent()->StackAbove(new_layer, old_layer); |
| 240 |
| 241 CrossFadeAnimation(window_, std::move(old_layer_owner), gfx::Tween::EASE_OUT); |
| 242 } |
| 243 |
| 244 void WmWindowAura::SetBoundsInScreen(const gfx::Rect& bounds_in_screen, |
| 245 const gfx::Display& dst_display) { |
| 246 window_->SetBoundsInScreen(bounds_in_screen, dst_display); |
| 247 } |
| 248 |
| 249 gfx::Rect WmWindowAura::GetBoundsInScreen() const { |
| 250 return window_->GetBoundsInScreen(); |
| 251 } |
| 252 |
| 253 const gfx::Rect& WmWindowAura::GetBounds() const { |
| 254 return window_->bounds(); |
| 255 } |
| 256 |
| 257 gfx::Rect WmWindowAura::GetTargetBounds() { |
| 258 return window_->GetTargetBounds(); |
| 259 } |
| 260 |
| 261 void WmWindowAura::ClearRestoreBounds() { |
| 262 window_->ClearProperty(aura::client::kRestoreBoundsKey); |
| 263 } |
| 264 |
| 265 void WmWindowAura::SetRestoreBoundsInScreen(const gfx::Rect& bounds) { |
| 266 window_->SetProperty(aura::client::kRestoreBoundsKey, new gfx::Rect(bounds)); |
| 267 } |
| 268 |
| 269 gfx::Rect WmWindowAura::GetRestoreBoundsInScreen() const { |
| 270 return *window_->GetProperty(aura::client::kRestoreBoundsKey); |
| 271 } |
| 272 |
| 273 void WmWindowAura::OnWMEvent(const wm::WMEvent* event) { |
| 274 ash::wm::GetWindowState(window_)->OnWMEvent(event); |
| 275 } |
| 276 |
| 277 bool WmWindowAura::Contains(const WmWindow* other) const { |
| 278 return other |
| 279 ? window_->Contains( |
| 280 static_cast<const WmWindowAura*>(other)->window_) |
| 281 : false; |
| 282 } |
| 283 |
| 284 void WmWindowAura::SetShowState(ui::WindowShowState show_state) { |
| 285 window_->SetProperty(aura::client::kShowStateKey, show_state); |
| 286 } |
| 287 |
| 288 ui::WindowShowState WmWindowAura::GetShowState() const { |
| 289 return window_->GetProperty(aura::client::kShowStateKey); |
| 290 } |
| 291 |
| 292 void WmWindowAura::SetCapture() { |
| 293 window_->SetCapture(); |
| 294 } |
| 295 |
| 296 bool WmWindowAura::HasCapture() { |
| 297 return window_->HasCapture(); |
| 298 } |
| 299 |
| 300 void WmWindowAura::ReleaseCapture() { |
| 301 window_->ReleaseCapture(); |
| 302 } |
| 303 |
| 304 bool WmWindowAura::HasRestoreBounds() const { |
| 305 return window_->GetProperty(aura::client::kRestoreBoundsKey) != nullptr; |
| 306 } |
| 307 |
| 308 bool WmWindowAura::CanMaximize() const { |
| 309 return window_->GetProperty(aura::client::kCanMaximizeKey); |
| 310 } |
| 311 |
| 312 bool WmWindowAura::CanMinimize() const { |
| 313 return window_->GetProperty(aura::client::kCanMinimizeKey); |
| 314 } |
| 315 |
| 316 bool WmWindowAura::CanResize() const { |
| 317 return window_->GetProperty(aura::client::kCanResizeKey); |
| 318 } |
| 319 |
| 320 bool WmWindowAura::CanActivate() const { |
| 321 return ::wm::CanActivateWindow(window_); |
| 322 } |
| 323 |
| 324 void WmWindowAura::StackChildAtTop(WmWindow* child) { |
| 325 window_->StackChildAtTop(GetAuraWindow(child)); |
| 326 } |
| 327 |
| 328 void WmWindowAura::StackChildAbove(WmWindow* child, WmWindow* target) { |
| 329 window_->StackChildAbove(GetAuraWindow(child), GetAuraWindow(target)); |
| 330 } |
| 331 |
| 332 void WmWindowAura::StackChildBelow(WmWindow* child, WmWindow* target) { |
| 333 window_->StackChildBelow(GetAuraWindow(child), GetAuraWindow(target)); |
| 334 } |
| 335 |
| 336 void WmWindowAura::SetAlwaysOnTop(bool value) { |
| 337 window_->SetProperty(aura::client::kAlwaysOnTopKey, value); |
| 338 } |
| 339 |
| 340 bool WmWindowAura::IsAlwaysOnTop() const { |
| 341 return window_->GetProperty(aura::client::kAlwaysOnTopKey); |
| 342 } |
| 343 |
| 344 void WmWindowAura::Hide() { |
| 345 window_->Hide(); |
| 346 } |
| 347 |
| 348 void WmWindowAura::Show() { |
| 349 window_->Show(); |
| 350 } |
| 351 |
| 352 bool WmWindowAura::IsActive() const { |
| 353 return IsActiveWindow(window_); |
| 354 } |
| 355 |
| 356 void WmWindowAura::Activate() { |
| 357 ActivateWindow(window_); |
| 358 } |
| 359 |
| 360 void WmWindowAura::Deactivate() { |
| 361 DeactivateWindow(window_); |
| 362 } |
| 363 |
| 364 void WmWindowAura::Maximize() { |
| 365 return window_->SetProperty(aura::client::kShowStateKey, |
| 366 ui::SHOW_STATE_MAXIMIZED); |
| 367 } |
| 368 |
| 369 void WmWindowAura::Minimize() { |
| 370 window_->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MINIMIZED); |
| 371 } |
| 372 |
| 373 void WmWindowAura::Unminimize() { |
| 374 window_->SetProperty( |
| 375 aura::client::kShowStateKey, |
| 376 window_->GetProperty(aura::client::kRestoreShowStateKey)); |
| 377 window_->ClearProperty(aura::client::kRestoreShowStateKey); |
| 378 } |
| 379 |
| 380 std::vector<WmWindow*> WmWindowAura::GetChildren() { |
| 381 const std::vector<aura::Window*>& aura_children = window_->children(); |
| 382 std::vector<WmWindow*> result(aura_children.size()); |
| 383 for (size_t i = 0; i < aura_children.size(); ++i) |
| 384 result[i] = Get(aura_children[i]); |
| 385 return result; |
| 386 } |
| 387 |
| 388 WmWindow* WmWindowAura::GetChildByShellWindowId(int id) { |
| 389 return Get(window_->GetChildById(id)); |
| 390 } |
| 391 |
| 392 void WmWindowAura::AddObserver(WmWindowObserver* observer) { |
| 393 observers_.AddObserver(observer); |
| 394 } |
| 395 |
| 396 void WmWindowAura::RemoveObserver(WmWindowObserver* observer) { |
| 397 observers_.RemoveObserver(observer); |
| 398 } |
| 399 |
| 400 WmWindowAura::~WmWindowAura() { |
| 401 window_->RemoveObserver(this); |
| 402 } |
| 403 |
| 404 void WmWindowAura::OnWindowHierarchyChanged( |
| 405 const HierarchyChangeParams& params) { |
| 406 WmWindowObserver::TreeChangeParams wm_params; |
| 407 wm_params.target = Get(params.target); |
| 408 wm_params.new_parent = Get(params.new_parent); |
| 409 wm_params.old_parent = Get(params.old_parent); |
| 410 FOR_EACH_OBSERVER(WmWindowObserver, observers_, |
| 411 OnWindowTreeChanged(this, wm_params)); |
| 412 } |
| 413 |
| 414 void WmWindowAura::OnWindowStackingChanged(aura::Window* window) { |
| 415 FOR_EACH_OBSERVER(WmWindowObserver, observers_, |
| 416 OnWindowStackingChanged(this)); |
| 417 } |
| 418 |
| 419 void WmWindowAura::OnWindowPropertyChanged(aura::Window* window, |
| 420 const void* key, |
| 421 intptr_t old) { |
| 422 if (key == aura::client::kShowStateKey) { |
| 423 ash::wm::GetWindowState(window_)->OnWindowShowStateChanged(); |
| 424 return; |
| 425 } |
| 426 WmWindowProperty wm_property; |
| 427 if (key == kSnapChildrenToPixelBoundary) { |
| 428 wm_property = WmWindowProperty::SNAP_CHILDREN_TO_PIXEL_BOUDARY; |
| 429 } else if (key == aura::client::kAlwaysOnTopKey) { |
| 430 wm_property = WmWindowProperty::ALWAYS_ON_TOP; |
| 431 } else { |
| 432 return; |
| 433 } |
| 434 FOR_EACH_OBSERVER(WmWindowObserver, observers_, |
| 435 OnWindowPropertyChanged(this, wm_property, old)); |
| 436 } |
| 437 |
| 438 void WmWindowAura::OnWindowBoundsChanged(aura::Window* window, |
| 439 const gfx::Rect& old_bounds, |
| 440 const gfx::Rect& new_bounds) { |
| 441 FOR_EACH_OBSERVER(WmWindowObserver, observers_, |
| 442 OnWindowBoundsChanged(this, old_bounds, new_bounds)); |
| 443 } |
| 444 |
| 445 void WmWindowAura::OnWindowDestroying(aura::Window* window) { |
| 446 FOR_EACH_OBSERVER(WmWindowObserver, observers_, OnWindowDestroying(this)); |
| 447 } |
| 448 |
| 449 } // namespace wm |
| 450 } // namespace ash |
| OLD | NEW |