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

Unified Diff: ash/wm/workspace/workspace_window_resizer.cc

Issue 10834097: Allow the user to drag a window from one display to another (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review Created 8 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ash/wm/workspace/workspace_window_resizer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ash/wm/workspace/workspace_window_resizer.cc
diff --git a/ash/wm/workspace/workspace_window_resizer.cc b/ash/wm/workspace/workspace_window_resizer.cc
index 324e9f2aee7773c44b464abb662c02f5787755b6..6aced0eb385504f0fcd18325b6675c6ac8939fff 100644
--- a/ash/wm/workspace/workspace_window_resizer.cc
+++ b/ash/wm/workspace/workspace_window_resizer.cc
@@ -40,6 +40,20 @@ bool ShouldSnapToEdge(int distance_from_edge, int grid_size) {
distance_from_edge > -grid_size * 2;
}
+bool HasSecondaryRootWindow() {
+ return Shell::GetAllRootWindows().size() > 1;
+}
+
+aura::RootWindow* GetAnotherRootWindow(aura::RootWindow* root_window) {
+ Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
+ if (root_windows.size() < 2)
+ return NULL; // an extended display is not connected.
+ DCHECK_EQ(2U, root_windows.size());
+ if (root_windows[0] == root_window)
+ return root_windows[1];
+ return root_windows[0];
+}
+
} // namespace
// static
@@ -68,10 +82,8 @@ WorkspaceWindowResizer* WorkspaceWindowResizer::Create(
void WorkspaceWindowResizer::Drag(const gfx::Point& location_in_screen,
int event_flags) {
- // TODO(yusukes): Implement dragging a window from one display to another.
aura::RootWindow* current_root = Shell::GetRootWindowAt(location_in_screen);
- if (current_root != window()->GetRootWindow())
- return;
+ const bool in_original_root = (window()->GetRootWindow() == current_root);
gfx::Point location_in_root = location_in_screen;
aura::client::GetScreenPositionClient(current_root)->
@@ -79,8 +91,8 @@ void WorkspaceWindowResizer::Drag(const gfx::Point& location_in_screen,
int grid_size = event_flags & ui::EF_CONTROL_DOWN ?
0 : ash::Shell::GetInstance()->GetGridSize();
- gfx::Rect bounds =
- CalculateBoundsForDrag(details_, location_in_root, grid_size);
+ gfx::Rect bounds = // in |window()->GetRootWindow()|'s coordinates.
+ CalculateBoundsForDrag(details_, location_in_screen, grid_size);
if (wm::IsWindowNormal(details_.window))
AdjustBoundsForMainWindow(&bounds, grid_size);
@@ -89,7 +101,20 @@ void WorkspaceWindowResizer::Drag(const gfx::Point& location_in_screen,
RestackWindows();
did_move_or_resize_ = true;
}
- UpdatePhantomWindow(location_in_root, bounds, grid_size);
+
+ // Hide a phantom window for snapping if the cursor is in another root window.
+ if (in_original_root)
+ UpdatePhantomWindow(location_in_root, bounds, grid_size);
+ else
+ phantom_window_controller_.reset();
+
+ // Show a phantom window for dragging in another root window.
+ aura::RootWindow* another_root =
+ GetAnotherRootWindow(window()->GetRootWindow());
+ gfx::Rect bounds_in_screen =
+ ScreenAsh::ConvertRectToScreen(window()->GetRootWindow(), bounds);
+ UpdateDragPhantomWindow(another_root, bounds_in_screen);
+
if (!attached_windows_.empty())
LayoutAttachedWindows(bounds, grid_size);
if (bounds != details_.window->bounds())
@@ -98,6 +123,7 @@ void WorkspaceWindowResizer::Drag(const gfx::Point& location_in_screen,
}
void WorkspaceWindowResizer::CompleteDrag(int event_flags) {
+ drag_phantom_window_controller_.reset();
phantom_window_controller_.reset();
if (!did_move_or_resize_ || details_.window_component != HTCAPTION)
return;
@@ -143,6 +169,7 @@ void WorkspaceWindowResizer::CompleteDrag(int event_flags) {
}
void WorkspaceWindowResizer::RevertDrag() {
+ drag_phantom_window_controller_.reset();
phantom_window_controller_.reset();
if (!did_move_or_resize_)
@@ -310,17 +337,23 @@ void WorkspaceWindowResizer::CalculateAttachedSizes(
void WorkspaceWindowResizer::AdjustBoundsForMainWindow(
gfx::Rect* bounds, int grid_size) const {
- // Always keep kMinOnscreenHeight on the bottom.
+ // Always keep kMinOnscreenHeight on the bottom except when an extended
+ // display is available and a window is being dragged.
gfx::Rect work_area(
ScreenAsh::GetDisplayWorkAreaBoundsInParent(details_.window));
int max_y = AlignToGridRoundUp(work_area.bottom() - kMinOnscreenHeight,
grid_size);
- if (bounds->y() > max_y)
+ if ((details_.window_component != HTCAPTION || !HasSecondaryRootWindow()) &&
+ bounds->y() > max_y) {
bounds->set_y(max_y);
+ }
- // Don't allow dragging above the top of the display.
- if (bounds->y() <= work_area.y())
+ // Don't allow dragging above the top of the display except when an extended
+ // display is available and a window is being dragged.
+ if ((details_.window_component != HTCAPTION || !HasSecondaryRootWindow()) &&
+ bounds->y() <= work_area.y()) {
bounds->set_y(work_area.y());
+ }
if (grid_size >= 0 && details_.window_component == HTCAPTION)
SnapToWorkAreaEdges(work_area, bounds, grid_size);
@@ -389,6 +422,33 @@ int WorkspaceWindowResizer::PrimaryAxisCoordinate(int x, int y) const {
return 0;
}
+void WorkspaceWindowResizer::UpdateDragPhantomWindow(
+ aura::RootWindow* another_root,
+ const gfx::Rect& window_bounds_in_screen) {
+ if (!another_root) {
+ // An extended display is not available.
+ drag_phantom_window_controller_.reset();
+ return;
+ }
+
+ // It's available. Show a phantom window on the display if needed.
+ const gfx::Rect root_bounds_in_screen(another_root->GetBoundsInScreen());
+ const gfx::Rect phantom(
+ root_bounds_in_screen.Intersect(window_bounds_in_screen));
+
+ if (!phantom.IsEmpty()) {
+ if (!drag_phantom_window_controller_.get()) {
+ drag_phantom_window_controller_.reset(
+ new PhantomWindowController(window()));
+ drag_phantom_window_controller_->Show(phantom);
+ } else {
+ drag_phantom_window_controller_->SetBounds(phantom); // no animation
+ }
+ } else {
+ drag_phantom_window_controller_.reset();
+ }
+}
+
void WorkspaceWindowResizer::UpdatePhantomWindow(const gfx::Point& location,
const gfx::Rect& bounds,
int grid_size) {
« no previous file with comments | « ash/wm/workspace/workspace_window_resizer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698