Index: ash/display/display_controller.cc |
diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc |
index a4eceb48bb21abb1c6697eb46ab5557eebcdd370..456b831235a36e971c5e3bb6e08f7ee21f7567a8 100644 |
--- a/ash/display/display_controller.cc |
+++ b/ash/display/display_controller.cc |
@@ -9,6 +9,7 @@ |
#include "ash/root_window_controller.h" |
#include "ash/screen_ash.h" |
#include "ash/shell.h" |
+#include "ash/wm/coordinate_conversion.h" |
#include "ash/wm/property_util.h" |
#include "ash/wm/window_util.h" |
#include "base/command_line.h" |
@@ -23,7 +24,8 @@ namespace ash { |
namespace internal { |
DisplayController::DisplayController() |
- : secondary_display_layout_(RIGHT) { |
+ : secondary_display_layout_(RIGHT), |
+ dont_warp_mouse_(false) { |
aura::Env::GetInstance()->display_manager()->AddObserver(this); |
} |
@@ -123,35 +125,41 @@ void DisplayController::SetSecondaryDisplayLayout( |
bool DisplayController::WarpMouseCursorIfNecessary( |
aura::RootWindow* current_root, |
const gfx::Point& point_in_root) { |
- if (root_windows_.size() < 2) |
+ if (root_windows_.size() < 2 || dont_warp_mouse_) |
return false; |
+ // The pointer might be outside the |current_root|. Get the root window where |
+ // the pointer is currently on. |
+ std::pair<aura::RootWindow*, gfx::Point> actual_location = |
+ wm::GetRootWindowRelativeToWindow(current_root, point_in_root); |
+ current_root = actual_location.first; |
+ // Don't use |point_in_root| below. Instead, use |actual_location.second| |
+ // which is in |actual_location.first|'s coordinates. |
+ |
gfx::Rect root_bounds = current_root->bounds(); |
int offset_x = 0; |
int offset_y = 0; |
- if (point_in_root.x() <= root_bounds.x()) { |
- offset_x = -1; |
- } else if (point_in_root.x() >= root_bounds.right() - 1) { |
- offset_x = 1; |
- } else if (point_in_root.y() <= root_bounds.y()) { |
- offset_y = -1; |
- } else if (point_in_root.y() >= root_bounds.bottom() - 1) { |
- offset_y = 1; |
+ if (actual_location.second.x() <= root_bounds.x()) { |
+ // Use -2, not -1, to avoid infinite loop of pointer warp. |
+ offset_x = -2; |
+ } else if (actual_location.second.x() >= root_bounds.right() - 1) { |
+ offset_x = 2; |
+ } else if (actual_location.second.y() <= root_bounds.y()) { |
+ offset_y = -2; |
+ } else if (actual_location.second.y() >= root_bounds.bottom() - 1) { |
+ offset_y = 2; |
} else { |
return false; |
} |
- gfx::Point point_in_screen(point_in_root); |
- aura::client::ScreenPositionClient* screen_position_client = |
- aura::client::GetScreenPositionClient(current_root); |
- screen_position_client->ConvertPointToScreen(current_root, |
- &point_in_screen); |
+ gfx::Point point_in_screen(actual_location.second); |
+ wm::ConvertPointToScreen(current_root, &point_in_screen); |
point_in_screen.Offset(offset_x, offset_y); |
- aura::RootWindow* dst_root = Shell::GetRootWindowAt(point_in_screen); |
+ |
+ aura::RootWindow* dst_root = wm::GetRootWindowAt(point_in_screen); |
gfx::Point point_in_dst_root(point_in_screen); |
+ wm::ConvertPointFromScreen(dst_root, &point_in_dst_root); |
- screen_position_client->ConvertPointFromScreen(dst_root, |
- &point_in_dst_root); |
if (dst_root->bounds().Contains(point_in_dst_root)) { |
DCHECK_NE(dst_root, current_root); |
dst_root->MoveCursorTo(point_in_dst_root); |