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

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

Issue 2040743002: exo: Implement version 2 of remote shell interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@remote-shell-version-2
Patch Set: popup placement fix Created 4 years, 6 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 "ash/aura/wm_window_aura.h" 7 #include "ash/aura/wm_window_aura.h"
8 #include "ash/common/shell_window_ids.h" 8 #include "ash/common/shell_window_ids.h"
9 #include "ash/common/wm/window_resizer.h" 9 #include "ash/common/wm/window_resizer.h"
10 #include "ash/common/wm/window_state.h" 10 #include "ash/common/wm/window_state.h"
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 //////////////////////////////////////////////////////////////////////////////// 154 ////////////////////////////////////////////////////////////////////////////////
155 // ShellSurface, public: 155 // ShellSurface, public:
156 156
157 DEFINE_LOCAL_WINDOW_PROPERTY_KEY(std::string*, kApplicationIdKey, nullptr) 157 DEFINE_LOCAL_WINDOW_PROPERTY_KEY(std::string*, kApplicationIdKey, nullptr)
158 DEFINE_LOCAL_WINDOW_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr) 158 DEFINE_LOCAL_WINDOW_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr)
159 159
160 ShellSurface::ShellSurface(Surface* surface, 160 ShellSurface::ShellSurface(Surface* surface,
161 ShellSurface* parent, 161 ShellSurface* parent,
162 const gfx::Rect& initial_bounds, 162 const gfx::Rect& initial_bounds,
163 bool activatable, 163 bool activatable,
164 bool resizeable,
165 int container) 164 int container)
166 : widget_(nullptr), 165 : widget_(nullptr),
167 surface_(surface), 166 surface_(surface),
168 parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr), 167 parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr),
169 initial_bounds_(initial_bounds), 168 initial_bounds_(initial_bounds),
170 activatable_(activatable), 169 activatable_(activatable),
171 resizeable_(resizeable),
172 container_(container), 170 container_(container),
171 pending_show_widget_(false),
173 scale_(1.0), 172 scale_(1.0),
174 pending_scale_(1.0), 173 pending_scale_(1.0),
175 scoped_configure_(nullptr), 174 scoped_configure_(nullptr),
176 ignore_window_bounds_changes_(false), 175 ignore_window_bounds_changes_(false),
177 resize_component_(HTCAPTION), 176 resize_component_(HTCAPTION),
178 pending_resize_component_(HTCAPTION) { 177 pending_resize_component_(HTCAPTION) {
179 ash::Shell::GetInstance()->activation_client()->AddObserver(this); 178 ash::Shell::GetInstance()->activation_client()->AddObserver(this);
180 surface_->SetSurfaceDelegate(this); 179 surface_->SetSurfaceDelegate(this);
181 surface_->AddSurfaceObserver(this); 180 surface_->AddSurfaceObserver(this);
182 surface_->Show(); 181 surface_->Show();
183 set_owned_by_client(); 182 set_owned_by_client();
184 if (parent_) 183 if (parent_)
185 parent_->AddObserver(this); 184 parent_->AddObserver(this);
186 } 185 }
187 186
188 ShellSurface::ShellSurface(Surface* surface) 187 ShellSurface::ShellSurface(Surface* surface)
189 : ShellSurface(surface, 188 : ShellSurface(surface,
190 nullptr, 189 nullptr,
191 gfx::Rect(), 190 gfx::Rect(),
192 true, 191 true,
193 true,
194 ash::kShellWindowId_DefaultContainer) {} 192 ash::kShellWindowId_DefaultContainer) {}
195 193
196 ShellSurface::~ShellSurface() { 194 ShellSurface::~ShellSurface() {
197 DCHECK(!scoped_configure_); 195 DCHECK(!scoped_configure_);
198 ash::Shell::GetInstance()->activation_client()->RemoveObserver(this); 196 ash::Shell::GetInstance()->activation_client()->RemoveObserver(this);
199 if (surface_) { 197 if (surface_) {
200 if (scale_ != 1.0) 198 if (scale_ != 1.0)
201 surface_->SetTransform(gfx::Transform()); 199 surface_->SetTransform(gfx::Transform());
202 surface_->SetSurfaceDelegate(nullptr); 200 surface_->SetSurfaceDelegate(nullptr);
203 surface_->RemoveSurfaceObserver(this); 201 surface_->RemoveSurfaceObserver(this);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 261
264 if (!widget_) 262 if (!widget_)
265 CreateShellSurfaceWidget(ui::SHOW_STATE_MAXIMIZED); 263 CreateShellSurfaceWidget(ui::SHOW_STATE_MAXIMIZED);
266 264
267 // Note: This will ask client to configure its surface even if already 265 // Note: This will ask client to configure its surface even if already
268 // maximized. 266 // maximized.
269 ScopedConfigure scoped_configure(this, true); 267 ScopedConfigure scoped_configure(this, true);
270 widget_->Maximize(); 268 widget_->Maximize();
271 } 269 }
272 270
271 void ShellSurface::Minimize() {
272 TRACE_EVENT0("exo", "ShellSurface::Minimize");
273
274 if (!widget_)
275 return;
276
277 // Note: This will ask client to configure its surface even if already
278 // minimized.
279 ScopedConfigure scoped_configure(this, true);
280 widget_->Minimize();
281 }
282
273 void ShellSurface::Restore() { 283 void ShellSurface::Restore() {
274 TRACE_EVENT0("exo", "ShellSurface::Restore"); 284 TRACE_EVENT0("exo", "ShellSurface::Restore");
275 285
276 if (!widget_) 286 if (!widget_)
277 return; 287 return;
278 288
279 // Note: This will ask client to configure its surface even if not already 289 // Note: This will ask client to configure its surface even if not already
280 // maximized. 290 // maximized or minimized.
281 ScopedConfigure scoped_configure(this, true); 291 ScopedConfigure scoped_configure(this, true);
282 widget_->Restore(); 292 widget_->Restore();
283 } 293 }
284 294
285 void ShellSurface::SetFullscreen(bool fullscreen) { 295 void ShellSurface::SetFullscreen(bool fullscreen) {
286 TRACE_EVENT1("exo", "ShellSurface::SetFullscreen", "fullscreen", fullscreen); 296 TRACE_EVENT1("exo", "ShellSurface::SetFullscreen", "fullscreen", fullscreen);
287 297
288 if (!widget_) 298 if (!widget_)
289 CreateShellSurfaceWidget(ui::SHOW_STATE_FULLSCREEN); 299 CreateShellSurfaceWidget(ui::SHOW_STATE_FULLSCREEN);
290 300
(...skipping 27 matching lines...) Expand all
318 void ShellSurface::SetApplicationId(const std::string& application_id) { 328 void ShellSurface::SetApplicationId(const std::string& application_id) {
319 TRACE_EVENT1("exo", "ShellSurface::SetApplicationId", "application_id", 329 TRACE_EVENT1("exo", "ShellSurface::SetApplicationId", "application_id",
320 application_id); 330 application_id);
321 331
322 application_id_ = application_id; 332 application_id_ = application_id;
323 } 333 }
324 334
325 void ShellSurface::Move() { 335 void ShellSurface::Move() {
326 TRACE_EVENT0("exo", "ShellSurface::Move"); 336 TRACE_EVENT0("exo", "ShellSurface::Move");
327 337
328 if (widget_) 338 if (widget_ && !widget_->movement_disabled())
329 AttemptToStartDrag(HTCAPTION); 339 AttemptToStartDrag(HTCAPTION);
330 } 340 }
331 341
332 void ShellSurface::Resize(int component) { 342 void ShellSurface::Resize(int component) {
333 TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component); 343 TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component);
334 344
335 if (widget_) 345 if (widget_ && !widget_->movement_disabled())
336 AttemptToStartDrag(component); 346 AttemptToStartDrag(component);
337 } 347 }
338 348
339 void ShellSurface::Close() { 349 void ShellSurface::Close() {
340 if (!close_callback_.is_null()) 350 if (!close_callback_.is_null())
341 close_callback_.Run(); 351 close_callback_.Run();
342 } 352 }
343 353
344 void ShellSurface::SetGeometry(const gfx::Rect& geometry) { 354 void ShellSurface::SetGeometry(const gfx::Rect& geometry) {
345 TRACE_EVENT1("exo", "ShellSurface::SetGeometry", "geometry", 355 TRACE_EVENT1("exo", "ShellSurface::SetGeometry", "geometry",
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 446
437 // Update surface scale. 447 // Update surface scale.
438 if (pending_scale_ != scale_) { 448 if (pending_scale_ != scale_) {
439 gfx::Transform transform; 449 gfx::Transform transform;
440 DCHECK_NE(pending_scale_, 0.0); 450 DCHECK_NE(pending_scale_, 0.0);
441 transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_); 451 transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_);
442 surface_->SetTransform(transform); 452 surface_->SetTransform(transform);
443 scale_ = pending_scale_; 453 scale_ = pending_scale_;
444 } 454 }
445 455
446 // Show widget if not already visible. 456 // Show widget if needed.
447 if (!widget_->IsClosed() && !widget_->IsVisible()) 457 if (pending_show_widget_) {
458 DCHECK(!widget_->IsClosed());
459 DCHECK(!widget_->IsVisible());
460 pending_show_widget_ = false;
448 widget_->Show(); 461 widget_->Show();
462 }
449 } 463 }
450 } 464 }
451 465
452 bool ShellSurface::IsSurfaceSynchronized() const { 466 bool ShellSurface::IsSurfaceSynchronized() const {
453 // A shell surface is always desynchronized. 467 // A shell surface is always desynchronized.
454 return false; 468 return false;
455 } 469 }
456 470
457 //////////////////////////////////////////////////////////////////////////////// 471 ////////////////////////////////////////////////////////////////////////////////
458 // SurfaceObserver overrides: 472 // SurfaceObserver overrides:
(...skipping 14 matching lines...) Expand all
473 // Note: In its use in the Wayland server implementation, the surface 487 // Note: In its use in the Wayland server implementation, the surface
474 // destroyed callback may destroy the ShellSurface instance. This call needs 488 // destroyed callback may destroy the ShellSurface instance. This call needs
475 // to be last so that the instance can be destroyed. 489 // to be last so that the instance can be destroyed.
476 if (!surface_destroyed_callback_.is_null()) 490 if (!surface_destroyed_callback_.is_null())
477 surface_destroyed_callback_.Run(); 491 surface_destroyed_callback_.Run();
478 } 492 }
479 493
480 //////////////////////////////////////////////////////////////////////////////// 494 ////////////////////////////////////////////////////////////////////////////////
481 // views::WidgetDelegate overrides: 495 // views::WidgetDelegate overrides:
482 496
483 bool ShellSurface::CanMaximize() const { 497 bool ShellSurface::CanResize() const {
484 return resizeable_; 498 return initial_bounds_.IsEmpty();
485 } 499 }
486 500
487 bool ShellSurface::CanResize() const { 501 bool ShellSurface::CanMaximize() const {
488 return resizeable_; 502 return true;
503 }
504
505 bool ShellSurface::CanMinimize() const {
506 return true;
489 } 507 }
490 508
491 base::string16 ShellSurface::GetWindowTitle() const { 509 base::string16 ShellSurface::GetWindowTitle() const {
492 return title_; 510 return title_;
493 } 511 }
494 512
495 void ShellSurface::WindowClosing() { 513 void ShellSurface::WindowClosing() {
496 if (resizer_) 514 if (resizer_)
497 EndDrag(true /* revert */); 515 EndDrag(true /* revert */);
498 SetEnabled(false); 516 SetEnabled(false);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 ash::wm::WindowStateType new_type = window_state->GetStateType(); 564 ash::wm::WindowStateType new_type = window_state->GetStateType();
547 if (old_type == ash::wm::WINDOW_STATE_TYPE_MAXIMIZED || 565 if (old_type == ash::wm::WINDOW_STATE_TYPE_MAXIMIZED ||
548 new_type == ash::wm::WINDOW_STATE_TYPE_MAXIMIZED || 566 new_type == ash::wm::WINDOW_STATE_TYPE_MAXIMIZED ||
549 old_type == ash::wm::WINDOW_STATE_TYPE_FULLSCREEN || 567 old_type == ash::wm::WINDOW_STATE_TYPE_FULLSCREEN ||
550 new_type == ash::wm::WINDOW_STATE_TYPE_FULLSCREEN) { 568 new_type == ash::wm::WINDOW_STATE_TYPE_FULLSCREEN) {
551 Configure(); 569 Configure();
552 } 570 }
553 571
554 if (widget_) 572 if (widget_)
555 UpdateWidgetBounds(); 573 UpdateWidgetBounds();
574
575 if (!state_changed_callback_.is_null())
576 state_changed_callback_.Run(old_type, new_type);
556 } 577 }
557 578
558 //////////////////////////////////////////////////////////////////////////////// 579 ////////////////////////////////////////////////////////////////////////////////
559 // aura::WindowObserver overrides: 580 // aura::WindowObserver overrides:
560 581
561 void ShellSurface::OnWindowBoundsChanged(aura::Window* window, 582 void ShellSurface::OnWindowBoundsChanged(aura::Window* window,
562 const gfx::Rect& old_bounds, 583 const gfx::Rect& old_bounds,
563 const gfx::Rect& new_bounds) { 584 const gfx::Rect& new_bounds) {
564 if (!widget_ || !surface_ || ignore_window_bounds_changes_) 585 if (!widget_ || !surface_ || ignore_window_bounds_changes_)
565 return; 586 return;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 704
684 views::Widget::InitParams params; 705 views::Widget::InitParams params;
685 params.type = views::Widget::InitParams::TYPE_WINDOW; 706 params.type = views::Widget::InitParams::TYPE_WINDOW;
686 params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET; 707 params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET;
687 params.delegate = this; 708 params.delegate = this;
688 params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; 709 params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE;
689 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 710 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
690 params.show_state = show_state; 711 params.show_state = show_state;
691 params.parent = 712 params.parent =
692 ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), container_); 713 ash::Shell::GetContainer(ash::Shell::GetPrimaryRootWindow(), container_);
693 if (!initial_bounds_.IsEmpty()) { 714 params.bounds = initial_bounds_;
694 params.bounds = initial_bounds_;
695 if (parent_) {
696 aura::Window::ConvertRectToTarget(GetMainSurface(parent_), params.parent,
697 &params.bounds);
698 }
699 }
700 bool activatable = activatable_ && !surface_->GetHitTestBounds().IsEmpty(); 715 bool activatable = activatable_ && !surface_->GetHitTestBounds().IsEmpty();
701 params.activatable = activatable ? views::Widget::InitParams::ACTIVATABLE_YES 716 params.activatable = activatable ? views::Widget::InitParams::ACTIVATABLE_YES
702 : views::Widget::InitParams::ACTIVATABLE_NO; 717 : views::Widget::InitParams::ACTIVATABLE_NO;
703 718
704 // Note: NativeWidget owns this widget. 719 // Note: NativeWidget owns this widget.
705 widget_ = new ShellSurfaceWidget(this); 720 widget_ = new ShellSurfaceWidget(this);
706 widget_->Init(params); 721 widget_->Init(params);
707 722
723 // Disable movement if initial bounds were specified.
724 widget_->set_movement_disabled(!initial_bounds_.IsEmpty());
725
708 aura::Window* window = widget_->GetNativeWindow(); 726 aura::Window* window = widget_->GetNativeWindow();
709 window->SetName("ExoShellSurface"); 727 window->SetName("ExoShellSurface");
710 window->AddChild(surface_); 728 window->AddChild(surface_);
711 window->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter)); 729 window->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter));
712 SetApplicationId(window, &application_id_); 730 SetApplicationId(window, &application_id_);
713 SetMainSurface(window, surface_); 731 SetMainSurface(window, surface_);
714 732
715 // Start tracking changes to window bounds and window state. 733 // Start tracking changes to window bounds and window state.
716 window->AddObserver(this); 734 window->AddObserver(this);
717 ash::wm::GetWindowState(window)->AddObserver(this); 735 ash::wm::GetWindowState(window)->AddObserver(this);
718 736
719 // Make shell surface a transient child if |parent_| has been set. 737 // Make shell surface a transient child if |parent_| has been set.
720 if (parent_) 738 if (parent_)
721 wm::AddTransientChild(parent_, window); 739 wm::AddTransientChild(parent_, window);
722 740
723 // Allow Ash to manage the position of a top-level shell surfaces if show 741 // Allow Ash to manage the position of a top-level shell surfaces if show
724 // state is one that allows auto positioning and |initial_bounds_| has 742 // state is one that allows auto positioning and |initial_bounds_| has
725 // not been set. 743 // not been set.
726 ash::wm::GetWindowState(window)->set_window_position_managed( 744 ash::wm::GetWindowState(window)->set_window_position_managed(
727 ash::wm::ToWindowShowState(ash::wm::WINDOW_STATE_TYPE_AUTO_POSITIONED) == 745 ash::wm::ToWindowShowState(ash::wm::WINDOW_STATE_TYPE_AUTO_POSITIONED) ==
728 show_state && 746 show_state &&
729 initial_bounds_.IsEmpty()); 747 initial_bounds_.IsEmpty());
748
749 // Show widget next time Commit() is called.
750 pending_show_widget_ = true;
730 } 751 }
731 752
732 void ShellSurface::Configure() { 753 void ShellSurface::Configure() {
733 DCHECK(widget_); 754 DCHECK(widget_);
734 755
735 // Delay configure callback if |scoped_configure_| is set. 756 // Delay configure callback if |scoped_configure_| is set.
736 if (scoped_configure_) { 757 if (scoped_configure_) {
737 scoped_configure_->set_needs_configure(); 758 scoped_configure_->set_needs_configure();
738 return; 759 return;
739 } 760 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 ash::WindowResizer::kBoundsChange_Resizes; 891 ash::WindowResizer::kBoundsChange_Resizes;
871 } 892 }
872 893
873 gfx::Rect ShellSurface::GetVisibleBounds() const { 894 gfx::Rect ShellSurface::GetVisibleBounds() const {
874 // Use |geometry_| if set, otherwise use the visual bounds of the surface. 895 // Use |geometry_| if set, otherwise use the visual bounds of the surface.
875 return geometry_.IsEmpty() ? gfx::Rect(surface_->layer()->size()) : geometry_; 896 return geometry_.IsEmpty() ? gfx::Rect(surface_->layer()->size()) : geometry_;
876 } 897 }
877 898
878 gfx::Point ShellSurface::GetSurfaceOrigin() const { 899 gfx::Point ShellSurface::GetSurfaceOrigin() const {
879 gfx::Rect window_bounds = widget_->GetWindowBoundsInScreen(); 900 gfx::Rect window_bounds = widget_->GetWindowBoundsInScreen();
901
902 // If initial bounds were specified then surface origin is always relative
903 // to those bounds.
904 if (!initial_bounds_.IsEmpty())
905 return initial_bounds_.origin() - window_bounds.OffsetFromOrigin();
906
880 gfx::Rect visible_bounds = GetVisibleBounds(); 907 gfx::Rect visible_bounds = GetVisibleBounds();
881
882 switch (resize_component_) { 908 switch (resize_component_) {
883 case HTCAPTION: 909 case HTCAPTION:
884 return origin_ - visible_bounds.OffsetFromOrigin(); 910 return origin_ - visible_bounds.OffsetFromOrigin();
885 case HTBOTTOM: 911 case HTBOTTOM:
886 case HTRIGHT: 912 case HTRIGHT:
887 case HTBOTTOMRIGHT: 913 case HTBOTTOMRIGHT:
888 return gfx::Point() - visible_bounds.OffsetFromOrigin(); 914 return gfx::Point() - visible_bounds.OffsetFromOrigin();
889 case HTTOP: 915 case HTTOP:
890 case HTTOPRIGHT: 916 case HTTOPRIGHT:
891 return gfx::Point(0, window_bounds.height() - visible_bounds.height()) - 917 return gfx::Point(0, window_bounds.height() - visible_bounds.height()) -
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 DCHECK(!ignore_window_bounds_changes_); 963 DCHECK(!ignore_window_bounds_changes_);
938 ignore_window_bounds_changes_ = true; 964 ignore_window_bounds_changes_ = true;
939 widget_->SetBounds(new_widget_bounds); 965 widget_->SetBounds(new_widget_bounds);
940 ignore_window_bounds_changes_ = false; 966 ignore_window_bounds_changes_ = false;
941 967
942 // A change to the widget size requires surface bounds to be re-adjusted. 968 // A change to the widget size requires surface bounds to be re-adjusted.
943 surface_->SetBounds(gfx::Rect(GetSurfaceOrigin(), surface_->layer()->size())); 969 surface_->SetBounds(gfx::Rect(GetSurfaceOrigin(), surface_->layer()->size()));
944 } 970 }
945 971
946 } // namespace exo 972 } // namespace exo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698