Chromium Code Reviews| 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/aura/wm_window_aura.h" | 9 #include "ash/aura/wm_window_aura.h" |
| 10 #include "ash/common/frame/custom_frame_view_ash.h" | |
| 10 #include "ash/common/shelf/wm_shelf.h" | 11 #include "ash/common/shelf/wm_shelf.h" |
| 11 #include "ash/common/wm/window_resizer.h" | 12 #include "ash/common/wm/window_resizer.h" |
| 12 #include "ash/common/wm/window_state.h" | 13 #include "ash/common/wm/window_state.h" |
| 13 #include "ash/common/wm/window_state_delegate.h" | 14 #include "ash/common/wm/window_state_delegate.h" |
| 14 #include "ash/common/wm_shell.h" | 15 #include "ash/common/wm_shell.h" |
| 15 #include "ash/public/cpp/shell_window_ids.h" | 16 #include "ash/public/cpp/shell_window_ids.h" |
| 16 #include "ash/wm/window_state_aura.h" | 17 #include "ash/wm/window_state_aura.h" |
| 17 #include "ash/wm/window_util.h" | 18 #include "ash/wm/window_util.h" |
| 18 #include "base/logging.h" | 19 #include "base/logging.h" |
| 19 #include "base/macros.h" | 20 #include "base/macros.h" |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 30 #include "ui/aura/window_targeter.h" | 31 #include "ui/aura/window_targeter.h" |
| 31 #include "ui/aura/window_tree_host.h" | 32 #include "ui/aura/window_tree_host.h" |
| 32 #include "ui/base/accelerators/accelerator.h" | 33 #include "ui/base/accelerators/accelerator.h" |
| 33 #include "ui/gfx/path.h" | 34 #include "ui/gfx/path.h" |
| 34 #include "ui/views/widget/widget.h" | 35 #include "ui/views/widget/widget.h" |
| 35 #include "ui/views/widget/widget_observer.h" | 36 #include "ui/views/widget/widget_observer.h" |
| 36 #include "ui/wm/core/coordinate_conversion.h" | 37 #include "ui/wm/core/coordinate_conversion.h" |
| 37 #include "ui/wm/core/shadow.h" | 38 #include "ui/wm/core/shadow.h" |
| 38 #include "ui/wm/core/shadow_controller.h" | 39 #include "ui/wm/core/shadow_controller.h" |
| 39 #include "ui/wm/core/shadow_types.h" | 40 #include "ui/wm/core/shadow_types.h" |
| 41 #include "ui/wm/core/window_animations.h" | |
| 40 #include "ui/wm/core/window_util.h" | 42 #include "ui/wm/core/window_util.h" |
| 41 | 43 |
| 42 #if defined(OS_CHROMEOS) | 44 #if defined(OS_CHROMEOS) |
| 43 #include "chromeos/audio/chromeos_sounds.h" | 45 #include "chromeos/audio/chromeos_sounds.h" |
| 44 #endif | 46 #endif |
| 45 | 47 |
| 46 namespace exo { | 48 namespace exo { |
| 47 namespace { | 49 namespace { |
| 48 | 50 |
| 49 // This is a struct for accelerator keys used to close ShellSurfaces. | 51 // This is a struct for accelerator keys used to close ShellSurfaces. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 93 | 95 |
| 94 // Overridden from aura::WindowTargeter: | 96 // Overridden from aura::WindowTargeter: |
| 95 bool EventLocationInsideBounds(aura::Window* window, | 97 bool EventLocationInsideBounds(aura::Window* window, |
| 96 const ui::LocatedEvent& event) const override { | 98 const ui::LocatedEvent& event) const override { |
| 97 Surface* surface = ShellSurface::GetMainSurface(window); | 99 Surface* surface = ShellSurface::GetMainSurface(window); |
| 98 if (!surface) | 100 if (!surface) |
| 99 return false; | 101 return false; |
| 100 | 102 |
| 101 gfx::Point local_point = event.location(); | 103 gfx::Point local_point = event.location(); |
| 102 | 104 |
| 105 if (window->parent()) { | |
| 106 aura::Window::ConvertPointToTarget(window->parent(), window, | |
| 107 &local_point); | |
| 108 } | |
| 109 | |
| 110 int component = widget_->non_client_view()->NonClientHitTest(local_point); | |
| 111 if (component != HTNOWHERE && component != HTCLIENT) | |
| 112 return true; | |
| 113 | |
| 103 // If there is an underlay, test against it's bounds instead since it will | 114 // If there is an underlay, test against it's bounds instead since it will |
| 104 // be equal or larger than the surface's bounds. | 115 // be equal or larger than the surface's bounds. |
| 105 aura::Window* shadow_underlay = | 116 aura::Window* shadow_underlay = |
| 106 static_cast<ShellSurface*>( | 117 static_cast<ShellSurface*>( |
| 107 widget_->widget_delegate()->GetContentsView()) | 118 widget_->widget_delegate()->GetContentsView()) |
| 108 ->shadow_underlay(); | 119 ->shadow_underlay(); |
| 109 if (shadow_underlay) { | 120 if (shadow_underlay) { |
| 110 if (window->parent()) | 121 aura::Window::ConvertPointToTarget(window, shadow_underlay, &local_point); |
| 111 aura::Window::ConvertPointToTarget(window->parent(), shadow_underlay, | |
| 112 &local_point); | |
| 113 return gfx::Rect(shadow_underlay->layer()->size()).Contains(local_point); | 122 return gfx::Rect(shadow_underlay->layer()->size()).Contains(local_point); |
| 114 } | 123 } |
| 115 | 124 |
| 116 if (window->parent()) | |
| 117 aura::Window::ConvertPointToTarget(window->parent(), window, | |
| 118 &local_point); | |
| 119 | |
| 120 aura::Window::ConvertPointToTarget(window, surface->window(), &local_point); | 125 aura::Window::ConvertPointToTarget(window, surface->window(), &local_point); |
| 121 return surface->HitTestRect(gfx::Rect(local_point, gfx::Size(1, 1))); | 126 return surface->HitTestRect(gfx::Rect(local_point, gfx::Size(1, 1))); |
| 122 } | 127 } |
| 123 | 128 |
| 124 ui::EventTarget* FindTargetForEvent(ui::EventTarget* root, | 129 ui::EventTarget* FindTargetForEvent(ui::EventTarget* root, |
| 125 ui::Event* event) override { | 130 ui::Event* event) override { |
| 126 aura::Window* window = static_cast<aura::Window*>(root); | 131 aura::Window* window = static_cast<aura::Window*>(root); |
| 127 Surface* surface = ShellSurface::GetMainSurface(window); | 132 Surface* surface = ShellSurface::GetMainSurface(window); |
| 128 | 133 |
| 129 // Send events which are outside of the surface's bounds to the underlay. | 134 // Send events which are outside of the surface's bounds to the underlay. |
| 130 aura::Window* shadow_underlay = | 135 aura::Window* shadow_underlay = |
| 131 static_cast<ShellSurface*>( | 136 static_cast<ShellSurface*>( |
| 132 widget_->widget_delegate()->GetContentsView()) | 137 widget_->widget_delegate()->GetContentsView()) |
| 133 ->shadow_underlay(); | 138 ->shadow_underlay(); |
| 134 if (surface && event->IsLocatedEvent() && shadow_underlay) { | 139 if (surface && event->IsLocatedEvent() && shadow_underlay) { |
| 135 gfx::Point local_point = event->AsLocatedEvent()->location(); | 140 gfx::Point local_point = event->AsLocatedEvent()->location(); |
| 136 aura::Window::ConvertPointToTarget(window, surface->window(), | 141 int component = widget_->non_client_view()->NonClientHitTest(local_point); |
| 137 &local_point); | 142 if (component == HTNOWHERE) |
| 138 if (!surface->HitTestRect(gfx::Rect(local_point, gfx::Size(1, 1)))) | |
| 139 return shadow_underlay; | 143 return shadow_underlay; |
| 140 } | 144 } |
| 141 return aura::WindowTargeter::FindTargetForEvent(root, event); | 145 return aura::WindowTargeter::FindTargetForEvent(root, event); |
| 142 } | 146 } |
| 143 | 147 |
| 144 private: | 148 private: |
| 145 views::Widget* const widget_; | 149 views::Widget* const widget_; |
| 146 | 150 |
| 147 DISALLOW_COPY_AND_ASSIGN(CustomWindowTargeter); | 151 DISALLOW_COPY_AND_ASSIGN(CustomWindowTargeter); |
| 148 }; | 152 }; |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 326 | 330 |
| 327 //////////////////////////////////////////////////////////////////////////////// | 331 //////////////////////////////////////////////////////////////////////////////// |
| 328 // ShellSurface, public: | 332 // ShellSurface, public: |
| 329 | 333 |
| 330 DEFINE_LOCAL_WINDOW_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr) | 334 DEFINE_LOCAL_WINDOW_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr) |
| 331 | 335 |
| 332 ShellSurface::ShellSurface(Surface* surface, | 336 ShellSurface::ShellSurface(Surface* surface, |
| 333 ShellSurface* parent, | 337 ShellSurface* parent, |
| 334 const gfx::Rect& initial_bounds, | 338 const gfx::Rect& initial_bounds, |
| 335 bool activatable, | 339 bool activatable, |
| 340 bool can_minimize, | |
| 336 int container) | 341 int container) |
| 337 : widget_(nullptr), | 342 : widget_(nullptr), |
| 338 surface_(surface), | 343 surface_(surface), |
| 339 parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr), | 344 parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr), |
| 340 initial_bounds_(initial_bounds), | 345 initial_bounds_(initial_bounds), |
| 341 activatable_(activatable), | 346 activatable_(activatable), |
| 347 can_minimize_(can_minimize), | |
| 342 container_(container) { | 348 container_(container) { |
| 343 WMHelper::GetInstance()->AddActivationObserver(this); | 349 WMHelper::GetInstance()->AddActivationObserver(this); |
| 344 surface_->SetSurfaceDelegate(this); | 350 surface_->SetSurfaceDelegate(this); |
| 345 surface_->AddSurfaceObserver(this); | 351 surface_->AddSurfaceObserver(this); |
| 346 surface_->window()->Show(); | 352 surface_->window()->Show(); |
| 347 set_owned_by_client(); | 353 set_owned_by_client(); |
| 348 if (parent_) | 354 if (parent_) |
| 349 parent_->AddObserver(this); | 355 parent_->AddObserver(this); |
| 350 } | 356 } |
| 351 | 357 |
| 352 ShellSurface::ShellSurface(Surface* surface) | 358 ShellSurface::ShellSurface(Surface* surface) |
| 353 : ShellSurface(surface, | 359 : ShellSurface(surface, |
| 354 nullptr, | 360 nullptr, |
| 355 gfx::Rect(), | 361 gfx::Rect(), |
| 356 true, | 362 true, |
| 363 true, | |
| 357 ash::kShellWindowId_DefaultContainer) {} | 364 ash::kShellWindowId_DefaultContainer) {} |
| 358 | 365 |
| 359 ShellSurface::~ShellSurface() { | 366 ShellSurface::~ShellSurface() { |
| 360 DCHECK(!scoped_configure_); | 367 DCHECK(!scoped_configure_); |
| 361 if (resizer_) | 368 if (resizer_) |
| 362 EndDrag(false /* revert */); | 369 EndDrag(false /* revert */); |
| 363 if (widget_) { | 370 if (widget_) { |
| 364 ash::wm::GetWindowState(widget_->GetNativeWindow())->RemoveObserver(this); | 371 ash::wm::GetWindowState(widget_->GetNativeWindow())->RemoveObserver(this); |
| 365 widget_->GetNativeWindow()->RemoveObserver(this); | 372 widget_->GetNativeWindow()->RemoveObserver(this); |
| 366 if (widget_->IsVisible()) | 373 if (widget_->IsVisible()) |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 571 geometry.ToString()); | 578 geometry.ToString()); |
| 572 | 579 |
| 573 if (geometry.IsEmpty()) { | 580 if (geometry.IsEmpty()) { |
| 574 DLOG(WARNING) << "Surface geometry must be non-empty"; | 581 DLOG(WARNING) << "Surface geometry must be non-empty"; |
| 575 return; | 582 return; |
| 576 } | 583 } |
| 577 | 584 |
| 578 pending_geometry_ = geometry; | 585 pending_geometry_ = geometry; |
| 579 } | 586 } |
| 580 | 587 |
| 581 void ShellSurface::SetRectangularShadow(const gfx::Rect& content_bounds) { | 588 void ShellSurface::SetRectangularShadow(bool enabled) { |
| 582 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadow", "content_bounds", | 589 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadow", "enabled", enabled); |
| 583 content_bounds.ToString()); | 590 |
| 591 shadow_enabled_ = enabled; | |
| 592 } | |
| 593 | |
| 594 void ShellSurface::SetRectangularShadowContentBounds( | |
| 595 const gfx::Rect& content_bounds) { | |
| 596 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadowContentBounds", | |
| 597 "content_bounds", content_bounds.ToString()); | |
| 584 | 598 |
| 585 shadow_content_bounds_ = content_bounds; | 599 shadow_content_bounds_ = content_bounds; |
| 586 } | 600 } |
| 587 | 601 |
| 588 void ShellSurface::SetRectangularShadowBackgroundOpacity(float opacity) { | 602 void ShellSurface::SetRectangularShadowBackgroundOpacity(float opacity) { |
| 589 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadowBackgroundOpacity", | 603 TRACE_EVENT1("exo", "ShellSurface::SetRectangularShadowBackgroundOpacity", |
| 590 "opacity", opacity); | 604 "opacity", opacity); |
| 591 | 605 |
| 592 rectangular_shadow_background_opacity_ = opacity; | 606 shadow_background_opacity_ = opacity; |
| 607 } | |
| 608 | |
| 609 void ShellSurface::SetFrame(bool enabled) { | |
| 610 TRACE_EVENT1("exo", "ShellSurface::SetFrame", "enabled", enabled); | |
| 611 | |
| 612 frame_enabled_ = enabled; | |
| 593 } | 613 } |
| 594 | 614 |
| 595 void ShellSurface::SetScale(double scale) { | 615 void ShellSurface::SetScale(double scale) { |
| 596 TRACE_EVENT1("exo", "ShellSurface::SetScale", "scale", scale); | 616 TRACE_EVENT1("exo", "ShellSurface::SetScale", "scale", scale); |
| 597 | 617 |
| 598 if (scale <= 0.0) { | 618 if (scale <= 0.0) { |
| 599 DLOG(WARNING) << "Surface scale must be greater than 0"; | 619 DLOG(WARNING) << "Surface scale must be greater than 0"; |
| 600 return; | 620 return; |
| 601 } | 621 } |
| 602 | 622 |
| 603 pending_scale_ = scale; | 623 pending_scale_ = scale; |
| 604 } | 624 } |
| 605 | 625 |
| 606 void ShellSurface::SetTopInset(int height) { | 626 void ShellSurface::SetTopInset(int height) { |
| 607 TRACE_EVENT1("exo", "ShellSurface::SetTopInset", "height", height); | 627 TRACE_EVENT1("exo", "ShellSurface::SetTopInset", "height", height); |
| 608 | 628 |
| 609 pending_top_inset_height_ = height; | 629 pending_top_inset_height_ = height; |
| 610 } | 630 } |
| 611 | 631 |
| 612 void ShellSurface::SetOrigin(const gfx::Point& origin) { | 632 void ShellSurface::SetOrigin(const gfx::Point& origin) { |
| 613 TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString()); | 633 TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString()); |
| 614 | 634 |
| 615 initial_bounds_ = gfx::Rect(origin, gfx::Size(1, 1)); | 635 initial_bounds_ = gfx::Rect(origin, gfx::Size(1, 1)); |
| 616 } | 636 } |
| 617 | 637 |
| 618 void ShellSurface::SetActivatable(bool activatable) { | 638 void ShellSurface::SetContainer(int container) { |
| 619 TRACE_EVENT1("exo", "ShellSurface::SetActivatable", "activatable", | 639 TRACE_EVENT1("exo", "ShellSurface::SetContainer", "container", container); |
| 620 activatable); | |
| 621 | 640 |
| 622 activatable_ = activatable; | 641 container_ = container; |
| 623 } | 642 } |
| 624 | 643 |
| 625 // static | 644 // static |
| 626 void ShellSurface::SetMainSurface(aura::Window* window, Surface* surface) { | 645 void ShellSurface::SetMainSurface(aura::Window* window, Surface* surface) { |
| 627 window->SetProperty(kMainSurfaceKey, surface); | 646 window->SetProperty(kMainSurfaceKey, surface); |
| 628 } | 647 } |
| 629 | 648 |
| 630 // static | 649 // static |
| 631 Surface* ShellSurface::GetMainSurface(const aura::Window* window) { | 650 Surface* ShellSurface::GetMainSurface(const aura::Window* window) { |
| 632 return window->GetProperty(kMainSurfaceKey); | 651 return window->GetProperty(kMainSurfaceKey); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 669 UpdateWidgetBounds(); | 688 UpdateWidgetBounds(); |
| 670 UpdateShadow(); | 689 UpdateShadow(); |
| 671 | 690 |
| 672 // Apply new top inset height. | 691 // Apply new top inset height. |
| 673 if (pending_top_inset_height_ != top_inset_height_) { | 692 if (pending_top_inset_height_ != top_inset_height_) { |
| 674 widget_->GetNativeWindow()->SetProperty(aura::client::kTopViewInset, | 693 widget_->GetNativeWindow()->SetProperty(aura::client::kTopViewInset, |
| 675 pending_top_inset_height_); | 694 pending_top_inset_height_); |
| 676 top_inset_height_ = pending_top_inset_height_; | 695 top_inset_height_ = pending_top_inset_height_; |
| 677 } | 696 } |
| 678 | 697 |
| 679 gfx::Point surface_origin = GetSurfaceOrigin(); | |
| 680 | |
| 681 // System modal container is used by clients to implement overlay | 698 // System modal container is used by clients to implement overlay |
| 682 // windows using a single ShellSurface instance. If hit-test | 699 // windows using a single ShellSurface instance. If hit-test |
| 683 // region is empty, then it is non interactive window and won't be | 700 // region is empty, then it is non interactive window and won't be |
| 684 // activated. | 701 // activated. |
| 685 if (container_ == ash::kShellWindowId_SystemModalContainer) { | 702 if (container_ == ash::kShellWindowId_SystemModalContainer) { |
| 686 gfx::Rect hit_test_bounds = | 703 gfx::Rect hit_test_bounds = surface_->GetHitTestBounds(); |
| 687 surface_->GetHitTestBounds() + surface_origin.OffsetFromOrigin(); | |
| 688 | 704 |
| 689 // Prevent window from being activated when hit test bounds are empty. | 705 // Prevent window from being activated when hit test bounds are empty. |
| 690 bool activatable = activatable_ && !hit_test_bounds.IsEmpty(); | 706 bool activatable = activatable_ && !hit_test_bounds.IsEmpty(); |
| 691 if (activatable != CanActivate()) { | 707 if (activatable != CanActivate()) { |
| 692 set_can_activate(activatable); | 708 set_can_activate(activatable); |
| 693 // Activate or deactivate window if activation state changed. | 709 // Activate or deactivate window if activation state changed. |
| 694 if (activatable) | 710 if (activatable) |
| 695 wm::ActivateWindow(widget_->GetNativeWindow()); | 711 wm::ActivateWindow(widget_->GetNativeWindow()); |
| 696 else if (widget_->IsActive()) | 712 else if (widget_->IsActive()) |
| 697 wm::DeactivateWindow(widget_->GetNativeWindow()); | 713 wm::DeactivateWindow(widget_->GetNativeWindow()); |
| 698 } | 714 } |
| 699 } | 715 } |
| 700 | 716 |
| 717 gfx::Rect client_view_bounds = | |
| 718 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); | |
| 719 | |
| 701 // Update surface bounds. | 720 // Update surface bounds. |
| 702 surface_->window()->SetBounds( | 721 surface_->window()->SetBounds( |
| 703 gfx::Rect(surface_origin, surface_->window()->layer()->size())); | 722 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), |
| 723 surface_->window()->layer()->size())); | |
| 704 | 724 |
| 705 // Update surface scale. | 725 // Update surface scale. |
| 706 if (pending_scale_ != scale_) { | 726 if (pending_scale_ != scale_) { |
| 707 gfx::Transform transform; | 727 gfx::Transform transform; |
| 708 DCHECK_NE(pending_scale_, 0.0); | 728 DCHECK_NE(pending_scale_, 0.0); |
| 709 transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_); | 729 transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_); |
| 710 surface_->window()->SetTransform(transform); | 730 surface_->window()->SetTransform(transform); |
| 711 scale_ = pending_scale_; | 731 scale_ = pending_scale_; |
| 712 } | 732 } |
| 713 | 733 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 751 | 771 |
| 752 //////////////////////////////////////////////////////////////////////////////// | 772 //////////////////////////////////////////////////////////////////////////////// |
| 753 // views::WidgetDelegate overrides: | 773 // views::WidgetDelegate overrides: |
| 754 | 774 |
| 755 bool ShellSurface::CanResize() const { | 775 bool ShellSurface::CanResize() const { |
| 756 return initial_bounds_.IsEmpty(); | 776 return initial_bounds_.IsEmpty(); |
| 757 } | 777 } |
| 758 | 778 |
| 759 bool ShellSurface::CanMaximize() const { | 779 bool ShellSurface::CanMaximize() const { |
| 760 // Shell surfaces in system modal container cannot be maximized. | 780 // Shell surfaces in system modal container cannot be maximized. |
| 761 return container_ != ash::kShellWindowId_SystemModalContainer; | 781 if (container_ == ash::kShellWindowId_SystemModalContainer) |
| 782 return false; | |
| 783 | |
| 784 // Non-transient shell surfaces can be maximized. | |
| 785 return !parent_; | |
| 762 } | 786 } |
| 763 | 787 |
| 764 bool ShellSurface::CanMinimize() const { | 788 bool ShellSurface::CanMinimize() const { |
| 765 // Shell surfaces in system modal container cannot be minimized. | 789 return can_minimize_; |
| 766 return container_ != ash::kShellWindowId_SystemModalContainer; | |
| 767 } | 790 } |
| 768 | 791 |
| 769 base::string16 ShellSurface::GetWindowTitle() const { | 792 base::string16 ShellSurface::GetWindowTitle() const { |
| 770 return title_; | 793 return title_; |
| 771 } | 794 } |
| 772 | 795 |
| 773 void ShellSurface::WindowClosing() { | 796 void ShellSurface::WindowClosing() { |
| 774 if (resizer_) | 797 if (resizer_) |
| 775 EndDrag(true /* revert */); | 798 EndDrag(true /* revert */); |
| 776 SetEnabled(false); | 799 SetEnabled(false); |
| 777 widget_ = nullptr; | 800 widget_ = nullptr; |
| 778 shadow_overlay_ = nullptr; | 801 shadow_overlay_ = nullptr; |
| 779 shadow_underlay_ = nullptr; | 802 shadow_underlay_ = nullptr; |
| 780 } | 803 } |
| 781 | 804 |
| 782 views::Widget* ShellSurface::GetWidget() { | 805 views::Widget* ShellSurface::GetWidget() { |
| 783 return widget_; | 806 return widget_; |
| 784 } | 807 } |
| 785 | 808 |
| 786 const views::Widget* ShellSurface::GetWidget() const { | 809 const views::Widget* ShellSurface::GetWidget() const { |
| 787 return widget_; | 810 return widget_; |
| 788 } | 811 } |
| 789 | 812 |
| 790 views::View* ShellSurface::GetContentsView() { | 813 views::View* ShellSurface::GetContentsView() { |
| 791 return this; | 814 return this; |
| 792 } | 815 } |
| 793 | 816 |
| 794 views::NonClientFrameView* ShellSurface::CreateNonClientFrameView( | 817 views::NonClientFrameView* ShellSurface::CreateNonClientFrameView( |
| 795 views::Widget* widget) { | 818 views::Widget* widget) { |
| 819 aura::Window* window = widget_->GetNativeWindow(); | |
| 820 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); | |
| 821 // Set delegate for handling of fullscreening. | |
| 822 window_state->SetDelegate(std::unique_ptr<ash::wm::WindowStateDelegate>( | |
| 823 new CustomWindowStateDelegate(widget_))); | |
| 824 | |
| 825 if (frame_enabled_) | |
| 826 return new ash::CustomFrameViewAsh(widget); | |
| 827 | |
| 796 return new CustomFrameView(widget); | 828 return new CustomFrameView(widget); |
| 797 } | 829 } |
| 798 | 830 |
| 799 bool ShellSurface::WidgetHasHitTestMask() const { | 831 bool ShellSurface::WidgetHasHitTestMask() const { |
| 800 return surface_ ? surface_->HasHitTestMask() : false; | 832 return surface_ ? surface_->HasHitTestMask() : false; |
| 801 } | 833 } |
| 802 | 834 |
| 803 void ShellSurface::GetWidgetHitTestMask(gfx::Path* mask) const { | 835 void ShellSurface::GetWidgetHitTestMask(gfx::Path* mask) const { |
| 804 DCHECK(WidgetHasHitTestMask()); | 836 DCHECK(WidgetHasHitTestMask()); |
| 805 surface_->GetHitTestMask(mask); | 837 surface_->GetHitTestMask(mask); |
| 806 gfx::Point origin = surface_->window()->bounds().origin(); | 838 gfx::Point origin = surface_->window()->bounds().origin(); |
| 807 mask->offset(SkIntToScalar(origin.x()), SkIntToScalar(origin.y())); | 839 mask->offset(SkIntToScalar(origin.x()), SkIntToScalar(origin.y())); |
| 808 } | 840 } |
| 809 | 841 |
| 810 //////////////////////////////////////////////////////////////////////////////// | 842 //////////////////////////////////////////////////////////////////////////////// |
| 811 // views::Views overrides: | 843 // views::Views overrides: |
| 812 | 844 |
| 813 gfx::Size ShellSurface::GetPreferredSize() const { | 845 gfx::Size ShellSurface::GetPreferredSize() const { |
| 814 if (!geometry_.IsEmpty()) | 846 if (!geometry_.IsEmpty()) |
| 815 return geometry_.size(); | 847 return geometry_.size(); |
| 816 | 848 |
| 817 return surface_ ? surface_->window()->layer()->size() : gfx::Size(); | 849 return surface_ ? surface_->window()->layer()->size() : gfx::Size(); |
| 818 } | 850 } |
| 819 | 851 |
| 852 gfx::Size ShellSurface::GetMinimumSize() const { | |
| 853 return gfx::Size(1, 1); | |
| 854 } | |
| 855 | |
| 820 //////////////////////////////////////////////////////////////////////////////// | 856 //////////////////////////////////////////////////////////////////////////////// |
| 821 // ash::wm::WindowStateObserver overrides: | 857 // ash::wm::WindowStateObserver overrides: |
| 822 | 858 |
| 823 void ShellSurface::OnPreWindowStateTypeChange( | 859 void ShellSurface::OnPreWindowStateTypeChange( |
| 824 ash::wm::WindowState* window_state, | 860 ash::wm::WindowState* window_state, |
| 825 ash::wm::WindowStateType old_type) { | 861 ash::wm::WindowStateType old_type) { |
| 826 ash::wm::WindowStateType new_type = window_state->GetStateType(); | 862 ash::wm::WindowStateType new_type = window_state->GetStateType(); |
| 827 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || | 863 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || |
| 828 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { | 864 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { |
| 829 // When transitioning in/out of maximized or fullscreen mode we need to | 865 // When transitioning in/out of maximized or fullscreen mode we need to |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 870 if (new_bounds.size() == old_bounds.size()) | 906 if (new_bounds.size() == old_bounds.size()) |
| 871 return; | 907 return; |
| 872 | 908 |
| 873 // If size changed then give the client a chance to produce new contents | 909 // If size changed then give the client a chance to produce new contents |
| 874 // before origin on screen is changed by adding offset to the next configure | 910 // before origin on screen is changed by adding offset to the next configure |
| 875 // request and offset |origin_| by the same distance. | 911 // request and offset |origin_| by the same distance. |
| 876 gfx::Vector2d origin_offset = new_bounds.origin() - old_bounds.origin(); | 912 gfx::Vector2d origin_offset = new_bounds.origin() - old_bounds.origin(); |
| 877 pending_origin_config_offset_ += origin_offset; | 913 pending_origin_config_offset_ += origin_offset; |
| 878 origin_ -= origin_offset; | 914 origin_ -= origin_offset; |
| 879 | 915 |
| 916 gfx::Rect client_view_bounds = | |
| 917 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); | |
| 918 | |
| 919 // Update surface bounds. | |
| 880 surface_->window()->SetBounds( | 920 surface_->window()->SetBounds( |
| 881 gfx::Rect(GetSurfaceOrigin(), surface_->window()->layer()->size())); | 921 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), |
| 922 surface_->window()->layer()->size())); | |
| 882 | 923 |
| 883 // The shadow size may be updated to match the widget. Change it back | 924 // The shadow size may be updated to match the widget. Change it back |
| 884 // to the shadow content size. | 925 // to the shadow content size. |
| 885 // TODO(oshima): When the arc window reiszing is enabled, we may want to | 926 // TODO(oshima): When the arc window reiszing is enabled, we may want to |
| 886 // implement shadow management here instead of using shadow controller. | 927 // implement shadow management here instead of using shadow controller. |
| 887 UpdateShadow(); | 928 UpdateShadow(); |
| 888 | 929 |
| 889 Configure(); | 930 Configure(); |
| 890 } | 931 } |
| 891 } | 932 } |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1044 window->AddObserver(this); | 1085 window->AddObserver(this); |
| 1045 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); | 1086 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); |
| 1046 window_state->AddObserver(this); | 1087 window_state->AddObserver(this); |
| 1047 | 1088 |
| 1048 // Absolete positioned shell surfaces may request the bounds that does not | 1089 // Absolete positioned shell surfaces may request the bounds that does not |
| 1049 // fill the entire work area / display in maximized / fullscreen state. | 1090 // fill the entire work area / display in maximized / fullscreen state. |
| 1050 // Allow such clients to update the bounds in these states. | 1091 // Allow such clients to update the bounds in these states. |
| 1051 if (!initial_bounds_.IsEmpty()) | 1092 if (!initial_bounds_.IsEmpty()) |
| 1052 window_state->set_allow_set_bounds_in_maximized(true); | 1093 window_state->set_allow_set_bounds_in_maximized(true); |
| 1053 | 1094 |
| 1095 // Notify client of initial state. | |
|
Daniele Castagna
2016/12/08 20:19:13
This can go away.
reveman
2016/12/11 07:14:04
Done.
| |
| 1054 // Notify client of initial state if different than normal. | 1096 // Notify client of initial state if different than normal. |
| 1055 if (window_state->GetStateType() != ash::wm::WINDOW_STATE_TYPE_NORMAL && | 1097 if (window_state->GetStateType() != ash::wm::WINDOW_STATE_TYPE_NORMAL && |
| 1056 !state_changed_callback_.is_null()) { | 1098 !state_changed_callback_.is_null()) { |
| 1057 state_changed_callback_.Run(ash::wm::WINDOW_STATE_TYPE_NORMAL, | 1099 state_changed_callback_.Run(ash::wm::WINDOW_STATE_TYPE_NORMAL, |
| 1058 window_state->GetStateType()); | 1100 window_state->GetStateType()); |
| 1059 } | 1101 } |
| 1060 | 1102 |
| 1061 // Disable movement if initial bounds were specified. | 1103 // Disable movement if initial bounds were specified. |
| 1062 widget_->set_movement_disabled(!initial_bounds_.IsEmpty()); | 1104 widget_->set_movement_disabled(!initial_bounds_.IsEmpty()); |
| 1063 window_state->set_ignore_keyboard_bounds_change(!initial_bounds_.IsEmpty()); | 1105 window_state->set_ignore_keyboard_bounds_change(!initial_bounds_.IsEmpty()); |
| 1064 | 1106 |
| 1065 // AutoHide shelf in fullscreen state. | 1107 // AutoHide shelf in fullscreen state. |
| 1066 window_state->set_hide_shelf_when_fullscreen(false); | 1108 window_state->set_hide_shelf_when_fullscreen(false); |
| 1067 | 1109 |
| 1068 // Allow Ash to manage the position of a top-level shell surfaces if show | 1110 // Fade visibility animations for non-activatable windows. |
| 1069 // state is one that allows auto positioning and |initial_bounds_| has | 1111 if (!activatable_) { |
| 1070 // not been set. | 1112 wm::SetWindowVisibilityAnimationType( |
| 1071 window_state->set_window_position_managed( | 1113 window, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); |
| 1072 ash::wm::ToWindowShowState(ash::wm::WINDOW_STATE_TYPE_AUTO_POSITIONED) == | 1114 } |
|
Daniele Castagna
2016/12/08 20:19:13
:( the animations were cool.
reveman
2016/12/11 07:14:04
sorry. maybe we'll enable them again in the future
| |
| 1073 show_state && | |
| 1074 initial_bounds_.IsEmpty()); | |
| 1075 | 1115 |
| 1076 // Register close window accelerators. | 1116 // Register close window accelerators. |
| 1077 views::FocusManager* focus_manager = widget_->GetFocusManager(); | 1117 views::FocusManager* focus_manager = widget_->GetFocusManager(); |
| 1078 for (const auto& entry : kCloseWindowAccelerators) { | 1118 for (const auto& entry : kCloseWindowAccelerators) { |
| 1079 focus_manager->RegisterAccelerator( | 1119 focus_manager->RegisterAccelerator( |
| 1080 ui::Accelerator(entry.keycode, entry.modifiers), | 1120 ui::Accelerator(entry.keycode, entry.modifiers), |
| 1081 ui::AcceleratorManager::kNormalPriority, this); | 1121 ui::AcceleratorManager::kNormalPriority, this); |
| 1082 } | 1122 } |
| 1083 | 1123 |
| 1084 // Set delegate for handling of fullscreening. | |
| 1085 window_state->SetDelegate(std::unique_ptr<ash::wm::WindowStateDelegate>( | |
| 1086 new CustomWindowStateDelegate(widget_))); | |
| 1087 | |
| 1088 // Receive accessibility changes to update shadow underlay. | 1124 // Receive accessibility changes to update shadow underlay. |
| 1089 WMHelper::GetInstance()->AddAccessibilityObserver(this); | 1125 WMHelper::GetInstance()->AddAccessibilityObserver(this); |
| 1090 | 1126 |
| 1091 // Show widget next time Commit() is called. | 1127 // Show widget next time Commit() is called. |
| 1092 pending_show_widget_ = true; | 1128 pending_show_widget_ = true; |
| 1093 } | 1129 } |
| 1094 | 1130 |
| 1095 void ShellSurface::Configure() { | 1131 void ShellSurface::Configure() { |
| 1096 DCHECK(widget_); | 1132 DCHECK(widget_); |
| 1097 | 1133 |
| 1098 // Delay configure callback if |scoped_configure_| is set. | 1134 // Delay configure callback if |scoped_configure_| is set. |
| 1099 if (scoped_configure_) { | 1135 if (scoped_configure_) { |
| 1100 scoped_configure_->set_needs_configure(); | 1136 scoped_configure_->set_needs_configure(); |
| 1101 return; | 1137 return; |
| 1102 } | 1138 } |
| 1103 | 1139 |
| 1104 gfx::Vector2d origin_offset = pending_origin_config_offset_; | 1140 gfx::Vector2d origin_offset = pending_origin_config_offset_; |
| 1105 pending_origin_config_offset_ = gfx::Vector2d(); | 1141 pending_origin_config_offset_ = gfx::Vector2d(); |
| 1106 | 1142 |
| 1143 ash::wm::WindowState* window_state = | |
| 1144 ash::wm::GetWindowState(widget_->GetNativeWindow()); | |
| 1145 | |
| 1107 // If surface is being resized, save the resize direction. | 1146 // If surface is being resized, save the resize direction. |
| 1108 int resize_component = | 1147 int resize_component = window_state->is_dragged() |
| 1109 resizer_ ? resizer_->details().window_component : HTCAPTION; | 1148 ? window_state->drag_details()->window_component |
| 1149 : HTCAPTION; | |
| 1110 | 1150 |
| 1111 if (configure_callback_.is_null()) { | 1151 uint32_t serial = 0; |
| 1152 if (!configure_callback_.is_null()) { | |
| 1153 const views::NonClientView* non_client_view = widget_->non_client_view(); | |
| 1154 serial = configure_callback_.Run( | |
| 1155 non_client_view->frame_view()->GetBoundsForClientView().size(), | |
| 1156 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(), | |
| 1157 IsResizing(), widget_->IsActive()); | |
| 1158 } | |
| 1159 | |
| 1160 if (!serial) { | |
| 1112 pending_origin_offset_ += origin_offset; | 1161 pending_origin_offset_ += origin_offset; |
| 1113 pending_resize_component_ = resize_component; | 1162 pending_resize_component_ = resize_component; |
| 1114 return; | 1163 return; |
| 1115 } | 1164 } |
| 1116 | 1165 |
| 1117 uint32_t serial = configure_callback_.Run( | |
| 1118 widget_->GetWindowBoundsInScreen().size(), | |
| 1119 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(), | |
| 1120 IsResizing(), widget_->IsActive()); | |
| 1121 | |
| 1122 // Apply origin offset and resize component at the first Commit() after this | 1166 // Apply origin offset and resize component at the first Commit() after this |
| 1123 // configure request has been acknowledged. | 1167 // configure request has been acknowledged. |
| 1124 pending_configs_.push_back({serial, origin_offset, resize_component}); | 1168 pending_configs_.push_back({serial, origin_offset, resize_component}); |
| 1125 LOG_IF(WARNING, pending_configs_.size() > 100) | 1169 LOG_IF(WARNING, pending_configs_.size() > 100) |
| 1126 << "Number of pending configure acks for shell surface has reached: " | 1170 << "Number of pending configure acks for shell surface has reached: " |
| 1127 << pending_configs_.size(); | 1171 << pending_configs_.size(); |
| 1128 } | 1172 } |
| 1129 | 1173 |
| 1130 void ShellSurface::AttemptToStartDrag(int component) { | 1174 void ShellSurface::AttemptToStartDrag(int component) { |
| 1131 DCHECK(widget_); | 1175 DCHECK(widget_); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1219 resizer_.reset(); | 1263 resizer_.reset(); |
| 1220 | 1264 |
| 1221 // Notify client that resizing state has changed. | 1265 // Notify client that resizing state has changed. |
| 1222 if (was_resizing) | 1266 if (was_resizing) |
| 1223 Configure(); | 1267 Configure(); |
| 1224 | 1268 |
| 1225 UpdateWidgetBounds(); | 1269 UpdateWidgetBounds(); |
| 1226 } | 1270 } |
| 1227 | 1271 |
| 1228 bool ShellSurface::IsResizing() const { | 1272 bool ShellSurface::IsResizing() const { |
| 1229 if (!resizer_) | 1273 ash::wm::WindowState* window_state = |
| 1274 ash::wm::GetWindowState(widget_->GetNativeWindow()); | |
| 1275 if (!window_state->is_dragged()) | |
| 1230 return false; | 1276 return false; |
| 1231 | 1277 |
| 1232 return resizer_->details().bounds_change & | 1278 return window_state->drag_details()->bounds_change & |
| 1233 ash::WindowResizer::kBoundsChange_Resizes; | 1279 ash::WindowResizer::kBoundsChange_Resizes; |
| 1234 } | 1280 } |
| 1235 | 1281 |
| 1236 gfx::Rect ShellSurface::GetVisibleBounds() const { | 1282 gfx::Rect ShellSurface::GetVisibleBounds() const { |
| 1237 // Use |geometry_| if set, otherwise use the visual bounds of the surface. | 1283 // Use |geometry_| if set, otherwise use the visual bounds of the surface. |
| 1238 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size()) | 1284 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size()) |
| 1239 : geometry_; | 1285 : geometry_; |
| 1240 } | 1286 } |
| 1241 | 1287 |
| 1242 gfx::Point ShellSurface::GetSurfaceOrigin() const { | 1288 gfx::Point ShellSurface::GetSurfaceOrigin() const { |
| 1243 gfx::Rect window_bounds = widget_->GetNativeWindow()->bounds(); | |
| 1244 | |
| 1245 // If initial bounds were specified then surface origin is always relative | 1289 // If initial bounds were specified then surface origin is always relative |
| 1246 // to those bounds. | 1290 // to those bounds. |
| 1247 if (!initial_bounds_.IsEmpty()) { | 1291 if (!initial_bounds_.IsEmpty()) { |
| 1248 gfx::Point origin = window_bounds.origin(); | 1292 gfx::Point origin = widget_->GetNativeWindow()->bounds().origin(); |
| 1249 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &origin); | 1293 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &origin); |
| 1250 return initial_bounds_.origin() - origin.OffsetFromOrigin(); | 1294 return initial_bounds_.origin() - origin.OffsetFromOrigin(); |
| 1251 } | 1295 } |
| 1252 | 1296 |
| 1253 gfx::Rect visible_bounds = GetVisibleBounds(); | 1297 gfx::Rect visible_bounds = GetVisibleBounds(); |
| 1298 gfx::Rect client_bounds = | |
| 1299 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); | |
| 1254 switch (resize_component_) { | 1300 switch (resize_component_) { |
| 1255 case HTCAPTION: | 1301 case HTCAPTION: |
| 1256 return origin_ - visible_bounds.OffsetFromOrigin(); | 1302 return origin_ - visible_bounds.OffsetFromOrigin(); |
| 1257 case HTBOTTOM: | 1303 case HTBOTTOM: |
| 1258 case HTRIGHT: | 1304 case HTRIGHT: |
| 1259 case HTBOTTOMRIGHT: | 1305 case HTBOTTOMRIGHT: |
| 1260 return gfx::Point() - visible_bounds.OffsetFromOrigin(); | 1306 return gfx::Point() - visible_bounds.OffsetFromOrigin(); |
| 1261 case HTTOP: | 1307 case HTTOP: |
| 1262 case HTTOPRIGHT: | 1308 case HTTOPRIGHT: |
| 1263 return gfx::Point(0, window_bounds.height() - visible_bounds.height()) - | 1309 return gfx::Point(0, client_bounds.height() - visible_bounds.height()) - |
| 1264 visible_bounds.OffsetFromOrigin(); | 1310 visible_bounds.OffsetFromOrigin(); |
| 1265 break; | 1311 break; |
| 1266 case HTLEFT: | 1312 case HTLEFT: |
| 1267 case HTBOTTOMLEFT: | 1313 case HTBOTTOMLEFT: |
| 1268 return gfx::Point(window_bounds.width() - visible_bounds.width(), 0) - | 1314 return gfx::Point(client_bounds.width() - visible_bounds.width(), 0) - |
| 1269 visible_bounds.OffsetFromOrigin(); | 1315 visible_bounds.OffsetFromOrigin(); |
| 1270 case HTTOPLEFT: | 1316 case HTTOPLEFT: |
| 1271 return gfx::Point(window_bounds.width() - visible_bounds.width(), | 1317 return gfx::Point(client_bounds.width() - visible_bounds.width(), |
| 1272 window_bounds.height() - visible_bounds.height()) - | 1318 client_bounds.height() - visible_bounds.height()) - |
| 1273 visible_bounds.OffsetFromOrigin(); | 1319 visible_bounds.OffsetFromOrigin(); |
| 1274 default: | 1320 default: |
| 1275 NOTREACHED(); | 1321 NOTREACHED(); |
| 1276 return gfx::Point(); | 1322 return gfx::Point(); |
| 1277 } | 1323 } |
| 1278 } | 1324 } |
| 1279 | 1325 |
| 1280 void ShellSurface::UpdateWidgetBounds() { | 1326 void ShellSurface::UpdateWidgetBounds() { |
| 1281 DCHECK(widget_); | 1327 DCHECK(widget_); |
| 1282 | 1328 |
| 1283 // Return early if the shell is currently managing the bounds of the widget. | 1329 // Return early if the shell is currently managing the bounds of the widget. |
| 1284 // 1) When a window is either maximized/fullscreen/pinned, and the bounds | 1330 // 1) When a window is either maximized/fullscreen/pinned, and the bounds |
| 1285 // isn't controlled by a client. | 1331 // isn't controlled by a client. |
| 1286 ash::wm::WindowState* window_state = | 1332 ash::wm::WindowState* window_state = |
| 1287 ash::wm::GetWindowState(widget_->GetNativeWindow()); | 1333 ash::wm::GetWindowState(widget_->GetNativeWindow()); |
| 1288 if (window_state->IsMaximizedOrFullscreenOrPinned() && | 1334 if (window_state->IsMaximizedOrFullscreenOrPinned() && |
| 1289 !window_state->allow_set_bounds_in_maximized()) { | 1335 !window_state->allow_set_bounds_in_maximized()) { |
| 1290 return; | 1336 return; |
| 1291 } | 1337 } |
| 1292 | 1338 |
| 1293 // 2) When a window is being dragged. | 1339 // 2) When a window is being dragged. |
| 1294 if (IsResizing()) | 1340 if (IsResizing()) |
| 1295 return; | 1341 return; |
| 1296 | 1342 |
| 1297 // Return early if there is pending configure requests. | 1343 // Return early if there is pending configure requests. |
| 1298 if (!pending_configs_.empty() || scoped_configure_) | 1344 if (!pending_configs_.empty() || scoped_configure_) |
| 1299 return; | 1345 return; |
| 1300 | 1346 |
| 1301 gfx::Rect visible_bounds = GetVisibleBounds(); | 1347 gfx::Rect visible_bounds = GetVisibleBounds(); |
| 1302 gfx::Rect new_widget_bounds = visible_bounds; | 1348 gfx::Rect new_widget_bounds = |
| 1349 widget_->non_client_view()->GetWindowBoundsForClientBounds( | |
| 1350 visible_bounds); | |
| 1303 | 1351 |
| 1304 // Avoid changing widget origin unless initial bounds were specified and | 1352 // Avoid changing widget origin unless initial bounds were specified and |
| 1305 // widget origin is always relative to it. | 1353 // widget origin is always relative to it. |
| 1306 if (initial_bounds_.IsEmpty()) { | 1354 if (initial_bounds_.IsEmpty()) { |
| 1307 new_widget_bounds.set_origin(widget_->GetWindowBoundsInScreen().origin()); | 1355 new_widget_bounds.set_origin(widget_->GetWindowBoundsInScreen().origin()); |
| 1308 } else { | 1356 } else { |
| 1309 new_widget_bounds.set_origin(initial_bounds_.origin() + | 1357 new_widget_bounds.set_origin(initial_bounds_.origin() + |
| 1310 visible_bounds.OffsetFromOrigin()); | 1358 visible_bounds.OffsetFromOrigin()); |
| 1311 } | 1359 } |
| 1312 | 1360 |
| 1313 // Update widget origin using the surface origin if the current location of | 1361 // Update widget origin using the surface origin if the current location of |
| 1314 // surface is being anchored to one side of the widget as a result of a | 1362 // surface is being anchored to one side of the widget as a result of a |
| 1315 // resize operation. | 1363 // resize operation. |
| 1316 if (resize_component_ != HTCAPTION) { | 1364 if (resize_component_ != HTCAPTION) { |
| 1317 gfx::Point new_widget_origin = | 1365 gfx::Point new_widget_origin = |
| 1318 GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin(); | 1366 GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin(); |
| 1319 wm::ConvertPointToScreen(widget_->GetNativeWindow(), &new_widget_origin); | 1367 wm::ConvertPointToScreen(widget_->GetNativeWindow(), &new_widget_origin); |
| 1320 new_widget_bounds.set_origin(new_widget_origin); | 1368 new_widget_bounds.set_origin(new_widget_origin); |
| 1321 } | 1369 } |
| 1322 | 1370 |
| 1323 // Set |ignore_window_bounds_changes_| as this change to window bounds | 1371 // Set |ignore_window_bounds_changes_| as this change to window bounds |
| 1324 // should not result in a configure request. | 1372 // should not result in a configure request. |
| 1325 DCHECK(!ignore_window_bounds_changes_); | 1373 DCHECK(!ignore_window_bounds_changes_); |
| 1326 ignore_window_bounds_changes_ = true; | 1374 ignore_window_bounds_changes_ = true; |
| 1327 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) | 1375 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) |
| 1328 widget_->SetBounds(new_widget_bounds); | 1376 widget_->SetBounds(new_widget_bounds); |
| 1329 ignore_window_bounds_changes_ = false; | 1377 ignore_window_bounds_changes_ = false; |
| 1330 | 1378 |
| 1379 gfx::Rect client_view_bounds = | |
| 1380 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); | |
| 1381 | |
| 1331 // A change to the widget size requires surface bounds to be re-adjusted. | 1382 // A change to the widget size requires surface bounds to be re-adjusted. |
| 1332 surface_->window()->SetBounds( | 1383 surface_->window()->SetBounds( |
| 1333 gfx::Rect(GetSurfaceOrigin(), surface_->window()->layer()->size())); | 1384 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), |
| 1385 surface_->window()->layer()->size())); | |
| 1334 } | 1386 } |
| 1335 | 1387 |
| 1336 void ShellSurface::UpdateShadow() { | 1388 void ShellSurface::UpdateShadow() { |
| 1337 if (!widget_) | 1389 if (!widget_) |
| 1338 return; | 1390 return; |
| 1339 aura::Window* window = widget_->GetNativeWindow(); | 1391 aura::Window* window = widget_->GetNativeWindow(); |
| 1340 if (shadow_content_bounds_.IsEmpty()) { | 1392 if (!shadow_enabled_) { |
| 1341 wm::SetShadowType(window, wm::SHADOW_TYPE_NONE); | 1393 wm::SetShadowType(window, wm::SHADOW_TYPE_NONE); |
| 1342 if (shadow_underlay_) | 1394 if (shadow_underlay_) |
| 1343 shadow_underlay_->Hide(); | 1395 shadow_underlay_->Hide(); |
| 1344 } else { | 1396 } else { |
| 1345 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR); | 1397 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR); |
| 1346 | 1398 |
| 1399 gfx::Rect shadow_content_bounds = shadow_content_bounds_; | |
| 1400 if (shadow_content_bounds.IsEmpty()) | |
| 1401 shadow_content_bounds = window->bounds(); | |
| 1402 | |
| 1347 // TODO(oshima): Adjust the coordinates from client screen to | 1403 // TODO(oshima): Adjust the coordinates from client screen to |
| 1348 // chromeos screen when multi displays are supported. | 1404 // chromeos screen when multi displays are supported. |
| 1349 gfx::Point origin = window->bounds().origin(); | 1405 gfx::Point origin = window->bounds().origin(); |
| 1350 gfx::Point shadow_origin = shadow_content_bounds_.origin(); | 1406 gfx::Point shadow_origin = shadow_content_bounds.origin(); |
| 1351 shadow_origin -= origin.OffsetFromOrigin(); | 1407 shadow_origin -= origin.OffsetFromOrigin(); |
| 1352 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds_.size()); | 1408 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size()); |
| 1353 | 1409 |
| 1354 // Always create and show the underlay, even in maximized/fullscreen. | 1410 // Always create and show the underlay, even in maximized/fullscreen. |
| 1355 if (!shadow_underlay_) { | 1411 if (!shadow_underlay_) { |
| 1356 shadow_underlay_ = new aura::Window(nullptr); | 1412 shadow_underlay_ = new aura::Window(nullptr); |
| 1357 shadow_underlay_event_handler_ = | 1413 shadow_underlay_event_handler_ = |
| 1358 base::MakeUnique<ShadowUnderlayEventHandler>(); | 1414 base::MakeUnique<ShadowUnderlayEventHandler>(); |
| 1359 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get()); | 1415 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get()); |
| 1360 DCHECK(shadow_underlay_->owned_by_parent()); | 1416 DCHECK(shadow_underlay_->owned_by_parent()); |
| 1361 // Ensure the background area inside the shadow is solid black. | 1417 // Ensure the background area inside the shadow is solid black. |
| 1362 // Clients that provide translucent contents should not be using | 1418 // Clients that provide translucent contents should not be using |
| 1363 // rectangular shadows as this method requires opaque contents to | 1419 // rectangular shadows as this method requires opaque contents to |
| 1364 // cast a shadow that represent it correctly. | 1420 // cast a shadow that represent it correctly. |
| 1365 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR); | 1421 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR); |
| 1366 shadow_underlay_->layer()->SetColor(SK_ColorBLACK); | 1422 shadow_underlay_->layer()->SetColor(SK_ColorBLACK); |
| 1367 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely()); | 1423 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely()); |
| 1368 window->AddChild(shadow_underlay_); | 1424 window->AddChild(shadow_underlay_); |
| 1369 window->StackChildAtBottom(shadow_underlay_); | 1425 window->StackChildAtBottom(shadow_underlay_); |
| 1370 } | 1426 } |
| 1371 | 1427 |
| 1372 bool underlay_capture_events = | 1428 bool underlay_capture_events = |
| 1373 WMHelper::GetInstance()->IsSpokenFeedbackEnabled() && | 1429 WMHelper::GetInstance()->IsSpokenFeedbackEnabled() && |
| 1374 widget_->IsActive(); | 1430 widget_->IsActive(); |
| 1375 | 1431 |
| 1376 float shadow_underlay_opacity = rectangular_shadow_background_opacity_; | 1432 float shadow_underlay_opacity = shadow_background_opacity_; |
| 1377 // Put the black background layer behind the window if | 1433 // Put the black background layer behind the window if |
| 1378 // 1) the window is in immersive fullscreen or is active with | 1434 // 1) the window is in immersive fullscreen or is active with |
| 1379 // spoken feedback enabled. | 1435 // spoken feedback enabled. |
| 1380 // 2) the window can control the bounds of the window in fullscreen ( | 1436 // 2) the window can control the bounds of the window in fullscreen ( |
| 1381 // thus the background can be visible). | 1437 // thus the background can be visible). |
| 1382 // 3) the window has no transform (the transformed background may | 1438 // 3) the window has no transform (the transformed background may |
| 1383 // not cover the entire background, e.g. overview mode). | 1439 // not cover the entire background, e.g. overview mode). |
| 1384 if ((widget_->IsFullscreen() || underlay_capture_events) && | 1440 if ((widget_->IsFullscreen() || underlay_capture_events) && |
| 1385 ash::wm::GetWindowState(window)->allow_set_bounds_in_maximized() && | 1441 ash::wm::GetWindowState(window)->allow_set_bounds_in_maximized() && |
| 1386 window->layer()->GetTargetTransform().IsIdentity()) { | 1442 window->layer()->GetTargetTransform().IsIdentity()) { |
| 1387 gfx::Point origin; | 1443 gfx::Point origin; |
| 1388 origin -= window->bounds().origin().OffsetFromOrigin(); | 1444 origin -= window->bounds().origin().OffsetFromOrigin(); |
| 1389 shadow_bounds.set_origin(origin); | 1445 shadow_bounds.set_origin(origin); |
| 1390 shadow_bounds.set_size(window->parent()->bounds().size()); | 1446 shadow_bounds.set_size(window->parent()->bounds().size()); |
| 1391 shadow_underlay_opacity = 1.0f; | 1447 shadow_underlay_opacity = 1.0f; |
| 1392 } | 1448 } |
| 1393 | 1449 |
| 1394 shadow_underlay_->SetBounds(shadow_bounds); | 1450 gfx::Rect shadow_underlay_bounds = shadow_bounds; |
| 1451 | |
| 1452 // Constrain the underlay bounds to the client area in case shell surface | |
| 1453 // frame is enabled. | |
| 1454 if (frame_enabled_) { | |
| 1455 shadow_underlay_bounds.Intersect( | |
| 1456 widget_->non_client_view()->frame_view()->GetBoundsForClientView()); | |
| 1457 } | |
| 1458 | |
| 1459 shadow_underlay_->SetBounds(shadow_underlay_bounds); | |
| 1395 | 1460 |
| 1396 // TODO(oshima): Setting to the same value should be no-op. | 1461 // TODO(oshima): Setting to the same value should be no-op. |
| 1397 // crbug.com/642223. | 1462 // crbug.com/642223. |
| 1398 if (shadow_underlay_opacity != | 1463 if (shadow_underlay_opacity != |
| 1399 shadow_underlay_->layer()->GetTargetOpacity()) { | 1464 shadow_underlay_->layer()->GetTargetOpacity()) { |
| 1400 shadow_underlay_->layer()->SetOpacity(shadow_underlay_opacity); | 1465 shadow_underlay_->layer()->SetOpacity(shadow_underlay_opacity); |
| 1401 } | 1466 } |
| 1402 | 1467 |
| 1403 shadow_underlay_->Show(); | 1468 shadow_underlay_->Show(); |
| 1404 | 1469 |
| 1405 wm::Shadow* shadow = wm::ShadowController::GetShadowForWindow(window); | 1470 wm::Shadow* shadow = wm::ShadowController::GetShadowForWindow(window); |
| 1406 // Maximized/Fullscreen window does not create a shadow. | 1471 // Maximized/Fullscreen window does not create a shadow. |
| 1407 if (!shadow) | 1472 if (!shadow) |
| 1408 return; | 1473 return; |
| 1409 | 1474 |
| 1410 if (!shadow_overlay_) { | 1475 if (!shadow_overlay_) { |
| 1411 shadow_overlay_ = new aura::Window(nullptr); | 1476 shadow_overlay_ = new aura::Window(nullptr); |
| 1412 DCHECK(shadow_overlay_->owned_by_parent()); | 1477 DCHECK(shadow_overlay_->owned_by_parent()); |
| 1413 shadow_overlay_->set_ignore_events(true); | 1478 shadow_overlay_->set_ignore_events(true); |
| 1414 shadow_overlay_->Init(ui::LAYER_NOT_DRAWN); | 1479 shadow_overlay_->Init(ui::LAYER_NOT_DRAWN); |
| 1415 shadow_overlay_->layer()->Add(shadow->layer()); | 1480 shadow_overlay_->layer()->Add(shadow->layer()); |
| 1416 window->AddChild(shadow_overlay_); | 1481 window->AddChild(shadow_overlay_); |
| 1417 shadow_overlay_->Show(); | 1482 shadow_overlay_->Show(); |
| 1418 } | 1483 } |
| 1419 shadow_overlay_->SetBounds(shadow_bounds); | 1484 shadow_overlay_->SetBounds(shadow_bounds); |
| 1420 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size())); | 1485 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size())); |
| 1486 // Surfaces that can't be activated are usually menus and tooltips. Use a | |
| 1487 // small style shadow for them. | |
| 1488 if (!activatable_) | |
| 1489 shadow->SetStyle(wm::Shadow::STYLE_SMALL); | |
| 1421 } | 1490 } |
| 1422 } | 1491 } |
| 1423 | 1492 |
| 1424 } // namespace exo | 1493 } // namespace exo |
| OLD | NEW |