summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authoryusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-06 18:27:46 +0000
committeryusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-06 18:27:46 +0000
commit7203a5ecc10ca59ef838d4e31dc4566cd1b33780 (patch)
tree60b69c2c4845eebffbeeecf8c9d8280863d81354 /ash
parent8fee1c35d91f2984c9a738008d5728e893ef91a5 (diff)
downloadchromium_src-7203a5ecc10ca59ef838d4e31dc4566cd1b33780.zip
chromium_src-7203a5ecc10ca59ef838d4e31dc4566cd1b33780.tar.gz
chromium_src-7203a5ecc10ca59ef838d4e31dc4566cd1b33780.tar.bz2
Allow the cursor to warp even when a window is dragged.
This is the first step toward implementing crbug.com/136816 (Implement dragging window from one display to another). BUG=136816 TEST=try Review URL: https://chromiumcodereview.appspot.com/10835047 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150116 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/ash.gyp2
-rw-r--r--ash/display/display_controller.cc44
-rw-r--r--ash/display/display_controller.h7
-rw-r--r--ash/display/mouse_cursor_event_filter.cc11
-rw-r--r--ash/display/screen_position_controller.cc3
-rw-r--r--ash/extended_desktop_unittest.cc35
-rw-r--r--ash/screen_ash.cc3
-rw-r--r--ash/shell.cc14
-rw-r--r--ash/shell.h9
-rw-r--r--ash/ui_controls_ash.cc3
-rw-r--r--ash/wm/coordinate_conversion.cc91
-rw-r--r--ash/wm/coordinate_conversion.h53
-rw-r--r--ash/wm/default_window_resizer.cc9
-rw-r--r--ash/wm/stacking_controller.cc3
-rw-r--r--ash/wm/workspace/phantom_window_controller.cc6
-rw-r--r--ash/wm/workspace/workspace_window_resizer.cc33
-rw-r--r--ash/wm/workspace/workspace_window_resizer.h3
17 files changed, 259 insertions, 70 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp
index 2647000..d092ae8 100644
--- a/ash/ash.gyp
+++ b/ash/ash.gyp
@@ -236,6 +236,8 @@
'wm/base_layout_manager.h',
'wm/capture_controller.cc',
'wm/capture_controller.h',
+ 'wm/coordinate_conversion.cc',
+ 'wm/coordinate_conversion.h',
'wm/cursor_manager.cc',
'wm/cursor_manager.h',
'wm/custom_frame_view_ash.cc',
diff --git a/ash/display/display_controller.cc b/ash/display/display_controller.cc
index a4eceb4..456b831 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);
diff --git a/ash/display/display_controller.h b/ash/display/display_controller.h
index 7a151fb..f625ee5 100644
--- a/ash/display/display_controller.h
+++ b/ash/display/display_controller.h
@@ -68,6 +68,10 @@ class ASH_EXPORT DisplayController : public aura::DisplayObserver {
}
void SetSecondaryDisplayLayout(SecondaryDisplayLayout layout);
+ void set_dont_warp_mouse(bool dont_warp_mouse) {
+ dont_warp_mouse_ = dont_warp_mouse;
+ }
+
// Warps the mouse cursor to an alternate root window when the
// |point_in_root|, which is the location of the mouse cursor,
// hits or exceeds the edge of the |root_window| and the mouse cursor
@@ -96,6 +100,9 @@ class ASH_EXPORT DisplayController : public aura::DisplayObserver {
SecondaryDisplayLayout secondary_display_layout_;
+ // If true, the mouse pointer can't move from one display to another.
+ bool dont_warp_mouse_;
+
DISALLOW_COPY_AND_ASSIGN(DisplayController);
};
diff --git a/ash/display/mouse_cursor_event_filter.cc b/ash/display/mouse_cursor_event_filter.cc
index 9b6d297..c103f08 100644
--- a/ash/display/mouse_cursor_event_filter.cc
+++ b/ash/display/mouse_cursor_event_filter.cc
@@ -31,9 +31,14 @@ bool MouseCursorEventFilter::PreHandleKeyEvent(aura::Window* target,
bool MouseCursorEventFilter::PreHandleMouseEvent(aura::Window* target,
aura::MouseEvent* event) {
- if (event->type() != ui::ET_MOUSE_MOVED ||
- ash::Shell::GetInstance()->cursor_manager()->is_cursor_locked())
- return false;
+ // Handle both MOVED and DRAGGED events here because when the mouse pointer
+ // enters the other root window while dragging, the underlying window system
+ // (at least X11) stops generating a ui::ET_MOUSE_MOVED event.
+ if (event->type() != ui::ET_MOUSE_MOVED &&
+ event->type() != ui::ET_MOUSE_DRAGGED) {
+ return false;
+ }
+
aura::RootWindow* current_root = target->GetRootWindow();
gfx::Point location_in_root(event->location());
aura::Window::ConvertPointToWindow(target, current_root, &location_in_root);
diff --git a/ash/display/screen_position_controller.cc b/ash/display/screen_position_controller.cc
index 93794ac..430a718 100644
--- a/ash/display/screen_position_controller.cc
+++ b/ash/display/screen_position_controller.cc
@@ -7,6 +7,7 @@
#include "ash/display/display_controller.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
+#include "ash/wm/coordinate_conversion.h"
#include "ash/wm/system_modal_container_layout_manager.h"
#include "ash/wm/window_properties.h"
#include "ui/aura/client/activation_client.h"
@@ -89,7 +90,7 @@ void ScreenPositionController::SetBounds(
// Don't move a transient windows to other root window.
// It moves when its transient_parent moves.
if (!window->transient_parent()) {
- aura::RootWindow* dst_root = Shell::GetRootWindowMatching(bounds);
+ aura::RootWindow* dst_root = wm::GetRootWindowMatching(bounds);
aura::Window* dst_container = NULL;
if (dst_root != window->GetRootWindow()) {
int container_id = window->parent()->id();
diff --git a/ash/extended_desktop_unittest.cc b/ash/extended_desktop_unittest.cc
index e5fafa4..387e168 100644
--- a/ash/extended_desktop_unittest.cc
+++ b/ash/extended_desktop_unittest.cc
@@ -6,6 +6,7 @@
#include "ash/display/multi_display_manager.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
+#include "ash/wm/coordinate_conversion.h"
#include "ash/wm/property_util.h"
#include "ash/wm/window_cycle_controller.h"
#include "ash/wm/window_util.h"
@@ -245,17 +246,17 @@ TEST_F(ExtendedDesktopTest, GetRootWindowAt) {
internal::DisplayController::LEFT);
Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
- EXPECT_EQ(root_windows[1], Shell::GetRootWindowAt(gfx::Point(-400, 100)));
- EXPECT_EQ(root_windows[1], Shell::GetRootWindowAt(gfx::Point(-1, 100)));
- EXPECT_EQ(root_windows[0], Shell::GetRootWindowAt(gfx::Point(0, 300)));
- EXPECT_EQ(root_windows[0], Shell::GetRootWindowAt(gfx::Point(700,300)));
+ EXPECT_EQ(root_windows[1], wm::GetRootWindowAt(gfx::Point(-400, 100)));
+ EXPECT_EQ(root_windows[1], wm::GetRootWindowAt(gfx::Point(-1, 100)));
+ EXPECT_EQ(root_windows[0], wm::GetRootWindowAt(gfx::Point(0, 300)));
+ EXPECT_EQ(root_windows[0], wm::GetRootWindowAt(gfx::Point(700,300)));
// Zero origin.
- EXPECT_EQ(root_windows[0], Shell::GetRootWindowAt(gfx::Point(0, 0)));
+ EXPECT_EQ(root_windows[0], wm::GetRootWindowAt(gfx::Point(0, 0)));
// Out of range point should return the primary root window
- EXPECT_EQ(root_windows[0], Shell::GetRootWindowAt(gfx::Point(-600, 0)));
- EXPECT_EQ(root_windows[0], Shell::GetRootWindowAt(gfx::Point(701, 100)));
+ EXPECT_EQ(root_windows[0], wm::GetRootWindowAt(gfx::Point(-600, 0)));
+ EXPECT_EQ(root_windows[0], wm::GetRootWindowAt(gfx::Point(701, 100)));
}
TEST_F(ExtendedDesktopTest, GetRootWindowMatching) {
@@ -267,33 +268,33 @@ TEST_F(ExtendedDesktopTest, GetRootWindowMatching) {
// Containing rect.
EXPECT_EQ(root_windows[1],
- Shell::GetRootWindowMatching(gfx::Rect(-300, 10, 50, 50)));
+ wm::GetRootWindowMatching(gfx::Rect(-300, 10, 50, 50)));
EXPECT_EQ(root_windows[0],
- Shell::GetRootWindowMatching(gfx::Rect(100, 10, 50, 50)));
+ wm::GetRootWindowMatching(gfx::Rect(100, 10, 50, 50)));
// Intersecting rect.
EXPECT_EQ(root_windows[1],
- Shell::GetRootWindowMatching(gfx::Rect(-200, 0, 300, 300)));
+ wm::GetRootWindowMatching(gfx::Rect(-200, 0, 300, 300)));
EXPECT_EQ(root_windows[0],
- Shell::GetRootWindowMatching(gfx::Rect(-100, 0, 300, 300)));
+ wm::GetRootWindowMatching(gfx::Rect(-100, 0, 300, 300)));
// Zero origin.
EXPECT_EQ(root_windows[0],
- Shell::GetRootWindowMatching(gfx::Rect(0, 0, 0, 0)));
+ wm::GetRootWindowMatching(gfx::Rect(0, 0, 0, 0)));
EXPECT_EQ(root_windows[0],
- Shell::GetRootWindowMatching(gfx::Rect(0, 0, 1, 1)));
+ wm::GetRootWindowMatching(gfx::Rect(0, 0, 1, 1)));
// Empty rect.
EXPECT_EQ(root_windows[1],
- Shell::GetRootWindowMatching(gfx::Rect(-400, 100, 0, 0)));
+ wm::GetRootWindowMatching(gfx::Rect(-400, 100, 0, 0)));
EXPECT_EQ(root_windows[0],
- Shell::GetRootWindowMatching(gfx::Rect(100, 100, 0, 0)));
+ wm::GetRootWindowMatching(gfx::Rect(100, 100, 0, 0)));
// Out of range rect should return the primary root window.
EXPECT_EQ(root_windows[0],
- Shell::GetRootWindowMatching(gfx::Rect(-600, -300, 50, 50)));
+ wm::GetRootWindowMatching(gfx::Rect(-600, -300, 50, 50)));
EXPECT_EQ(root_windows[0],
- Shell::GetRootWindowMatching(gfx::Rect(0, 1000, 50, 50)));
+ wm::GetRootWindowMatching(gfx::Rect(0, 1000, 50, 50)));
}
TEST_F(ExtendedDesktopTest, Capture) {
diff --git a/ash/screen_ash.cc b/ash/screen_ash.cc
index 34ce7c6..231b806 100644
--- a/ash/screen_ash.cc
+++ b/ash/screen_ash.cc
@@ -5,6 +5,7 @@
#include "ash/screen_ash.h"
#include "ash/shell.h"
+#include "ash/wm/coordinate_conversion.h"
#include "ash/wm/shelf_layout_manager.h"
#include "base/logging.h"
#include "ui/aura/client/screen_position_client.h"
@@ -83,7 +84,7 @@ gfx::Point ScreenAsh::GetCursorScreenPoint() {
gfx::NativeWindow ScreenAsh::GetWindowAtCursorScreenPoint() {
const gfx::Point point = gfx::Screen::GetCursorScreenPoint();
- return Shell::GetRootWindowAt(point)->GetTopWindowContainingPoint(point);
+ return wm::GetRootWindowAt(point)->GetTopWindowContainingPoint(point);
}
int ScreenAsh::GetNumDisplays() {
diff --git a/ash/shell.cc b/ash/shell.cc
index 3e21f2f..c6eb4d3 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -334,20 +334,6 @@ aura::RootWindow* Shell::GetActiveRootWindow() {
}
// static
-aura::RootWindow* Shell::GetRootWindowAt(const gfx::Point& point) {
- const gfx::Display& display = gfx::Screen::GetDisplayNearestPoint(point);
- return Shell::GetInstance()->display_controller()->
- GetRootWindowForDisplayId(display.id());
-}
-
-// static
-aura::RootWindow* Shell::GetRootWindowMatching(const gfx::Rect& rect) {
- const gfx::Display& display = gfx::Screen::GetDisplayMatching(rect);
- return Shell::GetInstance()->display_controller()->
- GetRootWindowForDisplayId(display.id());
-}
-
-// static
Shell::RootWindowList Shell::GetAllRootWindows() {
return Shell::GetInstance()->display_controller()->
GetAllRootWindows();
diff --git a/ash/shell.h b/ash/shell.h
index ee76740..bb712a4 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -166,15 +166,6 @@ class ASH_EXPORT Shell : ash::CursorDelegate {
// until the another window who has a different root window becomes active.
static aura::RootWindow* GetActiveRootWindow();
- // Returns the RootWindow at |point| in the virtual screen coordinates.
- // Returns NULL if the root window does not exist at the given
- // point.
- static aura::RootWindow* GetRootWindowAt(const gfx::Point& point);
-
- // Returns the RootWindow that shares the most area with |rect| in
- // the virtual scren coordinates.
- static aura::RootWindow* GetRootWindowMatching(const gfx::Rect& rect);
-
// Returns all root windows. In non extended desktop mode, this
// returns the primary root window only.
static RootWindowList GetAllRootWindows();
diff --git a/ash/ui_controls_ash.cc b/ash/ui_controls_ash.cc
index 6069c61..4c60c54 100644
--- a/ash/ui_controls_ash.cc
+++ b/ash/ui_controls_ash.cc
@@ -4,6 +4,7 @@
#include "ash/shell.h"
#include "ash/shell_factory.h"
+#include "ash/wm/coordinate_conversion.h"
#include "ash/wm/window_properties.h"
#include "ui/aura/root_window.h"
#include "ui/aura/ui_controls_aura.h"
@@ -33,7 +34,7 @@ ui_controls::UIControlsAura* GetUIControlsForRootWindow(
// absolute screen coordinates. NULL if there is no RootWindow under the
// |point|.
ui_controls::UIControlsAura* GetUIControlsAt(const gfx::Point& point) {
- aura::RootWindow* root = Shell::GetRootWindowAt(point);
+ aura::RootWindow* root = wm::GetRootWindowAt(point);
return root ? GetUIControlsForRootWindow(root) : NULL;
}
diff --git a/ash/wm/coordinate_conversion.cc b/ash/wm/coordinate_conversion.cc
new file mode 100644
index 0000000..55dd25a
--- /dev/null
+++ b/ash/wm/coordinate_conversion.cc
@@ -0,0 +1,91 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/wm/coordinate_conversion.h"
+
+#include "ash/display/display_controller.h"
+#include "ash/shell.h"
+#include "ui/aura/client/screen_position_client.h"
+#include "ui/aura/root_window.h"
+#include "ui/gfx/display.h"
+#include "ui/gfx/point.h"
+#include "ui/gfx/rect.h"
+#include "ui/gfx/screen.h"
+
+namespace ash {
+namespace wm {
+
+aura::RootWindow* GetRootWindowAt(const gfx::Point& point) {
+ const gfx::Display& display = gfx::Screen::GetDisplayNearestPoint(point);
+ // TODO(yusukes): Move coordinate_conversion.cc and .h to ui/aura/ once
+ // GetRootWindowForDisplayId() is moved to aura::Env.
+ return Shell::GetInstance()->display_controller()->
+ GetRootWindowForDisplayId(display.id());
+}
+
+aura::RootWindow* GetRootWindowMatching(const gfx::Rect& rect) {
+ const gfx::Display& display = gfx::Screen::GetDisplayMatching(rect);
+ return Shell::GetInstance()->display_controller()->
+ GetRootWindowForDisplayId(display.id());
+}
+
+std::pair<aura::RootWindow*, gfx::Point> GetRootWindowRelativeToWindow(
+ aura::Window* window,
+ const gfx::Point& location) {
+ aura::RootWindow* root_window = window->GetRootWindow();
+ gfx::Point location_in_root(location);
+ aura::Window::ConvertPointToWindow(window, root_window, &location_in_root);
+
+#if defined(USE_X11)
+ // This conversion is necessary for dealing with the "pointer warp" feature in
+ // ash/display/display_controller.cc. For example, if we have two displays,
+ // say 1000x1000 (primary) and 500x500 (extended one on the right), and start
+ // dragging a window at (999, 123), and then move the pointer to the right,
+ // the pointer suddenly warps to the extended display. The destination is
+ // (0, 123) in the secondary root window's coordinates, or (1000, 123) in the
+ // screen coordinates. However, since the mouse is captured during drag, a
+ // weird LocatedEvent, something like (0, 1123) in the *primary* root window's
+ // coordinates, is sent to Chrome (Remember that in the native X11 world, the
+ // two root windows are always stacked vertically regardless of the display
+ // layout in Ash). We need to figure out that (0, 1123) in the primary root
+ // window's coordinates is actually (0, 123) in the extended root window's
+ // coordinates.
+ if (!root_window->ContainsPointInRoot(location_in_root)) {
+ gfx::Point location_in_native = location_in_root;
+ root_window->ConvertPointToNativeScreen(&location_in_native);
+
+ Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+ for (size_t i = 0; i < root_windows.size(); ++i) {
+ gfx::Point native_origin = root_windows[i]->bounds().origin();
+ root_windows[i]->ConvertPointToNativeScreen(&native_origin);
+ gfx::Rect native_bounds = root_windows[i]->bounds();
+ native_bounds.set_origin(native_origin);
+ if (native_bounds.Contains(location_in_native)) {
+ root_window = root_windows[i];
+ location_in_root = location_in_native;
+ location_in_root.Offset(-native_bounds.x(), -native_bounds.y());
+ break;
+ }
+ }
+ }
+#else
+ // TODO(yusukes): Support non-X11 platforms if necessary.
+#endif
+
+ return std::make_pair(root_window, location_in_root);
+}
+
+void ConvertPointToScreen(aura::Window* window, gfx::Point* point) {
+ aura::client::GetScreenPositionClient(window->GetRootWindow())->
+ ConvertPointToScreen(window, point);
+}
+
+void ConvertPointFromScreen(aura::Window* window,
+ gfx::Point* point_in_screen) {
+ aura::client::GetScreenPositionClient(window->GetRootWindow())->
+ ConvertPointFromScreen(window, point_in_screen);
+}
+
+} // namespace wm
+} // namespace ash
diff --git a/ash/wm/coordinate_conversion.h b/ash/wm/coordinate_conversion.h
new file mode 100644
index 0000000..207afd4
--- /dev/null
+++ b/ash/wm/coordinate_conversion.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_WM_COORDINATE_CONVERSION_H_
+#define ASH_WM_COORDINATE_CONVERSION_H_
+
+#include "ash/ash_export.h"
+
+#include "ui/gfx/point.h"
+
+namespace aura {
+class RootWindow;
+class Window;
+} // namespace gfx
+
+namespace gfx {
+class Rect;
+} // namespace gfx
+
+namespace ash {
+namespace wm {
+
+// Returns the RootWindow at |point| in the virtual screen coordinates.
+// Returns NULL if the root window does not exist at the given
+// point.
+ASH_EXPORT aura::RootWindow* GetRootWindowAt(const gfx::Point& point);
+
+// Returns the RootWindow that shares the most area with |rect| in
+// the virtual scren coordinates.
+ASH_EXPORT aura::RootWindow* GetRootWindowMatching(const gfx::Rect& rect);
+
+// Finds the root window at |location| in |window|'s coordinates and returns a
+// pair of root window and location in that root window's coordinates. The
+// function usually returns |window->GetRootWindow()|, but if the mouse pointer
+// is moved outside the |window|'s root while the mouse is captured, it returns
+// the other root window.
+ASH_EXPORT std::pair<aura::RootWindow*, gfx::Point>
+GetRootWindowRelativeToWindow(aura::Window* window, const gfx::Point& location);
+
+// Converts the |point| from a given |window|'s coordinates into the screen
+// coordinates.
+ASH_EXPORT void ConvertPointToScreen(aura::Window* window, gfx::Point* point);
+
+// Converts the |point| from the screen coordinates to a given |window|'s
+// coordinates.
+ASH_EXPORT void ConvertPointFromScreen(aura::Window* window,
+ gfx::Point* point_in_screen);
+
+} // namespace wm
+} // namespace ash
+
+#endif // ASH_WM_COORDINATE_CONVERSION_H_
diff --git a/ash/wm/default_window_resizer.cc b/ash/wm/default_window_resizer.cc
index 4368c73..c0a71f2 100644
--- a/ash/wm/default_window_resizer.cc
+++ b/ash/wm/default_window_resizer.cc
@@ -5,6 +5,7 @@
#include "ash/wm/default_window_resizer.h"
#include "ash/shell.h"
+#include "ash/wm/coordinate_conversion.h"
#include "ash/wm/cursor_manager.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h"
@@ -33,6 +34,14 @@ DefaultWindowResizer::Create(aura::Window* window,
}
void DefaultWindowResizer::Drag(const gfx::Point& location, int event_flags) {
+ std::pair<aura::RootWindow*, gfx::Point> actual_location =
+ wm::GetRootWindowRelativeToWindow(details_.window->parent(), location);
+
+ // TODO(mazda|yusukes): Implement dragging an item from one display to another
+ aura::RootWindow* current_root = actual_location.first;
+ if (current_root != details_.window->GetRootWindow())
+ return;
+
int grid_size = event_flags & ui::EF_CONTROL_DOWN ?
0 : ash::Shell::GetInstance()->GetGridSize();
gfx::Rect bounds(CalculateBoundsForDrag(details_, location, grid_size));
diff --git a/ash/wm/stacking_controller.cc b/ash/wm/stacking_controller.cc
index 452be23..73b30f2 100644
--- a/ash/wm/stacking_controller.cc
+++ b/ash/wm/stacking_controller.cc
@@ -8,6 +8,7 @@
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/always_on_top_controller.h"
+#include "ash/wm/coordinate_conversion.h"
#include "ash/wm/window_properties.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/root_window.h"
@@ -28,7 +29,7 @@ aura::RootWindow* FindContainerRoot(const gfx::Rect& bounds) {
bounds.IsEmpty())) {
return Shell::GetActiveRootWindow();
}
- return Shell::GetRootWindowMatching(bounds);
+ return wm::GetRootWindowMatching(bounds);
}
aura::Window* GetContainerById(aura::RootWindow* root, int id) {
diff --git a/ash/wm/workspace/phantom_window_controller.cc b/ash/wm/workspace/phantom_window_controller.cc
index 656dc69..a33f0ed 100644
--- a/ash/wm/workspace/phantom_window_controller.cc
+++ b/ash/wm/workspace/phantom_window_controller.cc
@@ -6,6 +6,7 @@
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
+#include "ash/wm/coordinate_conversion.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
@@ -127,9 +128,8 @@ void PhantomWindowController::CreatePhantomWidget(const gfx::Rect& bounds) {
// PhantomWindowController is used by FrameMaximizeButton to highlight the
// launcher button. Put the phantom in the same window as the launcher so that
// the phantom is visible.
- params.parent = Shell::GetContainer(
- Shell::GetInstance()->GetRootWindowMatching(bounds),
- kShellWindowId_LauncherContainer);
+ params.parent = Shell::GetContainer(wm::GetRootWindowMatching(bounds),
+ kShellWindowId_LauncherContainer);
params.can_activate = false;
params.keep_on_top = true;
phantom_widget_->set_focus_on_creation(false);
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc
index a683465..000260c 100644
--- a/ash/wm/workspace/workspace_window_resizer.cc
+++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -7,14 +7,18 @@
#include <algorithm>
#include <cmath>
+#include "ash/display/display_controller.h"
#include "ash/screen_ash.h"
#include "ash/shell.h"
+#include "ash/wm/coordinate_conversion.h"
#include "ash/wm/cursor_manager.h"
#include "ash/wm/property_util.h"
#include "ash/wm/window_util.h"
#include "ash/wm/workspace/phantom_window_controller.h"
#include "ash/wm/workspace/snap_sizer.h"
+#include "ui/aura/client/aura_constants.h"
#include "ui/aura/env.h"
+#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/hit_test.h"
@@ -46,7 +50,9 @@ const int WorkspaceWindowResizer::kMinOnscreenSize = 20;
const int WorkspaceWindowResizer::kMinOnscreenHeight = 32;
WorkspaceWindowResizer::~WorkspaceWindowResizer() {
- ash::Shell::GetInstance()->cursor_manager()->UnlockCursor();
+ Shell* shell = Shell::GetInstance();
+ shell->display_controller()->set_dont_warp_mouse(false);
+ shell->cursor_manager()->UnlockCursor();
}
// static
@@ -61,6 +67,14 @@ WorkspaceWindowResizer* WorkspaceWindowResizer::Create(
}
void WorkspaceWindowResizer::Drag(const gfx::Point& location, int event_flags) {
+ std::pair<aura::RootWindow*, gfx::Point> actual_location =
+ wm::GetRootWindowRelativeToWindow(window()->parent(), location);
+
+ // TODO(yusukes): Implement dragging a window from one display to another.
+ aura::RootWindow* current_root = actual_location.first;
+ if (current_root != window()->GetRootWindow())
+ return;
+
int grid_size = event_flags & ui::EF_CONTROL_DOWN ?
0 : ash::Shell::GetInstance()->GetGridSize();
gfx::Rect bounds = CalculateBoundsForDrag(details_, location, grid_size);
@@ -164,7 +178,16 @@ WorkspaceWindowResizer::WorkspaceWindowResizer(
snap_type_(SNAP_NONE),
num_mouse_moves_since_bounds_change_(0) {
DCHECK(details_.is_resizable);
- ash::Shell::GetInstance()->cursor_manager()->LockCursor();
+
+ Shell* shell = Shell::GetInstance();
+ shell->cursor_manager()->LockCursor();
+
+ // The pointer should be confined in one display during resizing a window
+ // because the window cannot span two displays at the same time anyway. The
+ // exception is window/tab dragging operation. During that operation,
+ // |dont_warp_mouse_| should be set to false so that the user could move a
+ // window/tab to another display.
+ shell->display_controller()->set_dont_warp_mouse(!ShouldAllowMouseWarp());
// Only support attaching to the right/bottom.
DCHECK(attached_windows_.empty() ||
@@ -441,5 +464,11 @@ WorkspaceWindowResizer::SnapType WorkspaceWindowResizer::GetSnapType(
return SNAP_NONE;
}
+bool WorkspaceWindowResizer::ShouldAllowMouseWarp() const {
+ return (details_.window_component == HTCAPTION) &&
+ (window()->GetProperty(aura::client::kModalKey) == ui::MODAL_TYPE_NONE) &&
+ (window()->type() == aura::client::WINDOW_TYPE_NORMAL);
+}
+
} // namespace internal
} // namespace ash
diff --git a/ash/wm/workspace/workspace_window_resizer.h b/ash/wm/workspace/workspace_window_resizer.h
index 3b28e1e..018a7cc 100644
--- a/ash/wm/workspace/workspace_window_resizer.h
+++ b/ash/wm/workspace/workspace_window_resizer.h
@@ -119,6 +119,9 @@ class ASH_EXPORT WorkspaceWindowResizer : public WindowResizer {
// snapping should be used.
SnapType GetSnapType(const gfx::Point& location) const;
+ // Returns true if we should allow the mouse pointer to warp.
+ bool ShouldAllowMouseWarp() const;
+
aura::Window* window() const { return details_.window; }
const Details details_;