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

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

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

Powered by Google App Engine
This is Rietveld 408576698