Chromium Code Reviews| Index: ash/wm/maximize_mode/workspace_backdrop_delegate.cc |
| diff --git a/ash/wm/maximize_mode/workspace_backdrop_delegate.cc b/ash/wm/maximize_mode/workspace_backdrop_delegate.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b03ea253892f69081aa2686e97389e2276f57022 |
| --- /dev/null |
| +++ b/ash/wm/maximize_mode/workspace_backdrop_delegate.cc |
| @@ -0,0 +1,128 @@ |
| +// Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "ash/wm/maximize_mode/workspace_backdrop_delegate.h" |
| + |
| +#include "ash/wm/window_animations.h" |
| +#include "ui/aura/window.h" |
| +#include "ui/compositor/layer.h" |
| +#include "ui/compositor/scoped_layer_animation_settings.h" |
| +#include "ui/views/background.h" |
| +#include "ui/views/corewm/window_util.h" |
| +#include "ui/views/widget/widget.h" |
| + |
| +namespace ash { |
| + |
| +namespace internal { |
| + |
| +namespace { |
| + |
| +// The opacity of the backdrop. |
| +const float kBackdropOpacity = 0.5f; |
| + |
| +} // namespace |
| + |
| +WorkspaceBackdropDelegate::WorkspaceBackdropDelegate(aura::Window* container) |
| + : background_(NULL), |
| + container_(container), |
| + inside_(false) { |
| + background_ = new views::Widget; |
|
sky
2014/03/06 21:34:13
Is there a reason why you don't use a layer direct
Mr4D (OOO till 08-26)
2014/03/07 01:00:12
Yes, swallowing events.
|
| + views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL); |
| + params.parent = container_; |
| + params.bounds = container_->bounds(); |
| + // To disallow the MRU list from picking this window up it should not be |
| + // activateable. |
| + params.can_activate = false; |
| + background_->Init(params); |
| + background_->GetNativeView()->SetName("WorkspaceBackdropDelegate"); |
| + views::View* contents_view = new views::View(); |
| + contents_view->set_background( |
|
sky
2014/03/06 21:34:13
I'm skeptical you need a widget here, but if you d
Mr4D (OOO till 08-26)
2014/03/07 01:00:12
Done.
|
| + views::Background::CreateSolidBackground(SK_ColorBLACK)); |
| + contents_view->SetEnabled(true); |
| + background_->SetContentsView(contents_view); |
| + Show(); |
| + RestackBackdrop(); |
| + container_->AddObserver(this); |
| +} |
| + |
| +WorkspaceBackdropDelegate::~WorkspaceBackdropDelegate() { |
| + container_->RemoveObserver(this); |
| + ui::ScopedLayerAnimationSettings settings( |
| + background_->GetNativeView()->layer()->GetAnimator()); |
| + background_->Close(); |
| + settings.AddObserver(views::corewm::CreateHidingWindowAnimationObserver( |
| + background_->GetNativeView())); |
| + background_->GetNativeView()->layer()->SetOpacity(0.0f); |
| +} |
| + |
| +void WorkspaceBackdropDelegate::RestackBackdrop() { |
| + // Avoid recursive calls. |
| + if (inside_) |
| + return; |
| + // We are stuffing the backdrop behind the first visible & qualifying |
| + // window in the given container. |
| + const aura::Window::Windows& windows = container_->children(); |
| + for (aura::Window::Windows::const_reverse_iterator window_iter = |
|
sky
2014/03/06 21:34:13
nit: I think this would be easier to follow if you
Mr4D (OOO till 08-26)
2014/03/07 01:00:12
Done.
|
| + windows.rbegin(); |
| + window_iter != windows.rend(); ++window_iter) { |
| + aura::Window* window = *window_iter; |
| + if (window->IsVisible() && |
| + window->type() == ui::wm::WINDOW_TYPE_NORMAL) { |
|
sky
2014/03/06 21:34:13
If window has a transient parent in the same conta
Mr4D (OOO till 08-26)
2014/03/07 01:00:12
As long as the transient window can get Alt+Tabbed
|
| + // Check if the window has already the backdrop directly behind it. |
| + if (++window_iter != windows.rend()) { |
| + if (*window_iter == background_->GetNativeWindow() && |
| + background_->IsVisible()) { |
| + return; |
| + } |
| + } |
| + // We are changing the order of windows which will cause recursion. |
| + inside_ = true; |
|
sky
2014/03/06 21:34:13
Use autoreset. Please rename inside_ to better mat
Mr4D (OOO till 08-26)
2014/03/07 01:00:12
Done.
|
| + if (!background_->IsVisible()) |
| + Show(); |
| + // Since the backdrop needs to be immediately behind the window and the |
| + // stacking functions only guarantee a "it's above or below", we need |
| + // to re-arrange the two windows twice. |
| + container_->StackChildAbove(background_->GetNativeView(), window); |
| + container_->StackChildAbove(window, background_->GetNativeView()); |
| + inside_ = false; |
| + return; |
| + } |
| + } |
| + // Hide backdrop since no suitable window was found. |
| + if (background_->IsVisible()) |
| + background_->Hide(); |
| +} |
| + |
| +void WorkspaceBackdropDelegate::OnWindowBoundsChanged(aura::Window* window, |
| + const gfx::Rect& old_bounds, |
| + const gfx::Rect& new_bounds) OVERRIDE { |
| + // The container size has changed and the layer needs to be adapt to it. |
| + AdjustToContainerBounds(); |
| +} |
| + |
| +void WorkspaceBackdropDelegate::AdjustToContainerBounds() { |
| + // Cover the entire container window. |
| + gfx::Rect target_rect(gfx::Point(0, 0), container_->bounds().size()); |
| + if (target_rect != background_->GetNativeWindow()->bounds()) { |
| + // This needs to be instantly. |
| + ui::ScopedLayerAnimationSettings settings( |
| + background_->GetNativeView()->layer()->GetAnimator()); |
| + settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(0)); |
| + background_->GetNativeWindow()->SetBounds(target_rect); |
| + if (!background_->IsVisible()) |
| + background_->GetNativeView()->layer()->SetOpacity(kBackdropOpacity); |
| + } |
| +} |
| + |
| +void WorkspaceBackdropDelegate::Show() { |
| + background_->GetNativeView()->layer()->SetOpacity(0.0f); |
| + background_->Show(); |
| + ui::ScopedLayerAnimationSettings settings( |
| + background_->GetNativeView()->layer()->GetAnimator()); |
| + background_->Show(); |
| + background_->GetNativeView()->layer()->SetOpacity(kBackdropOpacity); |
| +} |
| + |
| +} // namespace internal |
| +} // namespace ash |