diff options
author | yusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-06 18:27:46 +0000 |
---|---|---|
committer | yusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-06 18:27:46 +0000 |
commit | 7203a5ecc10ca59ef838d4e31dc4566cd1b33780 (patch) | |
tree | 60b69c2c4845eebffbeeecf8c9d8280863d81354 /ash | |
parent | 8fee1c35d91f2984c9a738008d5728e893ef91a5 (diff) | |
download | chromium_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.gyp | 2 | ||||
-rw-r--r-- | ash/display/display_controller.cc | 44 | ||||
-rw-r--r-- | ash/display/display_controller.h | 7 | ||||
-rw-r--r-- | ash/display/mouse_cursor_event_filter.cc | 11 | ||||
-rw-r--r-- | ash/display/screen_position_controller.cc | 3 | ||||
-rw-r--r-- | ash/extended_desktop_unittest.cc | 35 | ||||
-rw-r--r-- | ash/screen_ash.cc | 3 | ||||
-rw-r--r-- | ash/shell.cc | 14 | ||||
-rw-r--r-- | ash/shell.h | 9 | ||||
-rw-r--r-- | ash/ui_controls_ash.cc | 3 | ||||
-rw-r--r-- | ash/wm/coordinate_conversion.cc | 91 | ||||
-rw-r--r-- | ash/wm/coordinate_conversion.h | 53 | ||||
-rw-r--r-- | ash/wm/default_window_resizer.cc | 9 | ||||
-rw-r--r-- | ash/wm/stacking_controller.cc | 3 | ||||
-rw-r--r-- | ash/wm/workspace/phantom_window_controller.cc | 6 | ||||
-rw-r--r-- | ash/wm/workspace/workspace_window_resizer.cc | 33 | ||||
-rw-r--r-- | ash/wm/workspace/workspace_window_resizer.h | 3 |
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_; |