OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/exo/shell_surface.h" | 5 #include "components/exo/shell_surface.h" |
6 | 6 |
7 #include <algorithm> | |
8 | |
7 #include "ash/aura/wm_window_aura.h" | 9 #include "ash/aura/wm_window_aura.h" |
10 #include "ash/common/accessibility_delegate.h" | |
8 #include "ash/common/shelf/wm_shelf.h" | 11 #include "ash/common/shelf/wm_shelf.h" |
9 #include "ash/common/shell_window_ids.h" | 12 #include "ash/common/shell_window_ids.h" |
13 #include "ash/common/system/tray/system_tray_notifier.h" | |
10 #include "ash/common/wm/window_resizer.h" | 14 #include "ash/common/wm/window_resizer.h" |
11 #include "ash/common/wm/window_state.h" | 15 #include "ash/common/wm/window_state.h" |
12 #include "ash/common/wm/window_state_delegate.h" | 16 #include "ash/common/wm/window_state_delegate.h" |
13 #include "ash/common/wm_shell.h" | 17 #include "ash/common/wm_shell.h" |
14 #include "ash/wm/window_state_aura.h" | 18 #include "ash/wm/window_state_aura.h" |
15 #include "ash/wm/window_util.h" | 19 #include "ash/wm/window_util.h" |
16 #include "base/logging.h" | 20 #include "base/logging.h" |
17 #include "base/macros.h" | 21 #include "base/macros.h" |
18 #include "base/memory/ptr_util.h" | 22 #include "base/memory/ptr_util.h" |
19 #include "base/strings/utf_string_conversions.h" | 23 #include "base/strings/utf_string_conversions.h" |
(...skipping 10 matching lines...) Expand all Loading... | |
30 #include "ui/base/accelerators/accelerator.h" | 34 #include "ui/base/accelerators/accelerator.h" |
31 #include "ui/gfx/path.h" | 35 #include "ui/gfx/path.h" |
32 #include "ui/views/widget/widget.h" | 36 #include "ui/views/widget/widget.h" |
33 #include "ui/views/widget/widget_observer.h" | 37 #include "ui/views/widget/widget_observer.h" |
34 #include "ui/wm/core/coordinate_conversion.h" | 38 #include "ui/wm/core/coordinate_conversion.h" |
35 #include "ui/wm/core/shadow.h" | 39 #include "ui/wm/core/shadow.h" |
36 #include "ui/wm/core/shadow_controller.h" | 40 #include "ui/wm/core/shadow_controller.h" |
37 #include "ui/wm/core/shadow_types.h" | 41 #include "ui/wm/core/shadow_types.h" |
38 #include "ui/wm/core/window_util.h" | 42 #include "ui/wm/core/window_util.h" |
39 | 43 |
44 #if defined(OS_CHROMEOS) | |
45 #include "chromeos/audio/chromeos_sounds.h" | |
46 #endif | |
47 | |
40 DECLARE_WINDOW_PROPERTY_TYPE(std::string*) | 48 DECLARE_WINDOW_PROPERTY_TYPE(std::string*) |
41 | 49 |
42 namespace exo { | 50 namespace exo { |
43 namespace { | 51 namespace { |
44 | 52 |
45 // This is a struct for accelerator keys used to close ShellSurfaces. | 53 // This is a struct for accelerator keys used to close ShellSurfaces. |
46 const struct Accelerator { | 54 const struct Accelerator { |
47 ui::KeyboardCode keycode; | 55 ui::KeyboardCode keycode; |
48 int modifiers; | 56 int modifiers; |
49 } kCloseWindowAccelerators[] = { | 57 } kCloseWindowAccelerators[] = { |
(...skipping 30 matching lines...) Expand all Loading... | |
80 void SizeConstraintsChanged() override {} | 88 void SizeConstraintsChanged() override {} |
81 | 89 |
82 private: | 90 private: |
83 views::Widget* const widget_; | 91 views::Widget* const widget_; |
84 | 92 |
85 DISALLOW_COPY_AND_ASSIGN(CustomFrameView); | 93 DISALLOW_COPY_AND_ASSIGN(CustomFrameView); |
86 }; | 94 }; |
87 | 95 |
88 class CustomWindowTargeter : public aura::WindowTargeter { | 96 class CustomWindowTargeter : public aura::WindowTargeter { |
89 public: | 97 public: |
90 CustomWindowTargeter() {} | 98 CustomWindowTargeter(views::Widget* widget) : widget_(widget) {} |
91 ~CustomWindowTargeter() override {} | 99 ~CustomWindowTargeter() override {} |
92 | 100 |
93 // Overridden from aura::WindowTargeter: | 101 // Overridden from aura::WindowTargeter: |
94 bool EventLocationInsideBounds(aura::Window* window, | 102 bool EventLocationInsideBounds(aura::Window* window, |
95 const ui::LocatedEvent& event) const override { | 103 const ui::LocatedEvent& event) const override { |
96 Surface* surface = ShellSurface::GetMainSurface(window); | 104 Surface* surface = ShellSurface::GetMainSurface(window); |
97 if (!surface) | 105 if (!surface) |
98 return false; | 106 return false; |
99 | 107 |
100 gfx::Point local_point = event.location(); | 108 gfx::Point local_point = event.location(); |
109 | |
110 // If the underlay is accepting events, test against it's bounds instead | |
111 // since it will be larger than (and contain) the surface's bounds. | |
112 aura::Window* shadow_underlay = | |
113 static_cast<ShellSurface*>( | |
114 widget_->widget_delegate()->GetContentsView()) | |
115 ->shadow_underlay(); | |
116 if (shadow_underlay && !shadow_underlay->ignore_events()) { | |
117 aura::Window::ConvertPointToTarget(window->parent(), shadow_underlay, | |
reveman
2016/09/30 20:51:10
It's confusing that one piece of code assumes wind
erosky
2016/09/30 21:24:16
Done.
| |
118 &local_point); | |
119 return gfx::Rect(shadow_underlay->layer()->size()).Contains(local_point); | |
120 } | |
121 | |
101 if (window->parent()) | 122 if (window->parent()) |
102 aura::Window::ConvertPointToTarget(window->parent(), window, | 123 aura::Window::ConvertPointToTarget(window->parent(), window, |
103 &local_point); | 124 &local_point); |
104 | 125 |
105 aura::Window::ConvertPointToTarget(window, surface->window(), &local_point); | 126 aura::Window::ConvertPointToTarget(window, surface->window(), &local_point); |
106 return surface->HitTestRect(gfx::Rect(local_point, gfx::Size(1, 1))); | 127 return surface->HitTestRect(gfx::Rect(local_point, gfx::Size(1, 1))); |
107 } | 128 } |
108 | 129 |
130 ui::EventTarget* FindTargetForEvent(ui::EventTarget* root, | |
reveman
2016/09/30 20:51:10
FYI, sub-surface can have bounds outside the surfa
erosky
2016/09/30 21:24:16
Acknowledged.
| |
131 ui::Event* event) override { | |
132 aura::Window* window = static_cast<aura::Window*>(root); | |
133 Surface* surface = ShellSurface::GetMainSurface(window); | |
134 | |
135 // Send events which are outside of the surface's bounds to the underlay. | |
136 aura::Window* shadow_underlay = | |
137 static_cast<ShellSurface*>( | |
138 widget_->widget_delegate()->GetContentsView()) | |
139 ->shadow_underlay(); | |
140 if (surface && event->IsLocatedEvent() && shadow_underlay && | |
141 !shadow_underlay->ignore_events()) { | |
142 gfx::Point local_point = event->AsLocatedEvent()->location(); | |
143 aura::Window::ConvertPointToTarget(window, surface->window(), | |
144 &local_point); | |
145 if (!surface->HitTestRect(gfx::Rect(local_point, gfx::Size(1, 1)))) | |
146 return shadow_underlay; | |
147 } | |
148 return aura::WindowTargeter::FindTargetForEvent(root, event); | |
149 } | |
150 | |
109 private: | 151 private: |
152 views::Widget* widget_; | |
reveman
2016/09/30 20:51:10
nit: views::Widget* const widget_;
erosky
2016/09/30 21:24:16
Done.
| |
153 | |
110 DISALLOW_COPY_AND_ASSIGN(CustomWindowTargeter); | 154 DISALLOW_COPY_AND_ASSIGN(CustomWindowTargeter); |
111 }; | 155 }; |
112 | 156 |
113 // Handles a user's fullscreen request (Shift+F4/F4). | 157 // Handles a user's fullscreen request (Shift+F4/F4). |
114 class CustomWindowStateDelegate : public ash::wm::WindowStateDelegate, | 158 class CustomWindowStateDelegate : public ash::wm::WindowStateDelegate, |
115 public views::WidgetObserver { | 159 public views::WidgetObserver { |
116 public: | 160 public: |
117 explicit CustomWindowStateDelegate(views::Widget* widget) : widget_(widget) { | 161 explicit CustomWindowStateDelegate(views::Widget* widget) : widget_(widget) { |
118 widget_->AddObserver(this); | 162 widget_->AddObserver(this); |
119 } | 163 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
159 if (GetFocusManager()->ProcessAccelerator(ui::Accelerator(*event))) | 203 if (GetFocusManager()->ProcessAccelerator(ui::Accelerator(*event))) |
160 event->StopPropagation(); | 204 event->StopPropagation(); |
161 } | 205 } |
162 | 206 |
163 private: | 207 private: |
164 ShellSurface* const shell_surface_; | 208 ShellSurface* const shell_surface_; |
165 | 209 |
166 DISALLOW_COPY_AND_ASSIGN(ShellSurfaceWidget); | 210 DISALLOW_COPY_AND_ASSIGN(ShellSurfaceWidget); |
167 }; | 211 }; |
168 | 212 |
213 class ShadowUnderlayEventHandler : public ui::EventHandler { | |
214 public: | |
215 ShadowUnderlayEventHandler() {} | |
216 ~ShadowUnderlayEventHandler() override {} | |
217 | |
218 // Overridden from ui::EventHandler: | |
219 void OnEvent(ui::Event* event) override { | |
220 // If the event is targeted at the underlay, it means the user has made an | |
221 // interaction that is outside the surface's bounds and we want to capture | |
222 // it (usually when in spoken feedback mode). Handle the event (to prevent | |
223 // behind-windows from receiving it) and play an earcon to notify the user. | |
224 if (event->IsLocatedEvent()) { | |
225 #if defined(OS_CHROMEOS) | |
226 const ui::EventType kEarconEventTypes[] = {ui::ET_MOUSE_PRESSED, | |
227 ui::ET_MOUSEWHEEL, | |
228 ui::ET_TOUCH_PRESSED, | |
229 ui::ET_POINTER_DOWN, | |
230 ui::ET_POINTER_WHEEL_CHANGED, | |
231 ui::ET_GESTURE_BEGIN, | |
232 ui::ET_SCROLL, | |
233 ui::ET_SCROLL_FLING_START}; | |
234 bool is_earcon_event_type = | |
235 std::find(std::begin(kEarconEventTypes), std::end(kEarconEventTypes), | |
236 event->type()) != std::end(kEarconEventTypes); | |
237 if (is_earcon_event_type) | |
238 ash::WmShell::Get()->accessibility_delegate()->PlayEarcon( | |
239 chromeos::SOUND_VOLUME_ADJUST); | |
240 #endif | |
241 event->SetHandled(); | |
242 } | |
243 } | |
244 | |
245 private: | |
246 DISALLOW_COPY_AND_ASSIGN(ShadowUnderlayEventHandler); | |
247 }; | |
248 | |
169 } // namespace | 249 } // namespace |
170 | 250 |
171 // Helper class used to coalesce a number of changes into one "configure" | 251 // Helper class used to coalesce a number of changes into one "configure" |
172 // callback. Callbacks are suppressed while an instance of this class is | 252 // callback. Callbacks are suppressed while an instance of this class is |
173 // instantiated and instead called when the instance is destroyed. | 253 // instantiated and instead called when the instance is destroyed. |
174 // If |force_configure_| is true ShellSurface::Configure() will be called | 254 // If |force_configure_| is true ShellSurface::Configure() will be called |
175 // even if no changes to shell surface took place during the lifetime of the | 255 // even if no changes to shell surface took place during the lifetime of the |
176 // ScopedConfigure instance. | 256 // ScopedConfigure instance. |
177 class ShellSurface::ScopedConfigure { | 257 class ShellSurface::ScopedConfigure { |
178 public: | 258 public: |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
295 } | 375 } |
296 WMHelper::GetInstance()->RemoveActivationObserver(this); | 376 WMHelper::GetInstance()->RemoveActivationObserver(this); |
297 if (parent_) | 377 if (parent_) |
298 parent_->RemoveObserver(this); | 378 parent_->RemoveObserver(this); |
299 if (surface_) { | 379 if (surface_) { |
300 if (scale_ != 1.0) | 380 if (scale_ != 1.0) |
301 surface_->window()->SetTransform(gfx::Transform()); | 381 surface_->window()->SetTransform(gfx::Transform()); |
302 surface_->SetSurfaceDelegate(nullptr); | 382 surface_->SetSurfaceDelegate(nullptr); |
303 surface_->RemoveSurfaceObserver(this); | 383 surface_->RemoveSurfaceObserver(this); |
304 } | 384 } |
385 ash::WmShell::Get()->system_tray_notifier()->RemoveAccessibilityObserver( | |
386 this); | |
305 } | 387 } |
306 | 388 |
307 void ShellSurface::AcknowledgeConfigure(uint32_t serial) { | 389 void ShellSurface::AcknowledgeConfigure(uint32_t serial) { |
308 TRACE_EVENT1("exo", "ShellSurface::AcknowledgeConfigure", "serial", serial); | 390 TRACE_EVENT1("exo", "ShellSurface::AcknowledgeConfigure", "serial", serial); |
309 | 391 |
310 // Apply all configs that are older or equal to |serial|. The result is that | 392 // Apply all configs that are older or equal to |serial|. The result is that |
311 // the origin of the main surface will move and the resize direction will | 393 // the origin of the main surface will move and the resize direction will |
312 // change to reflect the acknowledgement of configure request with |serial| | 394 // change to reflect the acknowledgement of configure request with |serial| |
313 // at the next call to Commit(). | 395 // at the next call to Commit(). |
314 while (!pending_configs_.empty()) { | 396 while (!pending_configs_.empty()) { |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
719 // views::Views overrides: | 801 // views::Views overrides: |
720 | 802 |
721 gfx::Size ShellSurface::GetPreferredSize() const { | 803 gfx::Size ShellSurface::GetPreferredSize() const { |
722 if (!geometry_.IsEmpty()) | 804 if (!geometry_.IsEmpty()) |
723 return geometry_.size(); | 805 return geometry_.size(); |
724 | 806 |
725 return surface_ ? surface_->window()->layer()->size() : gfx::Size(); | 807 return surface_ ? surface_->window()->layer()->size() : gfx::Size(); |
726 } | 808 } |
727 | 809 |
728 //////////////////////////////////////////////////////////////////////////////// | 810 //////////////////////////////////////////////////////////////////////////////// |
811 // ash::AccessibilityObserver overrides: | |
812 | |
813 void ShellSurface::OnAccessibilityModeChanged( | |
814 ash::AccessibilityNotificationVisibility) { | |
815 UpdateShadow(); | |
816 } | |
817 | |
818 //////////////////////////////////////////////////////////////////////////////// | |
729 // ash::wm::WindowStateObserver overrides: | 819 // ash::wm::WindowStateObserver overrides: |
730 | 820 |
731 void ShellSurface::OnPreWindowStateTypeChange( | 821 void ShellSurface::OnPreWindowStateTypeChange( |
732 ash::wm::WindowState* window_state, | 822 ash::wm::WindowState* window_state, |
733 ash::wm::WindowStateType old_type) { | 823 ash::wm::WindowStateType old_type) { |
734 ash::wm::WindowStateType new_type = window_state->GetStateType(); | 824 ash::wm::WindowStateType new_type = window_state->GetStateType(); |
735 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || | 825 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || |
736 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { | 826 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { |
737 // When transitioning in/out of maximized or fullscreen mode we need to | 827 // When transitioning in/out of maximized or fullscreen mode we need to |
738 // make sure we have a configure callback before we allow the default | 828 // make sure we have a configure callback before we allow the default |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
814 void ShellSurface::OnWindowActivated( | 904 void ShellSurface::OnWindowActivated( |
815 aura::Window* gained_active, | 905 aura::Window* gained_active, |
816 aura::Window* lost_active) { | 906 aura::Window* lost_active) { |
817 if (!widget_) | 907 if (!widget_) |
818 return; | 908 return; |
819 | 909 |
820 if (gained_active == widget_->GetNativeWindow() || | 910 if (gained_active == widget_->GetNativeWindow() || |
821 lost_active == widget_->GetNativeWindow()) { | 911 lost_active == widget_->GetNativeWindow()) { |
822 DCHECK(activatable_); | 912 DCHECK(activatable_); |
823 Configure(); | 913 Configure(); |
914 UpdateShadow(); | |
824 } | 915 } |
825 } | 916 } |
826 | 917 |
827 //////////////////////////////////////////////////////////////////////////////// | 918 //////////////////////////////////////////////////////////////////////////////// |
828 // ui::EventHandler overrides: | 919 // ui::EventHandler overrides: |
829 | 920 |
830 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) { | 921 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) { |
831 if (!resizer_) { | 922 if (!resizer_) { |
832 views::View::OnKeyEvent(event); | 923 views::View::OnKeyEvent(event); |
833 return; | 924 return; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
929 params.activatable = activatable ? views::Widget::InitParams::ACTIVATABLE_YES | 1020 params.activatable = activatable ? views::Widget::InitParams::ACTIVATABLE_YES |
930 : views::Widget::InitParams::ACTIVATABLE_NO; | 1021 : views::Widget::InitParams::ACTIVATABLE_NO; |
931 | 1022 |
932 // Note: NativeWidget owns this widget. | 1023 // Note: NativeWidget owns this widget. |
933 widget_ = new ShellSurfaceWidget(this); | 1024 widget_ = new ShellSurfaceWidget(this); |
934 widget_->Init(params); | 1025 widget_->Init(params); |
935 | 1026 |
936 aura::Window* window = widget_->GetNativeWindow(); | 1027 aura::Window* window = widget_->GetNativeWindow(); |
937 window->SetName("ExoShellSurface"); | 1028 window->SetName("ExoShellSurface"); |
938 window->AddChild(surface_->window()); | 1029 window->AddChild(surface_->window()); |
939 window->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter)); | 1030 window->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter(widget_))); |
940 SetApplicationId(window, &application_id_); | 1031 SetApplicationId(window, &application_id_); |
941 SetMainSurface(window, surface_); | 1032 SetMainSurface(window, surface_); |
942 | 1033 |
943 // Start tracking changes to window bounds and window state. | 1034 // Start tracking changes to window bounds and window state. |
944 window->AddObserver(this); | 1035 window->AddObserver(this); |
945 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); | 1036 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); |
946 window_state->AddObserver(this); | 1037 window_state->AddObserver(this); |
947 | 1038 |
948 // Absolete positioned shell surfaces may request the bounds that does not | 1039 // Absolete positioned shell surfaces may request the bounds that does not |
949 // fill the entire work area / display in maximized / fullscreen state. | 1040 // fill the entire work area / display in maximized / fullscreen state. |
(...skipping 25 matching lines...) Expand all Loading... | |
975 for (const auto& entry : kCloseWindowAccelerators) { | 1066 for (const auto& entry : kCloseWindowAccelerators) { |
976 focus_manager->RegisterAccelerator( | 1067 focus_manager->RegisterAccelerator( |
977 ui::Accelerator(entry.keycode, entry.modifiers), | 1068 ui::Accelerator(entry.keycode, entry.modifiers), |
978 ui::AcceleratorManager::kNormalPriority, this); | 1069 ui::AcceleratorManager::kNormalPriority, this); |
979 } | 1070 } |
980 | 1071 |
981 // Set delegate for handling of fullscreening. | 1072 // Set delegate for handling of fullscreening. |
982 window_state->SetDelegate(std::unique_ptr<ash::wm::WindowStateDelegate>( | 1073 window_state->SetDelegate(std::unique_ptr<ash::wm::WindowStateDelegate>( |
983 new CustomWindowStateDelegate(widget_))); | 1074 new CustomWindowStateDelegate(widget_))); |
984 | 1075 |
1076 // Receive accessibility changes to update shadow underlay. | |
1077 ash::WmShell::Get()->system_tray_notifier()->AddAccessibilityObserver(this); | |
1078 | |
985 // Show widget next time Commit() is called. | 1079 // Show widget next time Commit() is called. |
986 pending_show_widget_ = true; | 1080 pending_show_widget_ = true; |
987 } | 1081 } |
988 | 1082 |
989 void ShellSurface::Configure() { | 1083 void ShellSurface::Configure() { |
990 DCHECK(widget_); | 1084 DCHECK(widget_); |
991 | 1085 |
992 // Delay configure callback if |scoped_configure_| is set. | 1086 // Delay configure callback if |scoped_configure_| is set. |
993 if (scoped_configure_) { | 1087 if (scoped_configure_) { |
994 scoped_configure_->set_needs_configure(); | 1088 scoped_configure_->set_needs_configure(); |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1234 // TODO(oshima): Adjust the coordinates from client screen to | 1328 // TODO(oshima): Adjust the coordinates from client screen to |
1235 // chromeos screen when multi displays are supported. | 1329 // chromeos screen when multi displays are supported. |
1236 gfx::Point origin = window->bounds().origin(); | 1330 gfx::Point origin = window->bounds().origin(); |
1237 gfx::Point shadow_origin = shadow_content_bounds_.origin(); | 1331 gfx::Point shadow_origin = shadow_content_bounds_.origin(); |
1238 shadow_origin -= origin.OffsetFromOrigin(); | 1332 shadow_origin -= origin.OffsetFromOrigin(); |
1239 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds_.size()); | 1333 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds_.size()); |
1240 | 1334 |
1241 // Always create and show the underlay, even in maximized/fullscreen. | 1335 // Always create and show the underlay, even in maximized/fullscreen. |
1242 if (!shadow_underlay_) { | 1336 if (!shadow_underlay_) { |
1243 shadow_underlay_ = new aura::Window(nullptr); | 1337 shadow_underlay_ = new aura::Window(nullptr); |
1338 shadow_underlay_handler_ = base::MakeUnique<ShadowUnderlayEventHandler>(); | |
1339 shadow_underlay_->SetTargetHandler(shadow_underlay_handler_.get()); | |
1244 DCHECK(shadow_underlay_->owned_by_parent()); | 1340 DCHECK(shadow_underlay_->owned_by_parent()); |
1245 shadow_underlay_->set_ignore_events(true); | |
1246 // Ensure the background area inside the shadow is solid black. | 1341 // Ensure the background area inside the shadow is solid black. |
1247 // Clients that provide translucent contents should not be using | 1342 // Clients that provide translucent contents should not be using |
1248 // rectangular shadows as this method requires opaque contents to | 1343 // rectangular shadows as this method requires opaque contents to |
1249 // cast a shadow that represent it correctly. | 1344 // cast a shadow that represent it correctly. |
1250 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR); | 1345 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR); |
1251 shadow_underlay_->layer()->SetColor(SK_ColorBLACK); | 1346 shadow_underlay_->layer()->SetColor(SK_ColorBLACK); |
1252 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely()); | 1347 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely()); |
1253 window->AddChild(shadow_underlay_); | 1348 window->AddChild(shadow_underlay_); |
1254 window->StackChildAtBottom(shadow_underlay_); | 1349 window->StackChildAtBottom(shadow_underlay_); |
1255 } | 1350 } |
1256 | 1351 |
1352 bool underlay_capture_events = ash::WmShell::Get() | |
1353 ->accessibility_delegate() | |
1354 ->IsSpokenFeedbackEnabled() && | |
1355 widget_->IsActive(); | |
1356 shadow_underlay_->set_ignore_events(!underlay_capture_events); | |
1357 | |
1257 float shadow_underlay_opacity = rectangular_shadow_background_opacity_; | 1358 float shadow_underlay_opacity = rectangular_shadow_background_opacity_; |
1258 // Put the black background layer behind the window if | 1359 // Put the black background layer behind the window if |
1259 // 1) the window is in immersive fullscreen. | 1360 // 1) the window is in immersive fullscreen or is active with |
1361 // spoken feedback enabled. | |
1260 // 2) the window can control the bounds of the window in fullscreen ( | 1362 // 2) the window can control the bounds of the window in fullscreen ( |
1261 // thus the background can be visible). | 1363 // thus the background can be visible). |
1262 // 3) the window has no transform (the transformed background may | 1364 // 3) the window has no transform (the transformed background may |
1263 // not cover the entire background, e.g. overview mode). | 1365 // not cover the entire background, e.g. overview mode). |
1264 if (widget_->IsFullscreen() && | 1366 if ((widget_->IsFullscreen() || underlay_capture_events) && |
1265 ash::wm::GetWindowState(window)->allow_set_bounds_in_maximized() && | 1367 ash::wm::GetWindowState(window)->allow_set_bounds_in_maximized() && |
1266 window->layer()->transform().IsIdentity()) { | 1368 window->layer()->GetTargetTransform().IsIdentity()) { |
1267 gfx::Point origin; | 1369 gfx::Point origin; |
1268 origin -= window->bounds().origin().OffsetFromOrigin(); | 1370 origin -= window->bounds().origin().OffsetFromOrigin(); |
1269 shadow_bounds.set_origin(origin); | 1371 shadow_bounds.set_origin(origin); |
1270 shadow_bounds.set_size(window->parent()->bounds().size()); | 1372 shadow_bounds.set_size(window->parent()->bounds().size()); |
1271 shadow_underlay_opacity = 1.0f; | 1373 shadow_underlay_opacity = 1.0f; |
1272 } | 1374 } |
1273 | 1375 |
1274 shadow_underlay_->SetBounds(shadow_bounds); | 1376 shadow_underlay_->SetBounds(shadow_bounds); |
1275 | 1377 |
1276 // TODO(oshima): Setting to the same value should be no-op. | 1378 // TODO(oshima): Setting to the same value should be no-op. |
(...skipping 18 matching lines...) Expand all Loading... | |
1295 shadow_overlay_->layer()->Add(shadow->layer()); | 1397 shadow_overlay_->layer()->Add(shadow->layer()); |
1296 window->AddChild(shadow_overlay_); | 1398 window->AddChild(shadow_overlay_); |
1297 shadow_overlay_->Show(); | 1399 shadow_overlay_->Show(); |
1298 } | 1400 } |
1299 shadow_overlay_->SetBounds(shadow_bounds); | 1401 shadow_overlay_->SetBounds(shadow_bounds); |
1300 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size())); | 1402 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size())); |
1301 } | 1403 } |
1302 } | 1404 } |
1303 | 1405 |
1304 } // namespace exo | 1406 } // namespace exo |
OLD | NEW |