123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- // Copyright 2015 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/window_dimmer.h"
- #include "ash/root_window_controller.h"
- #include "ash/style/ash_color_provider_source.h"
- #include "ash/style/style_util.h"
- #include "base/time/time.h"
- #include "ui/aura/window.h"
- #include "ui/color/color_id.h"
- #include "ui/color/color_provider.h"
- #include "ui/color/color_provider_source_observer.h"
- #include "ui/compositor/layer.h"
- #include "ui/wm/core/visibility_controller.h"
- #include "ui/wm/core/window_animations.h"
- namespace ash {
- namespace {
- const int kDefaultDimAnimationDurationMs = 200;
- const float kDefaultDimOpacity = 0.5f;
- } // namespace
- WindowDimmer::WindowDimmer(aura::Window* parent,
- bool animate,
- Delegate* delegate)
- : parent_(parent),
- window_(new aura::Window(nullptr, aura::client::WINDOW_TYPE_NORMAL)),
- delegate_(delegate) {
- window_->Init(ui::LAYER_SOLID_COLOR);
- window_->SetName("Dimming Window");
- if (animate) {
- ::wm::SetWindowVisibilityChangesAnimated(window_);
- ::wm::SetWindowVisibilityAnimationType(
- window_, ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
- ::wm::SetWindowVisibilityAnimationDuration(
- window_, base::Milliseconds(kDefaultDimAnimationDurationMs));
- }
- window_->AddObserver(this);
- SetDimOpacity(kDefaultDimOpacity);
- parent->AddChild(window_);
- parent->AddObserver(this);
- parent->StackChildAtTop(window_);
- // The window is not fully opaque. Set the transparent bit so that it
- // interacts properly with aura::WindowOcclusionTracker.
- // https://crbug.com/833814
- window_->SetTransparent(true);
- window_->SetBounds(gfx::Rect(parent_->bounds().size()));
- // `this` may already start observing the color provider source through
- // `OnWindowAddedToRootWindow` if `window_` is alreadyed added to the root
- // window.
- if (!GetColorProviderSource()) {
- auto* color_provider_source =
- StyleUtil::GetColorProviderSourceForWindow(window_);
- if (color_provider_source)
- ui::ColorProviderSourceObserver::Observe(color_provider_source);
- }
- }
- WindowDimmer::~WindowDimmer() {
- if (parent_)
- parent_->RemoveObserver(this);
- if (window_) {
- window_->RemoveObserver(this);
- // See class description for details on ownership.
- delete window_;
- }
- }
- void WindowDimmer::SetDimOpacity(float target_opacity) {
- // Once this function is called, reset the `dim_color_type_`, which means we
- // don't need to update the color on window's layer on native theme updated.
- // Since after this call the color on the layer will be updated to the default
- // dimming color which is Black.
- dim_color_type_.reset();
- DCHECK(window_);
- window_->layer()->SetColor(SkColorSetA(SK_ColorBLACK, 255 * target_opacity));
- }
- void WindowDimmer::SetDimColor(ui::ColorId color_id) {
- DCHECK(window_);
- dim_color_type_ = color_id;
- UpdateDimColor();
- }
- void WindowDimmer::OnWindowBoundsChanged(aura::Window* window,
- const gfx::Rect& old_bounds,
- const gfx::Rect& new_bounds,
- ui::PropertyChangeReason reason) {
- if (window == parent_)
- window_->SetBounds(gfx::Rect(new_bounds.size()));
- }
- void WindowDimmer::OnWindowDestroying(aura::Window* window) {
- if (window == parent_) {
- parent_->RemoveObserver(this);
- parent_ = nullptr;
- if (delegate_) {
- delegate_->OnDimmedWindowDestroying(window);
- // `this` can be deleted above. So don't access any member after this.
- }
- } else {
- DCHECK_EQ(window_, window);
- window_->RemoveObserver(this);
- window_ = nullptr;
- }
- }
- void WindowDimmer::OnWindowHierarchyChanging(
- const HierarchyChangeParams& params) {
- if (params.receiver == window_ && params.target == params.receiver) {
- // This may happen on a display change or some unexpected condition. Hide
- // the window to ensure it isn't obscuring the wrong thing.
- window_->Hide();
- }
- }
- void WindowDimmer::OnWindowParentChanged(aura::Window* window,
- aura::Window* parent) {
- if (delegate_ && window == parent_)
- delegate_->OnDimmedWindowParentChanged(window);
- }
- void WindowDimmer::OnWindowAddedToRootWindow(aura::Window* window) {
- if (GetColorProviderSource())
- return;
- // There's a chance when `this` is being created, `window_` is not added to
- // the root window yet, hence we should observe the `color_provider_source`
- // which is owned by the `RootWindowController` here.
- auto* color_provider_source =
- StyleUtil::GetColorProviderSourceForWindow(window);
- DCHECK(color_provider_source);
- ui::ColorProviderSourceObserver::Observe(color_provider_source);
- UpdateDimColor();
- }
- void WindowDimmer::OnColorProviderChanged() {
- UpdateDimColor();
- }
- void WindowDimmer::UpdateDimColor() {
- if (!window_)
- return;
- if (!dim_color_type_.has_value())
- return;
- auto* color_provider_source = GetColorProviderSource();
- if (!color_provider_source)
- return;
- auto dimming_color = color_provider_source->GetColorProvider()->GetColor(
- dim_color_type_.value());
- DCHECK_NE(SkColorGetA(dimming_color), SK_AlphaOPAQUE);
- window_->layer()->SetColor(dimming_color);
- }
- } // namespace ash
|