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

Side by Side Diff: ash/wm/dock/docked_window_resizer.cc

Issue 13896026: Stick windows to sides of workspaces (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Dock with zero width (small fix for shelf auto-hide) Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ash/wm/dock/docked_window_resizer.h"
6
7 #include "ash/ash_switches.h"
8 #include "ash/display/display_controller.h"
9 #include "ash/launcher/launcher.h"
10 #include "ash/root_window_controller.h"
11 #include "ash/screen_ash.h"
12 #include "ash/shelf/shelf_types.h"
13 #include "ash/shelf/shelf_widget.h"
14 #include "ash/shell.h"
15 #include "ash/shell_window_ids.h"
16 #include "ash/wm/coordinate_conversion.h"
17 #include "ash/wm/dock/docked_window_layout_manager.h"
18 #include "ash/wm/property_util.h"
19 #include "ash/wm/window_properties.h"
20 #include "ash/wm/workspace_controller.h"
21 #include "base/command_line.h"
22 #include "ui/aura/client/aura_constants.h"
23 #include "ui/aura/env.h"
24 #include "ui/aura/root_window.h"
25 #include "ui/aura/window.h"
26 #include "ui/aura/window_delegate.h"
27 #include "ui/base/hit_test.h"
28 #include "ui/base/ui_base_types.h"
29 #include "ui/gfx/screen.h"
30 #include "ui/views/widget/widget.h"
31
32 namespace ash {
33
34 namespace {
35
36 // How far we have to drag to undock a window.
37 const int kSnapToDockDistance = 32;
38
39 } // namespace
stevenjb 2013/06/13 17:54:41 nit: 2 spaces before //
varkha 2013/06/13 20:19:14 Done.
40
41 DockedWindowResizer::~DockedWindowResizer() {
42 }
43
44 // static
45 DockedWindowResizer*
46 DockedWindowResizer::Create(WindowResizer* next_window_resizer,
47 aura::Window* window,
48 const gfx::Point& location,
49 int window_component) {
50 Details details(window, location, window_component);
51 return details.is_resizable ?
52 new DockedWindowResizer(next_window_resizer, details) : NULL;
53 }
54
55 void DockedWindowResizer::Drag(const gfx::Point& location, int event_flags) {
56 last_location_ = location;
57 wm::ConvertPointToScreen(GetTarget()->parent(), &last_location_);
58 if (!did_move_or_resize_) {
59 did_move_or_resize_ = true;
60 StartedDragging();
61 }
62 gfx::Point offset;
63 gfx::Rect bounds(CalculateBoundsForDrag(details_, location));
64 MaybeSnapToSide(bounds, &offset);
65 gfx::Point modified_location(location.x() + offset.x(),
66 location.y() + offset.y());
67 next_window_resizer_->Drag(modified_location, event_flags);
68 }
69
70 void DockedWindowResizer::CompleteDrag(int event_flags) {
71 // The root window can change when dragging into a different screen.
72 next_window_resizer_->CompleteDrag(event_flags);
73 FinishDragging();
74 }
75
76 void DockedWindowResizer::RevertDrag() {
77 next_window_resizer_->RevertDrag();
78 FinishDragging();
79 }
80
81 aura::Window* DockedWindowResizer::GetTarget() {
82 return next_window_resizer_->GetTarget();
83 }
84
85 DockedWindowResizer::DockedWindowResizer(WindowResizer* next_window_resizer,
86 const Details& details)
87 : details_(details),
88 next_window_resizer_(next_window_resizer),
89 dock_layout_(NULL),
90 did_move_or_resize_(false) {
91 DCHECK(details_.is_resizable);
92 aura::Window* dock_container = Shell::GetContainer(
93 details.window->GetRootWindow(),
94 internal::kShellWindowId_DockedContainer);
95 DCHECK(dock_container->id() == internal::kShellWindowId_DockedContainer);
96 dock_layout_ = static_cast<internal::DockedWindowLayoutManager*>(
97 dock_container->layout_manager());
98 }
99
100 void DockedWindowResizer::MaybeSnapToSide(const gfx::Rect& bounds,
101 gfx::Point* offset) {
102 aura::Window* dock_container = Shell::GetContainer(
103 wm::GetRootWindowAt(last_location_),
104 internal::kShellWindowId_DockedContainer);
105 DCHECK(dock_container->id() == internal::kShellWindowId_DockedContainer);
106 internal::DockedWindowLayoutManager* dock_layout =
107 static_cast<internal::DockedWindowLayoutManager*>(
108 dock_container->layout_manager());
109
110 internal::DockedAlignment dock_alignment = dock_layout->alignment();
111 if (dock_alignment == internal::DOCKED_ALIGNMENT_NONE) {
112 if (GetTarget() == dock_layout_->dragged_window())
113 dock_alignment = internal::DOCKED_ALIGNMENT_ANY;
114 else
115 return;
stevenjb 2013/06/13 17:54:41 nit: invert if, no else (prefer early exit)
varkha 2013/06/13 20:19:14 Done.
116 }
117
118 gfx::Rect dock_bounds = ScreenAsh::ConvertRectFromScreen(
119 GetTarget()->parent(), dock_container->GetBoundsInScreen());
120
121 switch (dock_alignment) {
122 case internal::DOCKED_ALIGNMENT_LEFT:
123 if (abs(bounds.x() - dock_bounds.x()) < kSnapToDockDistance)
124 offset->set_x(dock_bounds.x() - bounds.x());
125 break;
126 case internal::DOCKED_ALIGNMENT_RIGHT:
127 if (abs(bounds.right() - dock_bounds.right()) < kSnapToDockDistance)
128 offset->set_x(dock_bounds.right() - bounds.right());
129 break;
130 case internal::DOCKED_ALIGNMENT_ANY:
131 if (abs(bounds.x() - dock_bounds.x()) < kSnapToDockDistance)
132 offset->set_x(dock_bounds.x() - bounds.x());
133 if (abs(bounds.right() - dock_bounds.right()) < kSnapToDockDistance)
134 offset->set_x(dock_bounds.right() - bounds.right());
135 break;
136 case internal::DOCKED_ALIGNMENT_NONE:
137 NOTREACHED() << "Nothing to do when no windows are docked";
138 break;
139 }
140 }
141
142 void DockedWindowResizer::StartedDragging() {
143 // Tell the dock layout manager that we are dragging this window.
144 dock_layout_->StartDragging(GetTarget());
145 }
146
147 void DockedWindowResizer::FinishDragging() {
148 if (!did_move_or_resize_)
149 return;
150
151 aura::Window* window = GetTarget();
152 bool should_dock = false;
153 if ((details_.bounds_change & WindowResizer::kBoundsChange_Repositions) &&
154 CommandLine::ForCurrentProcess()->HasSwitch(
155 switches::kAshEnableDockedWindows)) {
156 should_dock = internal::DockedWindowLayoutManager::ShouldWindowDock(
157 window, last_location_);
158 }
159
160 // Check if desired docked state is not same as current.
161 // If not same dock or undock accordingly.
162 if (should_dock !=
163 (window->parent()->id() == internal::kShellWindowId_DockedContainer)) {
164 if (should_dock) {
165 aura::Window* dock_container = Shell::GetContainer(
166 window->GetRootWindow(),
167 internal::kShellWindowId_DockedContainer);
168 dock_container->AddChild(window);
169 } else {
170 // Reparent the window back to workspace.
171 // We need to be careful to give SetDefaultParentByRootWindow location in
172 // the right root window (matching the logic in DragWindowResizer) based
173 // on which root window a mouse pointer is in. We want to undock into the
174 // right screen near the edge of a multiscreen setup (based on where the
175 // mouse is).
176 gfx::Rect near_last_location(last_location_, gfx::Size());
177 // Reparenting will cause Relayout and possible dock shrinking.
178 window->SetDefaultParentByRootWindow(window->GetRootWindow(),
179 near_last_location);
180 // A maximized workspace may be active so we may need to switch
181 // to a parent workspace of the window being dragged out.
182 internal::WorkspaceController* workspace_controller =
183 GetRootWindowController(
184 window->GetRootWindow())->workspace_controller();
185 workspace_controller->SetActiveWorkspaceByWindow(window);
186 }
187 }
188 dock_layout_->FinishDragging();
189 }
190
191 } // namespace aura
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698