workspace_backdrop_delegate.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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_; 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params.bounds = container_->bounds(); 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. 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params.can_activate = false; 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) 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::RestackBackdrop() { 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Avoid recursive calls. 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (in_restacking_) 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* window = GetCurrentTopWindow(); 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!window) { 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Hide backdrop since no suitable window was found. 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->Hide(); 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (window == background_->GetNativeWindow() && 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->IsVisible()) { 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We are changing the order of windows which will cause recursion. 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::AutoReset<bool> lock(&in_restacking_, true); 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!background_->IsVisible()) 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Show(); 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Since the backdrop needs to be immediately behind the window and the 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // stacking functions only guarantee a "it's above or below", we need 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // to re-arrange the two windows twice. 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) container_->StackChildAbove(background_->GetNativeView(), window); 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) container_->StackChildAbove(window, background_->GetNativeView()); 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)aura::Window* WorkspaceBackdropDelegate::GetCurrentTopWindow() { 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const aura::Window::Windows& windows = container_->children(); 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (aura::Window::Windows::const_reverse_iterator window_iter = 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) windows.rbegin(); 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_iter != windows.rend(); ++window_iter) { 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* window = *window_iter; 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (window->TargetVisibility() && 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->type() == ui::wm::WINDOW_TYPE_NORMAL && 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::wm::CanActivateWindow(window)) 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return window; 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NULL; 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::AdjustToContainerBounds() { 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Cover the entire container window. 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect target_rect(gfx::Point(0, 0), container_->bounds().size()); 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (target_rect != background_->GetNativeWindow()->bounds()) { 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This needs to be instant. 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::ScopedLayerAnimationSettings settings( 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->GetAnimator()); 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(0)); 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeWindow()->SetBounds(target_rect); 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!background_->IsVisible()) 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->SetOpacity(kBackdropOpacity); 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::Show() { 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->SetOpacity(0.0f); 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->Show(); 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::ScopedLayerAnimationSettings settings( 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->GetAnimator()); 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->SetOpacity(kBackdropOpacity); 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace ash 157