workspace_backdrop_delegate.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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" 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/wm/core/window_util.h" 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace ash { 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace internal { 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// The opacity of the backdrop. 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const float kBackdropOpacity = 0.5f; 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)WorkspaceBackdropDelegate::WorkspaceBackdropDelegate(aura::Window* container) 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : background_(NULL), 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) container_(container), 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) in_restacking_(false) { 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_ = new views::Widget; 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) views::Widget::InitParams params( 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params.parent = container_; 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params.bounds = container_->bounds(); 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params.layer_type = aura::WINDOW_LAYER_SOLID_COLOR; 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // To disallow the MRU list from picking this window up it should not be 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // activateable. 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) params.can_activate = false; 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->Init(params); 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->SetName("WorkspaceBackdropDelegate"); 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->SetColor(SK_ColorBLACK); 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Show(); 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RestackBackdrop(); 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) container_->AddObserver(this); 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)WorkspaceBackdropDelegate::~WorkspaceBackdropDelegate() { 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) container_->RemoveObserver(this); 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::ScopedLayerAnimationSettings settings( 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->GetAnimator()); 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->Close(); 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) settings.AddObserver(::wm::CreateHidingWindowAnimationObserver( 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView())); 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->SetOpacity(0.0f); 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnWindowBoundsChanged( 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* window, 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect& old_bounds, 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const gfx::Rect& new_bounds) { 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // The container size has changed and the layer needs to be adapt to it. 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AdjustToContainerBounds(); 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnWindowAddedToLayout(aura::Window* child) { 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RestackBackdrop(); 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnWindowRemovedFromLayout(aura::Window* child) { 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RestackBackdrop(); 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnChildWindowVisibilityChanged( 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* child, 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool visible) { 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RestackBackdrop(); 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnWindowStackingChanged(aura::Window* window) { 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RestackBackdrop(); 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::OnPostWindowStateTypeChange( 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) wm::WindowState* window_state, 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) wm::WindowStateType old_type) { 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RestackBackdrop(); 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::RestackBackdrop() { 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Avoid recursive calls. 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (in_restacking_) 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* window = GetCurrentTopWindow(); 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!window) { 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Hide backdrop since no suitable window was found. 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->Hide(); 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (window == background_->GetNativeWindow() && 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->IsVisible()) { 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // We are changing the order of windows which will cause recursion. 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::AutoReset<bool> lock(&in_restacking_, true); 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!background_->IsVisible()) 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Show(); 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Since the backdrop needs to be immediately behind the window and the 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // stacking functions only guarantee a "it's above or below", we need 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // to re-arrange the two windows twice. 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) container_->StackChildAbove(background_->GetNativeView(), window); 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) container_->StackChildAbove(window, background_->GetNativeView()); 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)aura::Window* WorkspaceBackdropDelegate::GetCurrentTopWindow() { 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const aura::Window::Windows& windows = container_->children(); 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (aura::Window::Windows::const_reverse_iterator window_iter = 120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) windows.rbegin(); 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window_iter != windows.rend(); ++window_iter) { 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) aura::Window* window = *window_iter; 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (window->TargetVisibility() && 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) window->type() == ui::wm::WINDOW_TYPE_NORMAL && 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ash::wm::CanActivateWindow(window)) 126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return window; 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NULL; 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::AdjustToContainerBounds() { 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Cover the entire container window. 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gfx::Rect target_rect(gfx::Point(0, 0), container_->bounds().size()); 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (target_rect != background_->GetNativeWindow()->bounds()) { 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This needs to be instant. 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::ScopedLayerAnimationSettings settings( 137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->GetAnimator()); 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(0)); 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeWindow()->SetBounds(target_rect); 140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!background_->IsVisible()) 141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->SetOpacity(kBackdropOpacity); 142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WorkspaceBackdropDelegate::Show() { 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->SetOpacity(0.0f); 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->Show(); 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ui::ScopedLayerAnimationSettings settings( 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->GetAnimator()); 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) background_->GetNativeView()->layer()->SetOpacity(kBackdropOpacity); 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace internal 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace ash 155