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

Side by Side Diff: ash/common/wm/workspace/workspace_window_resizer.cc

Issue 2700523004: Remove docked windows entirely in M59. (Closed)
Patch Set: oshima + mfomitchev comments Created 3 years, 9 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ash/common/wm/workspace/workspace_window_resizer.h" 5 #include "ash/common/wm/workspace/workspace_window_resizer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "ash/common/ash_switches.h"
13 #include "ash/common/metrics/user_metrics_action.h" 12 #include "ash/common/metrics/user_metrics_action.h"
14 #include "ash/common/wm/default_window_resizer.h" 13 #include "ash/common/wm/default_window_resizer.h"
15 #include "ash/common/wm/dock/docked_window_layout_manager.h"
16 #include "ash/common/wm/dock/docked_window_resizer.h"
17 #include "ash/common/wm/panels/panel_window_resizer.h" 14 #include "ash/common/wm/panels/panel_window_resizer.h"
18 #include "ash/common/wm/window_positioning_utils.h" 15 #include "ash/common/wm/window_positioning_utils.h"
19 #include "ash/common/wm/window_state.h" 16 #include "ash/common/wm/window_state.h"
20 #include "ash/common/wm/wm_event.h" 17 #include "ash/common/wm/wm_event.h"
21 #include "ash/common/wm/wm_screen_util.h" 18 #include "ash/common/wm/wm_screen_util.h"
22 #include "ash/common/wm/workspace/phantom_window_controller.h" 19 #include "ash/common/wm/workspace/phantom_window_controller.h"
23 #include "ash/common/wm/workspace/two_step_edge_cycler.h" 20 #include "ash/common/wm/workspace/two_step_edge_cycler.h"
24 #include "ash/common/wm_lookup.h" 21 #include "ash/common/wm_lookup.h"
25 #include "ash/common/wm_shell.h" 22 #include "ash/common/wm_shell.h"
26 #include "ash/common/wm_window.h" 23 #include "ash/common/wm_window.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 // implement proper transition from one resizer to another during or at the 57 // implement proper transition from one resizer to another during or at the
61 // end of the drag. This also causes http://crbug.com/247085. 58 // end of the drag. This also causes http://crbug.com/247085.
62 // It seems the only thing the panel or dock resizer needs to do is notify the 59 // It seems the only thing the panel or dock resizer needs to do is notify the
63 // layout manager when a docked window is being dragged. We should have a 60 // layout manager when a docked window is being dragged. We should have a
64 // better way of doing this, perhaps by having a way of observing drags or 61 // better way of doing this, perhaps by having a way of observing drags or
65 // having a generic drag window wrapper which informs a layout manager that a 62 // having a generic drag window wrapper which informs a layout manager that a
66 // drag has started or stopped. 63 // drag has started or stopped.
67 // It may be possible to refactor and eliminate chaining. 64 // It may be possible to refactor and eliminate chaining.
68 std::unique_ptr<WindowResizer> window_resizer; 65 std::unique_ptr<WindowResizer> window_resizer;
69 66
70 if (!window_state->IsNormalOrSnapped() && !window_state->IsDocked()) 67 if (!window_state->IsNormalOrSnapped())
71 return std::unique_ptr<WindowResizer>(); 68 return std::unique_ptr<WindowResizer>();
72 69
73 int bounds_change = 70 int bounds_change =
74 WindowResizer::GetBoundsChangeForWindowComponent(window_component); 71 WindowResizer::GetBoundsChangeForWindowComponent(window_component);
75 if (bounds_change == WindowResizer::kBoundsChangeDirection_None) 72 if (bounds_change == WindowResizer::kBoundsChangeDirection_None)
76 return std::unique_ptr<WindowResizer>(); 73 return std::unique_ptr<WindowResizer>();
77 74
78 window_state->CreateDragDetails(point_in_parent, window_component, source); 75 window_state->CreateDragDetails(point_in_parent, window_component, source);
79 const int parent_shell_window_id = 76 const int parent_shell_window_id =
80 window->GetParent() ? window->GetParent()->GetShellWindowId() : -1; 77 window->GetParent() ? window->GetParent()->GetShellWindowId() : -1;
81 if (window->GetParent() && 78 if (window->GetParent() &&
82 (parent_shell_window_id == kShellWindowId_DefaultContainer || 79 (parent_shell_window_id == kShellWindowId_DefaultContainer ||
83 parent_shell_window_id == kShellWindowId_DockedContainer ||
84 parent_shell_window_id == kShellWindowId_PanelContainer)) { 80 parent_shell_window_id == kShellWindowId_PanelContainer)) {
85 window_resizer.reset( 81 window_resizer.reset(
86 WorkspaceWindowResizer::Create(window_state, std::vector<WmWindow*>())); 82 WorkspaceWindowResizer::Create(window_state, std::vector<WmWindow*>()));
87 } else { 83 } else {
88 window_resizer.reset(DefaultWindowResizer::Create(window_state)); 84 window_resizer.reset(DefaultWindowResizer::Create(window_state));
89 } 85 }
90 window_resizer = window->GetShell()->CreateDragWindowResizer( 86 window_resizer = window->GetShell()->CreateDragWindowResizer(
91 std::move(window_resizer), window_state); 87 std::move(window_resizer), window_state);
92 if (window->GetType() == ui::wm::WINDOW_TYPE_PANEL) 88 if (window->GetType() == ui::wm::WINDOW_TYPE_PANEL) {
93 window_resizer.reset( 89 window_resizer.reset(
94 PanelWindowResizer::Create(window_resizer.release(), window_state)); 90 PanelWindowResizer::Create(window_resizer.release(), window_state));
95 if (window_resizer && window->GetParent() && !window->GetTransientParent() &&
96 (parent_shell_window_id == kShellWindowId_DefaultContainer ||
97 parent_shell_window_id == kShellWindowId_DockedContainer ||
98 parent_shell_window_id == kShellWindowId_PanelContainer)) {
99 window_resizer.reset(
100 DockedWindowResizer::Create(window_resizer.release(), window_state));
101 } 91 }
102 return window_resizer; 92 return window_resizer;
103 } 93 }
104 94
105 namespace { 95 namespace {
106 96
107 // Snapping distance used instead of WorkspaceWindowResizer::kScreenEdgeInset 97 // Snapping distance used instead of WorkspaceWindowResizer::kScreenEdgeInset
108 // when resizing a window using touchscreen. 98 // when resizing a window using touchscreen.
109 const int kScreenEdgeInsetForTouchDrag = 32; 99 const int kScreenEdgeInsetForTouchDrag = 32;
110 100
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 return; 372 return;
383 } 373 }
384 const bool in_original_root = !root || root == GetTarget()->GetRootWindow(); 374 const bool in_original_root = !root || root == GetTarget()->GetRootWindow();
385 // Hide a phantom window for snapping if the cursor is in another root window. 375 // Hide a phantom window for snapping if the cursor is in another root window.
386 if (in_original_root) { 376 if (in_original_root) {
387 UpdateSnapPhantomWindow(location_in_parent, bounds); 377 UpdateSnapPhantomWindow(location_in_parent, bounds);
388 } else { 378 } else {
389 snap_type_ = SNAP_NONE; 379 snap_type_ = SNAP_NONE;
390 snap_phantom_window_controller_.reset(); 380 snap_phantom_window_controller_.reset();
391 edge_cycler_.reset(); 381 edge_cycler_.reset();
392 SetDraggedWindowDocked(false);
393 } 382 }
394 } 383 }
395 384
396 void WorkspaceWindowResizer::CompleteDrag() { 385 void WorkspaceWindowResizer::CompleteDrag() {
397 if (!did_move_or_resize_) 386 if (!did_move_or_resize_)
398 return; 387 return;
399 388
400 window_state()->set_bounds_changed_by_user(true); 389 window_state()->set_bounds_changed_by_user(true);
401 snap_phantom_window_controller_.reset(); 390 snap_phantom_window_controller_.reset();
402 391
403 // If the window's state type changed over the course of the drag do not snap 392 // If the window's state type changed over the course of the drag do not snap
404 // the window. This happens when the user minimizes or maximizes the window 393 // the window. This happens when the user minimizes or maximizes the window
405 // using a keyboard shortcut while dragging it. 394 // using a keyboard shortcut while dragging it.
406 if (window_state()->GetStateType() != details().initial_state_type) 395 if (window_state()->GetStateType() != details().initial_state_type)
407 return; 396 return;
408 397
409 bool snapped = false; 398 bool snapped = false;
410 if (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT) { 399 if (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT) {
411 if (!window_state()->HasRestoreBounds()) { 400 if (!window_state()->HasRestoreBounds()) {
412 gfx::Rect initial_bounds = GetTarget()->GetParent()->ConvertRectToScreen( 401 gfx::Rect initial_bounds = GetTarget()->GetParent()->ConvertRectToScreen(
413 details().initial_bounds_in_parent); 402 details().initial_bounds_in_parent);
414 window_state()->SetRestoreBoundsInScreen( 403 window_state()->SetRestoreBoundsInScreen(
415 details().restore_bounds.IsEmpty() ? initial_bounds 404 details().restore_bounds.IsEmpty() ? initial_bounds
416 : details().restore_bounds); 405 : details().restore_bounds);
417 } 406 }
418 if (!dock_layout_->is_dragged_window_docked()) { 407 // TODO(oshima): Add event source type to WMEvent and move
419 // TODO(oshima): Add event source type to WMEvent and move 408 // metrics recording inside WindowState::OnWMEvent.
420 // metrics recording inside WindowState::OnWMEvent. 409 const wm::WMEvent event(snap_type_ == SNAP_LEFT ? wm::WM_EVENT_SNAP_LEFT
421 const wm::WMEvent event(snap_type_ == SNAP_LEFT 410 : wm::WM_EVENT_SNAP_RIGHT);
422 ? wm::WM_EVENT_SNAP_LEFT 411 window_state()->OnWMEvent(&event);
423 : wm::WM_EVENT_SNAP_RIGHT); 412 shell_->RecordUserMetricsAction(snap_type_ == SNAP_LEFT
424 window_state()->OnWMEvent(&event); 413 ? UMA_DRAG_MAXIMIZE_LEFT
425 shell_->RecordUserMetricsAction(snap_type_ == SNAP_LEFT 414 : UMA_DRAG_MAXIMIZE_RIGHT);
426 ? UMA_DRAG_MAXIMIZE_LEFT 415 snapped = true;
427 : UMA_DRAG_MAXIMIZE_RIGHT);
428 snapped = true;
429 }
430 } 416 }
431 417
432 if (!snapped) { 418 if (!snapped) {
433 if (window_state()->IsSnapped()) { 419 if (window_state()->IsSnapped()) {
434 // Keep the window snapped if the user resizes the window such that the 420 // Keep the window snapped if the user resizes the window such that the
435 // window has valid bounds for a snapped window. Always unsnap the window 421 // window has valid bounds for a snapped window. Always unsnap the window
436 // if the user dragged the window via the caption area because doing this 422 // if the user dragged the window via the caption area because doing this
437 // is slightly less confusing. 423 // is slightly less confusing.
438 if (details().window_component == HTCAPTION || 424 if (details().window_component == HTCAPTION ||
439 !AreBoundsValidSnappedBounds(window_state()->GetStateType(), 425 !AreBoundsValidSnappedBounds(window_state()->GetStateType(),
440 GetTarget()->GetBounds())) { 426 GetTarget()->GetBounds())) {
441 // Set the window to WINDOW_STATE_TYPE_NORMAL but keep the 427 // Set the window to WINDOW_STATE_TYPE_NORMAL but keep the
442 // window at the bounds that the user has moved/resized the 428 // window at the bounds that the user has moved/resized the
443 // window to. 429 // window to.
444 window_state()->SaveCurrentBoundsForRestore(); 430 window_state()->SaveCurrentBoundsForRestore();
445 window_state()->Restore(); 431 window_state()->Restore();
446 } 432 }
447 } else if (!dock_layout_->is_dragged_window_docked()) { 433 } else {
448 // The window was not snapped and is not snapped. This is a user 434 // The window was not snapped and is not snapped. This is a user
449 // resize/drag and so the current bounds should be maintained, clearing 435 // resize/drag and so the current bounds should be maintained, clearing
450 // any prior restore bounds. When the window is docked the restore bound 436 // any prior restore bounds. When the window is docked the restore bound
451 // must be kept so the docked state can be reverted properly. 437 // must be kept so the docked state can be reverted properly.
452 window_state()->ClearRestoreBounds(); 438 window_state()->ClearRestoreBounds();
453 } 439 }
454 } 440 }
455 } 441 }
456 442
457 void WorkspaceWindowResizer::RevertDrag() { 443 void WorkspaceWindowResizer::RevertDrag() {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 weak_ptr_factory_(this) { 489 weak_ptr_factory_(this) {
504 DCHECK(details().is_resizable); 490 DCHECK(details().is_resizable);
505 491
506 // A mousemove should still show the cursor even if the window is 492 // A mousemove should still show the cursor even if the window is
507 // being moved or resized with touch, so do not lock the cursor. 493 // being moved or resized with touch, so do not lock the cursor.
508 if (details().source != aura::client::WINDOW_MOVE_SOURCE_TOUCH) { 494 if (details().source != aura::client::WINDOW_MOVE_SOURCE_TOUCH) {
509 shell_->LockCursor(); 495 shell_->LockCursor();
510 did_lock_cursor_ = true; 496 did_lock_cursor_ = true;
511 } 497 }
512 498
513 dock_layout_ = DockedWindowLayoutManager::Get(GetTarget());
514
515 // Only support attaching to the right/bottom. 499 // Only support attaching to the right/bottom.
516 DCHECK(attached_windows_.empty() || (details().window_component == HTRIGHT || 500 DCHECK(attached_windows_.empty() || (details().window_component == HTRIGHT ||
517 details().window_component == HTBOTTOM)); 501 details().window_component == HTBOTTOM));
518 502
519 // TODO: figure out how to deal with window going off the edge. 503 // TODO: figure out how to deal with window going off the edge.
520 504
521 // Calculate sizes so that we can maintain the ratios if we need to resize. 505 // Calculate sizes so that we can maintain the ratios if we need to resize.
522 int total_available = 0; 506 int total_available = 0;
523 for (size_t i = 0; i < attached_windows_.size(); ++i) { 507 for (size_t i = 0; i < attached_windows_.size(); ++i) {
524 gfx::Size min(attached_windows_[i]->GetMinimumSize()); 508 gfx::Size min(attached_windows_[i]->GetMinimumSize());
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 void WorkspaceWindowResizer::UpdateSnapPhantomWindow(const gfx::Point& location, 852 void WorkspaceWindowResizer::UpdateSnapPhantomWindow(const gfx::Point& location,
869 const gfx::Rect& bounds) { 853 const gfx::Rect& bounds) {
870 if (!did_move_or_resize_ || details().window_component != HTCAPTION) 854 if (!did_move_or_resize_ || details().window_component != HTCAPTION)
871 return; 855 return;
872 856
873 SnapType last_type = snap_type_; 857 SnapType last_type = snap_type_;
874 snap_type_ = GetSnapType(location); 858 snap_type_ = GetSnapType(location);
875 if (snap_type_ == SNAP_NONE || snap_type_ != last_type) { 859 if (snap_type_ == SNAP_NONE || snap_type_ != last_type) {
876 snap_phantom_window_controller_.reset(); 860 snap_phantom_window_controller_.reset();
877 edge_cycler_.reset(); 861 edge_cycler_.reset();
878 if (snap_type_ == SNAP_NONE) { 862 if (snap_type_ == SNAP_NONE)
879 SetDraggedWindowDocked(false);
880 return; 863 return;
881 }
882 } 864 }
883 865
884 DCHECK(snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT); 866 DCHECK(snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT);
885 DockedAlignment desired_alignment = (snap_type_ == SNAP_LEFT)
886 ? DOCKED_ALIGNMENT_LEFT
887 : DOCKED_ALIGNMENT_RIGHT;
888 const bool can_dock =
889 ash::switches::DockedWindowsEnabled() &&
890 dock_layout_->CanDockWindow(GetTarget(), desired_alignment) &&
891 dock_layout_->GetAlignmentOfWindow(GetTarget()) != DOCKED_ALIGNMENT_NONE;
892 if (!can_dock) {
893 // If the window cannot be docked, undock the window. This may change the
894 // workspace bounds and hence |snap_type_|.
895 SetDraggedWindowDocked(false);
896 snap_type_ = GetSnapType(location);
897 }
898 const bool can_snap = snap_type_ != SNAP_NONE && window_state()->CanSnap(); 867 const bool can_snap = snap_type_ != SNAP_NONE && window_state()->CanSnap();
899 if (!can_snap && !can_dock) { 868 if (!can_snap) {
900 snap_type_ = SNAP_NONE; 869 snap_type_ = SNAP_NONE;
901 snap_phantom_window_controller_.reset(); 870 snap_phantom_window_controller_.reset();
902 edge_cycler_.reset(); 871 edge_cycler_.reset();
903 return; 872 return;
904 } 873 }
905 if (!edge_cycler_) { 874 if (!edge_cycler_) {
906 edge_cycler_.reset(new TwoStepEdgeCycler( 875 edge_cycler_.reset(new TwoStepEdgeCycler(
907 location, snap_type_ == SNAP_LEFT 876 location, snap_type_ == SNAP_LEFT
908 ? TwoStepEdgeCycler::DIRECTION_LEFT 877 ? TwoStepEdgeCycler::DIRECTION_LEFT
909 : TwoStepEdgeCycler::DIRECTION_RIGHT)); 878 : TwoStepEdgeCycler::DIRECTION_RIGHT));
910 } else { 879 } else {
911 edge_cycler_->OnMove(location); 880 edge_cycler_->OnMove(location);
912 } 881 }
913 882
914 // Update phantom window with snapped or docked guide bounds. 883 // Update phantom window with snapped or docked guide bounds.
915 // Windows that cannot be snapped or are less wide than kMaxDockWidth can get 884 // Windows that cannot be snapped or are less wide than kMaxDockWidth can get
916 // docked without going through a snapping sequence. 885 // docked without going through a snapping sequence.
917 gfx::Rect phantom_bounds; 886 gfx::Rect phantom_bounds =
varkha 2017/02/28 00:59:02 Can be const.
afakhry 2017/03/09 22:28:27 Done.
918 const bool should_dock = 887 (snap_type_ == SNAP_LEFT)
919 can_dock && (!can_snap || 888 ? wm::GetDefaultLeftSnappedWindowBoundsInParent(GetTarget())
920 GetTarget()->GetBounds().width() <= 889 : wm::GetDefaultRightSnappedWindowBoundsInParent(GetTarget());
921 DockedWindowLayoutManager::kMaxDockWidth ||
922 edge_cycler_->use_second_mode() ||
923 dock_layout_->is_dragged_window_docked());
924 if (should_dock) {
925 SetDraggedWindowDocked(true);
926 phantom_bounds = GetTarget()->GetParent()->ConvertRectFromScreen(
927 dock_layout_->dragged_bounds());
928 } else {
929 phantom_bounds =
930 (snap_type_ == SNAP_LEFT)
931 ? wm::GetDefaultLeftSnappedWindowBoundsInParent(GetTarget())
932 : wm::GetDefaultRightSnappedWindowBoundsInParent(GetTarget());
933 }
934 890
935 if (!snap_phantom_window_controller_) { 891 if (!snap_phantom_window_controller_) {
936 snap_phantom_window_controller_.reset( 892 snap_phantom_window_controller_.reset(
937 new PhantomWindowController(GetTarget())); 893 new PhantomWindowController(GetTarget()));
938 } 894 }
939 snap_phantom_window_controller_->Show( 895 snap_phantom_window_controller_->Show(
940 GetTarget()->GetParent()->ConvertRectToScreen(phantom_bounds)); 896 GetTarget()->GetParent()->ConvertRectToScreen(phantom_bounds));
941 } 897 }
942 898
943 void WorkspaceWindowResizer::RestackWindows() { 899 void WorkspaceWindowResizer::RestackWindows() {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
986 inset_right = kScreenEdgeInsetForTouchDrag; 942 inset_right = kScreenEdgeInsetForTouchDrag;
987 area.Inset(inset_left, 0, inset_right, 0); 943 area.Inset(inset_left, 0, inset_right, 0);
988 } 944 }
989 if (location.x() <= area.x()) 945 if (location.x() <= area.x())
990 return SNAP_LEFT; 946 return SNAP_LEFT;
991 if (location.x() >= area.right() - 1) 947 if (location.x() >= area.right() - 1)
992 return SNAP_RIGHT; 948 return SNAP_RIGHT;
993 return SNAP_NONE; 949 return SNAP_NONE;
994 } 950 }
995 951
996 void WorkspaceWindowResizer::SetDraggedWindowDocked(bool should_dock) {
997 if (should_dock) {
998 if (!dock_layout_->is_dragged_window_docked()) {
999 window_state()->set_bounds_changed_by_user(false);
1000 dock_layout_->DockDraggedWindow(GetTarget());
1001 }
1002 } else {
1003 if (dock_layout_->is_dragged_window_docked()) {
1004 dock_layout_->UndockDraggedWindow();
1005 window_state()->set_bounds_changed_by_user(true);
1006 }
1007 }
1008 }
1009
1010 bool WorkspaceWindowResizer::AreBoundsValidSnappedBounds( 952 bool WorkspaceWindowResizer::AreBoundsValidSnappedBounds(
1011 wm::WindowStateType snapped_type, 953 wm::WindowStateType snapped_type,
1012 const gfx::Rect& bounds_in_parent) const { 954 const gfx::Rect& bounds_in_parent) const {
1013 DCHECK(snapped_type == wm::WINDOW_STATE_TYPE_LEFT_SNAPPED || 955 DCHECK(snapped_type == wm::WINDOW_STATE_TYPE_LEFT_SNAPPED ||
1014 snapped_type == wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED); 956 snapped_type == wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED);
1015 gfx::Rect snapped_bounds = wm::GetDisplayWorkAreaBoundsInParent(GetTarget()); 957 gfx::Rect snapped_bounds = wm::GetDisplayWorkAreaBoundsInParent(GetTarget());
1016 if (snapped_type == wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED) 958 if (snapped_type == wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED)
1017 snapped_bounds.set_x(snapped_bounds.right() - bounds_in_parent.width()); 959 snapped_bounds.set_x(snapped_bounds.right() - bounds_in_parent.width());
1018 snapped_bounds.set_width(bounds_in_parent.width()); 960 snapped_bounds.set_width(bounds_in_parent.width());
1019 return bounds_in_parent == snapped_bounds; 961 return bounds_in_parent == snapped_bounds;
1020 } 962 }
1021 963
1022 } // namespace ash 964 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698