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

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 (drag resizer instance) 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
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 const gfx::Point& DockedWindowResizer::GetInitialLocation() const {
86 return details_.initial_location_in_parent;
87 }
88
89 DockedWindowResizer::DockedWindowResizer(WindowResizer* next_window_resizer,
90 const Details& details)
91 : details_(details),
92 next_window_resizer_(next_window_resizer),
93 dock_layout_(NULL),
94 did_move_or_resize_(false) {
95 DCHECK(details_.is_resizable);
96 aura::Window* dock_container = Shell::GetContainer(
97 details.window->GetRootWindow(),
98 internal::kShellWindowId_DockedContainer);
99 DCHECK(dock_container->id() == internal::kShellWindowId_DockedContainer);
100 dock_layout_ = static_cast<internal::DockedWindowLayoutManager*>(
101 dock_container->layout_manager());
102 }
103
104 void DockedWindowResizer::MaybeSnapToSide(const gfx::Rect& bounds,
105 gfx::Point* offset) {
106 aura::Window* dock_container = Shell::GetContainer(
107 wm::GetRootWindowAt(last_location_),
108 internal::kShellWindowId_DockedContainer);
109 DCHECK(dock_container->id() == internal::kShellWindowId_DockedContainer);
110 internal::DockedWindowLayoutManager* dock_layout =
111 static_cast<internal::DockedWindowLayoutManager*>(
112 dock_container->layout_manager());
113
114 internal::DockedAlignment dock_alignment = dock_layout->alignment();
115 if (dock_alignment == internal::DOCKED_ALIGNMENT_NONE) {
116 if (GetTarget() != dock_layout_->dragged_window())
117 return;
118 dock_alignment = internal::DOCKED_ALIGNMENT_ANY;
119 }
120
121 gfx::Rect dock_bounds = ScreenAsh::ConvertRectFromScreen(
122 GetTarget()->parent(), dock_container->GetBoundsInScreen());
123
124 switch (dock_alignment) {
125 case internal::DOCKED_ALIGNMENT_LEFT:
126 if (abs(bounds.x() - dock_bounds.x()) < kSnapToDockDistance)
127 offset->set_x(dock_bounds.x() - bounds.x());
128 break;
129 case internal::DOCKED_ALIGNMENT_RIGHT:
130 if (abs(bounds.right() - dock_bounds.right()) < kSnapToDockDistance)
131 offset->set_x(dock_bounds.right() - bounds.right());
132 break;
133 case internal::DOCKED_ALIGNMENT_ANY:
134 if (abs(bounds.x() - dock_bounds.x()) < kSnapToDockDistance)
135 offset->set_x(dock_bounds.x() - bounds.x());
136 if (abs(bounds.right() - dock_bounds.right()) < kSnapToDockDistance)
137 offset->set_x(dock_bounds.right() - bounds.right());
138 break;
139 case internal::DOCKED_ALIGNMENT_NONE:
140 NOTREACHED() << "Nothing to do when no windows are docked";
141 break;
142 }
143 }
144
145 void DockedWindowResizer::StartedDragging() {
146 // Tell the dock layout manager that we are dragging this window.
147 dock_layout_->StartDragging(GetTarget());
148 }
149
150 void DockedWindowResizer::FinishDragging() {
151 if (!did_move_or_resize_)
152 return;
153
154 aura::Window* window = GetTarget();
155 bool should_dock = false;
156 if ((details_.bounds_change & WindowResizer::kBoundsChange_Repositions) &&
157 CommandLine::ForCurrentProcess()->HasSwitch(
158 switches::kAshEnableDockedWindows)) {
159 should_dock = internal::DockedWindowLayoutManager::ShouldWindowDock(
160 window, last_location_);
161 }
162
163 // Check if desired docked state is not same as current.
164 // If not same dock or undock accordingly.
165 if (should_dock !=
166 (window->parent()->id() == internal::kShellWindowId_DockedContainer)) {
167 if (should_dock) {
168 aura::Window* dock_container = Shell::GetContainer(
169 window->GetRootWindow(),
170 internal::kShellWindowId_DockedContainer);
171 dock_container->AddChild(window);
172 } else {
173 // Reparent the window back to workspace.
174 // We need to be careful to give SetDefaultParentByRootWindow location in
175 // the right root window (matching the logic in DragWindowResizer) based
176 // on which root window a mouse pointer is in. We want to undock into the
177 // right screen near the edge of a multiscreen setup (based on where the
178 // mouse is).
179 gfx::Rect near_last_location(last_location_, gfx::Size());
180 // Reparenting will cause Relayout and possible dock shrinking.
181 window->SetDefaultParentByRootWindow(window->GetRootWindow(),
182 near_last_location);
183 // A maximized workspace may be active so we may need to switch
184 // to a parent workspace of the window being dragged out.
185 internal::WorkspaceController* workspace_controller =
186 GetRootWindowController(
187 window->GetRootWindow())->workspace_controller();
188 workspace_controller->SetActiveWorkspaceByWindow(window);
189 }
190 }
191 dock_layout_->FinishDragging();
192 }
193
194 } // namespace aura
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698