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

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

Issue 2396883003: exo: Fix dragging edge cases (Closed)
Patch Set: Fix presubmit errors Created 4 years, 2 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/aura/wm_window_aura.h" 9 #include "ash/aura/wm_window_aura.h"
10 #include "ash/common/shelf/wm_shelf.h" 10 #include "ash/common/shelf/wm_shelf.h"
11 #include "ash/common/shell_window_ids.h" 11 #include "ash/common/shell_window_ids.h"
12 #include "ash/common/wm/window_resizer.h" 12 #include "ash/common/wm/window_resizer.h"
13 #include "ash/common/wm/window_state.h" 13 #include "ash/common/wm/window_state.h"
14 #include "ash/common/wm/window_state_delegate.h" 14 #include "ash/common/wm/window_state_delegate.h"
15 #include "ash/common/wm_shell.h" 15 #include "ash/common/wm_shell.h"
16 #include "ash/wm/drag_window_resizer.h"
16 #include "ash/wm/window_state_aura.h" 17 #include "ash/wm/window_state_aura.h"
17 #include "ash/wm/window_util.h" 18 #include "ash/wm/window_util.h"
18 #include "base/logging.h" 19 #include "base/logging.h"
19 #include "base/macros.h" 20 #include "base/macros.h"
20 #include "base/memory/ptr_util.h" 21 #include "base/memory/ptr_util.h"
21 #include "base/strings/utf_string_conversions.h" 22 #include "base/strings/utf_string_conversions.h"
22 #include "base/trace_event/trace_event.h" 23 #include "base/trace_event/trace_event.h"
23 #include "base/trace_event/trace_event_argument.h" 24 #include "base/trace_event/trace_event_argument.h"
25 #include "components/exo/display.h"
24 #include "components/exo/surface.h" 26 #include "components/exo/surface.h"
25 #include "ui/aura/client/aura_constants.h" 27 #include "ui/aura/client/aura_constants.h"
26 #include "ui/aura/client/cursor_client.h" 28 #include "ui/aura/client/cursor_client.h"
27 #include "ui/aura/window.h" 29 #include "ui/aura/window.h"
28 #include "ui/aura/window_event_dispatcher.h" 30 #include "ui/aura/window_event_dispatcher.h"
29 #include "ui/aura/window_property.h" 31 #include "ui/aura/window_property.h"
30 #include "ui/aura/window_targeter.h" 32 #include "ui/aura/window_targeter.h"
31 #include "ui/aura/window_tree_host.h" 33 #include "ui/aura/window_tree_host.h"
32 #include "ui/base/accelerators/accelerator.h" 34 #include "ui/base/accelerators/accelerator.h"
33 #include "ui/gfx/path.h" 35 #include "ui/gfx/path.h"
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 widget_->RemoveObserver(this); 181 widget_->RemoveObserver(this);
180 widget_ = nullptr; 182 widget_ = nullptr;
181 } 183 }
182 184
183 private: 185 private:
184 views::Widget* widget_; 186 views::Widget* widget_;
185 187
186 DISALLOW_COPY_AND_ASSIGN(CustomWindowStateDelegate); 188 DISALLOW_COPY_AND_ASSIGN(CustomWindowStateDelegate);
187 }; 189 };
188 190
191 class CustomWindowResizer : public ash::WindowResizer {
192 public:
193 explicit CustomWindowResizer(ash::wm::WindowState* window_state)
194 : WindowResizer(window_state), shell_(GetTarget()->GetShell()) {
195 shell_->LockCursor();
196 }
197
198 ~CustomWindowResizer() override { shell_->UnlockCursor(); }
199
200 // ash::WindowResizer:
201 void Drag(const gfx::Point& location, int event_flags) override {}
202 void CompleteDrag() override {}
203 void RevertDrag() override {}
204
205 private:
206 ash::WmShell* const shell_;
207
208 DISALLOW_COPY_AND_ASSIGN(CustomWindowResizer);
209 };
210
189 class ShellSurfaceWidget : public views::Widget { 211 class ShellSurfaceWidget : public views::Widget {
190 public: 212 public:
191 explicit ShellSurfaceWidget(ShellSurface* shell_surface) 213 explicit ShellSurfaceWidget(ShellSurface* shell_surface)
192 : shell_surface_(shell_surface) {} 214 : shell_surface_(shell_surface) {}
193 215
194 // Overridden from views::Widget 216 // Overridden from views::Widget
195 void Close() override { shell_surface_->Close(); } 217 void Close() override { shell_surface_->Close(); }
196 void OnKeyEvent(ui::KeyEvent* event) override { 218 void OnKeyEvent(ui::KeyEvent* event) override {
197 // TODO(hidehiko): Handle ESC + SHIFT + COMMAND accelerator key 219 // TODO(hidehiko): Handle ESC + SHIFT + COMMAND accelerator key
198 // to escape pinned mode. 220 // to escape pinned mode.
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 saved_animations_disabled_); 347 saved_animations_disabled_);
326 } 348 }
327 } 349 }
328 350
329 //////////////////////////////////////////////////////////////////////////////// 351 ////////////////////////////////////////////////////////////////////////////////
330 // ShellSurface, public: 352 // ShellSurface, public:
331 353
332 DEFINE_LOCAL_WINDOW_PROPERTY_KEY(std::string*, kApplicationIdKey, nullptr) 354 DEFINE_LOCAL_WINDOW_PROPERTY_KEY(std::string*, kApplicationIdKey, nullptr)
333 DEFINE_LOCAL_WINDOW_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr) 355 DEFINE_LOCAL_WINDOW_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr)
334 356
335 ShellSurface::ShellSurface(Surface* surface, 357 ShellSurface::ShellSurface(const Display& display,
358 Surface* surface,
336 ShellSurface* parent, 359 ShellSurface* parent,
337 const gfx::Rect& initial_bounds, 360 const gfx::Rect& initial_bounds,
338 bool activatable, 361 bool activatable,
339 int container) 362 int container)
340 : widget_(nullptr), 363 : display_(display),
364 widget_(nullptr),
341 surface_(surface), 365 surface_(surface),
342 parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr), 366 parent_(parent ? parent->GetWidget()->GetNativeWindow() : nullptr),
343 initial_bounds_(initial_bounds), 367 initial_bounds_(initial_bounds),
344 activatable_(activatable), 368 activatable_(activatable),
345 container_(container) { 369 container_(container) {
346 WMHelper::GetInstance()->AddActivationObserver(this); 370 WMHelper::GetInstance()->AddActivationObserver(this);
371 WMHelper::GetInstance()->AddShellObserver(this);
347 surface_->SetSurfaceDelegate(this); 372 surface_->SetSurfaceDelegate(this);
348 surface_->AddSurfaceObserver(this); 373 surface_->AddSurfaceObserver(this);
349 surface_->window()->Show(); 374 surface_->window()->Show();
350 set_owned_by_client(); 375 set_owned_by_client();
351 if (parent_) 376 if (parent_)
352 parent_->AddObserver(this); 377 parent_->AddObserver(this);
353 } 378 }
354 379
355 ShellSurface::ShellSurface(Surface* surface) 380 ShellSurface::ShellSurface(const Display& display, Surface* surface)
356 : ShellSurface(surface, 381 : ShellSurface(display,
382 surface,
357 nullptr, 383 nullptr,
358 gfx::Rect(), 384 gfx::Rect(),
359 true, 385 true,
360 ash::kShellWindowId_DefaultContainer) {} 386 ash::kShellWindowId_DefaultContainer) {}
361 387
362 ShellSurface::~ShellSurface() { 388 ShellSurface::~ShellSurface() {
363 DCHECK(!scoped_configure_); 389 DCHECK(!scoped_configure_);
364 if (resizer_) 390 EndDragOrMove(false /* revert */);
365 EndDrag(false /* revert */);
366 if (widget_) { 391 if (widget_) {
367 ash::wm::GetWindowState(widget_->GetNativeWindow())->RemoveObserver(this); 392 ash::wm::GetWindowState(widget_->GetNativeWindow())->RemoveObserver(this);
368 widget_->GetNativeWindow()->RemoveObserver(this); 393 widget_->GetNativeWindow()->RemoveObserver(this);
369 if (widget_->IsVisible()) 394 if (widget_->IsVisible())
370 widget_->Hide(); 395 widget_->Hide();
371 widget_->CloseNow(); 396 widget_->CloseNow();
372 } 397 }
373 WMHelper::GetInstance()->RemoveActivationObserver(this); 398 WMHelper::GetInstance()->RemoveActivationObserver(this);
399 WMHelper::GetInstance()->RemoveShellObserver(this);
374 if (parent_) 400 if (parent_)
375 parent_->RemoveObserver(this); 401 parent_->RemoveObserver(this);
376 if (surface_) { 402 if (surface_) {
377 if (scale_ != 1.0) 403 if (scale_ != 1.0)
378 surface_->window()->SetTransform(gfx::Transform()); 404 surface_->window()->SetTransform(gfx::Transform());
379 surface_->SetSurfaceDelegate(nullptr); 405 surface_->SetSurfaceDelegate(nullptr);
380 surface_->RemoveSurfaceObserver(this); 406 surface_->RemoveSurfaceObserver(this);
381 } 407 }
382 WMHelper::GetInstance()->RemoveAccessibilityObserver(this); 408 WMHelper::GetInstance()->RemoveAccessibilityObserver(this);
383 } 409 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 489
464 if (!widget_) 490 if (!widget_)
465 return; 491 return;
466 492
467 // Note: This will ask client to configure its surface even if not already 493 // Note: This will ask client to configure its surface even if not already
468 // maximized or minimized. 494 // maximized or minimized.
469 ScopedConfigure scoped_configure(this, true); 495 ScopedConfigure scoped_configure(this, true);
470 widget_->Restore(); 496 widget_->Restore();
471 } 497 }
472 498
499 void ShellSurface::SetMoving() {
500 TRACE_EVENT0("exo", "ShellSurface::SetMoving");
501
502 if (move_resizer_)
503 return;
504
505 ash::wm::WindowState* const window_state =
506 ash::wm::GetWindowState(widget_->GetNativeWindow());
507
508 DCHECK(!window_state->drag_details());
509 window_state->CreateDragDetails(GetMouseLocation(), HTCAPTION,
510 aura::client::WINDOW_MOVE_SOURCE_MOUSE);
511
512 // The resizer renders phantom windows, but does not control window movement.
513 move_resizer_.reset(ash::DragWindowResizer::Create(
514 new CustomWindowResizer(window_state), window_state));
515
516 surface_->window()->SetCapture();
517 }
518
519 void ShellSurface::UnsetMoving(bool revert) {
520 TRACE_EVENT1("exo", "ShellSurface::UnsetMoving", "revert", revert);
521
522 if (!move_resizer_)
523 return;
524
525 if (revert)
526 move_resizer_->RevertDrag();
527 else
528 move_resizer_->CompleteDrag();
529
530 move_resizer_.reset();
531 surface_->window()->ReleaseCapture();
532 }
533
473 void ShellSurface::SetFullscreen(bool fullscreen) { 534 void ShellSurface::SetFullscreen(bool fullscreen) {
474 TRACE_EVENT1("exo", "ShellSurface::SetFullscreen", "fullscreen", fullscreen); 535 TRACE_EVENT1("exo", "ShellSurface::SetFullscreen", "fullscreen", fullscreen);
475 536
476 if (!widget_) 537 if (!widget_)
477 CreateShellSurfaceWidget(ui::SHOW_STATE_FULLSCREEN); 538 CreateShellSurfaceWidget(ui::SHOW_STATE_FULLSCREEN);
478 539
479 // Note: This will ask client to configure its surface even if fullscreen 540 // Note: This will ask client to configure its surface even if fullscreen
480 // state doesn't change. 541 // state doesn't change.
481 ScopedConfigure scoped_configure(this, true); 542 ScopedConfigure scoped_configure(this, true);
482 widget_->SetFullscreen(fullscreen); 543 widget_->SetFullscreen(fullscreen);
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 if (activatable != CanActivate()) { 738 if (activatable != CanActivate()) {
678 set_can_activate(activatable); 739 set_can_activate(activatable);
679 // Activate or deactivate window if activation state changed. 740 // Activate or deactivate window if activation state changed.
680 if (activatable) 741 if (activatable)
681 wm::ActivateWindow(widget_->GetNativeWindow()); 742 wm::ActivateWindow(widget_->GetNativeWindow());
682 else if (widget_->IsActive()) 743 else if (widget_->IsActive())
683 wm::DeactivateWindow(widget_->GetNativeWindow()); 744 wm::DeactivateWindow(widget_->GetNativeWindow());
684 } 745 }
685 } 746 }
686 747
687 // Update surface bounds. 748 UpdateSurfaceBounds();
688 surface_->window()->SetBounds(
689 gfx::Rect(surface_origin, surface_->window()->layer()->size()));
690 749
691 // Update surface scale. 750 // Update surface scale.
692 if (pending_scale_ != scale_) { 751 if (pending_scale_ != scale_) {
693 gfx::Transform transform; 752 gfx::Transform transform;
694 DCHECK_NE(pending_scale_, 0.0); 753 DCHECK_NE(pending_scale_, 0.0);
695 transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_); 754 transform.Scale(1.0 / pending_scale_, 1.0 / pending_scale_);
696 surface_->window()->SetTransform(transform); 755 surface_->window()->SetTransform(transform);
697 scale_ = pending_scale_; 756 scale_ = pending_scale_;
698 } 757 }
699 758
700 // Show widget if needed. 759 // Show widget if needed.
701 if (pending_show_widget_) { 760 if (pending_show_widget_) {
702 DCHECK(!widget_->IsClosed()); 761 DCHECK(!widget_->IsClosed());
703 DCHECK(!widget_->IsVisible()); 762 DCHECK(!widget_->IsVisible());
704 pending_show_widget_ = false; 763 pending_show_widget_ = false;
705 widget_->Show(); 764 widget_->Show();
706 } 765 }
707 } 766 }
708 } 767 }
709 768
710 bool ShellSurface::IsSurfaceSynchronized() const { 769 bool ShellSurface::IsSurfaceSynchronized() const {
711 // A shell surface is always desynchronized. 770 // A shell surface is always desynchronized.
712 return false; 771 return false;
713 } 772 }
714 773
715 //////////////////////////////////////////////////////////////////////////////// 774 ////////////////////////////////////////////////////////////////////////////////
716 // SurfaceObserver overrides: 775 // SurfaceObserver overrides:
717 776
718 void ShellSurface::OnSurfaceDestroying(Surface* surface) { 777 void ShellSurface::OnSurfaceDestroying(Surface* surface) {
719 if (resizer_) 778 EndDragOrMove(false /* revert */);
720 EndDrag(false /* revert */);
721 if (widget_) 779 if (widget_)
722 SetMainSurface(widget_->GetNativeWindow(), nullptr); 780 SetMainSurface(widget_->GetNativeWindow(), nullptr);
723 surface->RemoveSurfaceObserver(this); 781 surface->RemoveSurfaceObserver(this);
724 surface_ = nullptr; 782 surface_ = nullptr;
725 783
726 // Hide widget before surface is destroyed. This allows hide animations to 784 // Hide widget before surface is destroyed. This allows hide animations to
727 // run using the current surface contents. 785 // run using the current surface contents.
728 if (widget_) 786 if (widget_)
729 widget_->Hide(); 787 widget_->Hide();
730 788
(...skipping 19 matching lines...) Expand all
750 bool ShellSurface::CanMinimize() const { 808 bool ShellSurface::CanMinimize() const {
751 // Shell surfaces in system modal container cannot be minimized. 809 // Shell surfaces in system modal container cannot be minimized.
752 return container_ != ash::kShellWindowId_SystemModalContainer; 810 return container_ != ash::kShellWindowId_SystemModalContainer;
753 } 811 }
754 812
755 base::string16 ShellSurface::GetWindowTitle() const { 813 base::string16 ShellSurface::GetWindowTitle() const {
756 return title_; 814 return title_;
757 } 815 }
758 816
759 void ShellSurface::WindowClosing() { 817 void ShellSurface::WindowClosing() {
760 if (resizer_) 818 EndDragOrMove(true /* revert */);
761 EndDrag(true /* revert */);
762 SetEnabled(false); 819 SetEnabled(false);
763 widget_ = nullptr; 820 widget_ = nullptr;
764 shadow_overlay_ = nullptr; 821 shadow_overlay_ = nullptr;
765 shadow_underlay_ = nullptr; 822 shadow_underlay_ = nullptr;
766 } 823 }
767 824
768 views::Widget* ShellSurface::GetWidget() { 825 views::Widget* ShellSurface::GetWidget() {
769 return widget_; 826 return widget_;
770 } 827 }
771 828
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 862
806 //////////////////////////////////////////////////////////////////////////////// 863 ////////////////////////////////////////////////////////////////////////////////
807 // ash::wm::WindowStateObserver overrides: 864 // ash::wm::WindowStateObserver overrides:
808 865
809 void ShellSurface::OnPreWindowStateTypeChange( 866 void ShellSurface::OnPreWindowStateTypeChange(
810 ash::wm::WindowState* window_state, 867 ash::wm::WindowState* window_state,
811 ash::wm::WindowStateType old_type) { 868 ash::wm::WindowStateType old_type) {
812 ash::wm::WindowStateType new_type = window_state->GetStateType(); 869 ash::wm::WindowStateType new_type = window_state->GetStateType();
813 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) || 870 if (ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(old_type) ||
814 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) { 871 ash::wm::IsMaximizedOrFullscreenOrPinnedWindowStateType(new_type)) {
872 EndDragOrMove(false /* revert */);
873
815 // When transitioning in/out of maximized or fullscreen mode we need to 874 // When transitioning in/out of maximized or fullscreen mode we need to
816 // make sure we have a configure callback before we allow the default 875 // make sure we have a configure callback before we allow the default
817 // cross-fade animations. The configure callback provides a mechanism for 876 // cross-fade animations. The configure callback provides a mechanism for
818 // the client to inform us that a frame has taken the state change into 877 // the client to inform us that a frame has taken the state change into
819 // account and without this cross-fade animations are unreliable. 878 // account and without this cross-fade animations are unreliable.
820 if (configure_callback_.is_null()) 879 if (configure_callback_.is_null())
821 scoped_animations_disabled_.reset(new ScopedAnimationsDisabled(this)); 880 scoped_animations_disabled_.reset(new ScopedAnimationsDisabled(this));
822 } 881 }
823 } 882 }
824 883
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 if (new_bounds.size() == old_bounds.size()) 915 if (new_bounds.size() == old_bounds.size())
857 return; 916 return;
858 917
859 // If size changed then give the client a chance to produce new contents 918 // If size changed then give the client a chance to produce new contents
860 // before origin on screen is changed by adding offset to the next configure 919 // before origin on screen is changed by adding offset to the next configure
861 // request and offset |origin_| by the same distance. 920 // request and offset |origin_| by the same distance.
862 gfx::Vector2d origin_offset = new_bounds.origin() - old_bounds.origin(); 921 gfx::Vector2d origin_offset = new_bounds.origin() - old_bounds.origin();
863 pending_origin_config_offset_ += origin_offset; 922 pending_origin_config_offset_ += origin_offset;
864 origin_ -= origin_offset; 923 origin_ -= origin_offset;
865 924
866 surface_->window()->SetBounds( 925 UpdateSurfaceBounds();
867 gfx::Rect(GetSurfaceOrigin(), surface_->window()->layer()->size()));
868 926
869 // The shadow size may be updated to match the widget. Change it back 927 // The shadow size may be updated to match the widget. Change it back
870 // to the shadow content size. 928 // to the shadow content size.
871 // TODO(oshima): When the arc window reiszing is enabled, we may want to 929 // TODO(oshima): When the arc window reiszing is enabled, we may want to
872 // implement shadow management here instead of using shadow controller. 930 // implement shadow management here instead of using shadow controller.
873 UpdateShadow(); 931 UpdateShadow();
874 932
875 Configure(); 933 Configure();
876 } 934 }
877 } 935 }
(...skipping 10 matching lines...) Expand all
888 946
889 //////////////////////////////////////////////////////////////////////////////// 947 ////////////////////////////////////////////////////////////////////////////////
890 // WMHelper::ActivationObserver overrides: 948 // WMHelper::ActivationObserver overrides:
891 949
892 void ShellSurface::OnWindowActivated( 950 void ShellSurface::OnWindowActivated(
893 aura::Window* gained_active, 951 aura::Window* gained_active,
894 aura::Window* lost_active) { 952 aura::Window* lost_active) {
895 if (!widget_) 953 if (!widget_)
896 return; 954 return;
897 955
956 if (lost_active == widget_->GetNativeWindow())
957 UnsetMoving(false /* revert */);
958
898 if (gained_active == widget_->GetNativeWindow() || 959 if (gained_active == widget_->GetNativeWindow() ||
899 lost_active == widget_->GetNativeWindow()) { 960 lost_active == widget_->GetNativeWindow()) {
900 DCHECK(activatable_); 961 DCHECK(activatable_);
901 Configure(); 962 Configure();
902 UpdateShadow(); 963 UpdateShadow();
903 } 964 }
904 } 965 }
905 966
906 //////////////////////////////////////////////////////////////////////////////// 967 ////////////////////////////////////////////////////////////////////////////////
968 // WMHelper::ShellObserver overrides:
969
970 void ShellSurface::OnOverviewModeStarted() {
971 EndDragOrMove(false /* revert */);
972 ignore_widget_bounds_changes_ = true;
973 }
974
975 void ShellSurface::OnOverviewModeEnded() {
976 ignore_widget_bounds_changes_ = false;
977 }
978
979 ////////////////////////////////////////////////////////////////////////////////
907 // WMHelper::AccessibilityObserver overrides: 980 // WMHelper::AccessibilityObserver overrides:
908 981
909 void ShellSurface::OnAccessibilityModeChanged() { 982 void ShellSurface::OnAccessibilityModeChanged() {
910 UpdateShadow(); 983 UpdateShadow();
911 } 984 }
912 985
913 //////////////////////////////////////////////////////////////////////////////// 986 ////////////////////////////////////////////////////////////////////////////////
914 // ui::EventHandler overrides: 987 // ui::EventHandler overrides:
915 988
916 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) { 989 void ShellSurface::OnKeyEvent(ui::KeyEvent* event) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 params.type = views::Widget::InitParams::TYPE_WINDOW; 1073 params.type = views::Widget::InitParams::TYPE_WINDOW;
1001 params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET; 1074 params.ownership = views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET;
1002 params.delegate = this; 1075 params.delegate = this;
1003 params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE; 1076 params.shadow_type = views::Widget::InitParams::SHADOW_TYPE_NONE;
1004 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; 1077 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
1005 params.show_state = show_state; 1078 params.show_state = show_state;
1006 // Make shell surface a transient child if |parent_| has been set. 1079 // Make shell surface a transient child if |parent_| has been set.
1007 params.parent = 1080 params.parent =
1008 parent_ ? parent_ : WMHelper::GetInstance()->GetContainer(container_); 1081 parent_ ? parent_ : WMHelper::GetInstance()->GetContainer(container_);
1009 params.bounds = initial_bounds_; 1082 params.bounds = initial_bounds_;
1083 display_.ConvertFromVirtualToScreen(&params.bounds);
1010 bool activatable = activatable_; 1084 bool activatable = activatable_;
1011 // ShellSurfaces in system modal container are only activatable if input 1085 // ShellSurfaces in system modal container are only activatable if input
1012 // region is non-empty. See OnCommitSurface() for more details. 1086 // region is non-empty. See OnCommitSurface() for more details.
1013 if (container_ == ash::kShellWindowId_SystemModalContainer) 1087 if (container_ == ash::kShellWindowId_SystemModalContainer)
1014 activatable &= !surface_->GetHitTestBounds().IsEmpty(); 1088 activatable &= !surface_->GetHitTestBounds().IsEmpty();
1015 params.activatable = activatable ? views::Widget::InitParams::ACTIVATABLE_YES 1089 params.activatable = activatable ? views::Widget::InitParams::ACTIVATABLE_YES
1016 : views::Widget::InitParams::ACTIVATABLE_NO; 1090 : views::Widget::InitParams::ACTIVATABLE_NO;
1017 1091
1018 // Note: NativeWidget owns this widget. 1092 // Note: NativeWidget owns this widget.
1019 widget_ = new ShellSurfaceWidget(this); 1093 widget_ = new ShellSurfaceWidget(this);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 void ShellSurface::AttemptToStartDrag(int component) { 1187 void ShellSurface::AttemptToStartDrag(int component) {
1114 DCHECK(widget_); 1188 DCHECK(widget_);
1115 1189
1116 // Cannot start another drag if one is already taking place. 1190 // Cannot start another drag if one is already taking place.
1117 if (resizer_) 1191 if (resizer_)
1118 return; 1192 return;
1119 1193
1120 if (widget_->GetNativeWindow()->HasCapture()) 1194 if (widget_->GetNativeWindow()->HasCapture())
1121 return; 1195 return;
1122 1196
1123 aura::Window* root_window = widget_->GetNativeWindow()->GetRootWindow();
1124 gfx::Point drag_location =
1125 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
1126 aura::Window::ConvertPointToTarget(
1127 root_window, widget_->GetNativeWindow()->parent(), &drag_location);
1128
1129 // Set the cursor before calling CreateWindowResizer(), as that will 1197 // Set the cursor before calling CreateWindowResizer(), as that will
1130 // eventually call LockCursor() and prevent the cursor from changing. 1198 // eventually call LockCursor() and prevent the cursor from changing.
1131 aura::client::CursorClient* cursor_client = 1199 aura::client::CursorClient* cursor_client = aura::client::GetCursorClient(
1132 aura::client::GetCursorClient(root_window); 1200 widget_->GetNativeWindow()->GetRootWindow());
1133 DCHECK(cursor_client); 1201 DCHECK(cursor_client);
1134 1202
1135 switch (component) { 1203 switch (component) {
1136 case HTCAPTION: 1204 case HTCAPTION:
1137 cursor_client->SetCursor(ui::kCursorPointer); 1205 cursor_client->SetCursor(ui::kCursorPointer);
1138 break; 1206 break;
1139 case HTTOP: 1207 case HTTOP:
1140 cursor_client->SetCursor(ui::kCursorNorthResize); 1208 cursor_client->SetCursor(ui::kCursorNorthResize);
1141 break; 1209 break;
1142 case HTTOPRIGHT: 1210 case HTTOPRIGHT:
(...skipping 16 matching lines...) Expand all
1159 break; 1227 break;
1160 case HTTOPLEFT: 1228 case HTTOPLEFT:
1161 cursor_client->SetCursor(ui::kCursorNorthWestResize); 1229 cursor_client->SetCursor(ui::kCursorNorthWestResize);
1162 break; 1230 break;
1163 default: 1231 default:
1164 NOTREACHED(); 1232 NOTREACHED();
1165 break; 1233 break;
1166 } 1234 }
1167 1235
1168 resizer_ = ash::CreateWindowResizer( 1236 resizer_ = ash::CreateWindowResizer(
1169 ash::WmWindowAura::Get(widget_->GetNativeWindow()), drag_location, 1237 ash::WmWindowAura::Get(widget_->GetNativeWindow()), GetMouseLocation(),
1170 component, aura::client::WINDOW_MOVE_SOURCE_MOUSE); 1238 component, aura::client::WINDOW_MOVE_SOURCE_MOUSE);
1171 if (!resizer_) 1239 if (!resizer_)
1172 return; 1240 return;
1173 1241
1174 // Apply pending origin offsets and resize direction before starting a new 1242 // Apply pending origin offsets and resize direction before starting a new
1175 // resize operation. These can still be pending if the client has acknowledged 1243 // resize operation. These can still be pending if the client has acknowledged
1176 // the configure request but not yet called Commit(). 1244 // the configure request but not yet called Commit().
1177 origin_ += pending_origin_offset_; 1245 origin_ += pending_origin_offset_;
1178 pending_origin_offset_ = gfx::Vector2d(); 1246 pending_origin_offset_ = gfx::Vector2d();
1179 resize_component_ = pending_resize_component_; 1247 resize_component_ = pending_resize_component_;
(...skipping 21 matching lines...) Expand all
1201 widget_->GetNativeWindow()->ReleaseCapture(); 1269 widget_->GetNativeWindow()->ReleaseCapture();
1202 resizer_.reset(); 1270 resizer_.reset();
1203 1271
1204 // Notify client that resizing state has changed. 1272 // Notify client that resizing state has changed.
1205 if (was_resizing) 1273 if (was_resizing)
1206 Configure(); 1274 Configure();
1207 1275
1208 UpdateWidgetBounds(); 1276 UpdateWidgetBounds();
1209 } 1277 }
1210 1278
1279 void ShellSurface::EndDragOrMove(bool revert) {
1280 if (resizer_)
1281 EndDrag(revert);
1282 else
1283 UnsetMoving(revert);
1284 }
1285
1211 bool ShellSurface::IsResizing() const { 1286 bool ShellSurface::IsResizing() const {
1212 if (!resizer_) 1287 if (!resizer_)
1213 return false; 1288 return false;
1214 1289
1215 return resizer_->details().bounds_change & 1290 return resizer_->details().bounds_change &
1216 ash::WindowResizer::kBoundsChange_Resizes; 1291 ash::WindowResizer::kBoundsChange_Resizes;
1217 } 1292 }
1218 1293
1219 gfx::Rect ShellSurface::GetVisibleBounds() const { 1294 gfx::Rect ShellSurface::GetVisibleBounds() const {
1220 // Use |geometry_| if set, otherwise use the visual bounds of the surface. 1295 // Use |geometry_| if set, otherwise use the visual bounds of the surface.
1221 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size()) 1296 return geometry_.IsEmpty() ? gfx::Rect(surface_->window()->layer()->size())
1222 : geometry_; 1297 : geometry_;
1223 } 1298 }
1224 1299
1225 gfx::Point ShellSurface::GetSurfaceOrigin() const { 1300 gfx::Point ShellSurface::GetSurfaceOrigin() const {
1226 gfx::Rect window_bounds = widget_->GetNativeWindow()->bounds(); 1301 gfx::Rect window_bounds = widget_->GetNativeWindow()->bounds();
1227 1302
1228 // If initial bounds were specified then surface origin is always relative 1303 // If initial bounds were specified then surface origin is always relative
1229 // to those bounds. 1304 // to those bounds.
1230 if (!initial_bounds_.IsEmpty()) 1305 if (!initial_bounds_.IsEmpty()) {
1231 return initial_bounds_.origin() - window_bounds.OffsetFromOrigin(); 1306 gfx::Point origin = window_bounds.origin();
1307 wm::ConvertPointToScreen(widget_->GetNativeWindow()->parent(), &origin);
1308 display_.ConvertFromScreenToVirtual(&origin);
1309 return initial_bounds_.origin() - origin.OffsetFromOrigin();
1310 }
1232 1311
1233 gfx::Rect visible_bounds = GetVisibleBounds(); 1312 gfx::Rect visible_bounds = GetVisibleBounds();
1234 switch (resize_component_) { 1313 switch (resize_component_) {
1235 case HTCAPTION: 1314 case HTCAPTION:
1236 return origin_ - visible_bounds.OffsetFromOrigin(); 1315 return origin_ - visible_bounds.OffsetFromOrigin();
1237 case HTBOTTOM: 1316 case HTBOTTOM:
1238 case HTRIGHT: 1317 case HTRIGHT:
1239 case HTBOTTOMRIGHT: 1318 case HTBOTTOMRIGHT:
1240 return gfx::Point() - visible_bounds.OffsetFromOrigin(); 1319 return gfx::Point() - visible_bounds.OffsetFromOrigin();
1241 case HTTOP: 1320 case HTTOP:
(...skipping 21 matching lines...) Expand all
1263 // Return early if the shell is currently managing the bounds of the widget. 1342 // Return early if the shell is currently managing the bounds of the widget.
1264 // 1) When a window is either maximized/fullscreen/pinned, and the bounds 1343 // 1) When a window is either maximized/fullscreen/pinned, and the bounds
1265 // isn't controlled by a client. 1344 // isn't controlled by a client.
1266 ash::wm::WindowState* window_state = 1345 ash::wm::WindowState* window_state =
1267 ash::wm::GetWindowState(widget_->GetNativeWindow()); 1346 ash::wm::GetWindowState(widget_->GetNativeWindow());
1268 if (window_state->IsMaximizedOrFullscreenOrPinned() && 1347 if (window_state->IsMaximizedOrFullscreenOrPinned() &&
1269 !window_state->allow_set_bounds_in_maximized()) { 1348 !window_state->allow_set_bounds_in_maximized()) {
1270 return; 1349 return;
1271 } 1350 }
1272 1351
1273 // 2) When a window is being dragged. 1352 // 2) When a window is being dragged, or is being moved by the shell.
1274 if (IsResizing()) 1353 if (IsResizing() || ignore_widget_bounds_changes_)
1275 return; 1354 return;
1276 1355
1277 // Return early if there is pending configure requests. 1356 // Return early if there is pending configure requests.
1278 if (!pending_configs_.empty() || scoped_configure_) 1357 if (!pending_configs_.empty() || scoped_configure_)
1279 return; 1358 return;
1280 1359
1281 gfx::Rect visible_bounds = GetVisibleBounds(); 1360 gfx::Rect visible_bounds = GetVisibleBounds(); // In virtual coordinates.
1282 gfx::Rect new_widget_bounds = visible_bounds; 1361 gfx::Rect new_widget_bounds = visible_bounds;
1283 1362
1284 // Avoid changing widget origin unless initial bounds were specified and 1363 // Avoid changing widget origin unless initial bounds were specified and
1285 // widget origin is always relative to it. 1364 // widget origin is always relative to it.
1286 if (initial_bounds_.IsEmpty()) 1365 if (initial_bounds_.IsEmpty())
1287 new_widget_bounds.set_origin(widget_->GetWindowBoundsInScreen().origin()); 1366 new_widget_bounds.set_origin(widget_->GetWindowBoundsInScreen().origin());
1288 1367
1368 else {
1369 new_widget_bounds.set_origin(initial_bounds_.origin() +
1370 visible_bounds.OffsetFromOrigin());
1371 display_.ConvertFromVirtualToScreen(&new_widget_bounds);
1372 }
1373
1289 // Update widget origin using the surface origin if the current location of 1374 // Update widget origin using the surface origin if the current location of
1290 // surface is being anchored to one side of the widget as a result of a 1375 // surface is being anchored to one side of the widget as a result of a
1291 // resize operation. 1376 // resize operation.
1292 if (resize_component_ != HTCAPTION) { 1377 if (resize_component_ != HTCAPTION) {
1293 gfx::Point new_widget_origin = 1378 gfx::Point new_widget_origin =
1294 GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin(); 1379 GetSurfaceOrigin() + visible_bounds.OffsetFromOrigin();
1295 wm::ConvertPointToScreen(widget_->GetNativeWindow(), &new_widget_origin); 1380 wm::ConvertPointToScreen(widget_->GetNativeWindow(), &new_widget_origin);
1296 new_widget_bounds.set_origin(new_widget_origin); 1381 new_widget_bounds.set_origin(new_widget_origin);
1297 } 1382 }
1298 1383
1299 // Set |ignore_window_bounds_changes_| as this change to window bounds 1384 // Set |ignore_window_bounds_changes_| as this change to window bounds
1300 // should not result in a configure request. 1385 // should not result in a configure request.
1301 DCHECK(!ignore_window_bounds_changes_); 1386 DCHECK(!ignore_window_bounds_changes_);
1302 ignore_window_bounds_changes_ = true; 1387 ignore_window_bounds_changes_ = true;
1303 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) 1388 if (widget_->GetWindowBoundsInScreen() != new_widget_bounds) {
1304 widget_->SetBounds(new_widget_bounds); 1389 if (!move_resizer_) {
1390 widget_->SetBounds(new_widget_bounds);
1391 UpdateSurfaceBounds();
1392 } else {
1393 // Convert from screen to display coordinates.
1394 gfx::Point origin = new_widget_bounds.origin();
1395 wm::ConvertPointFromScreen(widget_->GetNativeWindow()->parent(), &origin);
1396 new_widget_bounds.set_origin(origin);
1397
1398 // Move the window relative to the current display.
1399 widget_->GetNativeWindow()->SetBounds(new_widget_bounds);
1400 UpdateSurfaceBounds();
1401
1402 // Render phantom windows when beyond the current display.
1403 move_resizer_->Drag(GetMouseLocation(), 0);
1404 }
1405 }
1406
1305 ignore_window_bounds_changes_ = false; 1407 ignore_window_bounds_changes_ = false;
1408 }
1306 1409
1307 // A change to the widget size requires surface bounds to be re-adjusted. 1410 void ShellSurface::UpdateSurfaceBounds() {
1308 surface_->window()->SetBounds( 1411 surface_->window()->SetBounds(
1309 gfx::Rect(GetSurfaceOrigin(), surface_->window()->layer()->size())); 1412 gfx::Rect(GetSurfaceOrigin(), surface_->window()->layer()->size()));
1310 } 1413 }
1311 1414
1312 void ShellSurface::UpdateShadow() { 1415 void ShellSurface::UpdateShadow() {
1313 if (!widget_) 1416 if (!widget_)
1314 return; 1417 return;
1315 aura::Window* window = widget_->GetNativeWindow(); 1418 aura::Window* window = widget_->GetNativeWindow();
1316 if (shadow_content_bounds_.IsEmpty()) { 1419 if (shadow_content_bounds_.IsEmpty()) {
1317 wm::SetShadowType(window, wm::SHADOW_TYPE_NONE); 1420 wm::SetShadowType(window, wm::SHADOW_TYPE_NONE);
1318 if (shadow_underlay_) 1421 if (shadow_underlay_)
1319 shadow_underlay_->Hide(); 1422 shadow_underlay_->Hide();
1320 } else { 1423 } else {
1321 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR); 1424 wm::SetShadowType(window, wm::SHADOW_TYPE_RECTANGULAR);
1322 1425
1323 // TODO(oshima): Adjust the coordinates from client screen to
1324 // chromeos screen when multi displays are supported.
1325 gfx::Point origin = window->bounds().origin(); 1426 gfx::Point origin = window->bounds().origin();
1326 gfx::Point shadow_origin = shadow_content_bounds_.origin(); 1427 gfx::Point shadow_origin = shadow_content_bounds_.origin();
1428
1429 display_.ConvertFromVirtualToScreen(&shadow_origin);
1430 wm::ConvertPointFromScreen(window->parent(), &shadow_origin);
1327 shadow_origin -= origin.OffsetFromOrigin(); 1431 shadow_origin -= origin.OffsetFromOrigin();
1328 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds_.size()); 1432 gfx::Rect shadow_bounds(shadow_origin, shadow_content_bounds_.size());
1329 1433
1330 // Always create and show the underlay, even in maximized/fullscreen. 1434 // Always create and show the underlay, even in maximized/fullscreen.
1331 if (!shadow_underlay_) { 1435 if (!shadow_underlay_) {
1332 shadow_underlay_ = new aura::Window(nullptr); 1436 shadow_underlay_ = new aura::Window(nullptr);
1333 shadow_underlay_event_handler_ = 1437 shadow_underlay_event_handler_ =
1334 base::MakeUnique<ShadowUnderlayEventHandler>(); 1438 base::MakeUnique<ShadowUnderlayEventHandler>();
1335 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get()); 1439 shadow_underlay_->SetTargetHandler(shadow_underlay_event_handler_.get());
1336 DCHECK(shadow_underlay_->owned_by_parent()); 1440 DCHECK(shadow_underlay_->owned_by_parent());
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1390 shadow_overlay_->Init(ui::LAYER_NOT_DRAWN); 1494 shadow_overlay_->Init(ui::LAYER_NOT_DRAWN);
1391 shadow_overlay_->layer()->Add(shadow->layer()); 1495 shadow_overlay_->layer()->Add(shadow->layer());
1392 window->AddChild(shadow_overlay_); 1496 window->AddChild(shadow_overlay_);
1393 shadow_overlay_->Show(); 1497 shadow_overlay_->Show();
1394 } 1498 }
1395 shadow_overlay_->SetBounds(shadow_bounds); 1499 shadow_overlay_->SetBounds(shadow_bounds);
1396 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size())); 1500 shadow->SetContentBounds(gfx::Rect(shadow_bounds.size()));
1397 } 1501 }
1398 } 1502 }
1399 1503
1504 gfx::Point ShellSurface::GetMouseLocation() const {
1505 aura::Window* const root_window = widget_->GetNativeWindow()->GetRootWindow();
1506 gfx::Point location =
1507 root_window->GetHost()->dispatcher()->GetLastMouseLocationInRoot();
1508 aura::Window::ConvertPointToTarget(
1509 root_window, widget_->GetNativeWindow()->parent(), &location);
1510 return location;
1511 }
1512
1400 } // namespace exo 1513 } // namespace exo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698