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

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

Issue 2884623002: Refactor backdrop (Closed)
Patch Set: Generalize Backdrop Created 3 years, 7 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 <algorithm> 7 #include <algorithm>
8 8
9 #include "ash/frame/custom_frame_view_ash.h" 9 #include "ash/frame/custom_frame_view_ash.h"
10 #include "ash/public/cpp/shell_window_ids.h" 10 #include "ash/public/cpp/shell_window_ids.h"
(...skipping 26 matching lines...) Expand all
37 #include "ui/display/screen.h" 37 #include "ui/display/screen.h"
38 #include "ui/gfx/path.h" 38 #include "ui/gfx/path.h"
39 #include "ui/views/widget/widget.h" 39 #include "ui/views/widget/widget.h"
40 #include "ui/wm/core/coordinate_conversion.h" 40 #include "ui/wm/core/coordinate_conversion.h"
41 #include "ui/wm/core/shadow.h" 41 #include "ui/wm/core/shadow.h"
42 #include "ui/wm/core/shadow_controller.h" 42 #include "ui/wm/core/shadow_controller.h"
43 #include "ui/wm/core/shadow_types.h" 43 #include "ui/wm/core/shadow_types.h"
44 #include "ui/wm/core/window_animations.h" 44 #include "ui/wm/core/window_animations.h"
45 #include "ui/wm/core/window_util.h" 45 #include "ui/wm/core/window_util.h"
46 46
47 #if defined(OS_CHROMEOS)
48 #include "chromeos/audio/chromeos_sounds.h"
49 #endif
50
51 namespace exo { 47 namespace exo {
52 namespace { 48 namespace {
53 49
54 // This is a struct for accelerator keys used to close ShellSurfaces. 50 // This is a struct for accelerator keys used to close ShellSurfaces.
55 const struct Accelerator { 51 const struct Accelerator {
56 ui::KeyboardCode keycode; 52 ui::KeyboardCode keycode;
57 int modifiers; 53 int modifiers;
58 } kCloseWindowAccelerators[] = { 54 } kCloseWindowAccelerators[] = {
59 {ui::VKEY_W, ui::EF_CONTROL_DOWN}, 55 {ui::VKEY_W, ui::EF_CONTROL_DOWN},
60 {ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN}, 56 {ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN},
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 if (GetFocusManager()->ProcessAccelerator(ui::Accelerator(*event))) 179 if (GetFocusManager()->ProcessAccelerator(ui::Accelerator(*event)))
184 event->StopPropagation(); 180 event->StopPropagation();
185 } 181 }
186 182
187 private: 183 private:
188 ShellSurface* const shell_surface_; 184 ShellSurface* const shell_surface_;
189 185
190 DISALLOW_COPY_AND_ASSIGN(ShellSurfaceWidget); 186 DISALLOW_COPY_AND_ASSIGN(ShellSurfaceWidget);
191 }; 187 };
192 188
193 class ShadowUnderlayEventHandler : public ui::EventHandler {
194 public:
195 ShadowUnderlayEventHandler() {}
196 ~ShadowUnderlayEventHandler() override {}
197
198 // Overridden from ui::EventHandler:
199 void OnEvent(ui::Event* event) override {
200 // If the event is targeted at the underlay, it means the user has made an
201 // interaction that is outside the surface's bounds and we want to capture
202 // it (usually when in spoken feedback mode). Handle the event (to prevent
203 // behind-windows from receiving it) and play an earcon to notify the user.
204 if (event->IsLocatedEvent()) {
205 #if defined(OS_CHROMEOS)
206 const ui::EventType kEarconEventTypes[] = {ui::ET_MOUSE_PRESSED,
207 ui::ET_MOUSEWHEEL,
208 ui::ET_TOUCH_PRESSED,
209 ui::ET_POINTER_DOWN,
210 ui::ET_POINTER_WHEEL_CHANGED,
211 ui::ET_GESTURE_BEGIN,
212 ui::ET_SCROLL,
213 ui::ET_SCROLL_FLING_START};
214 bool is_earcon_event_type =
215 std::find(std::begin(kEarconEventTypes), std::end(kEarconEventTypes),
216 event->type()) != std::end(kEarconEventTypes);
217 if (is_earcon_event_type)
218 WMHelper::GetInstance()->PlayEarcon(chromeos::SOUND_VOLUME_ADJUST);
219 #endif
220 event->SetHandled();
221 }
222 }
223
224 private:
225 DISALLOW_COPY_AND_ASSIGN(ShadowUnderlayEventHandler);
226 };
227
228 } // namespace 189 } // namespace
229 190
230 // Helper class used to coalesce a number of changes into one "configure" 191 // Helper class used to coalesce a number of changes into one "configure"
231 // callback. Callbacks are suppressed while an instance of this class is 192 // callback. Callbacks are suppressed while an instance of this class is
232 // instantiated and instead called when the instance is destroyed. 193 // instantiated and instead called when the instance is destroyed.
233 // If |force_configure_| is true ShellSurface::Configure() will be called 194 // If |force_configure_| is true ShellSurface::Configure() will be called
234 // even if no changes to shell surface took place during the lifetime of the 195 // even if no changes to shell surface took place during the lifetime of the
235 // ScopedConfigure instance. 196 // ScopedConfigure instance.
236 class ShellSurface::ScopedConfigure { 197 class ShellSurface::ScopedConfigure {
237 public: 198 public:
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 WMHelper::GetInstance()->RemoveActivationObserver(this); 327 WMHelper::GetInstance()->RemoveActivationObserver(this);
367 WMHelper::GetInstance()->RemoveDisplayConfigurationObserver(this); 328 WMHelper::GetInstance()->RemoveDisplayConfigurationObserver(this);
368 if (parent_) 329 if (parent_)
369 parent_->RemoveObserver(this); 330 parent_->RemoveObserver(this);
370 if (surface_) { 331 if (surface_) {
371 if (scale_ != 1.0) 332 if (scale_ != 1.0)
372 surface_->window()->SetTransform(gfx::Transform()); 333 surface_->window()->SetTransform(gfx::Transform());
373 surface_->SetSurfaceDelegate(nullptr); 334 surface_->SetSurfaceDelegate(nullptr);
374 surface_->RemoveSurfaceObserver(this); 335 surface_->RemoveSurfaceObserver(this);
375 } 336 }
376 WMHelper::GetInstance()->RemoveAccessibilityObserver(this);
377 } 337 }
378 338
379 void ShellSurface::AcknowledgeConfigure(uint32_t serial) { 339 void ShellSurface::AcknowledgeConfigure(uint32_t serial) {
380 TRACE_EVENT1("exo", "ShellSurface::AcknowledgeConfigure", "serial", serial); 340 TRACE_EVENT1("exo", "ShellSurface::AcknowledgeConfigure", "serial", serial);
381 341
382 // Apply all configs that are older or equal to |serial|. The result is that 342 // Apply all configs that are older or equal to |serial|. The result is that
383 // the origin of the main surface will move and the resize direction will 343 // the origin of the main surface will move and the resize direction will
384 // change to reflect the acknowledgement of configure request with |serial| 344 // change to reflect the acknowledgement of configure request with |serial|
385 // at the next call to Commit(). 345 // at the next call to Commit().
386 while (!pending_configs_.empty()) { 346 while (!pending_configs_.empty()) {
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after
1031 991
1032 if (gained_active == widget_->GetNativeWindow() || 992 if (gained_active == widget_->GetNativeWindow() ||
1033 lost_active == widget_->GetNativeWindow()) { 993 lost_active == widget_->GetNativeWindow()) {
1034 DCHECK(activatable_); 994 DCHECK(activatable_);
1035 Configure(); 995 Configure();
1036 UpdateShadow(); 996 UpdateShadow();
1037 } 997 }
1038 } 998 }
1039 999
1040 //////////////////////////////////////////////////////////////////////////////// 1000 ////////////////////////////////////////////////////////////////////////////////
1041 // WMHelper::AccessibilityObserver overrides:
1042
1043 void ShellSurface::OnAccessibilityModeChanged() {
1044 UpdateShadow();
1045 }
1046
1047 ////////////////////////////////////////////////////////////////////////////////
1048 // WMHelper::DisplayConfigurationObserver overrides: 1001 // WMHelper::DisplayConfigurationObserver overrides:
1049 1002
1050 void ShellSurface::OnDisplayConfigurationChanged() { 1003 void ShellSurface::OnDisplayConfigurationChanged() {
1051 if (bounds_mode_ != BoundsMode::CLIENT) 1004 if (bounds_mode_ != BoundsMode::CLIENT)
1052 return; 1005 return;
1053 1006
1054 const display::Screen* screen = display::Screen::GetScreen(); 1007 const display::Screen* screen = display::Screen::GetScreen();
1055 int64_t primary_display_id = screen->GetPrimaryDisplay().id(); 1008 int64_t primary_display_id = screen->GetPrimaryDisplay().id();
1056 if (primary_display_id == primary_display_id_) 1009 if (primary_display_id == primary_display_id_)
1057 return; 1010 return;
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 } 1185 }
1233 1186
1234 // Register close window accelerators. 1187 // Register close window accelerators.
1235 views::FocusManager* focus_manager = widget_->GetFocusManager(); 1188 views::FocusManager* focus_manager = widget_->GetFocusManager();
1236 for (const auto& entry : kCloseWindowAccelerators) { 1189 for (const auto& entry : kCloseWindowAccelerators) {
1237 focus_manager->RegisterAccelerator( 1190 focus_manager->RegisterAccelerator(
1238 ui::Accelerator(entry.keycode, entry.modifiers), 1191 ui::Accelerator(entry.keycode, entry.modifiers),
1239 ui::AcceleratorManager::kNormalPriority, this); 1192 ui::AcceleratorManager::kNormalPriority, this);
1240 } 1193 }
1241 1194
1242 // Receive accessibility changes to update shadow underlay.
1243 WMHelper::GetInstance()->AddAccessibilityObserver(this);
1244
1245 // Show widget next time Commit() is called. 1195 // Show widget next time Commit() is called.
1246 pending_show_widget_ = true; 1196 pending_show_widget_ = true;
1247 } 1197 }
1248 1198
1249 void ShellSurface::Configure() { 1199 void ShellSurface::Configure() {
1250 // Delay configure callback if |scoped_configure_| is set. 1200 // Delay configure callback if |scoped_configure_| is set.
1251 if (scoped_configure_) { 1201 if (scoped_configure_) {
1252 scoped_configure_->set_needs_configure(); 1202 scoped_configure_->set_needs_configure();
1253 return; 1203 return;
1254 } 1204 }
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
1573 if (!widget_ || !surface_) 1523 if (!widget_ || !surface_)
1574 return; 1524 return;
1575 if (shadow_underlay_in_surface_ != pending_shadow_underlay_in_surface_) { 1525 if (shadow_underlay_in_surface_ != pending_shadow_underlay_in_surface_) {
1576 shadow_underlay_in_surface_ = pending_shadow_underlay_in_surface_; 1526 shadow_underlay_in_surface_ = pending_shadow_underlay_in_surface_;
1577 shadow_overlay_.reset(); 1527 shadow_overlay_.reset();
1578 shadow_underlay_.reset(); 1528 shadow_underlay_.reset();
1579 } 1529 }
1580 1530
1581 aura::Window* window = widget_->GetNativeWindow(); 1531 aura::Window* window = widget_->GetNativeWindow();
1582 1532
1583 bool underlay_capture_events = 1533 // Put the black background layer behind the window if
1584 WMHelper::GetInstance()->IsSpokenFeedbackEnabled() && widget_->IsActive(); 1534 // 1) the window is in immersive fullscreen, maximized or is active with
1585 bool black_background_enabled = 1535 // spoken feedback enabled.
1586 ((widget_->IsFullscreen() || widget_->IsMaximized()) || 1536 // 2) the window can control the bounds of the window in fullscreen (
1587 underlay_capture_events) && 1537 // thus the background can be visible).
1588 ash::wm::GetWindowState(window)->allow_set_bounds_direct() && 1538 // 3) the window has no transform (the transformed background may
1589 window->layer()->GetTargetTransform().IsIdentity(); 1539 // not cover the entire background, e.g. overview mode).
1540 bool enable_backdrop =
reveman 2017/05/15 13:46:22 nit: describes a state rather than an action so ba
oshima 2017/05/16 08:22:09 Done.
1541 (widget_->IsFullscreen() || widget_->IsMaximized()) &&
1542 ash::wm::GetWindowState(window)->allow_set_bounds_direct();
1543 if (window->GetProperty(aura::client::kHasBackdrop) != enable_backdrop)
reveman 2017/05/15 13:46:22 is this check necessary? is SetProprty not a no-op
oshima 2017/05/16 08:22:09 This is currently necessary. We probably can add i
1544 window->SetProperty(aura::client::kHasBackdrop, enable_backdrop);
1590 1545
1591 if (!shadow_enabled_ && !black_background_enabled) { 1546 if (!shadow_enabled_) {
1592 wm::SetShadowElevation(window, wm::ShadowElevation::NONE); 1547 wm::SetShadowElevation(window, wm::ShadowElevation::NONE);
1593 if (shadow_underlay_) 1548 if (shadow_underlay_)
1594 shadow_underlay_->Hide(); 1549 shadow_underlay_->Hide();
1595 } else { 1550 } else {
1596 wm::SetShadowElevation(window, wm::ShadowElevation::DEFAULT); 1551 wm::SetShadowElevation(window, wm::ShadowElevation::DEFAULT);
1597 gfx::Rect shadow_content_bounds = 1552 gfx::Rect shadow_content_bounds =
1598 gfx::ScaleToEnclosedRect(shadow_content_bounds_, 1.f / scale_); 1553 gfx::ScaleToEnclosedRect(shadow_content_bounds_, 1.f / scale_);
1599 1554
1600 // Convert from screen to display coordinates. 1555 // Convert from screen to display coordinates.
1601 if (!shadow_content_bounds.IsEmpty()) { 1556 if (!shadow_content_bounds.IsEmpty()) {
(...skipping 28 matching lines...) Expand all
1630 } 1585 }
1631 1586
1632 gfx::Point shadow_origin = shadow_content_bounds.origin(); 1587 gfx::Point shadow_origin = shadow_content_bounds.origin();
1633 shadow_origin -= window->bounds().OffsetFromOrigin(); 1588 shadow_origin -= window->bounds().OffsetFromOrigin();
1634 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size()); 1589 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size());
1635 1590
1636 // Always create and show the underlay, even in maximized/fullscreen. 1591 // Always create and show the underlay, even in maximized/fullscreen.
1637 if (!shadow_underlay_) { 1592 if (!shadow_underlay_) {
1638 shadow_underlay_ = base::MakeUnique<aura::Window>(nullptr); 1593 shadow_underlay_ = base::MakeUnique<aura::Window>(nullptr);
1639 shadow_underlay_->set_owned_by_parent(false); 1594 shadow_underlay_->set_owned_by_parent(false);
1640 shadow_underlay_event_handler_ =
1641 base::MakeUnique<ShadowUnderlayEventHandler>();
1642 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get());
1643 DCHECK(!shadow_underlay_->owned_by_parent()); 1595 DCHECK(!shadow_underlay_->owned_by_parent());
1644 // Ensure the background area inside the shadow is solid black. 1596 // Ensure the background area inside the shadow is solid black.
1645 // Clients that provide translucent contents should not be using 1597 // Clients that provide translucent contents should not be using
1646 // rectangular shadows as this method requires opaque contents to 1598 // rectangular shadows as this method requires opaque contents to
1647 // cast a shadow that represent it correctly. 1599 // cast a shadow that represent it correctly.
1648 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR); 1600 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR);
1649 shadow_underlay_->layer()->SetColor(SK_ColorBLACK); 1601 shadow_underlay_->layer()->SetColor(SK_ColorBLACK);
1650 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely()); 1602 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely());
1651 if (shadow_underlay_in_surface_) { 1603 if (shadow_underlay_in_surface_) {
1652 surface_->window()->AddChild(shadow_underlay()); 1604 surface_->window()->AddChild(shadow_underlay());
1653 surface_->window()->StackChildAtBottom(shadow_underlay()); 1605 surface_->window()->StackChildAtBottom(shadow_underlay());
1654 } else { 1606 } else {
1655 window->AddChild(shadow_underlay()); 1607 window->AddChild(shadow_underlay());
1656 window->StackChildAtBottom(shadow_underlay()); 1608 window->StackChildAtBottom(shadow_underlay());
1657 } 1609 }
1658 } 1610 }
1659 1611
1660 float shadow_underlay_opacity = shadow_background_opacity_; 1612 float shadow_underlay_opacity = shadow_background_opacity_;
1661 1613
1662 // Put the black background layer behind the window if
1663 // 1) the window is in immersive fullscreen, maximized or is active with
1664 // spoken feedback enabled.
1665 // 2) the window can control the bounds of the window in fullscreen (
1666 // thus the background can be visible).
1667 // 3) the window has no transform (the transformed background may
1668 // not cover the entire background, e.g. overview mode).
1669 if (black_background_enabled) {
1670 if (shadow_underlay_in_surface_) {
1671 shadow_underlay_bounds = gfx::Rect(surface_->window()->bounds().size());
1672 } else {
1673 gfx::Point origin;
1674 origin -= window->bounds().origin().OffsetFromOrigin();
1675 shadow_bounds.set_origin(origin);
1676 shadow_bounds.set_size(window->parent()->bounds().size());
1677 }
1678 shadow_underlay_opacity = 1.0f;
1679 }
1680
1681 if (!shadow_underlay_in_surface_) 1614 if (!shadow_underlay_in_surface_)
1682 shadow_underlay_bounds = shadow_bounds; 1615 shadow_underlay_bounds = shadow_bounds;
1683 1616
1684 // Constrain the underlay bounds to the client area in case shell surface 1617 // Constrain the underlay bounds to the client area in case shell surface
1685 // frame is enabled. 1618 // frame is enabled.
1686 if (frame_enabled_) { 1619 if (frame_enabled_) {
1687 shadow_underlay_bounds.Intersect( 1620 shadow_underlay_bounds.Intersect(
1688 widget_->non_client_view()->frame_view()->GetBoundsForClientView()); 1621 widget_->non_client_view()->frame_view()->GetBoundsForClientView());
1689 } 1622 }
1690 1623
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1736 gfx::Point ShellSurface::GetMouseLocation() const { 1669 gfx::Point ShellSurface::GetMouseLocation() const {
1737 aura::Window* const root_window = widget_->GetNativeWindow()->GetRootWindow(); 1670 aura::Window* const root_window = widget_->GetNativeWindow()->GetRootWindow();
1738 gfx::Point location = 1671 gfx::Point location =
1739 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot(); 1672 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
1740 aura::Window::ConvertPointToTarget( 1673 aura::Window::ConvertPointToTarget(
1741 root_window, widget_->GetNativeWindow()->parent(), &location); 1674 root_window, widget_->GetNativeWindow()->parent(), &location);
1742 return location; 1675 return location;
1743 } 1676 }
1744 1677
1745 } // namespace exo 1678 } // namespace exo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698