| 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/common/frame/custom_frame_view_ash.h" | 9 #include "ash/common/frame/custom_frame_view_ash.h" |
| 10 #include "ash/common/shelf/wm_shelf.h" | 10 #include "ash/common/shelf/wm_shelf.h" |
| (...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 DLOG(WARNING) << "Surface geometry must be non-empty"; | 589 DLOG(WARNING) << "Surface geometry must be non-empty"; |
| 590 return; | 590 return; |
| 591 } | 591 } |
| 592 | 592 |
| 593 pending_geometry_ = geometry; | 593 pending_geometry_ = geometry; |
| 594 } | 594 } |
| 595 | 595 |
| 596 void ShellSurface::SetRectangularShadowEnabled(bool enabled) { | 596 void ShellSurface::SetRectangularShadowEnabled(bool enabled) { |
| 597 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadowEnabled", "enabled", | 597 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadowEnabled", "enabled", |
| 598 enabled); | 598 enabled); |
| 599 shadow_underlay_in_surface_ = false; | 599 pending_shadow_underlay_in_surface_ = false; |
| 600 shadow_enabled_ = enabled; | 600 shadow_enabled_ = enabled; |
| 601 } | 601 } |
| 602 | 602 |
| 603 void ShellSurface::SetRectangularShadow_DEPRECATED( | 603 void ShellSurface::SetRectangularShadow_DEPRECATED( |
| 604 const gfx::Rect& content_bounds) { | 604 const gfx::Rect& content_bounds) { |
| 605 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadow_DEPRECATED", | 605 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadow_DEPRECATED", |
| 606 "content_bounds", content_bounds.ToString()); | 606 "content_bounds", content_bounds.ToString()); |
| 607 shadow_underlay_in_surface_ = false; | 607 pending_shadow_underlay_in_surface_ = false; |
| 608 shadow_content_bounds_ = content_bounds; | 608 shadow_content_bounds_ = content_bounds; |
| 609 shadow_enabled_ = !content_bounds.IsEmpty(); | 609 shadow_enabled_ = !content_bounds.IsEmpty(); |
| 610 } | 610 } |
| 611 | 611 |
| 612 void ShellSurface::SetRectangularSurfaceShadow( | 612 void ShellSurface::SetRectangularSurfaceShadow( |
| 613 const gfx::Rect& content_bounds) { | 613 const gfx::Rect& content_bounds) { |
| 614 TRACE_EVENT1("exo", "ShellSurface::SetRectangularSurfaceShadow", | 614 TRACE_EVENT1("exo", "ShellSurface::SetRectangularSurfaceShadow", |
| 615 "content_bounds", content_bounds.ToString()); | 615 "content_bounds", content_bounds.ToString()); |
| 616 shadow_underlay_in_surface_ = true; | 616 pending_shadow_underlay_in_surface_ = true; |
| 617 shadow_content_bounds_ = content_bounds; | 617 shadow_content_bounds_ = content_bounds; |
| 618 shadow_enabled_ = !content_bounds.IsEmpty(); | 618 shadow_enabled_ = !content_bounds.IsEmpty(); |
| 619 } | 619 } |
| 620 | 620 |
| 621 void ShellSurface::SetRectangularShadowBackgroundOpacity(float opacity) { | 621 void ShellSurface::SetRectangularShadowBackgroundOpacity(float opacity) { |
| 622 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadowBackgroundOpacity", | 622 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadowBackgroundOpacity", |
| 623 "opacity", opacity); | 623 "opacity", opacity); |
| 624 shadow_background_opacity_ = opacity; | 624 shadow_background_opacity_ = opacity; |
| 625 } | 625 } |
| 626 | 626 |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 if (bounds_mode_ != BoundsMode::CLIENT) | 860 if (bounds_mode_ != BoundsMode::CLIENT) |
| 861 return WidgetDelegate::GetSavedWindowPlacement(widget, bounds, show_state); | 861 return WidgetDelegate::GetSavedWindowPlacement(widget, bounds, show_state); |
| 862 return false; | 862 return false; |
| 863 } | 863 } |
| 864 | 864 |
| 865 void ShellSurface::WindowClosing() { | 865 void ShellSurface::WindowClosing() { |
| 866 if (resizer_) | 866 if (resizer_) |
| 867 EndDrag(true /* revert */); | 867 EndDrag(true /* revert */); |
| 868 SetEnabled(false); | 868 SetEnabled(false); |
| 869 widget_ = nullptr; | 869 widget_ = nullptr; |
| 870 shadow_overlay_ = nullptr; | |
| 871 shadow_underlay_ = nullptr; | |
| 872 } | 870 } |
| 873 | 871 |
| 874 views::Widget* ShellSurface::GetWidget() { | 872 views::Widget* ShellSurface::GetWidget() { |
| 875 return widget_; | 873 return widget_; |
| 876 } | 874 } |
| 877 | 875 |
| 878 const views::Widget* ShellSurface::GetWidget() const { | 876 const views::Widget* ShellSurface::GetWidget() const { |
| 879 return widget_; | 877 return widget_; |
| 880 } | 878 } |
| 881 | 879 |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1456 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); | 1454 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); |
| 1457 | 1455 |
| 1458 surface_->window()->SetBounds( | 1456 surface_->window()->SetBounds( |
| 1459 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), | 1457 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), |
| 1460 surface_->window()->layer()->size())); | 1458 surface_->window()->layer()->size())); |
| 1461 } | 1459 } |
| 1462 | 1460 |
| 1463 void ShellSurface::UpdateShadow() { | 1461 void ShellSurface::UpdateShadow() { |
| 1464 if (!widget_ || !surface_) | 1462 if (!widget_ || !surface_) |
| 1465 return; | 1463 return; |
| 1464 if (shadow_underlay_in_surface_ != pending_shadow_underlay_in_surface_) { |
| 1465 shadow_underlay_in_surface_ = pending_shadow_underlay_in_surface_; |
| 1466 shadow_overlay_.reset(); |
| 1467 shadow_underlay_.reset(); |
| 1468 } |
| 1469 |
| 1466 aura::Window* window = widget_->GetNativeWindow(); | 1470 aura::Window* window = widget_->GetNativeWindow(); |
| 1467 if (!shadow_enabled_) { | 1471 |
| 1472 bool underlay_capture_events = |
| 1473 WMHelper::GetInstance()->IsSpokenFeedbackEnabled() && widget_->IsActive(); |
| 1474 bool black_background_enabled = |
| 1475 ((widget_->IsFullscreen() || widget_->IsMaximized()) || |
| 1476 underlay_capture_events) && |
| 1477 ash::wm::GetWindowState(window)->allow_set_bounds_direct() && |
| 1478 window->layer()->GetTargetTransform().IsIdentity(); |
| 1479 |
| 1480 if (!shadow_enabled_ && !black_background_enabled) { |
| 1468 wm::SetShadowElevation(window, wm::ShadowElevation::NONE); | 1481 wm::SetShadowElevation(window, wm::ShadowElevation::NONE); |
| 1469 if (shadow_underlay_) | 1482 if (shadow_underlay_) |
| 1470 shadow_underlay_->Hide(); | 1483 shadow_underlay_->Hide(); |
| 1471 } else { | 1484 } else { |
| 1472 wm::SetShadowElevation(window, wm::ShadowElevation::MEDIUM); | 1485 wm::SetShadowElevation(window, wm::ShadowElevation::MEDIUM); |
| 1473 gfx::Rect shadow_content_bounds = | 1486 gfx::Rect shadow_content_bounds = |
| 1474 gfx::ScaleToEnclosedRect(shadow_content_bounds_, 1.f / scale_); | 1487 gfx::ScaleToEnclosedRect(shadow_content_bounds_, 1.f / scale_); |
| 1475 | 1488 |
| 1476 // Convert from screen to display coordinates. | 1489 // Convert from screen to display coordinates. |
| 1477 if (!shadow_content_bounds.IsEmpty()) { | 1490 if (!shadow_content_bounds.IsEmpty()) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1504 shadow_content_bounds.set_origin(origin); | 1517 shadow_content_bounds.set_origin(origin); |
| 1505 } | 1518 } |
| 1506 } | 1519 } |
| 1507 | 1520 |
| 1508 gfx::Point shadow_origin = shadow_content_bounds.origin(); | 1521 gfx::Point shadow_origin = shadow_content_bounds.origin(); |
| 1509 shadow_origin -= window->bounds().OffsetFromOrigin(); | 1522 shadow_origin -= window->bounds().OffsetFromOrigin(); |
| 1510 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size()); | 1523 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size()); |
| 1511 | 1524 |
| 1512 // Always create and show the underlay, even in maximized/fullscreen. | 1525 // Always create and show the underlay, even in maximized/fullscreen. |
| 1513 if (!shadow_underlay_) { | 1526 if (!shadow_underlay_) { |
| 1514 shadow_underlay_ = new aura::Window(nullptr); | 1527 shadow_underlay_ = base::MakeUnique<aura::Window>(nullptr); |
| 1528 shadow_underlay_->set_owned_by_parent(false); |
| 1515 shadow_underlay_event_handler_ = | 1529 shadow_underlay_event_handler_ = |
| 1516 base::MakeUnique<ShadowUnderlayEventHandler>(); | 1530 base::MakeUnique<ShadowUnderlayEventHandler>(); |
| 1517 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get()); | 1531 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get()); |
| 1518 DCHECK(shadow_underlay_->owned_by_parent()); | 1532 DCHECK(!shadow_underlay_->owned_by_parent()); |
| 1519 // Ensure the background area inside the shadow is solid black. | 1533 // Ensure the background area inside the shadow is solid black. |
| 1520 // Clients that provide translucent contents should not be using | 1534 // Clients that provide translucent contents should not be using |
| 1521 // rectangular shadows as this method requires opaque contents to | 1535 // rectangular shadows as this method requires opaque contents to |
| 1522 // cast a shadow that represent it correctly. | 1536 // cast a shadow that represent it correctly. |
| 1523 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR); | 1537 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR); |
| 1524 shadow_underlay_->layer()->SetColor(SK_ColorBLACK); | 1538 shadow_underlay_->layer()->SetColor(SK_ColorBLACK); |
| 1525 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely()); | 1539 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely()); |
| 1526 if (shadow_underlay_in_surface_) { | 1540 if (shadow_underlay_in_surface_) { |
| 1527 surface_->window()->AddChild(shadow_underlay_); | 1541 surface_->window()->AddChild(shadow_underlay()); |
| 1528 surface_->window()->StackChildAtBottom(shadow_underlay_); | 1542 surface_->window()->StackChildAtBottom(shadow_underlay()); |
| 1529 } else { | 1543 } else { |
| 1530 window->AddChild(shadow_underlay_); | 1544 window->AddChild(shadow_underlay()); |
| 1531 window->StackChildAtBottom(shadow_underlay_); | 1545 window->StackChildAtBottom(shadow_underlay()); |
| 1532 } | 1546 } |
| 1533 } | 1547 } |
| 1534 | 1548 |
| 1535 bool underlay_capture_events = | |
| 1536 WMHelper::GetInstance()->IsSpokenFeedbackEnabled() && | |
| 1537 widget_->IsActive(); | |
| 1538 | |
| 1539 float shadow_underlay_opacity = shadow_background_opacity_; | 1549 float shadow_underlay_opacity = shadow_background_opacity_; |
| 1540 | 1550 |
| 1541 // Put the black background layer behind the window if | 1551 // Put the black background layer behind the window if |
| 1542 // 1) the window is in immersive fullscreen, maximized or is active with | 1552 // 1) the window is in immersive fullscreen, maximized or is active with |
| 1543 // spoken feedback enabled. | 1553 // spoken feedback enabled. |
| 1544 // 2) the window can control the bounds of the window in fullscreen ( | 1554 // 2) the window can control the bounds of the window in fullscreen ( |
| 1545 // thus the background can be visible). | 1555 // thus the background can be visible). |
| 1546 // 3) the window has no transform (the transformed background may | 1556 // 3) the window has no transform (the transformed background may |
| 1547 // not cover the entire background, e.g. overview mode). | 1557 // not cover the entire background, e.g. overview mode). |
| 1548 if ((widget_->IsFullscreen() || widget_->IsMaximized() || | 1558 if (black_background_enabled) { |
| 1549 underlay_capture_events) && | |
| 1550 ash::wm::GetWindowState(window)->allow_set_bounds_direct() && | |
| 1551 window->layer()->GetTargetTransform().IsIdentity()) { | |
| 1552 if (shadow_underlay_in_surface_) { | 1559 if (shadow_underlay_in_surface_) { |
| 1553 shadow_underlay_bounds = gfx::Rect(surface_->window()->bounds().size()); | 1560 shadow_underlay_bounds = gfx::Rect(surface_->window()->bounds().size()); |
| 1554 } else { | 1561 } else { |
| 1555 gfx::Point origin; | 1562 gfx::Point origin; |
| 1556 origin -= window->bounds().origin().OffsetFromOrigin(); | 1563 origin -= window->bounds().origin().OffsetFromOrigin(); |
| 1557 shadow_bounds.set_origin(origin); | 1564 shadow_bounds.set_origin(origin); |
| 1558 shadow_bounds.set_size(window->parent()->bounds().size()); | 1565 shadow_bounds.set_size(window->parent()->bounds().size()); |
| 1559 } | 1566 } |
| 1560 shadow_underlay_opacity = 1.0f; | 1567 shadow_underlay_opacity = 1.0f; |
| 1561 } | 1568 } |
| 1562 | 1569 |
| 1563 if (!shadow_underlay_in_surface_) | 1570 if (!shadow_underlay_in_surface_) |
| 1564 shadow_underlay_bounds = shadow_bounds; | 1571 shadow_underlay_bounds = shadow_bounds; |
| 1565 | 1572 |
| 1566 // Constrain the underlay bounds to the client area in case shell surface | 1573 // Constrain the underlay bounds to the client area in case shell surface |
| 1567 // frame is enabled. | 1574 // frame is enabled. |
| 1568 if (frame_enabled_) { | 1575 if (frame_enabled_) { |
| 1569 shadow_underlay_bounds.Intersect( | 1576 shadow_underlay_bounds.Intersect( |
| 1570 widget_->non_client_view()->frame_view()->GetBoundsForClientView()); | 1577 widget_->non_client_view()->frame_view()->GetBoundsForClientView()); |
| 1571 } | 1578 } |
| 1572 | 1579 |
| 1573 shadow_underlay_->SetBounds(shadow_underlay_bounds); | 1580 shadow_underlay_->SetBounds(shadow_underlay_bounds); |
| 1574 | 1581 |
| 1582 if (!shadow_underlay_->IsVisible()) |
| 1583 shadow_underlay_->Show(); |
| 1584 |
| 1575 // TODO(oshima): Setting to the same value should be no-op. | 1585 // TODO(oshima): Setting to the same value should be no-op. |
| 1576 // crbug.com/642223. | 1586 // crbug.com/642223. |
| 1577 if (shadow_underlay_opacity != | 1587 if (shadow_underlay_opacity != |
| 1578 shadow_underlay_->layer()->GetTargetOpacity()) { | 1588 shadow_underlay_->layer()->GetTargetOpacity()) { |
| 1579 shadow_underlay_->layer()->SetOpacity(shadow_underlay_opacity); | 1589 shadow_underlay_->layer()->SetOpacity(shadow_underlay_opacity); |
| 1580 } | 1590 } |
| 1581 shadow_underlay_->Show(); | |
| 1582 | 1591 |
| 1583 wm::Shadow* shadow = wm::ShadowController::GetShadowForWindow(window); | 1592 wm::Shadow* shadow = wm::ShadowController::GetShadowForWindow(window); |
| 1584 // Maximized/Fullscreen window does not create a shadow. | 1593 // Maximized/Fullscreen window does not create a shadow. |
| 1585 if (!shadow) | 1594 if (!shadow) |
| 1586 return; | 1595 return; |
| 1587 | 1596 |
| 1588 if (!shadow_overlay_) { | 1597 if (!shadow_overlay_) { |
| 1589 shadow_overlay_ = new aura::Window(nullptr); | 1598 shadow_overlay_ = base::MakeUnique<aura::Window>(nullptr); |
| 1590 DCHECK(shadow_overlay_->owned_by_parent()); | 1599 shadow_overlay_->set_owned_by_parent(false); |
| 1600 DCHECK(!shadow_overlay_->owned_by_parent()); |
| 1591 shadow_overlay_->set_ignore_events(true); | 1601 shadow_overlay_->set_ignore_events(true); |
| 1592 shadow_overlay_->Init(ui::LAYER_NOT_DRAWN); | 1602 shadow_overlay_->Init(ui::LAYER_NOT_DRAWN); |
| 1593 shadow_overlay_->layer()->Add(shadow->layer()); | 1603 shadow_overlay_->layer()->Add(shadow->layer()); |
| 1594 window->AddChild(shadow_overlay_); | 1604 window->AddChild(shadow_overlay()); |
| 1595 | 1605 |
| 1596 if (shadow_underlay_in_surface_) { | 1606 if (shadow_underlay_in_surface_) { |
| 1597 window->StackChildBelow(shadow_overlay_, surface_->window()); | 1607 window->StackChildBelow(shadow_overlay(), surface_->window()); |
| 1598 } else { | 1608 } else { |
| 1599 window->StackChildAbove(shadow_overlay_, shadow_underlay_); | 1609 window->StackChildAbove(shadow_overlay(), shadow_underlay()); |
| 1600 } | 1610 } |
| 1601 shadow_overlay_->Show(); | 1611 shadow_overlay_->Show(); |
| 1602 } | 1612 } |
| 1603 shadow_overlay_->SetBounds(shadow_bounds); | 1613 shadow_overlay_->SetBounds(shadow_bounds); |
| 1604 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size())); | 1614 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size())); |
| 1605 // Surfaces that can't be activated are usually menus and tooltips. Use a | 1615 // Surfaces that can't be activated are usually menus and tooltips. Use a |
| 1606 // small style shadow for them. | 1616 // small style shadow for them. |
| 1607 if (!activatable_) | 1617 if (!activatable_) |
| 1608 shadow->SetElevation(wm::ShadowElevation::SMALL); | 1618 shadow->SetElevation(wm::ShadowElevation::SMALL); |
| 1609 // We don't have rounded corners unless frame is enabled. | 1619 // We don't have rounded corners unless frame is enabled. |
| 1610 if (!frame_enabled_) | 1620 if (!frame_enabled_) |
| 1611 shadow->SetRoundedCornerRadius(0); | 1621 shadow->SetRoundedCornerRadius(0); |
| 1612 } | 1622 } |
| 1613 } | 1623 } |
| 1614 | 1624 |
| 1615 } // namespace exo | 1625 } // namespace exo |
| OLD | NEW |