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

Side by Side Diff: ash/display/extended_mouse_warp_controller.cc

Issue 1823913002: Allow moving cursors between connected displays. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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 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 "ash/display/extended_mouse_warp_controller.h" 5 #include "ash/display/extended_mouse_warp_controller.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "ash/display/display_manager.h" 9 #include "ash/display/display_manager.h"
10 #include "ash/display/display_util.h" 10 #include "ash/display/display_util.h"
(...skipping 13 matching lines...) Expand all
24 24
25 // Maximum size on the display edge that initiate snapping phantom window, 25 // Maximum size on the display edge that initiate snapping phantom window,
26 // from the corner of the display. 26 // from the corner of the display.
27 const int kMaximumSnapHeight = 16; 27 const int kMaximumSnapHeight = 16;
28 28
29 // Minimum height of an indicator on the display edge that allows 29 // Minimum height of an indicator on the display edge that allows
30 // dragging a window. If two displays shares the edge smaller than 30 // dragging a window. If two displays shares the edge smaller than
31 // this, entire edge will be used as a draggable space. 31 // this, entire edge will be used as a draggable space.
32 const int kMinimumIndicatorHeight = 200; 32 const int kMinimumIndicatorHeight = 200;
33 33
34 const int kIndicatorThickness = 1;
35
36 // Helper method that maps a gfx::Display to an aura::Window. 34 // Helper method that maps a gfx::Display to an aura::Window.
37 aura::Window* GetRootWindowForDisplayId(int64_t display_id) { 35 aura::Window* GetRootWindowForDisplayId(int64_t display_id) {
38 return Shell::GetInstance() 36 return Shell::GetInstance()
39 ->window_tree_host_manager() 37 ->window_tree_host_manager()
40 ->GetRootWindowForDisplayId(display_id); 38 ->GetRootWindowForDisplayId(display_id);
41 } 39 }
42 40
43 // Helper method that maps an aura::Window to a gfx::Display. 41 // Helper method that maps an aura::Window to display id;
44 gfx::Display GetDisplayFromWindow(aura::Window* window) { 42 int64_t GetDisplayIdFromWindow(aura::Window* window) {
45 return gfx::Screen::GetScreen()->GetDisplayNearestWindow(window); 43 return gfx::Screen::GetScreen()->GetDisplayNearestWindow(window).id();
44 }
45
46 // Adjust the edge so that it has |barrier_size| gap at the top to
47 // trigger snap window action.
48 void AdjustSourceEdgeBounds(const gfx::Rect& display_bounds,
49 int barrier_size,
50 gfx::Rect* edge) {
51 DCHECK_GT(edge->height(), edge->width());
52 int target_y = display_bounds.y() + barrier_size;
53 if (target_y < edge->y())
54 return;
55
56 int available_height = edge->height() - kMinimumIndicatorHeight;
57 if (available_height <= 0)
58 return;
59 edge->Inset(0, std::min(available_height, target_y - edge->y()), 0, 0);
46 } 60 }
47 61
48 } // namespace 62 } // namespace
49 63
50 ExtendedMouseWarpController::WarpRegion::WarpRegion( 64 ExtendedMouseWarpController::WarpRegion::WarpRegion(
51 int64_t a_display_id, 65 int64_t a_display_id,
52 int64_t b_display_id, 66 int64_t b_display_id,
53 const gfx::Rect& a_indicator_bounds, 67 const gfx::Rect& a_indicator_bounds,
54 const gfx::Rect& b_indicator_bounds) 68 const gfx::Rect& b_indicator_bounds)
55 : a_display_id_(a_display_id), 69 : a_display_id_(a_display_id),
56 b_display_id_(b_display_id), 70 b_display_id_(b_display_id),
57 a_indicator_bounds_(a_indicator_bounds), 71 a_indicator_bounds_(a_indicator_bounds),
58 b_indicator_bounds_(b_indicator_bounds), 72 b_indicator_bounds_(b_indicator_bounds),
59 shared_display_edge_indicator_(nullptr) { 73 shared_display_edge_indicator_(nullptr) {
60 // Initialize edge bounds from indicator bounds. 74 // Initialize edge bounds from indicator bounds.
61 aura::Window* a_window = GetRootWindowForDisplayId(a_display_id); 75 aura::Window* a_window = GetRootWindowForDisplayId(a_display_id);
62 aura::Window* b_window = GetRootWindowForDisplayId(b_display_id); 76 aura::Window* b_window = GetRootWindowForDisplayId(b_display_id);
63 77
64 AshWindowTreeHost* a_ash_host = GetRootWindowController(a_window)->ash_host(); 78 AshWindowTreeHost* a_ash_host = GetRootWindowController(a_window)->ash_host();
65 AshWindowTreeHost* b_ash_host = GetRootWindowController(b_window)->ash_host(); 79 AshWindowTreeHost* b_ash_host = GetRootWindowController(b_window)->ash_host();
66 80
67 a_edge_bounds_in_native_ = 81 a_edge_bounds_in_native_ =
68 GetNativeEdgeBounds(a_ash_host, a_indicator_bounds); 82 GetNativeEdgeBounds(a_ash_host, a_indicator_bounds);
69 b_edge_bounds_in_native_ = 83 b_edge_bounds_in_native_ =
70 GetNativeEdgeBounds(b_ash_host, b_indicator_bounds); 84 GetNativeEdgeBounds(b_ash_host, b_indicator_bounds);
71 } 85 }
72 86
73 ExtendedMouseWarpController::WarpRegion::~WarpRegion() {} 87 ExtendedMouseWarpController::WarpRegion::~WarpRegion() {}
74 88
89 const gfx::Rect&
90 ExtendedMouseWarpController::WarpRegion::GetIndicatorBoundsForTest(
91 int64_t id) const {
92 if (a_display_id_ == id)
93 return a_indicator_bounds_;
94 CHECK_EQ(b_display_id_, id);
95 return b_indicator_bounds_;
96 }
97
75 ExtendedMouseWarpController::ExtendedMouseWarpController( 98 ExtendedMouseWarpController::ExtendedMouseWarpController(
76 aura::Window* drag_source) 99 aura::Window* drag_source)
77 : drag_source_root_(drag_source), 100 : drag_source_root_(drag_source),
78 allow_non_native_event_(false) { 101 allow_non_native_event_(false) {
79 ash::DisplayManager* display_manager = 102 ash::DisplayManager* display_manager =
80 Shell::GetInstance()->display_manager(); 103 Shell::GetInstance()->display_manager();
81 104 int64_t drag_source_id = drag_source ? GetDisplayIdFromWindow(drag_source)
82 // TODO(oshima): Use ComputeBondary instead and try all combinations. 105 : gfx::Display::kInvalidDisplayID;
83 for (const auto& placement : 106 DisplayList display_list = display_manager->active_display_list();
84 display_manager->GetCurrentDisplayLayout().placement_list) { 107 while (display_list.size() > 0) {
85 DisplayPlacement::Position position = placement.position; 108 gfx::Display display = display_list.back();
stevenjb 2016/03/24 18:08:29 Maybe add a comment here? I wrote something simila
86 const gfx::Display& a = 109 display_list.pop_back();
87 display_manager->GetDisplayForId(placement.parent_display_id); 110 for (const gfx::Display& peer : display_list) {
88 const gfx::Display& b = 111 scoped_ptr<WarpRegion> region =
89 display_manager->GetDisplayForId(placement.display_id); 112 CreateWarpRegion(display, peer, drag_source_id);
90 113 if (region)
91 if (position == DisplayPlacement::TOP || 114 AddWarpRegion(std::move(region), drag_source != nullptr);
92 position == DisplayPlacement::BOTTOM) {
93 AddWarpRegion(CreateHorizontalEdgeBounds(a, b, position),
94 drag_source != nullptr);
95 } else {
96 AddWarpRegion(CreateVerticalEdgeBounds(a, b, position),
97 drag_source != nullptr);
98 } 115 }
99 } 116 }
100 } 117 }
101 118
102 ExtendedMouseWarpController::~ExtendedMouseWarpController() { 119 ExtendedMouseWarpController::~ExtendedMouseWarpController() {
103 } 120 }
104 121
105 bool ExtendedMouseWarpController::WarpMouseCursor(ui::MouseEvent* event) { 122 bool ExtendedMouseWarpController::WarpMouseCursor(ui::MouseEvent* event) {
106 if (gfx::Screen::GetScreen()->GetNumDisplays() <= 1 || !enabled_) 123 if (gfx::Screen::GetScreen()->GetNumDisplays() <= 1 || !enabled_)
107 return false; 124 return false;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 GetRootWindowController(dst_window)->ash_host(); 189 GetRootWindowController(dst_window)->ash_host();
173 190
174 MoveCursorTo(target_ash_host, point_in_screen, update_mouse_location_now); 191 MoveCursorTo(target_ash_host, point_in_screen, update_mouse_location_now);
175 return true; 192 return true;
176 } 193 }
177 194
178 return false; 195 return false;
179 } 196 }
180 197
181 scoped_ptr<ExtendedMouseWarpController::WarpRegion> 198 scoped_ptr<ExtendedMouseWarpController::WarpRegion>
182 ExtendedMouseWarpController::CreateHorizontalEdgeBounds( 199 ExtendedMouseWarpController::CreateWarpRegion(const gfx::Display& a,
183 const gfx::Display& a, 200 const gfx::Display& b,
184 const gfx::Display& b, 201 int64_t drag_source_id) {
185 DisplayPlacement::Position position) { 202 gfx::Rect a_edge;
186 bool from_a = a.id() == GetDisplayFromWindow(drag_source_root_).id(); 203 gfx::Rect b_edge;
204 int snap_barrier = drag_source_id == gfx::Display::kInvalidDisplayID
205 ? 0
206 : kMaximumSnapHeight;
187 207
188 const gfx::Rect& a_bounds = a.bounds(); 208 if (!ComputeBoundary(a, b, &a_edge, &b_edge))
189 const gfx::Rect& b_bounds = b.bounds(); 209 return nullptr;
190 210
191 gfx::Rect a_indicator_bounds; 211 // Creates the snap window barrirer only when horizontally connected.
192 a_indicator_bounds.set_x(std::max(a_bounds.x(), b_bounds.x())); 212 if (a_edge.height() > a_edge.width()) {
193 a_indicator_bounds.set_width(std::min(a_bounds.right(), b_bounds.right()) - 213 if (drag_source_id == a.id())
194 a_indicator_bounds.x()); 214 AdjustSourceEdgeBounds(a.bounds(), snap_barrier, &a_edge);
195 a_indicator_bounds.set_height(kIndicatorThickness); 215 else if (drag_source_id == b.id())
196 a_indicator_bounds.set_y( 216 AdjustSourceEdgeBounds(b.bounds(), snap_barrier, &b_edge);
197 position == DisplayPlacement::TOP 217 }
198 ? a_bounds.y() - (from_a ? 0 : kIndicatorThickness)
199 : a_bounds.bottom() - (from_a ? kIndicatorThickness : 0));
200 218
201 gfx::Rect b_indicator_bounds; 219 return make_scoped_ptr(new WarpRegion(a.id(), b.id(), a_edge, b_edge));
202 b_indicator_bounds = a_indicator_bounds;
203 b_indicator_bounds.set_height(kIndicatorThickness);
204 b_indicator_bounds.set_y(
205 position == DisplayPlacement::TOP
206 ? a_bounds.y() - (from_a ? kIndicatorThickness : 0)
207 : a_bounds.bottom() - (from_a ? 0 : kIndicatorThickness));
208
209 return make_scoped_ptr(
210 new WarpRegion(a.id(), b.id(), a_indicator_bounds, b_indicator_bounds));
211 }
212
213 scoped_ptr<ExtendedMouseWarpController::WarpRegion>
214 ExtendedMouseWarpController::CreateVerticalEdgeBounds(
215 const gfx::Display& a,
216 const gfx::Display& b,
217 DisplayPlacement::Position position) {
218 int snap_height = drag_source_root_ ? kMaximumSnapHeight : 0;
219 bool in_a = a.id() == GetDisplayFromWindow(drag_source_root_).id();
220
221 const gfx::Rect& a_bounds = a.bounds();
222 const gfx::Rect& b_bounds = b.bounds();
223
224 int upper_shared_y = std::max(a_bounds.y(), b_bounds.y());
225 int lower_shared_y = std::min(a_bounds.bottom(), b_bounds.bottom());
226 int shared_height = lower_shared_y - upper_shared_y;
227
228 gfx::Rect a_indicator_bounds;
229 gfx::Rect b_indicator_bounds;
230
231 int dst_x = position == DisplayPlacement::LEFT
232 ? a_bounds.x() - (in_a ? kIndicatorThickness : 0)
233 : a_bounds.right() - (in_a ? 0 : kIndicatorThickness);
234 b_indicator_bounds.SetRect(dst_x, upper_shared_y, kIndicatorThickness,
235 shared_height);
236
237 // The indicator on the source display.
238 a_indicator_bounds.set_width(kIndicatorThickness);
239 a_indicator_bounds.set_x(position == DisplayPlacement::LEFT
240 ? a_bounds.x() - (in_a ? 0 : kIndicatorThickness)
241 : a_bounds.right() -
242 (in_a ? kIndicatorThickness : 0));
243
244 const gfx::Rect& source_bounds = in_a ? a_bounds : b_bounds;
245 int upper_indicator_y = source_bounds.y() + snap_height;
246 int lower_indicator_y = std::min(source_bounds.bottom(), lower_shared_y);
247
248 // This gives a hight that can be used without sacrifying the snap space.
249 int available_space =
250 lower_indicator_y - std::max(upper_shared_y, upper_indicator_y);
251
252 if (shared_height < kMinimumIndicatorHeight) {
253 // If the shared height is smaller than minimum height, use the
254 // entire height.
255 upper_indicator_y = upper_shared_y;
256 } else if (available_space < kMinimumIndicatorHeight) {
257 // Snap to the bottom.
258 upper_indicator_y =
259 std::max(upper_shared_y, lower_indicator_y + kMinimumIndicatorHeight);
260 } else {
261 upper_indicator_y = std::max(upper_indicator_y, upper_shared_y);
262 }
263 a_indicator_bounds.set_y(upper_indicator_y);
264 a_indicator_bounds.set_height(lower_indicator_y - upper_indicator_y);
265
266 return make_scoped_ptr(
267 new WarpRegion(a.id(), b.id(), a_indicator_bounds, b_indicator_bounds));
268 } 220 }
269 221
270 } // namespace ash 222 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698