summaryrefslogtreecommitdiffstats
path: root/ash/wm/screen_dimmer.cc
blob: 559faaf0d1654c5354adf4553d0ec80bcbd69e92 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Copyright (c) 2012 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/screen_dimmer.h"

#include "ash/shell.h"
#include "ash/wm/dim_window.h"
#include "base/time/time.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_property.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"

DECLARE_WINDOW_PROPERTY_TYPE(ash::ScreenDimmer*);

namespace ash {
namespace {
DEFINE_OWNED_WINDOW_PROPERTY_KEY(ScreenDimmer, kScreenDimmerKey, nullptr);

// Opacity when it's dimming the entire screen.
const float kDimmingLayerOpacityForRoot = 0.4f;

const int kRootWindowMagicId = -100;

std::vector<aura::Window*> GetAllContainers(int container_id) {
  return container_id == kRootWindowMagicId
             ? Shell::GetAllRootWindows()
             : Shell::GetContainersFromAllRootWindows(container_id, nullptr);
}

}  // namespace

// static
ScreenDimmer* ScreenDimmer::GetForContainer(int container_id) {
  aura::Window* primary_container = FindContainer(container_id);
  ScreenDimmer* dimmer = primary_container->GetProperty(kScreenDimmerKey);
  if (!dimmer) {
    dimmer = new ScreenDimmer(container_id);
    primary_container->SetProperty(kScreenDimmerKey, dimmer);
  }
  return dimmer;
}

// static
ScreenDimmer* ScreenDimmer::GetForRoot() {
  ScreenDimmer* dimmer = GetForContainer(kRootWindowMagicId);
  // Root window's dimmer
  dimmer->target_opacity_ = kDimmingLayerOpacityForRoot;
  return dimmer;
}

ScreenDimmer::ScreenDimmer(int container_id)
    : container_id_(container_id),
      target_opacity_(0.5f),
      is_dimming_(false),
      at_bottom_(false) {
  Shell::GetInstance()->AddShellObserver(this);
}

ScreenDimmer::~ScreenDimmer() {
  Shell::GetInstance()->RemoveShellObserver(this);
}

void ScreenDimmer::SetDimming(bool should_dim) {
  if (should_dim == is_dimming_)
    return;
  is_dimming_ = should_dim;

  Update(should_dim);
}

ScreenDimmer* ScreenDimmer::FindForTest(int container_id) {
  return FindContainer(container_id)->GetProperty(kScreenDimmerKey);
}

// static
aura::Window* ScreenDimmer::FindContainer(int container_id) {
  aura::Window* primary = Shell::GetPrimaryRootWindow();
  return container_id == kRootWindowMagicId
             ? primary
             : primary->GetChildById(container_id);
}

void ScreenDimmer::OnRootWindowAdded(aura::Window* root_window) {
  Update(is_dimming_);
}

void ScreenDimmer::Update(bool should_dim) {
  for (aura::Window* container : GetAllContainers(container_id_)) {
    DimWindow* dim = DimWindow::Get(container);
    if (should_dim) {
      if (!dim) {
        dim = new DimWindow(container);
        dim->SetDimOpacity(target_opacity_);
      }
      if (at_bottom_)
        dim->parent()->StackChildAtBottom(dim);
      else
        dim->parent()->StackChildAtTop(dim);
      dim->Show();
    } else {
      if (dim) {
        dim->Hide();
        delete dim;
      }
    }
  }
}

}  // namespace ash