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