1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/maximize_mode/workspace_backdrop_delegate.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/window_animations.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ash/wm/window_util.h" 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/auto_reset.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window.h" 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/compositor/layer.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h" 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/views/background.h" 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/views/widget/widget.h" 1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/wm/core/window_animations.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_util.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace ash { 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// The opacity of the backdrop. 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const float kBackdropOpacity = 0.5f; 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)WorkspaceBackdropDelegate::WorkspaceBackdropDelegate(aura::Window* container) 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : background_(NULL), 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) container_(container), 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) in_restacking_(false) { 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_ = new views::Widget; 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) views::Widget::InitParams params( 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params.parent = container_; 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) params.bounds = container_->GetBoundsInScreen(); 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params.layer_type = aura::WINDOW_LAYER_SOLID_COLOR; 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // To disallow the MRU list from picking this window up it should not be 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // activateable. 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) params.activatable = views::Widget::InitParams::ACTIVATABLE_NO; 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->Init(params); 400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Do not use the animation system. We don't want the bounds animation and 410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // opacity needs to get set to |kBackdropOpacity|. 420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ::wm::SetWindowVisibilityAnimationTransition( 430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch background_->GetNativeView(), 440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ::wm::ANIMATE_NONE); 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->SetName("WorkspaceBackdropDelegate"); 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->SetColor(SK_ColorBLACK); 470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Make sure that the layer covers visibly everything - including the shelf. 480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch background_->GetNativeView()->layer()->SetBounds(params.bounds); 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Show(); 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RestackBackdrop(); 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) container_->AddObserver(this); 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)WorkspaceBackdropDelegate::~WorkspaceBackdropDelegate() { 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) container_->RemoveObserver(this); 5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ::wm::ScopedHidingAnimationSettings hiding_settings( 5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) background_->GetNativeView()); 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->Close(); 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->SetOpacity(0.0f); 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnWindowBoundsChanged( 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* window, 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect& old_bounds, 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect& new_bounds) { 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The container size has changed and the layer needs to be adapt to it. 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AdjustToContainerBounds(); 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnWindowAddedToLayout(aura::Window* child) { 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RestackBackdrop(); 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnWindowRemovedFromLayout(aura::Window* child) { 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RestackBackdrop(); 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnChildWindowVisibilityChanged( 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* child, 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool visible) { 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RestackBackdrop(); 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnWindowStackingChanged(aura::Window* window) { 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RestackBackdrop(); 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnPostWindowStateTypeChange( 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) wm::WindowState* window_state, 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) wm::WindowStateType old_type) { 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RestackBackdrop(); 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void WorkspaceBackdropDelegate::OnDisplayWorkAreaInsetsChanged() { 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AdjustToContainerBounds(); 96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::RestackBackdrop() { 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Avoid recursive calls. 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (in_restacking_) 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* window = GetCurrentTopWindow(); 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!window) { 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Hide backdrop since no suitable window was found. 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->Hide(); 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (window == background_->GetNativeWindow() && 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->IsVisible()) { 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We are changing the order of windows which will cause recursion. 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::AutoReset<bool> lock(&in_restacking_, true); 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!background_->IsVisible()) 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Show(); 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Since the backdrop needs to be immediately behind the window and the 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // stacking functions only guarantee a "it's above or below", we need 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // to re-arrange the two windows twice. 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) container_->StackChildAbove(background_->GetNativeView(), window); 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) container_->StackChildAbove(window, background_->GetNativeView()); 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)aura::Window* WorkspaceBackdropDelegate::GetCurrentTopWindow() { 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const aura::Window::Windows& windows = container_->children(); 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (aura::Window::Windows::const_reverse_iterator window_iter = 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) windows.rbegin(); 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_iter != windows.rend(); ++window_iter) { 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* window = *window_iter; 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (window->TargetVisibility() && 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->type() == ui::wm::WINDOW_TYPE_NORMAL && 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::wm::CanActivateWindow(window)) 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return window; 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NULL; 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::AdjustToContainerBounds() { 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Cover the entire container window. 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect target_rect(gfx::Point(0, 0), container_->bounds().size()); 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (target_rect != background_->GetNativeWindow()->bounds()) { 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This needs to be instant. 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::ScopedLayerAnimationSettings settings( 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->GetAnimator()); 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(0)); 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeWindow()->SetBounds(target_rect); 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!background_->IsVisible()) 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->SetOpacity(kBackdropOpacity); 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::Show() { 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->SetOpacity(0.0f); 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->Show(); 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::ScopedLayerAnimationSettings settings( 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->GetAnimator()); 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->SetOpacity(kBackdropOpacity); 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace ash 161