Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(334)

Side by Side Diff: components/exo/shell_surface.cc

Issue 2688483003: exo: Refactor ShellSurface and WaylandRemoteShell (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698