Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: components/exo/shell_surface.cc

Issue 2361993003: Draw underlay behind android apps using talkback (Closed)
Patch Set: Properly show shadow on app launch Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "ash/aura/wm_window_aura.h" 7 #include "ash/aura/wm_window_aura.h"
8 #include "ash/common/accessibility_delegate.h"
8 #include "ash/common/shell_window_ids.h" 9 #include "ash/common/shell_window_ids.h"
10 #include "ash/common/system/tray/system_tray_notifier.h"
9 #include "ash/common/wm/window_resizer.h" 11 #include "ash/common/wm/window_resizer.h"
10 #include "ash/common/wm/window_state.h" 12 #include "ash/common/wm/window_state.h"
11 #include "ash/common/wm/window_state_delegate.h" 13 #include "ash/common/wm/window_state_delegate.h"
14 #include "ash/common/wm_shell.h"
12 #include "ash/shell.h" 15 #include "ash/shell.h"
13 #include "ash/wm/window_state_aura.h" 16 #include "ash/wm/window_state_aura.h"
14 #include "ash/wm/window_util.h" 17 #include "ash/wm/window_util.h"
15 #include "base/logging.h" 18 #include "base/logging.h"
16 #include "base/macros.h" 19 #include "base/macros.h"
17 #include "base/memory/ptr_util.h" 20 #include "base/memory/ptr_util.h"
18 #include "base/strings/utf_string_conversions.h" 21 #include "base/strings/utf_string_conversions.h"
19 #include "base/trace_event/trace_event.h" 22 #include "base/trace_event/trace_event.h"
20 #include "base/trace_event/trace_event_argument.h" 23 #include "base/trace_event/trace_event_argument.h"
21 #include "components/exo/surface.h" 24 #include "components/exo/surface.h"
22 #include "ui/aura/client/aura_constants.h" 25 #include "ui/aura/client/aura_constants.h"
23 #include "ui/aura/client/cursor_client.h" 26 #include "ui/aura/client/cursor_client.h"
24 #include "ui/aura/window.h" 27 #include "ui/aura/window.h"
25 #include "ui/aura/window_event_dispatcher.h" 28 #include "ui/aura/window_event_dispatcher.h"
26 #include "ui/aura/window_property.h" 29 #include "ui/aura/window_property.h"
27 #include "ui/aura/window_targeter.h" 30 #include "ui/aura/window_targeter.h"
28 #include "ui/aura/window_tree_host.h" 31 #include "ui/aura/window_tree_host.h"
29 #include "ui/base/accelerators/accelerator.h" 32 #include "ui/base/accelerators/accelerator.h"
30 #include "ui/gfx/path.h" 33 #include "ui/gfx/path.h"
31 #include "ui/views/widget/widget.h" 34 #include "ui/views/widget/widget.h"
32 #include "ui/views/widget/widget_observer.h" 35 #include "ui/views/widget/widget_observer.h"
33 #include "ui/wm/core/coordinate_conversion.h" 36 #include "ui/wm/core/coordinate_conversion.h"
34 #include "ui/wm/core/shadow.h" 37 #include "ui/wm/core/shadow.h"
35 #include "ui/wm/core/shadow_controller.h" 38 #include "ui/wm/core/shadow_controller.h"
36 #include "ui/wm/core/shadow_types.h" 39 #include "ui/wm/core/shadow_types.h"
37 #include "ui/wm/core/window_util.h" 40 #include "ui/wm/core/window_util.h"
38 41
42 #if defined(OS_CHROMEOS)
43 #include "chromeos/audio/chromeos_sounds.h"
44 #endif
45
39 DECLARE_WINDOW_PROPERTY_TYPE(std::string*) 46 DECLARE_WINDOW_PROPERTY_TYPE(std::string*)
40 47
41 namespace exo { 48 namespace exo {
42 namespace { 49 namespace {
43 50
44 // This is a struct for accelerator keys used to close ShellSurfaces. 51 // This is a struct for accelerator keys used to close ShellSurfaces.
45 const struct Accelerator { 52 const struct Accelerator {
46 ui::KeyboardCode keycode; 53 ui::KeyboardCode keycode;
47 int modifiers; 54 int modifiers;
48 } kCloseWindowAccelerators[] = { 55 } kCloseWindowAccelerators[] = {
(...skipping 28 matching lines...) Expand all
77 void UpdateWindowIcon() override {} 84 void UpdateWindowIcon() override {}
78 void UpdateWindowTitle() override {} 85 void UpdateWindowTitle() override {}
79 void SizeConstraintsChanged() override {} 86 void SizeConstraintsChanged() override {}
80 87
81 private: 88 private:
82 views::Widget* const widget_; 89 views::Widget* const widget_;
83 90
84 DISALLOW_COPY_AND_ASSIGN(CustomFrameView); 91 DISALLOW_COPY_AND_ASSIGN(CustomFrameView);
85 }; 92 };
86 93
87 class CustomWindowTargeter : public aura::WindowTargeter { 94 class CustomWindowTargeter : public aura::WindowTargeter {
reveman 2016/09/28 16:11:50 Does this really need to know about the shadow und
erosky 2016/09/28 19:21:12 This still needs to know about the shadow_underlay
88 public: 95 public:
89 CustomWindowTargeter() {} 96 CustomWindowTargeter() : shadow_underlay_(nullptr) {}
90 ~CustomWindowTargeter() override {} 97 ~CustomWindowTargeter() override {}
91 98
92 // Overridden from aura::WindowTargeter: 99 // Overridden from aura::WindowTargeter:
93 bool EventLocationInsideBounds(aura::Window* window, 100 bool EventLocationInsideBounds(aura::Window* window,
94 const ui::LocatedEvent& event) const override { 101 const ui::LocatedEvent& event) const override {
95 Surface* surface = ShellSurface::GetMainSurface(window); 102 Surface* surface = ShellSurface::GetMainSurface(window);
96 if (!surface) 103 if (!surface)
97 return false; 104 return false;
98 105
99 gfx::Point local_point = event.location(); 106 gfx::Point local_point = event.location();
100 if (window->parent()) 107
101 aura::Window::ConvertPointToTarget(window->parent(), window, 108 if (shadow_underlay_ && !shadow_underlay_->ignore_events()) {
109 aura::Window::ConvertPointToTarget(window->parent(), shadow_underlay_,
102 &local_point); 110 &local_point);
111 return gfx::Rect(shadow_underlay_->layer()->size()).Contains(local_point);
112 }
113
114 aura::Window::ConvertPointToTarget(window->parent(), window, &local_point);
103 115
104 aura::Window::ConvertPointToTarget(window, surface->window(), &local_point); 116 aura::Window::ConvertPointToTarget(window, surface->window(), &local_point);
105 return surface->HitTestRect(gfx::Rect(local_point, gfx::Size(1, 1))); 117 return surface->HitTestRect(gfx::Rect(local_point, gfx::Size(1, 1)));
106 } 118 }
107 119
120 ui::EventTarget* FindTargetForEvent(ui::EventTarget* root,
121 ui::Event* event) override {
122 aura::Window* window = static_cast<aura::Window*>(root);
123 Surface* surface = ShellSurface::GetMainSurface(window);
124 if (surface && event->IsLocatedEvent() && shadow_underlay_ &&
125 !shadow_underlay_->ignore_events()) {
126 gfx::Point local_point = event->AsLocatedEvent()->location();
127 aura::Window::ConvertPointToTarget(window, surface->window(),
128 &local_point);
129 if (!surface->HitTestRect(gfx::Rect(local_point, gfx::Size(1, 1))))
130 return shadow_underlay_;
131 }
132 return aura::WindowTargeter::FindTargetForEvent(root, event);
133 }
134
135 void set_shadow_underlay(aura::Window* shadow_underlay) {
136 shadow_underlay_ = shadow_underlay;
137 }
138
108 private: 139 private:
140 aura::Window* shadow_underlay_;
reveman 2016/09/28 16:11:51 nit: blank line before DISALLOW_..
erosky 2016/09/28 19:21:12 Done.
109 DISALLOW_COPY_AND_ASSIGN(CustomWindowTargeter); 141 DISALLOW_COPY_AND_ASSIGN(CustomWindowTargeter);
110 }; 142 };
111 143
112 // Handles a user's fullscreen request (Shift+F4/F4). 144 // Handles a user's fullscreen request (Shift+F4/F4).
113 class CustomWindowStateDelegate : public ash::wm::WindowStateDelegate, 145 class CustomWindowStateDelegate : public ash::wm::WindowStateDelegate,
114 public views::WidgetObserver { 146 public views::WidgetObserver {
115 public: 147 public:
116 explicit CustomWindowStateDelegate(views::Widget* widget) : widget_(widget) { 148 explicit CustomWindowStateDelegate(views::Widget* widget) : widget_(widget) {
117 widget_->AddObserver(this); 149 widget_->AddObserver(this);
118 } 150 }
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 } 326 }
295 WMHelper::GetInstance()->RemoveActivationObserver(this); 327 WMHelper::GetInstance()->RemoveActivationObserver(this);
296 if (parent_) 328 if (parent_)
297 parent_->RemoveObserver(this); 329 parent_->RemoveObserver(this);
298 if (surface_) { 330 if (surface_) {
299 if (scale_ != 1.0) 331 if (scale_ != 1.0)
300 surface_->window()->SetTransform(gfx::Transform()); 332 surface_->window()->SetTransform(gfx::Transform());
301 surface_->SetSurfaceDelegate(nullptr); 333 surface_->SetSurfaceDelegate(nullptr);
302 surface_->RemoveSurfaceObserver(this); 334 surface_->RemoveSurfaceObserver(this);
303 } 335 }
336 if (ash::WmShell::HasInstance() &&
337 ash::WmShell::Get()->system_tray_notifier()) {
reveman 2016/09/28 16:11:50 Do we have to check ash::WmShell::HasInstance() &&
erosky 2016/09/28 19:21:13 Done.
338 ash::WmShell::Get()->system_tray_notifier()->RemoveAccessibilityObserver(
339 this);
340 }
304 } 341 }
305 342
306 void ShellSurface::AcknowledgeConfigure(uint32_t serial) { 343 void ShellSurface::AcknowledgeConfigure(uint32_t serial) {
307 TRACE_EVENT1("exo", "ShellSurface::AcknowledgeConfigure", "serial", serial); 344 TRACE_EVENT1("exo", "ShellSurface::AcknowledgeConfigure", "serial", serial);
308 345
309 // Apply all configs that are older or equal to |serial|. The result is that 346 // Apply all configs that are older or equal to |serial|. The result is that
310 // the origin of the main surface will move and the resize direction will 347 // the origin of the main surface will move and the resize direction will
311 // change to reflect the acknowledgement of configure request with |serial| 348 // change to reflect the acknowledgement of configure request with |serial|
312 // at the next call to Commit(). 349 // at the next call to Commit().
313 while (!pending_configs_.empty()) { 350 while (!pending_configs_.empty()) {
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 // views::Views overrides: 755 // views::Views overrides:
719 756
720 gfx::Size ShellSurface::GetPreferredSize() const { 757 gfx::Size ShellSurface::GetPreferredSize() const {
721 if (!geometry_.IsEmpty()) 758 if (!geometry_.IsEmpty())
722 return geometry_.size(); 759 return geometry_.size();
723 760
724 return surface_ ? surface_->window()->layer()->size() : gfx::Size(); 761 return surface_ ? surface_->window()->layer()->size() : gfx::Size();
725 } 762 }
726 763
727 //////////////////////////////////////////////////////////////////////////////// 764 ////////////////////////////////////////////////////////////////////////////////
765 // ash::AccessibilityObserver overrides:
766
767 void ShellSurface::OnAccessibilityModeChanged(
768 ash::AccessibilityNotificationVisibility) {
769 audio_feedback_ =
770 ash::WmShell::Get()->accessibility_delegate()->IsSpokenFeedbackEnabled();
771 UpdateShadow();
772 }
773
774 ////////////////////////////////////////////////////////////////////////////////
728 // ash::wm::WindowStateObserver overrides: 775 // ash::wm::WindowStateObserver overrides:
729 776
730 void ShellSurface::OnPreWindowStateTypeChange( 777 void ShellSurface::OnPreWindowStateTypeChange(
731 ash::wm::WindowState* window_state, 778 ash::wm::WindowState* window_state,
732 ash::wm::WindowStateType old_type) { 779 ash::wm::WindowStateType old_type) {
733 ash::wm::WindowStateType new_type = window_state->GetStateType(); 780 ash::wm::WindowStateType new_type = window_state->GetStateType();
734 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || 781 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) ||
735 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { 782 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) {
736 // When transitioning in/out of maximized or fullscreen mode we need to 783 // When transitioning in/out of maximized or fullscreen mode we need to
737 // make sure we have a configure callback before we allow the default 784 // make sure we have a configure callback before we allow the default
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 void ShellSurface::OnWindowActivated( 860 void ShellSurface::OnWindowActivated(
814 aura::Window* gained_active, 861 aura::Window* gained_active,
815 aura::Window* lost_active) { 862 aura::Window* lost_active) {
816 if (!widget_) 863 if (!widget_)
817 return; 864 return;
818 865
819 if (gained_active == widget_->GetNativeWindow() || 866 if (gained_active == widget_->GetNativeWindow() ||
820 lost_active == widget_->GetNativeWindow()) { 867 lost_active == widget_->GetNativeWindow()) {
821 DCHECK(activatable_); 868 DCHECK(activatable_);
822 Configure(); 869 Configure();
870 UpdateShadow();
823 } 871 }
824 } 872 }
825 873
826 //////////////////////////////////////////////////////////////////////////////// 874 ////////////////////////////////////////////////////////////////////////////////
827 // ui::EventHandler overrides: 875 // ui::EventHandler overrides:
828 876
877 void ShellSurface::OnEvent(ui::Event* event) {
878 if (event->IsLocatedEvent() && event->target() == shadow_underlay_ &&
reveman 2016/09/28 16:11:50 Same here. Can this use "event->target() == widget
erosky 2016/09/28 19:21:12 widget_->GetNativeWindow() represents the actual a
879 shadow_underlay_ && !shadow_underlay_->ignore_events()) {
880 #if defined(OS_CHROMEOS)
881 ui::EventType sound_types[] = {
reveman 2016/09/28 16:11:51 nit: s/ui::EventType sound_types/const ui::EventTy
erosky 2016/09/28 19:21:13 Done.
882 ui::ET_TOUCH_PRESSED, ui::ET_POINTER_DOWN,
883 ui::ET_POINTER_WHEEL_CHANGED, ui::ET_SCROLL,
884 ui::ET_SCROLL_FLING_START, ui::ET_GESTURE_BEGIN,
885 ui::ET_MOUSE_PRESSED, ui::ET_MOUSEWHEEL};
886 for (ui::EventType e : sound_types) {
reveman 2016/09/28 16:11:50 nit: I think this would be a good place to use std
erosky 2016/09/28 19:21:13 Done.
887 if (event->type() == e) {
888 ash::WmShell::Get()->accessibility_delegate()->PlayEarcon(
889 chromeos::SOUND_VOLUME_ADJUST);
890 break;
891 }
892 }
893 #endif
894 event->SetHandled();
895 return;
896 }
897 views::View::OnEvent(event);
898 }
899
829 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) { 900 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) {
830 if (!resizer_) { 901 if (!resizer_) {
831 views::View::OnKeyEvent(event); 902 views::View::OnKeyEvent(event);
832 return; 903 return;
833 } 904 }
834 905
835 if (event->type() == ui::ET_KEY_PRESSED && 906 if (event->type() == ui::ET_KEY_PRESSED &&
836 event->key_code() == ui::VKEY_ESCAPE) { 907 event->key_code() == ui::VKEY_ESCAPE) {
837 EndDrag(true /* revert */); 908 EndDrag(true /* revert */);
838 } 909 }
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 for (const auto& entry : kCloseWindowAccelerators) { 1045 for (const auto& entry : kCloseWindowAccelerators) {
975 focus_manager->RegisterAccelerator( 1046 focus_manager->RegisterAccelerator(
976 ui::Accelerator(entry.keycode, entry.modifiers), 1047 ui::Accelerator(entry.keycode, entry.modifiers),
977 ui::AcceleratorManager::kNormalPriority, this); 1048 ui::AcceleratorManager::kNormalPriority, this);
978 } 1049 }
979 1050
980 // Set delegate for handling of fullscreening. 1051 // Set delegate for handling of fullscreening.
981 window_state->SetDelegate(std::unique_ptr<ash::wm::WindowStateDelegate>( 1052 window_state->SetDelegate(std::unique_ptr<ash::wm::WindowStateDelegate>(
982 new CustomWindowStateDelegate(widget_))); 1053 new CustomWindowStateDelegate(widget_)));
983 1054
1055 // Receive accessibility changes to update shadow underlay.
1056 ash::WmShell::Get()->system_tray_notifier()->AddAccessibilityObserver(this);
1057 audio_feedback_ =
1058 ash::WmShell::Get()->accessibility_delegate()->IsSpokenFeedbackEnabled();
1059
984 // Show widget next time Commit() is called. 1060 // Show widget next time Commit() is called.
985 pending_show_widget_ = true; 1061 pending_show_widget_ = true;
986 } 1062 }
987 1063
988 void ShellSurface::Configure() { 1064 void ShellSurface::Configure() {
989 DCHECK(widget_); 1065 DCHECK(widget_);
990 1066
991 // Delay configure callback if |scoped_configure_| is set. 1067 // Delay configure callback if |scoped_configure_| is set.
992 if (scoped_configure_) { 1068 if (scoped_configure_) {
993 scoped_configure_->set_needs_configure(); 1069 scoped_configure_->set_needs_configure();
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 // TODO(oshima): Adjust the coordinates from client screen to 1309 // TODO(oshima): Adjust the coordinates from client screen to
1234 // chromeos screen when multi displays are supported. 1310 // chromeos screen when multi displays are supported.
1235 gfx::Point origin = window->bounds().origin(); 1311 gfx::Point origin = window->bounds().origin();
1236 gfx::Point shadow_origin = shadow_content_bounds_.origin(); 1312 gfx::Point shadow_origin = shadow_content_bounds_.origin();
1237 shadow_origin -= origin.OffsetFromOrigin(); 1313 shadow_origin -= origin.OffsetFromOrigin();
1238 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds_.size()); 1314 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds_.size());
1239 1315
1240 // Always create and show the underlay, even in maximized/fullscreen. 1316 // Always create and show the underlay, even in maximized/fullscreen.
1241 if (!shadow_underlay_) { 1317 if (!shadow_underlay_) {
1242 shadow_underlay_ = new aura::Window(nullptr); 1318 shadow_underlay_ = new aura::Window(nullptr);
1319 shadow_underlay_->SetTargetHandler(this);
1243 DCHECK(shadow_underlay_->owned_by_parent()); 1320 DCHECK(shadow_underlay_->owned_by_parent());
1244 shadow_underlay_->set_ignore_events(true);
1245 // Ensure the background area inside the shadow is solid black. 1321 // Ensure the background area inside the shadow is solid black.
1246 // Clients that provide translucent contents should not be using 1322 // Clients that provide translucent contents should not be using
1247 // rectangular shadows as this method requires opaque contents to 1323 // rectangular shadows as this method requires opaque contents to
1248 // cast a shadow that represent it correctly. 1324 // cast a shadow that represent it correctly.
1249 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR); 1325 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR);
1250 shadow_underlay_->layer()->SetColor(SK_ColorBLACK); 1326 shadow_underlay_->layer()->SetColor(SK_ColorBLACK);
1251 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely()); 1327 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely());
1252 window->AddChild(shadow_underlay_); 1328 window->AddChild(shadow_underlay_);
1253 window->StackChildAtBottom(shadow_underlay_); 1329 window->StackChildAtBottom(shadow_underlay_);
1330 static_cast<CustomWindowTargeter*>(
1331 static_cast<ui::EventTarget*>(window)->GetEventTargeter())
1332 ->set_shadow_underlay(shadow_underlay_);
1254 } 1333 }
1255 1334
1335 bool underlay_capture_events = audio_feedback_ && widget_->IsActive();
1336 shadow_underlay_->set_ignore_events(!underlay_capture_events);
1337
1256 float shadow_underlay_opacity = rectangular_shadow_background_opacity_; 1338 float shadow_underlay_opacity = rectangular_shadow_background_opacity_;
1257 // Put the black background layer behind the window if 1339 // Put the black background layer behind the window if
1258 // 1) the window is in immersive fullscreen. 1340 // 1) the window is in immersive fullscreen or spoken_feedback/talkback
reveman 2016/09/28 16:11:50 nit: s/spoken_feedback/spoken feedback/ and remove
erosky 2016/09/28 19:21:13 Done.
1341 // is enabled.
1259 // 2) the window can control the bounds of the window in fullscreen ( 1342 // 2) the window can control the bounds of the window in fullscreen (
1260 // thus the background can be visible). 1343 // thus the background can be visible).
1261 // 3) the window has no transform (the transformed background may 1344 // 3) the window has no transform (the transformed background may
1262 // not cover the entire background, e.g. overview mode). 1345 // not cover the entire background, e.g. overview mode).
1263 if (widget_->IsFullscreen() && 1346 if ((widget_->IsFullscreen() || underlay_capture_events) &&
reveman 2016/09/28 16:11:50 use helper function?
erosky 2016/09/28 19:21:13 This is the only place where the check happens, so
1264 ash::wm::GetWindowState(window)->allow_set_bounds_in_maximized() && 1347 ash::wm::GetWindowState(window)->allow_set_bounds_in_maximized() &&
1265 window->layer()->transform().IsIdentity()) { 1348 window->layer()->GetTargetTransform().IsIdentity()) {
reveman 2016/09/28 16:11:50 is this needed as part of this patch?
erosky 2016/09/28 19:21:13 Yeah, otherwise the shadow won't initially show-up
1266 gfx::Point origin; 1349 gfx::Point origin;
1267 origin -= window->bounds().origin().OffsetFromOrigin(); 1350 origin -= window->bounds().origin().OffsetFromOrigin();
1268 shadow_bounds.set_origin(origin); 1351 shadow_bounds.set_origin(origin);
1269 shadow_bounds.set_size(window->parent()->bounds().size()); 1352 shadow_bounds.set_size(window->parent()->bounds().size());
1270 shadow_underlay_opacity = 1.0f; 1353 shadow_underlay_opacity = 1.0f;
1271 } 1354 }
1272 1355
1273 shadow_underlay_->SetBounds(shadow_bounds); 1356 shadow_underlay_->SetBounds(shadow_bounds);
1274 1357
1275 // TODO(oshima): Setting to the same value should be no-op. 1358 // TODO(oshima): Setting to the same value should be no-op.
(...skipping 18 matching lines...) Expand all
1294 shadow_overlay_->layer()->Add(shadow->layer()); 1377 shadow_overlay_->layer()->Add(shadow->layer());
1295 window->AddChild(shadow_overlay_); 1378 window->AddChild(shadow_overlay_);
1296 shadow_overlay_->Show(); 1379 shadow_overlay_->Show();
1297 } 1380 }
1298 shadow_overlay_->SetBounds(shadow_bounds); 1381 shadow_overlay_->SetBounds(shadow_bounds);
1299 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size())); 1382 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size()));
1300 } 1383 }
1301 } 1384 }
1302 1385
1303 } // namespace exo 1386 } // namespace exo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698