Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |