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/common/frame/custom_frame_view_ash.h" | 9 #include "ash/common/frame/custom_frame_view_ash.h" |
| 10 #include "ash/common/shelf/wm_shelf.h" | 10 #include "ash/common/shelf/wm_shelf.h" |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 328 } | 328 } |
| 329 } | 329 } |
| 330 | 330 |
| 331 //////////////////////////////////////////////////////////////////////////////// | 331 //////////////////////////////////////////////////////////////////////////////// |
| 332 // ShellSurface, public: | 332 // ShellSurface, public: |
| 333 | 333 |
| 334 DEFINE_LOCAL_UI_CLASS_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr) | 334 DEFINE_LOCAL_UI_CLASS_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr) |
| 335 | 335 |
| 336 ShellSurface::ShellSurface(Surface* surface, | 336 ShellSurface::ShellSurface(Surface* surface, |
| 337 ShellSurface* parent, | 337 ShellSurface* parent, |
| 338 const gfx::Rect& initial_bounds, | 338 BoundsMode bounds_mode, |
| 339 const gfx::Point& origin, | |
| 339 bool activatable, | 340 bool activatable, |
| 340 bool can_minimize, | 341 bool can_minimize, |
| 341 int container) | 342 int container) |
| 342 : widget_(nullptr), | 343 : widget_(nullptr), |
| 343 surface_(surface), | 344 surface_(surface), |
| 344 parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr), | 345 parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr), |
| 345 initial_bounds_(initial_bounds), | 346 bounds_mode_(bounds_mode), |
| 347 origin_(origin), | |
| 346 activatable_(activatable), | 348 activatable_(activatable), |
| 347 can_minimize_(can_minimize), | 349 can_minimize_(can_minimize), |
| 348 container_(container) { | 350 container_(container) { |
| 349 WMHelper::GetInstance()->AddActivationObserver(this); | 351 WMHelper::GetInstance()->AddActivationObserver(this); |
| 350 surface_->SetSurfaceDelegate(this); | 352 surface_->SetSurfaceDelegate(this); |
| 351 surface_->AddSurfaceObserver(this); | 353 surface_->AddSurfaceObserver(this); |
| 352 surface_->window()->Show(); | 354 surface_->window()->Show(); |
| 353 set_owned_by_client(); | 355 set_owned_by_client(); |
| 354 if (parent_) | 356 if (parent_) |
| 355 parent_->AddObserver(this); | 357 parent_->AddObserver(this); |
| 356 } | 358 } |
| 357 | 359 |
| 358 ShellSurface::ShellSurface(Surface* surface) | 360 ShellSurface::ShellSurface(Surface* surface) |
| 359 : ShellSurface(surface, | 361 : ShellSurface(surface, |
| 360 nullptr, | 362 nullptr, |
| 361 gfx::Rect(), | 363 BoundsMode::SHELL, |
| 364 gfx::Point(), | |
| 362 true, | 365 true, |
| 363 true, | 366 true, |
| 364 ash::kShellWindowId_DefaultContainer) {} | 367 ash::kShellWindowId_DefaultContainer) {} |
| 365 | 368 |
| 366 ShellSurface::~ShellSurface() { | 369 ShellSurface::~ShellSurface() { |
| 367 DCHECK(!scoped_configure_); | 370 DCHECK(!scoped_configure_); |
| 368 if (resizer_) | 371 if (resizer_) |
| 369 EndDrag(false /* revert */); | 372 EndDrag(false /* revert */); |
| 370 if (widget_) { | 373 if (widget_) { |
| 371 ash::wm::GetWindowState(widget_->GetNativeWindow())->RemoveObserver(this); | 374 ash::wm::GetWindowState(widget_->GetNativeWindow())->RemoveObserver(this); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 557 void ShellSurface::SetApplicationId(const std::string& application_id) { | 560 void ShellSurface::SetApplicationId(const std::string& application_id) { |
| 558 // Store the value in |application_id_| in case the window does not exist yet. | 561 // Store the value in |application_id_| in case the window does not exist yet. |
| 559 application_id_ = application_id; | 562 application_id_ = application_id; |
| 560 if (widget_ && widget_->GetNativeWindow()) | 563 if (widget_ && widget_->GetNativeWindow()) |
| 561 SetApplicationId(widget_->GetNativeWindow(), application_id); | 564 SetApplicationId(widget_->GetNativeWindow(), application_id); |
| 562 } | 565 } |
| 563 | 566 |
| 564 void ShellSurface::Move() { | 567 void ShellSurface::Move() { |
| 565 TRACE_EVENT0("exo", "ShellSurface::Move"); | 568 TRACE_EVENT0("exo", "ShellSurface::Move"); |
| 566 | 569 |
| 567 if (widget_ && !widget_->movement_disabled()) | 570 if (!widget_) |
| 568 AttemptToStartDrag(HTCAPTION); | 571 return; |
| 572 | |
| 573 switch (bounds_mode_) { | |
| 574 case BoundsMode::SHELL: | |
| 575 AttemptToStartDrag(HTCAPTION); | |
| 576 break; | |
| 577 case BoundsMode::CLIENT: | |
| 578 case BoundsMode::FIXED: | |
| 579 NOTREACHED(); | |
|
reveman
2017/02/09 04:50:15
How are we protected from a malicious client causi
Dominik Laskowski
2017/02/09 23:35:28
NOTREACHED only logs an error in release builds.
reveman
2017/02/10 02:10:53
A malicious client being able to crash a debug bui
| |
| 580 break; | |
| 581 } | |
|
reveman
2017/02/09 04:50:16
nit: please add return statements in the switch ca
Dominik Laskowski
2017/02/09 23:35:28
Done.
| |
| 569 } | 582 } |
| 570 | 583 |
| 571 void ShellSurface::Resize(int component) { | 584 void ShellSurface::Resize(int component) { |
| 572 TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component); | 585 TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component); |
| 573 | 586 |
| 574 if (widget_ && !widget_->movement_disabled()) | 587 if (!widget_) |
| 575 AttemptToStartDrag(component); | 588 return; |
| 589 | |
| 590 switch (bounds_mode_) { | |
|
reveman
2017/02/09 04:50:15
same comments here
Dominik Laskowski
2017/02/09 23:35:28
Done.
| |
| 591 case BoundsMode::SHELL: | |
| 592 AttemptToStartDrag(component); | |
| 593 break; | |
| 594 case BoundsMode::CLIENT: | |
| 595 case BoundsMode::FIXED: | |
| 596 NOTREACHED(); | |
| 597 break; | |
| 598 } | |
| 576 } | 599 } |
| 577 | 600 |
| 578 void ShellSurface::Close() { | 601 void ShellSurface::Close() { |
| 579 if (!close_callback_.is_null()) | 602 if (!close_callback_.is_null()) |
| 580 close_callback_.Run(); | 603 close_callback_.Run(); |
| 581 } | 604 } |
| 582 | 605 |
| 583 void ShellSurface::SetGeometry(const gfx::Rect& geometry) { | 606 void ShellSurface::SetGeometry(const gfx::Rect& geometry) { |
| 584 TRACE_EVENT1("exo", "ShellSurface::SetGeometry", "geometry", | 607 TRACE_EVENT1("exo", "ShellSurface::SetGeometry", "geometry", |
| 585 geometry.ToString()); | 608 geometry.ToString()); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 642 | 665 |
| 643 void ShellSurface::SetTopInset(int height) { | 666 void ShellSurface::SetTopInset(int height) { |
| 644 TRACE_EVENT1("exo", "ShellSurface::SetTopInset", "height", height); | 667 TRACE_EVENT1("exo", "ShellSurface::SetTopInset", "height", height); |
| 645 | 668 |
| 646 pending_top_inset_height_ = height; | 669 pending_top_inset_height_ = height; |
| 647 } | 670 } |
| 648 | 671 |
| 649 void ShellSurface::SetOrigin(const gfx::Point& origin) { | 672 void ShellSurface::SetOrigin(const gfx::Point& origin) { |
| 650 TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString()); | 673 TRACE_EVENT1("exo", "ShellSurface::SetOrigin", "origin", origin.ToString()); |
| 651 | 674 |
| 652 initial_bounds_ = gfx::Rect(origin, gfx::Size(1, 1)); | 675 origin_ = origin; |
| 653 } | 676 } |
| 654 | 677 |
| 655 void ShellSurface::SetActivatable(bool activatable) { | 678 void ShellSurface::SetActivatable(bool activatable) { |
| 656 TRACE_EVENT1("exo", "ShellSurface::SetActivatable", "activatable", | 679 TRACE_EVENT1("exo", "ShellSurface::SetActivatable", "activatable", |
| 657 activatable); | 680 activatable); |
| 658 | 681 |
| 659 activatable_ = activatable; | 682 activatable_ = activatable; |
| 660 } | 683 } |
| 661 | 684 |
| 662 void ShellSurface::SetContainer(int container) { | 685 void ShellSurface::SetContainer(int container) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 697 if (enabled() && !widget_) { | 720 if (enabled() && !widget_) { |
| 698 // Defer widget creation until surface contains some contents. | 721 // Defer widget creation until surface contains some contents. |
| 699 if (surface_->content_size().IsEmpty()) | 722 if (surface_->content_size().IsEmpty()) |
| 700 Configure(); | 723 Configure(); |
| 701 else | 724 else |
| 702 CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL); | 725 CreateShellSurfaceWidget(ui::SHOW_STATE_NORMAL); |
| 703 } | 726 } |
| 704 | 727 |
| 705 // Apply the accumulated pending origin offset to reflect acknowledged | 728 // Apply the accumulated pending origin offset to reflect acknowledged |
| 706 // configure requests. | 729 // configure requests. |
| 707 origin_ += pending_origin_offset_; | 730 origin_offset_ += pending_origin_offset_; |
| 708 pending_origin_offset_ = gfx::Vector2d(); | 731 pending_origin_offset_ = gfx::Vector2d(); |
| 709 | 732 |
| 710 // Update resize direction to reflect acknowledged configure requests. | 733 // Update resize direction to reflect acknowledged configure requests. |
| 711 resize_component_ = pending_resize_component_; | 734 resize_component_ = pending_resize_component_; |
| 712 | 735 |
| 713 if (widget_) { | 736 if (widget_) { |
| 714 // Apply new window geometry. | 737 // Apply new window geometry. |
| 715 geometry_ = pending_geometry_; | 738 geometry_ = pending_geometry_; |
| 716 | 739 |
| 717 UpdateWidgetBounds(); | 740 UpdateWidgetBounds(); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 736 if (activatable != CanActivate()) { | 759 if (activatable != CanActivate()) { |
| 737 set_can_activate(activatable); | 760 set_can_activate(activatable); |
| 738 // Activate or deactivate window if activation state changed. | 761 // Activate or deactivate window if activation state changed. |
| 739 if (activatable) | 762 if (activatable) |
| 740 wm::ActivateWindow(widget_->GetNativeWindow()); | 763 wm::ActivateWindow(widget_->GetNativeWindow()); |
| 741 else if (widget_->IsActive()) | 764 else if (widget_->IsActive()) |
| 742 wm::DeactivateWindow(widget_->GetNativeWindow()); | 765 wm::DeactivateWindow(widget_->GetNativeWindow()); |
| 743 } | 766 } |
| 744 } | 767 } |
| 745 | 768 |
| 746 gfx::Rect client_view_bounds = | 769 UpdateSurfaceBounds(); |
| 747 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); | |
| 748 | |
| 749 // Update surface bounds. | |
| 750 surface_->window()->SetBounds( | |
| 751 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), | |
| 752 surface_->window()->layer()->size())); | |
| 753 | 770 |
| 754 // Update surface scale. | 771 // Update surface scale. |
| 755 if (pending_scale_ != scale_) { | 772 if (pending_scale_ != scale_) { |
| 756 gfx::Transform transform; | 773 gfx::Transform transform; |
| 757 DCHECK_NE(pending_scale_, 0.0); | 774 DCHECK_NE(pending_scale_, 0.0); |
| 758 transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_); | 775 transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_); |
| 759 surface_->window()->SetTransform(transform); | 776 surface_->window()->SetTransform(transform); |
| 760 scale_ = pending_scale_; | 777 scale_ = pending_scale_; |
| 761 } | 778 } |
| 762 | 779 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 799 // destroyed callback may destroy the ShellSurface instance. This call needs | 816 // destroyed callback may destroy the ShellSurface instance. This call needs |
| 800 // to be last so that the instance can be destroyed. | 817 // to be last so that the instance can be destroyed. |
| 801 if (!surface_destroyed_callback_.is_null()) | 818 if (!surface_destroyed_callback_.is_null()) |
| 802 surface_destroyed_callback_.Run(); | 819 surface_destroyed_callback_.Run(); |
| 803 } | 820 } |
| 804 | 821 |
| 805 //////////////////////////////////////////////////////////////////////////////// | 822 //////////////////////////////////////////////////////////////////////////////// |
| 806 // views::WidgetDelegate overrides: | 823 // views::WidgetDelegate overrides: |
| 807 | 824 |
| 808 bool ShellSurface::CanResize() const { | 825 bool ShellSurface::CanResize() const { |
| 809 return initial_bounds_.IsEmpty(); | 826 return bounds_mode_ == BoundsMode::SHELL; |
| 810 } | 827 } |
| 811 | 828 |
| 812 bool ShellSurface::CanMaximize() const { | 829 bool ShellSurface::CanMaximize() const { |
| 813 // Shell surfaces in system modal container cannot be maximized. | 830 // Shell surfaces in system modal container cannot be maximized. |
| 814 if (container_ == ash::kShellWindowId_SystemModalContainer) | 831 if (container_ == ash::kShellWindowId_SystemModalContainer) |
| 815 return false; | 832 return false; |
| 816 | 833 |
| 817 // Non-transient shell surfaces can be maximized. | 834 // Non-transient shell surfaces can be maximized. |
| 818 return !parent_; | 835 return !parent_; |
| 819 } | 836 } |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 933 const gfx::Rect& old_bounds, | 950 const gfx::Rect& old_bounds, |
| 934 const gfx::Rect& new_bounds) { | 951 const gfx::Rect& new_bounds) { |
| 935 if (!widget_ || !surface_ || ignore_window_bounds_changes_) | 952 if (!widget_ || !surface_ || ignore_window_bounds_changes_) |
| 936 return; | 953 return; |
| 937 | 954 |
| 938 if (window == widget_->GetNativeWindow()) { | 955 if (window == widget_->GetNativeWindow()) { |
| 939 if (new_bounds.size() == old_bounds.size()) | 956 if (new_bounds.size() == old_bounds.size()) |
| 940 return; | 957 return; |
| 941 | 958 |
| 942 // If size changed then give the client a chance to produce new contents | 959 // If size changed then give the client a chance to produce new contents |
| 943 // before origin on screen is changed by adding offset to the next configure | 960 // before origin on screen is changed. Retain the old origin by reverting |
| 944 // request and offset |origin_| by the same distance. | 961 // the origin delta until the next configure is acknowledged. |
| 945 gfx::Vector2d origin_offset = new_bounds.origin() - old_bounds.origin(); | 962 const gfx::Vector2d delta = new_bounds.origin() - old_bounds.origin(); |
| 946 pending_origin_config_offset_ += origin_offset; | 963 origin_offset_ -= delta; |
| 947 origin_ -= origin_offset; | 964 pending_origin_offset_accumulator_ += delta; |
| 948 | 965 |
| 949 gfx::Rect client_view_bounds = | 966 UpdateSurfaceBounds(); |
| 950 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); | |
| 951 | |
| 952 // Update surface bounds. | |
| 953 surface_->window()->SetBounds( | |
| 954 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), | |
| 955 surface_->window()->layer()->size())); | |
| 956 | 967 |
| 957 // The shadow size may be updated to match the widget. Change it back | 968 // The shadow size may be updated to match the widget. Change it back |
| 958 // to the shadow content size. | 969 // to the shadow content size. |
| 959 // TODO(oshima): When the arc window reiszing is enabled, we may want to | 970 // TODO(oshima): When the arc window reiszing is enabled, we may want to |
| 960 // implement shadow management here instead of using shadow controller. | 971 // implement shadow management here instead of using shadow controller. |
| 961 UpdateShadow(); | 972 UpdateShadow(); |
| 962 | 973 |
| 963 Configure(); | 974 Configure(); |
| 964 } | 975 } |
| 965 } | 976 } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1087 views::Widget::InitParams params; | 1098 views::Widget::InitParams params; |
| 1088 params.type = views::Widget::InitParams::TYPE_WINDOW; | 1099 params.type = views::Widget::InitParams::TYPE_WINDOW; |
| 1089 params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET; | 1100 params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET; |
| 1090 params.delegate = this; | 1101 params.delegate = this; |
| 1091 params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; | 1102 params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; |
| 1092 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 1103 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
| 1093 params.show_state = show_state; | 1104 params.show_state = show_state; |
| 1094 // Make shell surface a transient child if |parent_| has been set. | 1105 // Make shell surface a transient child if |parent_| has been set. |
| 1095 params.parent = | 1106 params.parent = |
| 1096 parent_ ? parent_ : WMHelper::GetInstance()->GetContainer(container_); | 1107 parent_ ? parent_ : WMHelper::GetInstance()->GetContainer(container_); |
| 1097 params.bounds = initial_bounds_; | 1108 params.bounds = gfx::Rect(origin_, gfx::Size()); |
| 1098 bool activatable = activatable_; | 1109 bool activatable = activatable_; |
| 1099 // ShellSurfaces in system modal container are only activatable if input | 1110 // ShellSurfaces in system modal container are only activatable if input |
| 1100 // region is non-empty. See OnCommitSurface() for more details. | 1111 // region is non-empty. See OnCommitSurface() for more details. |
| 1101 if (container_ == ash::kShellWindowId_SystemModalContainer) | 1112 if (container_ == ash::kShellWindowId_SystemModalContainer) |
| 1102 activatable &= !surface_->GetHitTestBounds().IsEmpty(); | 1113 activatable &= !surface_->GetHitTestBounds().IsEmpty(); |
| 1103 params.activatable = activatable ? views::Widget::InitParams::ACTIVATABLE_YES | 1114 params.activatable = activatable ? views::Widget::InitParams::ACTIVATABLE_YES |
| 1104 : views::Widget::InitParams::ACTIVATABLE_NO; | 1115 : views::Widget::InitParams::ACTIVATABLE_NO; |
| 1105 | 1116 |
| 1106 // Note: NativeWidget owns this widget. | 1117 // Note: NativeWidget owns this widget. |
| 1107 widget_ = new ShellSurfaceWidget(this); | 1118 widget_ = new ShellSurfaceWidget(this); |
| 1108 widget_->Init(params); | 1119 widget_->Init(params); |
| 1109 | 1120 |
| 1110 aura::Window* window = widget_->GetNativeWindow(); | 1121 aura::Window* window = widget_->GetNativeWindow(); |
| 1111 window->SetName("ExoShellSurface"); | 1122 window->SetName("ExoShellSurface"); |
| 1112 window->SetProperty(aura::client::kAccessibilityFocusFallsbackToWidgetKey, | 1123 window->SetProperty(aura::client::kAccessibilityFocusFallsbackToWidgetKey, |
| 1113 false); | 1124 false); |
| 1114 window->AddChild(surface_->window()); | 1125 window->AddChild(surface_->window()); |
| 1115 window->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter(widget_))); | 1126 window->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter(widget_))); |
| 1116 SetApplicationId(window, application_id_); | 1127 SetApplicationId(window, application_id_); |
| 1117 SetMainSurface(window, surface_); | 1128 SetMainSurface(window, surface_); |
| 1118 | 1129 |
| 1130 const bool client_controls_bounds = bounds_mode_ == BoundsMode::CLIENT; | |
|
reveman
2017/02/09 04:50:15
nit: remove 'const'. doesn't hurt but typically no
Dominik Laskowski
2017/02/09 23:35:28
Removed variable along with check below.
| |
| 1131 | |
| 1119 // Start tracking changes to window bounds and window state. | 1132 // Start tracking changes to window bounds and window state. |
| 1120 window->AddObserver(this); | 1133 if (!client_controls_bounds) |
|
reveman
2017/02/09 04:50:15
can we add the observer unconditionally and instea
Dominik Laskowski
2017/02/09 23:35:28
Done.
| |
| 1134 window->AddObserver(this); | |
| 1121 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); | 1135 ash::wm::WindowState* window_state = ash::wm::GetWindowState(window); |
| 1122 window_state->AddObserver(this); | 1136 window_state->AddObserver(this); |
| 1123 | 1137 |
| 1124 // Absolete positioned shell surfaces may request the bounds that does not | 1138 // Allow the client to request bounds that do not fill the entire work area |
| 1125 // fill the entire work area / display in maximized / fullscreen state. | 1139 // when maximized, or the entire display when fullscreen. |
| 1126 // Allow such clients to update the bounds in these states. | 1140 window_state->set_allow_set_bounds_in_maximized(client_controls_bounds); |
| 1127 if (!initial_bounds_.IsEmpty()) | |
| 1128 window_state->set_allow_set_bounds_in_maximized(true); | |
| 1129 | 1141 |
| 1130 // Notify client of initial state if different than normal. | 1142 // Notify client of initial state if different than normal. |
| 1131 if (window_state->GetStateType() != ash::wm::WINDOW_STATE_TYPE_NORMAL && | 1143 if (window_state->GetStateType() != ash::wm::WINDOW_STATE_TYPE_NORMAL && |
| 1132 !state_changed_callback_.is_null()) { | 1144 !state_changed_callback_.is_null()) { |
| 1133 state_changed_callback_.Run(ash::wm::WINDOW_STATE_TYPE_NORMAL, | 1145 state_changed_callback_.Run(ash::wm::WINDOW_STATE_TYPE_NORMAL, |
| 1134 window_state->GetStateType()); | 1146 window_state->GetStateType()); |
| 1135 } | 1147 } |
| 1136 | 1148 |
| 1137 // Disable movement if initial bounds were specified. | 1149 // Disable movement if bounds are controlled by the client or fixed. |
| 1138 widget_->set_movement_disabled(!initial_bounds_.IsEmpty()); | 1150 const bool movement_disabled = bounds_mode_ != BoundsMode::SHELL; |
|
reveman
2017/02/09 04:50:15
nit: remove 'const'
Dominik Laskowski
2017/02/09 23:35:28
Done.
| |
| 1139 window_state->set_ignore_keyboard_bounds_change(!initial_bounds_.IsEmpty()); | 1151 widget_->set_movement_disabled(movement_disabled); |
| 1152 window_state->set_ignore_keyboard_bounds_change(movement_disabled); | |
| 1140 | 1153 |
| 1141 // AutoHide shelf in fullscreen state. | 1154 // AutoHide shelf in fullscreen state. |
| 1142 window_state->set_hide_shelf_when_fullscreen(false); | 1155 window_state->set_hide_shelf_when_fullscreen(false); |
| 1143 | 1156 |
| 1144 // Fade visibility animations for non-activatable windows. | 1157 // Fade visibility animations for non-activatable windows. |
| 1145 if (!activatable_) { | 1158 if (!activatable_) { |
| 1146 wm::SetWindowVisibilityAnimationType( | 1159 wm::SetWindowVisibilityAnimationType( |
| 1147 window, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); | 1160 window, wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); |
| 1148 } | 1161 } |
| 1149 | 1162 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1162 pending_show_widget_ = true; | 1175 pending_show_widget_ = true; |
| 1163 } | 1176 } |
| 1164 | 1177 |
| 1165 void ShellSurface::Configure() { | 1178 void ShellSurface::Configure() { |
| 1166 // Delay configure callback if |scoped_configure_| is set. | 1179 // Delay configure callback if |scoped_configure_| is set. |
| 1167 if (scoped_configure_) { | 1180 if (scoped_configure_) { |
| 1168 scoped_configure_->set_needs_configure(); | 1181 scoped_configure_->set_needs_configure(); |
| 1169 return; | 1182 return; |
| 1170 } | 1183 } |
| 1171 | 1184 |
| 1172 gfx::Vector2d origin_offset = pending_origin_config_offset_; | 1185 const gfx::Vector2d origin_offset = pending_origin_offset_accumulator_; |
|
reveman
2017/02/09 04:50:15
nit: remove 'const'
Dominik Laskowski
2017/02/09 23:35:28
Done.
| |
| 1173 pending_origin_config_offset_ = gfx::Vector2d(); | 1186 pending_origin_offset_accumulator_ = gfx::Vector2d(); |
| 1174 | 1187 |
| 1175 int resize_component = HTCAPTION; | 1188 int resize_component = HTCAPTION; |
| 1176 if (widget_) { | 1189 if (widget_) { |
| 1177 ash::wm::WindowState* window_state = | 1190 ash::wm::WindowState* window_state = |
| 1178 ash::wm::GetWindowState(widget_->GetNativeWindow()); | 1191 ash::wm::GetWindowState(widget_->GetNativeWindow()); |
| 1179 | 1192 |
| 1180 // If surface is being resized, save the resize direction. | 1193 // If surface is being resized, save the resize direction. |
| 1181 if (window_state->is_dragged()) | 1194 if (window_state->is_dragged()) |
| 1182 resize_component = window_state->drag_details()->window_component; | 1195 resize_component = window_state->drag_details()->window_component; |
| 1183 } | 1196 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1267 | 1280 |
| 1268 resizer_ = ash::CreateWindowResizer( | 1281 resizer_ = ash::CreateWindowResizer( |
| 1269 ash::WmWindow::Get(widget_->GetNativeWindow()), drag_location, component, | 1282 ash::WmWindow::Get(widget_->GetNativeWindow()), drag_location, component, |
| 1270 aura::client::WINDOW_MOVE_SOURCE_MOUSE); | 1283 aura::client::WINDOW_MOVE_SOURCE_MOUSE); |
| 1271 if (!resizer_) | 1284 if (!resizer_) |
| 1272 return; | 1285 return; |
| 1273 | 1286 |
| 1274 // Apply pending origin offsets and resize direction before starting a new | 1287 // Apply pending origin offsets and resize direction before starting a new |
| 1275 // resize operation. These can still be pending if the client has acknowledged | 1288 // resize operation. These can still be pending if the client has acknowledged |
| 1276 // the configure request but not yet called Commit(). | 1289 // the configure request but not yet called Commit(). |
| 1277 origin_ += pending_origin_offset_; | 1290 origin_offset_ += pending_origin_offset_; |
| 1278 pending_origin_offset_ = gfx::Vector2d(); | 1291 pending_origin_offset_ = gfx::Vector2d(); |
| 1279 resize_component_ = pending_resize_component_; | 1292 resize_component_ = pending_resize_component_; |
| 1280 | 1293 |
| 1281 WMHelper::GetInstance()->AddPreTargetHandler(this); | 1294 WMHelper::GetInstance()->AddPreTargetHandler(this); |
| 1282 widget_->GetNativeWindow()->SetCapture(); | 1295 widget_->GetNativeWindow()->SetCapture(); |
| 1283 | 1296 |
| 1284 // Notify client that resizing state has changed. | 1297 // Notify client that resizing state has changed. |
| 1285 if (IsResizing()) | 1298 if (IsResizing()) |
| 1286 Configure(); | 1299 Configure(); |
| 1287 } | 1300 } |
| 1288 | 1301 |
| 1289 void ShellSurface::EndDrag(bool revert) { | 1302 void ShellSurface::EndDrag(bool revert) { |
| 1290 DCHECK(widget_); | 1303 DCHECK(widget_); |
| 1291 DCHECK(resizer_); | 1304 DCHECK(resizer_); |
| 1292 | 1305 |
| 1293 bool was_resizing = IsResizing(); | 1306 switch (bounds_mode_) { |
| 1307 case BoundsMode::SHELL: { | |
| 1308 bool was_resizing = IsResizing(); | |
| 1294 | 1309 |
| 1295 if (revert) | 1310 if (revert) |
| 1296 resizer_->RevertDrag(); | 1311 resizer_->RevertDrag(); |
| 1297 else | 1312 else |
| 1298 resizer_->CompleteDrag(); | 1313 resizer_->CompleteDrag(); |
| 1299 | 1314 |
| 1300 WMHelper::GetInstance()->RemovePreTargetHandler(this); | 1315 WMHelper::GetInstance()->RemovePreTargetHandler(this); |
| 1301 widget_->GetNativeWindow()->ReleaseCapture(); | 1316 widget_->GetNativeWindow()->ReleaseCapture(); |
| 1302 resizer_.reset(); | 1317 resizer_.reset(); |
| 1303 | 1318 |
| 1304 // Notify client that resizing state has changed. | 1319 // Notify client that resizing state has changed. |
| 1305 if (was_resizing) | 1320 if (was_resizing) |
| 1306 Configure(); | 1321 Configure(); |
| 1307 | 1322 |
| 1308 UpdateWidgetBounds(); | 1323 UpdateWidgetBounds(); |
| 1324 break; | |
| 1325 } | |
| 1326 case BoundsMode::CLIENT: | |
| 1327 case BoundsMode::FIXED: | |
| 1328 NOTREACHED(); | |
|
reveman
2017/02/09 04:50:15
Can a malicious client cause this?
Dominik Laskowski
2017/02/09 23:35:28
Only debug builds would crash.
reveman
2017/02/10 02:10:53
Debug builds crashing is not ok.
| |
| 1329 break; | |
| 1330 } | |
|
reveman
2017/02/09 04:50:15
return above and NOTREACHED() here?
Dominik Laskowski
2017/02/09 23:35:28
Done.
| |
| 1309 } | 1331 } |
| 1310 | 1332 |
| 1311 bool ShellSurface::IsResizing() const { | 1333 bool ShellSurface::IsResizing() const { |
| 1312 ash::wm::WindowState* window_state = | 1334 ash::wm::WindowState* window_state = |
| 1313 ash::wm::GetWindowState(widget_->GetNativeWindow()); | 1335 ash::wm::GetWindowState(widget_->GetNativeWindow()); |
| 1314 if (!window_state->is_dragged()) | 1336 if (!window_state->is_dragged()) |
| 1315 return false; | 1337 return false; |
| 1316 | 1338 |
| 1317 return window_state->drag_details()->bounds_change & | 1339 return window_state->drag_details()->bounds_change & |
| 1318 ash::WindowResizer::kBoundsChange_Resizes; | 1340 ash::WindowResizer::kBoundsChange_Resizes; |
| 1319 } | 1341 } |
| 1320 | 1342 |
| 1321 gfx::Rect ShellSurface::GetVisibleBounds() const { | 1343 gfx::Rect ShellSurface::GetVisibleBounds() const { |
| 1322 // Use |geometry_| if set, otherwise use the visual bounds of the surface. | 1344 // Use |geometry_| if set, otherwise use the visual bounds of the surface. |
| 1323 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size()) | 1345 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size()) |
| 1324 : geometry_; | 1346 : geometry_; |
| 1325 } | 1347 } |
| 1326 | 1348 |
| 1327 gfx::Point ShellSurface::GetSurfaceOrigin() const { | 1349 gfx::Point ShellSurface::GetSurfaceOrigin() const { |
| 1328 // If initial bounds were specified then surface origin is always relative | 1350 // For client-positioned shell surfaces, the surface origin corresponds to the |
| 1329 // to those bounds. | 1351 // widget position relative to the origin specified by the client. Since the |
| 1330 if (!initial_bounds_.IsEmpty()) { | 1352 // surface is positioned relative to the widget, negate this vector to align |
| 1331 gfx::Point origin = widget_->GetNativeWindow()->bounds().origin(); | 1353 // the surface with the widget. |
| 1332 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &origin); | 1354 if (bounds_mode_ != BoundsMode::SHELL) { |
| 1333 return initial_bounds_.origin() - origin.OffsetFromOrigin(); | 1355 gfx::Point position = widget_->GetNativeWindow()->bounds().origin(); |
| 1356 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &position); | |
| 1357 return origin_ - position.OffsetFromOrigin(); | |
| 1334 } | 1358 } |
| 1335 | 1359 |
| 1336 gfx::Rect visible_bounds = GetVisibleBounds(); | 1360 gfx::Rect visible_bounds = GetVisibleBounds(); |
| 1337 gfx::Rect client_bounds = | 1361 gfx::Rect client_bounds = |
| 1338 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); | 1362 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); |
| 1339 switch (resize_component_) { | 1363 switch (resize_component_) { |
| 1340 case HTCAPTION: | 1364 case HTCAPTION: |
| 1341 return origin_ - visible_bounds.OffsetFromOrigin(); | 1365 return gfx::Point() + origin_offset_ - visible_bounds.OffsetFromOrigin(); |
| 1342 case HTBOTTOM: | 1366 case HTBOTTOM: |
| 1343 case HTRIGHT: | 1367 case HTRIGHT: |
| 1344 case HTBOTTOMRIGHT: | 1368 case HTBOTTOMRIGHT: |
| 1345 return gfx::Point() - visible_bounds.OffsetFromOrigin(); | 1369 return gfx::Point() - visible_bounds.OffsetFromOrigin(); |
| 1346 case HTTOP: | 1370 case HTTOP: |
| 1347 case HTTOPRIGHT: | 1371 case HTTOPRIGHT: |
| 1348 return gfx::Point(0, client_bounds.height() - visible_bounds.height()) - | 1372 return gfx::Point(0, client_bounds.height() - visible_bounds.height()) - |
| 1349 visible_bounds.OffsetFromOrigin(); | 1373 visible_bounds.OffsetFromOrigin(); |
| 1350 break; | |
| 1351 case HTLEFT: | 1374 case HTLEFT: |
| 1352 case HTBOTTOMLEFT: | 1375 case HTBOTTOMLEFT: |
| 1353 return gfx::Point(client_bounds.width() - visible_bounds.width(), 0) - | 1376 return gfx::Point(client_bounds.width() - visible_bounds.width(), 0) - |
| 1354 visible_bounds.OffsetFromOrigin(); | 1377 visible_bounds.OffsetFromOrigin(); |
| 1355 case HTTOPLEFT: | 1378 case HTTOPLEFT: |
| 1356 return gfx::Point(client_bounds.width() - visible_bounds.width(), | 1379 return gfx::Point(client_bounds.width() - visible_bounds.width(), |
| 1357 client_bounds.height() - visible_bounds.height()) - | 1380 client_bounds.height() - visible_bounds.height()) - |
| 1358 visible_bounds.OffsetFromOrigin(); | 1381 visible_bounds.OffsetFromOrigin(); |
| 1359 default: | 1382 default: |
| 1360 NOTREACHED(); | 1383 NOTREACHED(); |
| 1361 return gfx::Point(); | 1384 return gfx::Point(); |
| 1362 } | 1385 } |
| 1363 } | 1386 } |
| 1364 | 1387 |
| 1365 void ShellSurface::UpdateWidgetBounds() { | 1388 void ShellSurface::UpdateWidgetBounds() { |
| 1366 DCHECK(widget_); | 1389 DCHECK(widget_); |
| 1367 | 1390 |
| 1368 // Return early if the shell is currently managing the bounds of the widget. | 1391 // Return early if the shell is currently managing the bounds of the widget. |
| 1369 // 1) When a window is either maximized/fullscreen/pinned, and the bounds | 1392 if (bounds_mode_ == BoundsMode::SHELL) { |
| 1370 // isn't controlled by a client. | 1393 // 1) When a window is either maximized/fullscreen/pinned. |
| 1371 ash::wm::WindowState* window_state = | 1394 ash::wm::WindowState* window_state = |
| 1372 ash::wm::GetWindowState(widget_->GetNativeWindow()); | 1395 ash::wm::GetWindowState(widget_->GetNativeWindow()); |
| 1373 if (window_state->IsMaximizedOrFullscreenOrPinned() && | 1396 if (window_state->IsMaximizedOrFullscreenOrPinned()) |
| 1374 !window_state->allow_set_bounds_in_maximized()) { | 1397 return; |
| 1375 return; | 1398 |
| 1399 // 2) When a window is being dragged. | |
| 1400 if (IsResizing()) | |
| 1401 return; | |
| 1376 } | 1402 } |
| 1377 | 1403 |
| 1378 // 2) When a window is being dragged. | |
| 1379 if (IsResizing()) | |
| 1380 return; | |
| 1381 | |
| 1382 // Return early if there is pending configure requests. | 1404 // Return early if there is pending configure requests. |
| 1383 if (!pending_configs_.empty() || scoped_configure_) | 1405 if (!pending_configs_.empty() || scoped_configure_) |
| 1384 return; | 1406 return; |
| 1385 | 1407 |
| 1386 gfx::Rect visible_bounds = GetVisibleBounds(); | 1408 gfx::Rect visible_bounds = GetVisibleBounds(); |
| 1387 gfx::Rect new_widget_bounds = | 1409 gfx::Rect new_widget_bounds = |
| 1388 widget_->non_client_view()->GetWindowBoundsForClientBounds( | 1410 widget_->non_client_view()->GetWindowBoundsForClientBounds( |
| 1389 visible_bounds); | 1411 visible_bounds); |
| 1390 | 1412 |
| 1391 // Avoid changing widget origin unless initial bounds were specified and | 1413 switch (bounds_mode_) { |
| 1392 // widget origin is always relative to it. | 1414 case BoundsMode::CLIENT: |
| 1393 if (initial_bounds_.IsEmpty()) { | 1415 case BoundsMode::FIXED: |
| 1394 new_widget_bounds.set_origin(widget_->GetWindowBoundsInScreen().origin()); | 1416 // Position is relative to the origin. |
| 1395 } else { | 1417 new_widget_bounds += origin_.OffsetFromOrigin(); |
| 1396 new_widget_bounds.set_origin(initial_bounds_.origin() + | 1418 break; |
| 1397 visible_bounds.OffsetFromOrigin()); | 1419 case BoundsMode::SHELL: |
| 1398 } | 1420 // Update widget origin using the surface origin if the current location |
| 1399 | 1421 // of surface is being anchored to one side of the widget as a result of a |
| 1400 // Update widget origin using the surface origin if the current location of | 1422 // resize operation. |
| 1401 // surface is being anchored to one side of the widget as a result of a | 1423 if (resize_component_ != HTCAPTION) { |
| 1402 // resize operation. | 1424 gfx::Point widget_origin = |
| 1403 if (resize_component_ != HTCAPTION) { | 1425 GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin(); |
| 1404 gfx::Point new_widget_origin = | 1426 wm::ConvertPointToScreen(widget_->GetNativeWindow(), &widget_origin); |
| 1405 GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin(); | 1427 new_widget_bounds.set_origin(widget_origin); |
| 1406 wm::ConvertPointToScreen(widget_->GetNativeWindow(), &new_widget_origin); | 1428 } else { |
| 1407 new_widget_bounds.set_origin(new_widget_origin); | 1429 // Preserve widget position. |
| 1430 new_widget_bounds.set_origin( | |
| 1431 widget_->GetWindowBoundsInScreen().origin()); | |
| 1432 } | |
| 1433 break; | |
| 1408 } | 1434 } |
| 1409 | 1435 |
| 1410 // Set |ignore_window_bounds_changes_| as this change to window bounds | 1436 // Set |ignore_window_bounds_changes_| as this change to window bounds |
| 1411 // should not result in a configure request. | 1437 // should not result in a configure request. |
| 1412 DCHECK(!ignore_window_bounds_changes_); | 1438 DCHECK(!ignore_window_bounds_changes_); |
| 1413 ignore_window_bounds_changes_ = true; | 1439 ignore_window_bounds_changes_ = true; |
| 1414 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) | 1440 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) |
| 1415 widget_->SetBounds(new_widget_bounds); | 1441 widget_->SetBounds(new_widget_bounds); |
| 1416 ignore_window_bounds_changes_ = false; | 1442 ignore_window_bounds_changes_ = false; |
| 1443 } | |
| 1417 | 1444 |
| 1418 gfx::Rect client_view_bounds = | 1445 void ShellSurface::UpdateSurfaceBounds() { |
| 1446 const gfx::Rect client_view_bounds = | |
| 1419 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); | 1447 widget_->non_client_view()->frame_view()->GetBoundsForClientView(); |
| 1420 | 1448 |
| 1421 // A change to the widget size requires surface bounds to be re-adjusted. | |
| 1422 surface_->window()->SetBounds( | 1449 surface_->window()->SetBounds( |
| 1423 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), | 1450 gfx::Rect(GetSurfaceOrigin() + client_view_bounds.OffsetFromOrigin(), |
| 1424 surface_->window()->layer()->size())); | 1451 surface_->window()->layer()->size())); |
| 1425 } | 1452 } |
| 1426 | 1453 |
| 1427 void ShellSurface::UpdateShadow() { | 1454 void ShellSurface::UpdateShadow() { |
| 1428 if (!widget_) | 1455 if (!widget_) |
| 1429 return; | 1456 return; |
| 1430 aura::Window* window = widget_->GetNativeWindow(); | 1457 aura::Window* window = widget_->GetNativeWindow(); |
| 1431 if (!shadow_enabled_) { | 1458 if (!shadow_enabled_) { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1550 // small style shadow for them. | 1577 // small style shadow for them. |
| 1551 if (!activatable_) | 1578 if (!activatable_) |
| 1552 shadow->SetElevation(wm::ShadowElevation::SMALL); | 1579 shadow->SetElevation(wm::ShadowElevation::SMALL); |
| 1553 // We don't have rounded corners unless frame is enabled. | 1580 // We don't have rounded corners unless frame is enabled. |
| 1554 if (!frame_enabled_) | 1581 if (!frame_enabled_) |
| 1555 shadow->SetRoundedCornerRadius(0); | 1582 shadow->SetRoundedCornerRadius(0); |
| 1556 } | 1583 } |
| 1557 } | 1584 } |
| 1558 | 1585 |
| 1559 } // namespace exo | 1586 } // namespace exo |
| OLD | NEW |