| 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> | 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 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 DLOG(WARNING) << "Surface geometry must be non-empty"; | 620 DLOG(WARNING) << "Surface geometry must be non-empty"; |
| 621 return; | 621 return; |
| 622 } | 622 } |
| 623 | 623 |
| 624 pending_geometry_ = geometry; | 624 pending_geometry_ = geometry; |
| 625 } | 625 } |
| 626 | 626 |
| 627 void ShellSurface::SetRectangularShadowEnabled(bool enabled) { | 627 void ShellSurface::SetRectangularShadowEnabled(bool enabled) { |
| 628 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadowEnabled", "enabled", | 628 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadowEnabled", "enabled", |
| 629 enabled); | 629 enabled); |
| 630 shadow_underlay_in_surface_ = false; | 630 pending_shadow_underlay_in_surface_ = false; |
| 631 shadow_enabled_ = enabled; | 631 shadow_enabled_ = enabled; |
| 632 } | 632 } |
| 633 | 633 |
| 634 void ShellSurface::SetRectangularShadow_DEPRECATED( | 634 void ShellSurface::SetRectangularShadow_DEPRECATED( |
| 635 const gfx::Rect& content_bounds) { | 635 const gfx::Rect& content_bounds) { |
| 636 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadow_DEPRECATED", | 636 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadow_DEPRECATED", |
| 637 "content_bounds", content_bounds.ToString()); | 637 "content_bounds", content_bounds.ToString()); |
| 638 shadow_underlay_in_surface_ = false; | 638 pending_shadow_underlay_in_surface_ = false; |
| 639 shadow_content_bounds_ = content_bounds; | 639 shadow_content_bounds_ = content_bounds; |
| 640 shadow_enabled_ = !content_bounds.IsEmpty(); | 640 shadow_enabled_ = !content_bounds.IsEmpty(); |
| 641 } | 641 } |
| 642 | 642 |
| 643 void ShellSurface::SetRectangularSurfaceShadow( | 643 void ShellSurface::SetRectangularSurfaceShadow( |
| 644 const gfx::Rect& content_bounds) { | 644 const gfx::Rect& content_bounds) { |
| 645 TRACE_EVENT1("exo", "ShellSurface::SetRectangularSurfaceShadow", | 645 TRACE_EVENT1("exo", "ShellSurface::SetRectangularSurfaceShadow", |
| 646 "content_bounds", content_bounds.ToString()); | 646 "content_bounds", content_bounds.ToString()); |
| 647 shadow_underlay_in_surface_ = true; | 647 pending_shadow_underlay_in_surface_ = true; |
| 648 shadow_content_bounds_ = content_bounds; | 648 shadow_content_bounds_ = content_bounds; |
| 649 shadow_enabled_ = !content_bounds.IsEmpty(); | 649 shadow_enabled_ = !content_bounds.IsEmpty(); |
| 650 } | 650 } |
| 651 | 651 |
| 652 void ShellSurface::SetRectangularShadowBackgroundOpacity(float opacity) { | 652 void ShellSurface::SetRectangularShadowBackgroundOpacity(float opacity) { |
| 653 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadowBackgroundOpacity", | 653 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadowBackgroundOpacity", |
| 654 "opacity", opacity); | 654 "opacity", opacity); |
| 655 shadow_background_opacity_ = opacity; | 655 shadow_background_opacity_ = opacity; |
| 656 } | 656 } |
| 657 | 657 |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 if (bounds_mode_ != BoundsMode::CLIENT) | 869 if (bounds_mode_ != BoundsMode::CLIENT) |
| 870 return WidgetDelegate::GetSavedWindowPlacement(widget, bounds, show_state); | 870 return WidgetDelegate::GetSavedWindowPlacement(widget, bounds, show_state); |
| 871 return false; | 871 return false; |
| 872 } | 872 } |
| 873 | 873 |
| 874 void ShellSurface::WindowClosing() { | 874 void ShellSurface::WindowClosing() { |
| 875 if (resizer_) | 875 if (resizer_) |
| 876 EndDrag(true /* revert */); | 876 EndDrag(true /* revert */); |
| 877 SetEnabled(false); | 877 SetEnabled(false); |
| 878 widget_ = nullptr; | 878 widget_ = nullptr; |
| 879 shadow_overlay_ = nullptr; | |
| 880 shadow_underlay_ = nullptr; | |
| 881 } | 879 } |
| 882 | 880 |
| 883 views::Widget* ShellSurface::GetWidget() { | 881 views::Widget* ShellSurface::GetWidget() { |
| 884 return widget_; | 882 return widget_; |
| 885 } | 883 } |
| 886 | 884 |
| 887 const views::Widget* ShellSurface::GetWidget() const { | 885 const views::Widget* ShellSurface::GetWidget() const { |
| 888 return widget_; | 886 return widget_; |
| 889 } | 887 } |
| 890 | 888 |
| (...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1561 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); | 1559 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); |
| 1562 | 1560 |
| 1563 surface_->window()->SetBounds( | 1561 surface_->window()->SetBounds( |
| 1564 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), | 1562 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), |
| 1565 surface_->window()->layer()->size())); | 1563 surface_->window()->layer()->size())); |
| 1566 } | 1564 } |
| 1567 | 1565 |
| 1568 void ShellSurface::UpdateShadow() { | 1566 void ShellSurface::UpdateShadow() { |
| 1569 if (!widget_ || !surface_) | 1567 if (!widget_ || !surface_) |
| 1570 return; | 1568 return; |
| 1569 if (shadow_underlay_in_surface_ != pending_shadow_underlay_in_surface_) { |
| 1570 shadow_underlay_in_surface_ = pending_shadow_underlay_in_surface_; |
| 1571 shadow_overlay_.reset(); |
| 1572 shadow_underlay_.reset(); |
| 1573 } |
| 1574 |
| 1571 aura::Window* window = widget_->GetNativeWindow(); | 1575 aura::Window* window = widget_->GetNativeWindow(); |
| 1572 if (!shadow_enabled_) { | 1576 |
| 1577 bool underlay_capture_events = |
| 1578 WMHelper::GetInstance()->IsSpokenFeedbackEnabled() && widget_->IsActive(); |
| 1579 bool black_background_enabled = |
| 1580 ((widget_->IsFullscreen() || widget_->IsMaximized()) || |
| 1581 underlay_capture_events) && |
| 1582 ash::wm::GetWindowState(window)->allow_set_bounds_direct() && |
| 1583 window->layer()->GetTargetTransform().IsIdentity(); |
| 1584 |
| 1585 if (!shadow_enabled_ && !black_background_enabled) { |
| 1573 wm::SetShadowElevation(window, wm::ShadowElevation::NONE); | 1586 wm::SetShadowElevation(window, wm::ShadowElevation::NONE); |
| 1574 if (shadow_underlay_) | 1587 if (shadow_underlay_) |
| 1575 shadow_underlay_->Hide(); | 1588 shadow_underlay_->Hide(); |
| 1576 } else { | 1589 } else { |
| 1577 wm::SetShadowElevation(window, wm::ShadowElevation::MEDIUM); | 1590 wm::SetShadowElevation(window, wm::ShadowElevation::MEDIUM); |
| 1578 gfx::Rect shadow_content_bounds = | 1591 gfx::Rect shadow_content_bounds = |
| 1579 gfx::ScaleToEnclosedRect(shadow_content_bounds_, 1.f / scale_); | 1592 gfx::ScaleToEnclosedRect(shadow_content_bounds_, 1.f / scale_); |
| 1580 | 1593 |
| 1581 // Convert from screen to display coordinates. | 1594 // Convert from screen to display coordinates. |
| 1582 if (!shadow_content_bounds.IsEmpty()) { | 1595 if (!shadow_content_bounds.IsEmpty()) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1609 shadow_content_bounds.set_origin(origin); | 1622 shadow_content_bounds.set_origin(origin); |
| 1610 } | 1623 } |
| 1611 } | 1624 } |
| 1612 | 1625 |
| 1613 gfx::Point shadow_origin = shadow_content_bounds.origin(); | 1626 gfx::Point shadow_origin = shadow_content_bounds.origin(); |
| 1614 shadow_origin -= window->bounds().OffsetFromOrigin(); | 1627 shadow_origin -= window->bounds().OffsetFromOrigin(); |
| 1615 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size()); | 1628 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size()); |
| 1616 | 1629 |
| 1617 // Always create and show the underlay, even in maximized/fullscreen. | 1630 // Always create and show the underlay, even in maximized/fullscreen. |
| 1618 if (!shadow_underlay_) { | 1631 if (!shadow_underlay_) { |
| 1619 shadow_underlay_ = new aura::Window(nullptr); | 1632 shadow_underlay_ = base::MakeUnique<aura::Window>(nullptr); |
| 1633 shadow_underlay_->set_owned_by_parent(false); |
| 1620 shadow_underlay_event_handler_ = | 1634 shadow_underlay_event_handler_ = |
| 1621 base::MakeUnique<ShadowUnderlayEventHandler>(); | 1635 base::MakeUnique<ShadowUnderlayEventHandler>(); |
| 1622 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get()); | 1636 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get()); |
| 1623 DCHECK(shadow_underlay_->owned_by_parent()); | 1637 DCHECK(!shadow_underlay_->owned_by_parent()); |
| 1624 // Ensure the background area inside the shadow is solid black. | 1638 // Ensure the background area inside the shadow is solid black. |
| 1625 // Clients that provide translucent contents should not be using | 1639 // Clients that provide translucent contents should not be using |
| 1626 // rectangular shadows as this method requires opaque contents to | 1640 // rectangular shadows as this method requires opaque contents to |
| 1627 // cast a shadow that represent it correctly. | 1641 // cast a shadow that represent it correctly. |
| 1628 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR); | 1642 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR); |
| 1629 shadow_underlay_->layer()->SetColor(SK_ColorBLACK); | 1643 shadow_underlay_->layer()->SetColor(SK_ColorBLACK); |
| 1630 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely()); | 1644 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely()); |
| 1631 if (shadow_underlay_in_surface_) { | 1645 if (shadow_underlay_in_surface_) { |
| 1632 surface_->window()->AddChild(shadow_underlay_); | 1646 surface_->window()->AddChild(shadow_underlay()); |
| 1633 surface_->window()->StackChildAtBottom(shadow_underlay_); | 1647 surface_->window()->StackChildAtBottom(shadow_underlay()); |
| 1634 } else { | 1648 } else { |
| 1635 window->AddChild(shadow_underlay_); | 1649 window->AddChild(shadow_underlay()); |
| 1636 window->StackChildAtBottom(shadow_underlay_); | 1650 window->StackChildAtBottom(shadow_underlay()); |
| 1637 } | 1651 } |
| 1638 } | 1652 } |
| 1639 | 1653 |
| 1640 bool underlay_capture_events = | |
| 1641 WMHelper::GetInstance()->IsSpokenFeedbackEnabled() && | |
| 1642 widget_->IsActive(); | |
| 1643 | |
| 1644 float shadow_underlay_opacity = shadow_background_opacity_; | 1654 float shadow_underlay_opacity = shadow_background_opacity_; |
| 1645 | 1655 |
| 1646 // Put the black background layer behind the window if | 1656 // Put the black background layer behind the window if |
| 1647 // 1) the window is in immersive fullscreen, maximized or is active with | 1657 // 1) the window is in immersive fullscreen, maximized or is active with |
| 1648 // spoken feedback enabled. | 1658 // spoken feedback enabled. |
| 1649 // 2) the window can control the bounds of the window in fullscreen ( | 1659 // 2) the window can control the bounds of the window in fullscreen ( |
| 1650 // thus the background can be visible). | 1660 // thus the background can be visible). |
| 1651 // 3) the window has no transform (the transformed background may | 1661 // 3) the window has no transform (the transformed background may |
| 1652 // not cover the entire background, e.g. overview mode). | 1662 // not cover the entire background, e.g. overview mode). |
| 1653 if ((widget_->IsFullscreen() || widget_->IsMaximized() || | 1663 if (black_background_enabled) { |
| 1654 underlay_capture_events) && | |
| 1655 ash::wm::GetWindowState(window)->allow_set_bounds_direct() && | |
| 1656 window->layer()->GetTargetTransform().IsIdentity()) { | |
| 1657 if (shadow_underlay_in_surface_) { | 1664 if (shadow_underlay_in_surface_) { |
| 1658 shadow_underlay_bounds = gfx::Rect(surface_->window()->bounds().size()); | 1665 shadow_underlay_bounds = gfx::Rect(surface_->window()->bounds().size()); |
| 1659 } else { | 1666 } else { |
| 1660 gfx::Point origin; | 1667 gfx::Point origin; |
| 1661 origin -= window->bounds().origin().OffsetFromOrigin(); | 1668 origin -= window->bounds().origin().OffsetFromOrigin(); |
| 1662 shadow_bounds.set_origin(origin); | 1669 shadow_bounds.set_origin(origin); |
| 1663 shadow_bounds.set_size(window->parent()->bounds().size()); | 1670 shadow_bounds.set_size(window->parent()->bounds().size()); |
| 1664 } | 1671 } |
| 1665 shadow_underlay_opacity = 1.0f; | 1672 shadow_underlay_opacity = 1.0f; |
| 1666 } | 1673 } |
| 1667 | 1674 |
| 1668 if (!shadow_underlay_in_surface_) | 1675 if (!shadow_underlay_in_surface_) |
| 1669 shadow_underlay_bounds = shadow_bounds; | 1676 shadow_underlay_bounds = shadow_bounds; |
| 1670 | 1677 |
| 1671 // Constrain the underlay bounds to the client area in case shell surface | 1678 // Constrain the underlay bounds to the client area in case shell surface |
| 1672 // frame is enabled. | 1679 // frame is enabled. |
| 1673 if (frame_enabled_) { | 1680 if (frame_enabled_) { |
| 1674 shadow_underlay_bounds.Intersect( | 1681 shadow_underlay_bounds.Intersect( |
| 1675 widget_->non_client_view()->frame_view()->GetBoundsForClientView()); | 1682 widget_->non_client_view()->frame_view()->GetBoundsForClientView()); |
| 1676 } | 1683 } |
| 1677 | 1684 |
| 1678 shadow_underlay_->SetBounds(shadow_underlay_bounds); | 1685 shadow_underlay_->SetBounds(shadow_underlay_bounds); |
| 1679 | 1686 |
| 1680 shadow_underlay_->Show(); | 1687 if (!shadow_underlay_->IsVisible()) |
| 1688 shadow_underlay_->Show(); |
| 1681 | 1689 |
| 1682 // TODO(oshima): Setting to the same value should be no-op. | 1690 // TODO(oshima): Setting to the same value should be no-op. |
| 1683 // crbug.com/642223. | 1691 // crbug.com/642223. |
| 1684 if (shadow_underlay_opacity != | 1692 if (shadow_underlay_opacity != |
| 1685 shadow_underlay_->layer()->GetTargetOpacity()) { | 1693 shadow_underlay_->layer()->GetTargetOpacity()) { |
| 1686 shadow_underlay_->layer()->SetOpacity(shadow_underlay_opacity); | 1694 shadow_underlay_->layer()->SetOpacity(shadow_underlay_opacity); |
| 1687 } | 1695 } |
| 1688 | 1696 |
| 1689 wm::Shadow* shadow = wm::ShadowController::GetShadowForWindow(window); | 1697 wm::Shadow* shadow = wm::ShadowController::GetShadowForWindow(window); |
| 1690 // Maximized/Fullscreen window does not create a shadow. | 1698 // Maximized/Fullscreen window does not create a shadow. |
| 1691 if (!shadow) | 1699 if (!shadow) |
| 1692 return; | 1700 return; |
| 1693 | 1701 |
| 1694 if (!shadow_overlay_) { | 1702 if (!shadow_overlay_) { |
| 1695 shadow_overlay_ = new aura::Window(nullptr); | 1703 shadow_overlay_ = base::MakeUnique<aura::Window>(nullptr); |
| 1696 DCHECK(shadow_overlay_->owned_by_parent()); | 1704 shadow_overlay_->set_owned_by_parent(false); |
| 1705 DCHECK(!shadow_overlay_->owned_by_parent()); |
| 1697 shadow_overlay_->set_ignore_events(true); | 1706 shadow_overlay_->set_ignore_events(true); |
| 1698 shadow_overlay_->Init(ui::LAYER_NOT_DRAWN); | 1707 shadow_overlay_->Init(ui::LAYER_NOT_DRAWN); |
| 1699 shadow_overlay_->layer()->Add(shadow->layer()); | 1708 shadow_overlay_->layer()->Add(shadow->layer()); |
| 1700 window->AddChild(shadow_overlay_); | 1709 window->AddChild(shadow_overlay()); |
| 1701 | 1710 |
| 1702 if (shadow_underlay_in_surface_) { | 1711 if (shadow_underlay_in_surface_) { |
| 1703 window->StackChildBelow(shadow_overlay_, surface_->window()); | 1712 window->StackChildBelow(shadow_overlay(), surface_->window()); |
| 1704 } else { | 1713 } else { |
| 1705 window->StackChildAbove(shadow_overlay_, shadow_underlay_); | 1714 window->StackChildAbove(shadow_overlay(), shadow_underlay()); |
| 1706 } | 1715 } |
| 1707 shadow_overlay_->Show(); | 1716 shadow_overlay_->Show(); |
| 1708 } | 1717 } |
| 1709 shadow_overlay_->SetBounds(shadow_bounds); | 1718 shadow_overlay_->SetBounds(shadow_bounds); |
| 1710 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size())); | 1719 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size())); |
| 1711 // Surfaces that can't be activated are usually menus and tooltips. Use a | 1720 // Surfaces that can't be activated are usually menus and tooltips. Use a |
| 1712 // small style shadow for them. | 1721 // small style shadow for them. |
| 1713 if (!activatable_) | 1722 if (!activatable_) |
| 1714 shadow->SetElevation(wm::ShadowElevation::SMALL); | 1723 shadow->SetElevation(wm::ShadowElevation::SMALL); |
| 1715 // We don't have rounded corners unless frame is enabled. | 1724 // We don't have rounded corners unless frame is enabled. |
| 1716 if (!frame_enabled_) | 1725 if (!frame_enabled_) |
| 1717 shadow->SetRoundedCornerRadius(0); | 1726 shadow->SetRoundedCornerRadius(0); |
| 1718 } | 1727 } |
| 1719 } | 1728 } |
| 1720 | 1729 |
| 1721 gfx::Point ShellSurface::GetMouseLocation() const { | 1730 gfx::Point ShellSurface::GetMouseLocation() const { |
| 1722 aura::Window* const root_window = widget_->GetNativeWindow()->GetRootWindow(); | 1731 aura::Window* const root_window = widget_->GetNativeWindow()->GetRootWindow(); |
| 1723 gfx::Point location = | 1732 gfx::Point location = |
| 1724 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot(); | 1733 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot(); |
| 1725 aura::Window::ConvertPointToTarget( | 1734 aura::Window::ConvertPointToTarget( |
| 1726 root_window, widget_->GetNativeWindow()->parent(), &location); | 1735 root_window, widget_->GetNativeWindow()->parent(), &location); |
| 1727 return location; | 1736 return location; |
| 1728 } | 1737 } |
| 1729 | 1738 |
| 1730 } // namespace exo | 1739 } // namespace exo |
| OLD | NEW |