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 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1058 window_state->GetStateType()); | 1099 window_state->GetStateType()); |
1059 } | 1100 } |
1060 | 1101 |
1061 // Disable movement if initial bounds were specified. | 1102 // Disable movement if initial bounds were specified. |
1062 widget_->set_movement_disabled(!initial_bounds_.IsEmpty()); | 1103 widget_->set_movement_disabled(!initial_bounds_.IsEmpty()); |
1063 window_state->set_ignore_keyboard_bounds_change(!initial_bounds_.IsEmpty()); | 1104 window_state->set_ignore_keyboard_bounds_change(!initial_bounds_.IsEmpty()); |
1064 | 1105 |
1065 // AutoHide shelf in fullscreen state. | 1106 // AutoHide shelf in fullscreen state. |
1066 window_state->set_hide_shelf_when_fullscreen(false); | 1107 window_state->set_hide_shelf_when_fullscreen(false); |
1067 | 1108 |
1068 // Allow Ash to manage the position of a top-level shell surfaces if show | 1109 // Fade visibility animations for non-activatable windows. |
1069 // state is one that allows auto positioning and |initial_bounds_| has | 1110 if (!activatable_) { |
1070 // not been set. | 1111 wm::SetWindowVisibilityAnimationType( |
1071 window_state->set_window_position_managed( | 1112 window, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); |
1072 ash::wm::ToWindowShowState(ash::wm::WINDOW_STATE_TYPE_AUTO_POSITIONED) == | 1113 } |
1073 show_state && | |
1074 initial_bounds_.IsEmpty()); | |
1075 | 1114 |
1076 // Register close window accelerators. | 1115 // Register close window accelerators. |
1077 views::FocusManager* focus_manager = widget_->GetFocusManager(); | 1116 views::FocusManager* focus_manager = widget_->GetFocusManager(); |
1078 for (const auto& entry : kCloseWindowAccelerators) { | 1117 for (const auto& entry : kCloseWindowAccelerators) { |
1079 focus_manager->RegisterAccelerator( | 1118 focus_manager->RegisterAccelerator( |
1080 ui::Accelerator(entry.keycode, entry.modifiers), | 1119 ui::Accelerator(entry.keycode, entry.modifiers), |
1081 ui::AcceleratorManager::kNormalPriority, this); | 1120 ui::AcceleratorManager::kNormalPriority, this); |
1082 } | 1121 } |
1083 | 1122 |
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. | 1123 // Receive accessibility changes to update shadow underlay. |
1089 WMHelper::GetInstance()->AddAccessibilityObserver(this); | 1124 WMHelper::GetInstance()->AddAccessibilityObserver(this); |
1090 | 1125 |
1091 // Show widget next time Commit() is called. | 1126 // Show widget next time Commit() is called. |
1092 pending_show_widget_ = true; | 1127 pending_show_widget_ = true; |
1093 } | 1128 } |
1094 | 1129 |
1095 void ShellSurface::Configure() { | 1130 void ShellSurface::Configure() { |
1096 DCHECK(widget_); | 1131 DCHECK(widget_); |
1097 | 1132 |
1098 // Delay configure callback if |scoped_configure_| is set. | 1133 // Delay configure callback if |scoped_configure_| is set. |
1099 if (scoped_configure_) { | 1134 if (scoped_configure_) { |
1100 scoped_configure_->set_needs_configure(); | 1135 scoped_configure_->set_needs_configure(); |
1101 return; | 1136 return; |
1102 } | 1137 } |
1103 | 1138 |
1104 gfx::Vector2d origin_offset = pending_origin_config_offset_; | 1139 gfx::Vector2d origin_offset = pending_origin_config_offset_; |
1105 pending_origin_config_offset_ = gfx::Vector2d(); | 1140 pending_origin_config_offset_ = gfx::Vector2d(); |
1106 | 1141 |
| 1142 ash::wm::WindowState* window_state = |
| 1143 ash::wm::GetWindowState(widget_->GetNativeWindow()); |
| 1144 |
1107 // If surface is being resized, save the resize direction. | 1145 // If surface is being resized, save the resize direction. |
1108 int resize_component = | 1146 int resize_component = window_state->is_dragged() |
1109 resizer_ ? resizer_->details().window_component : HTCAPTION; | 1147 ? window_state->drag_details()->window_component |
| 1148 : HTCAPTION; |
1110 | 1149 |
1111 if (configure_callback_.is_null()) { | 1150 uint32_t serial = 0; |
| 1151 if (!configure_callback_.is_null()) { |
| 1152 const views::NonClientView* non_client_view = widget_->non_client_view(); |
| 1153 serial = configure_callback_.Run( |
| 1154 non_client_view->frame_view()->GetBoundsForClientView().size(), |
| 1155 ash::wm::GetWindowState(widget_->GetNativeWindow())->GetStateType(), |
| 1156 IsResizing(), widget_->IsActive()); |
| 1157 } |
| 1158 |
| 1159 if (!serial) { |
1112 pending_origin_offset_ += origin_offset; | 1160 pending_origin_offset_ += origin_offset; |
1113 pending_resize_component_ = resize_component; | 1161 pending_resize_component_ = resize_component; |
1114 return; | 1162 return; |
1115 } | 1163 } |
1116 | 1164 |
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 | 1165 // Apply origin offset and resize component at the first Commit() after this |
1123 // configure request has been acknowledged. | 1166 // configure request has been acknowledged. |
1124 pending_configs_.push_back({serial, origin_offset, resize_component}); | 1167 pending_configs_.push_back({serial, origin_offset, resize_component}); |
1125 LOG_IF(WARNING, pending_configs_.size() > 100) | 1168 LOG_IF(WARNING, pending_configs_.size() > 100) |
1126 << "Number of pending configure acks for shell surface has reached: " | 1169 << "Number of pending configure acks for shell surface has reached: " |
1127 << pending_configs_.size(); | 1170 << pending_configs_.size(); |
1128 } | 1171 } |
1129 | 1172 |
1130 void ShellSurface::AttemptToStartDrag(int component) { | 1173 void ShellSurface::AttemptToStartDrag(int component) { |
1131 DCHECK(widget_); | 1174 DCHECK(widget_); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1219 resizer_.reset(); | 1262 resizer_.reset(); |
1220 | 1263 |
1221 // Notify client that resizing state has changed. | 1264 // Notify client that resizing state has changed. |
1222 if (was_resizing) | 1265 if (was_resizing) |
1223 Configure(); | 1266 Configure(); |
1224 | 1267 |
1225 UpdateWidgetBounds(); | 1268 UpdateWidgetBounds(); |
1226 } | 1269 } |
1227 | 1270 |
1228 bool ShellSurface::IsResizing() const { | 1271 bool ShellSurface::IsResizing() const { |
1229 if (!resizer_) | 1272 ash::wm::WindowState* window_state = |
| 1273 ash::wm::GetWindowState(widget_->GetNativeWindow()); |
| 1274 if (!window_state->is_dragged()) |
1230 return false; | 1275 return false; |
1231 | 1276 |
1232 return resizer_->details().bounds_change & | 1277 return window_state->drag_details()->bounds_change & |
1233 ash::WindowResizer::kBoundsChange_Resizes; | 1278 ash::WindowResizer::kBoundsChange_Resizes; |
1234 } | 1279 } |
1235 | 1280 |
1236 gfx::Rect ShellSurface::GetVisibleBounds() const { | 1281 gfx::Rect ShellSurface::GetVisibleBounds() const { |
1237 // Use |geometry_| if set, otherwise use the visual bounds of the surface. | 1282 // Use |geometry_| if set, otherwise use the visual bounds of the surface. |
1238 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size()) | 1283 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size()) |
1239 : geometry_; | 1284 : geometry_; |
1240 } | 1285 } |
1241 | 1286 |
1242 gfx::Point ShellSurface::GetSurfaceOrigin() const { | 1287 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 | 1288 // If initial bounds were specified then surface origin is always relative |
1246 // to those bounds. | 1289 // to those bounds. |
1247 if (!initial_bounds_.IsEmpty()) { | 1290 if (!initial_bounds_.IsEmpty()) { |
1248 gfx::Point origin = window_bounds.origin(); | 1291 gfx::Point origin = widget_->GetNativeWindow()->bounds().origin(); |
1249 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &origin); | 1292 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &origin); |
1250 return initial_bounds_.origin() - origin.OffsetFromOrigin(); | 1293 return initial_bounds_.origin() - origin.OffsetFromOrigin(); |
1251 } | 1294 } |
1252 | 1295 |
1253 gfx::Rect visible_bounds = GetVisibleBounds(); | 1296 gfx::Rect visible_bounds = GetVisibleBounds(); |
| 1297 gfx::Rect client_bounds = |
| 1298 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); |
1254 switch (resize_component_) { | 1299 switch (resize_component_) { |
1255 case HTCAPTION: | 1300 case HTCAPTION: |
1256 return origin_ - visible_bounds.OffsetFromOrigin(); | 1301 return origin_ - visible_bounds.OffsetFromOrigin(); |
1257 case HTBOTTOM: | 1302 case HTBOTTOM: |
1258 case HTRIGHT: | 1303 case HTRIGHT: |
1259 case HTBOTTOMRIGHT: | 1304 case HTBOTTOMRIGHT: |
1260 return gfx::Point() - visible_bounds.OffsetFromOrigin(); | 1305 return gfx::Point() - visible_bounds.OffsetFromOrigin(); |
1261 case HTTOP: | 1306 case HTTOP: |
1262 case HTTOPRIGHT: | 1307 case HTTOPRIGHT: |
1263 return gfx::Point(0, window_bounds.height() - visible_bounds.height()) - | 1308 return gfx::Point(0, client_bounds.height() - visible_bounds.height()) - |
1264 visible_bounds.OffsetFromOrigin(); | 1309 visible_bounds.OffsetFromOrigin(); |
1265 break; | 1310 break; |
1266 case HTLEFT: | 1311 case HTLEFT: |
1267 case HTBOTTOMLEFT: | 1312 case HTBOTTOMLEFT: |
1268 return gfx::Point(window_bounds.width() - visible_bounds.width(), 0) - | 1313 return gfx::Point(client_bounds.width() - visible_bounds.width(), 0) - |
1269 visible_bounds.OffsetFromOrigin(); | 1314 visible_bounds.OffsetFromOrigin(); |
1270 case HTTOPLEFT: | 1315 case HTTOPLEFT: |
1271 return gfx::Point(window_bounds.width() - visible_bounds.width(), | 1316 return gfx::Point(client_bounds.width() - visible_bounds.width(), |
1272 window_bounds.height() - visible_bounds.height()) - | 1317 client_bounds.height() - visible_bounds.height()) - |
1273 visible_bounds.OffsetFromOrigin(); | 1318 visible_bounds.OffsetFromOrigin(); |
1274 default: | 1319 default: |
1275 NOTREACHED(); | 1320 NOTREACHED(); |
1276 return gfx::Point(); | 1321 return gfx::Point(); |
1277 } | 1322 } |
1278 } | 1323 } |
1279 | 1324 |
1280 void ShellSurface::UpdateWidgetBounds() { | 1325 void ShellSurface::UpdateWidgetBounds() { |
1281 DCHECK(widget_); | 1326 DCHECK(widget_); |
1282 | 1327 |
1283 // Return early if the shell is currently managing the bounds of the widget. | 1328 // 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 | 1329 // 1) When a window is either maximized/fullscreen/pinned, and the bounds |
1285 // isn't controlled by a client. | 1330 // isn't controlled by a client. |
1286 ash::wm::WindowState* window_state = | 1331 ash::wm::WindowState* window_state = |
1287 ash::wm::GetWindowState(widget_->GetNativeWindow()); | 1332 ash::wm::GetWindowState(widget_->GetNativeWindow()); |
1288 if (window_state->IsMaximizedOrFullscreenOrPinned() && | 1333 if (window_state->IsMaximizedOrFullscreenOrPinned() && |
1289 !window_state->allow_set_bounds_in_maximized()) { | 1334 !window_state->allow_set_bounds_in_maximized()) { |
1290 return; | 1335 return; |
1291 } | 1336 } |
1292 | 1337 |
1293 // 2) When a window is being dragged. | 1338 // 2) When a window is being dragged. |
1294 if (IsResizing()) | 1339 if (IsResizing()) |
1295 return; | 1340 return; |
1296 | 1341 |
1297 // Return early if there is pending configure requests. | 1342 // Return early if there is pending configure requests. |
1298 if (!pending_configs_.empty() || scoped_configure_) | 1343 if (!pending_configs_.empty() || scoped_configure_) |
1299 return; | 1344 return; |
1300 | 1345 |
1301 gfx::Rect visible_bounds = GetVisibleBounds(); | 1346 gfx::Rect visible_bounds = GetVisibleBounds(); |
1302 gfx::Rect new_widget_bounds = visible_bounds; | 1347 gfx::Rect new_widget_bounds = |
| 1348 widget_->non_client_view()->GetWindowBoundsForClientBounds( |
| 1349 visible_bounds); |
1303 | 1350 |
1304 // Avoid changing widget origin unless initial bounds were specified and | 1351 // Avoid changing widget origin unless initial bounds were specified and |
1305 // widget origin is always relative to it. | 1352 // widget origin is always relative to it. |
1306 if (initial_bounds_.IsEmpty()) { | 1353 if (initial_bounds_.IsEmpty()) { |
1307 new_widget_bounds.set_origin(widget_->GetWindowBoundsInScreen().origin()); | 1354 new_widget_bounds.set_origin(widget_->GetWindowBoundsInScreen().origin()); |
1308 } else { | 1355 } else { |
1309 new_widget_bounds.set_origin(initial_bounds_.origin() + | 1356 new_widget_bounds.set_origin(initial_bounds_.origin() + |
1310 visible_bounds.OffsetFromOrigin()); | 1357 visible_bounds.OffsetFromOrigin()); |
1311 } | 1358 } |
1312 | 1359 |
1313 // Update widget origin using the surface origin if the current location of | 1360 // 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 | 1361 // surface is being anchored to one side of the widget as a result of a |
1315 // resize operation. | 1362 // resize operation. |
1316 if (resize_component_ != HTCAPTION) { | 1363 if (resize_component_ != HTCAPTION) { |
1317 gfx::Point new_widget_origin = | 1364 gfx::Point new_widget_origin = |
1318 GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin(); | 1365 GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin(); |
1319 wm::ConvertPointToScreen(widget_->GetNativeWindow(), &new_widget_origin); | 1366 wm::ConvertPointToScreen(widget_->GetNativeWindow(), &new_widget_origin); |
1320 new_widget_bounds.set_origin(new_widget_origin); | 1367 new_widget_bounds.set_origin(new_widget_origin); |
1321 } | 1368 } |
1322 | 1369 |
1323 // Set |ignore_window_bounds_changes_| as this change to window bounds | 1370 // Set |ignore_window_bounds_changes_| as this change to window bounds |
1324 // should not result in a configure request. | 1371 // should not result in a configure request. |
1325 DCHECK(!ignore_window_bounds_changes_); | 1372 DCHECK(!ignore_window_bounds_changes_); |
1326 ignore_window_bounds_changes_ = true; | 1373 ignore_window_bounds_changes_ = true; |
1327 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) | 1374 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) |
1328 widget_->SetBounds(new_widget_bounds); | 1375 widget_->SetBounds(new_widget_bounds); |
1329 ignore_window_bounds_changes_ = false; | 1376 ignore_window_bounds_changes_ = false; |
1330 | 1377 |
| 1378 gfx::Rect client_view_bounds = |
| 1379 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); |
| 1380 |
1331 // A change to the widget size requires surface bounds to be re-adjusted. | 1381 // A change to the widget size requires surface bounds to be re-adjusted. |
1332 surface_->window()->SetBounds( | 1382 surface_->window()->SetBounds( |
1333 gfx::Rect(GetSurfaceOrigin(), surface_->window()->layer()->size())); | 1383 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), |
| 1384 surface_->window()->layer()->size())); |
1334 } | 1385 } |
1335 | 1386 |
1336 void ShellSurface::UpdateShadow() { | 1387 void ShellSurface::UpdateShadow() { |
1337 if (!widget_) | 1388 if (!widget_) |
1338 return; | 1389 return; |
1339 aura::Window* window = widget_->GetNativeWindow(); | 1390 aura::Window* window = widget_->GetNativeWindow(); |
1340 if (shadow_content_bounds_.IsEmpty()) { | 1391 if (!shadow_enabled_) { |
1341 wm::SetShadowType(window, wm::SHADOW_TYPE_NONE); | 1392 wm::SetShadowType(window, wm::SHADOW_TYPE_NONE); |
1342 if (shadow_underlay_) | 1393 if (shadow_underlay_) |
1343 shadow_underlay_->Hide(); | 1394 shadow_underlay_->Hide(); |
1344 } else { | 1395 } else { |
1345 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR); | 1396 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR); |
1346 | 1397 |
| 1398 gfx::Rect shadow_content_bounds = shadow_content_bounds_; |
| 1399 if (shadow_content_bounds.IsEmpty()) |
| 1400 shadow_content_bounds = window->bounds(); |
| 1401 |
1347 // TODO(oshima): Adjust the coordinates from client screen to | 1402 // TODO(oshima): Adjust the coordinates from client screen to |
1348 // chromeos screen when multi displays are supported. | 1403 // chromeos screen when multi displays are supported. |
1349 gfx::Point origin = window->bounds().origin(); | 1404 gfx::Point origin = window->bounds().origin(); |
1350 gfx::Point shadow_origin = shadow_content_bounds_.origin(); | 1405 gfx::Point shadow_origin = shadow_content_bounds.origin(); |
1351 shadow_origin -= origin.OffsetFromOrigin(); | 1406 shadow_origin -= origin.OffsetFromOrigin(); |
1352 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds_.size()); | 1407 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds.size()); |
1353 | 1408 |
1354 // Always create and show the underlay, even in maximized/fullscreen. | 1409 // Always create and show the underlay, even in maximized/fullscreen. |
1355 if (!shadow_underlay_) { | 1410 if (!shadow_underlay_) { |
1356 shadow_underlay_ = new aura::Window(nullptr); | 1411 shadow_underlay_ = new aura::Window(nullptr); |
1357 shadow_underlay_event_handler_ = | 1412 shadow_underlay_event_handler_ = |
1358 base::MakeUnique<ShadowUnderlayEventHandler>(); | 1413 base::MakeUnique<ShadowUnderlayEventHandler>(); |
1359 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get()); | 1414 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get()); |
1360 DCHECK(shadow_underlay_->owned_by_parent()); | 1415 DCHECK(shadow_underlay_->owned_by_parent()); |
1361 // Ensure the background area inside the shadow is solid black. | 1416 // Ensure the background area inside the shadow is solid black. |
1362 // Clients that provide translucent contents should not be using | 1417 // Clients that provide translucent contents should not be using |
1363 // rectangular shadows as this method requires opaque contents to | 1418 // rectangular shadows as this method requires opaque contents to |
1364 // cast a shadow that represent it correctly. | 1419 // cast a shadow that represent it correctly. |
1365 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR); | 1420 shadow_underlay_->Init(ui::LAYER_SOLID_COLOR); |
1366 shadow_underlay_->layer()->SetColor(SK_ColorBLACK); | 1421 shadow_underlay_->layer()->SetColor(SK_ColorBLACK); |
1367 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely()); | 1422 DCHECK(shadow_underlay_->layer()->fills_bounds_opaquely()); |
1368 window->AddChild(shadow_underlay_); | 1423 window->AddChild(shadow_underlay_); |
1369 window->StackChildAtBottom(shadow_underlay_); | 1424 window->StackChildAtBottom(shadow_underlay_); |
1370 } | 1425 } |
1371 | 1426 |
1372 bool underlay_capture_events = | 1427 bool underlay_capture_events = |
1373 WMHelper::GetInstance()->IsSpokenFeedbackEnabled() && | 1428 WMHelper::GetInstance()->IsSpokenFeedbackEnabled() && |
1374 widget_->IsActive(); | 1429 widget_->IsActive(); |
1375 | 1430 |
1376 float shadow_underlay_opacity = rectangular_shadow_background_opacity_; | 1431 float shadow_underlay_opacity = shadow_background_opacity_; |
1377 // Put the black background layer behind the window if | 1432 // Put the black background layer behind the window if |
1378 // 1) the window is in immersive fullscreen or is active with | 1433 // 1) the window is in immersive fullscreen or is active with |
1379 // spoken feedback enabled. | 1434 // spoken feedback enabled. |
1380 // 2) the window can control the bounds of the window in fullscreen ( | 1435 // 2) the window can control the bounds of the window in fullscreen ( |
1381 // thus the background can be visible). | 1436 // thus the background can be visible). |
1382 // 3) the window has no transform (the transformed background may | 1437 // 3) the window has no transform (the transformed background may |
1383 // not cover the entire background, e.g. overview mode). | 1438 // not cover the entire background, e.g. overview mode). |
1384 if ((widget_->IsFullscreen() || underlay_capture_events) && | 1439 if ((widget_->IsFullscreen() || underlay_capture_events) && |
1385 ash::wm::GetWindowState(window)->allow_set_bounds_in_maximized() && | 1440 ash::wm::GetWindowState(window)->allow_set_bounds_in_maximized() && |
1386 window->layer()->GetTargetTransform().IsIdentity()) { | 1441 window->layer()->GetTargetTransform().IsIdentity()) { |
1387 gfx::Point origin; | 1442 gfx::Point origin; |
1388 origin -= window->bounds().origin().OffsetFromOrigin(); | 1443 origin -= window->bounds().origin().OffsetFromOrigin(); |
1389 shadow_bounds.set_origin(origin); | 1444 shadow_bounds.set_origin(origin); |
1390 shadow_bounds.set_size(window->parent()->bounds().size()); | 1445 shadow_bounds.set_size(window->parent()->bounds().size()); |
1391 shadow_underlay_opacity = 1.0f; | 1446 shadow_underlay_opacity = 1.0f; |
1392 } | 1447 } |
1393 | 1448 |
1394 shadow_underlay_->SetBounds(shadow_bounds); | 1449 gfx::Rect shadow_underlay_bounds = shadow_bounds; |
| 1450 |
| 1451 // Constrain the underlay bounds to the client area in case shell surface |
| 1452 // frame is enabled. |
| 1453 if (frame_enabled_) { |
| 1454 shadow_underlay_bounds.Intersect( |
| 1455 widget_->non_client_view()->frame_view()->GetBoundsForClientView()); |
| 1456 } |
| 1457 |
| 1458 shadow_underlay_->SetBounds(shadow_underlay_bounds); |
1395 | 1459 |
1396 // TODO(oshima): Setting to the same value should be no-op. | 1460 // TODO(oshima): Setting to the same value should be no-op. |
1397 // crbug.com/642223. | 1461 // crbug.com/642223. |
1398 if (shadow_underlay_opacity != | 1462 if (shadow_underlay_opacity != |
1399 shadow_underlay_->layer()->GetTargetOpacity()) { | 1463 shadow_underlay_->layer()->GetTargetOpacity()) { |
1400 shadow_underlay_->layer()->SetOpacity(shadow_underlay_opacity); | 1464 shadow_underlay_->layer()->SetOpacity(shadow_underlay_opacity); |
1401 } | 1465 } |
1402 | 1466 |
1403 shadow_underlay_->Show(); | 1467 shadow_underlay_->Show(); |
1404 | 1468 |
1405 wm::Shadow* shadow = wm::ShadowController::GetShadowForWindow(window); | 1469 wm::Shadow* shadow = wm::ShadowController::GetShadowForWindow(window); |
1406 // Maximized/Fullscreen window does not create a shadow. | 1470 // Maximized/Fullscreen window does not create a shadow. |
1407 if (!shadow) | 1471 if (!shadow) |
1408 return; | 1472 return; |
1409 | 1473 |
1410 if (!shadow_overlay_) { | 1474 if (!shadow_overlay_) { |
1411 shadow_overlay_ = new aura::Window(nullptr); | 1475 shadow_overlay_ = new aura::Window(nullptr); |
1412 DCHECK(shadow_overlay_->owned_by_parent()); | 1476 DCHECK(shadow_overlay_->owned_by_parent()); |
1413 shadow_overlay_->set_ignore_events(true); | 1477 shadow_overlay_->set_ignore_events(true); |
1414 shadow_overlay_->Init(ui::LAYER_NOT_DRAWN); | 1478 shadow_overlay_->Init(ui::LAYER_NOT_DRAWN); |
1415 shadow_overlay_->layer()->Add(shadow->layer()); | 1479 shadow_overlay_->layer()->Add(shadow->layer()); |
1416 window->AddChild(shadow_overlay_); | 1480 window->AddChild(shadow_overlay_); |
1417 shadow_overlay_->Show(); | 1481 shadow_overlay_->Show(); |
1418 } | 1482 } |
1419 shadow_overlay_->SetBounds(shadow_bounds); | 1483 shadow_overlay_->SetBounds(shadow_bounds); |
1420 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size())); | 1484 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size())); |
| 1485 // Surfaces that can't be activated are usually menus and tooltips. Use a |
| 1486 // small style shadow for them. |
| 1487 if (!activatable_) |
| 1488 shadow->SetStyle(wm::Shadow::STYLE_SMALL); |
1421 } | 1489 } |
1422 } | 1490 } |
1423 | 1491 |
1424 } // namespace exo | 1492 } // namespace exo |
OLD | NEW |