diff options
author | skuhne@chromium.org <skuhne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-14 20:56:09 +0000 |
---|---|---|
committer | skuhne@chromium.org <skuhne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-14 20:56:09 +0000 |
commit | 1fe485eebeb04333b7618fa74e5ce4c973df228f (patch) | |
tree | d362f7d27662e88f6b237f01630878b3fd608ee6 /ash/wm/drag_window_resizer.cc | |
parent | 3d6d6765267a2c3fa6772e307afd78e95e7132f7 (diff) | |
download | chromium_src-1fe485eebeb04333b7618fa74e5ce4c973df228f.zip chromium_src-1fe485eebeb04333b7618fa74e5ce4c973df228f.tar.gz chromium_src-1fe485eebeb04333b7618fa74e5ce4c973df228f.tar.bz2 |
Adding the multi profile feature to allow drag of windows from the active desktop to another ones desktop.
How it works:
When multiple users are loaded, the current user can drag one of the windows on his desktop to a user's icon on the tray menu. If a transfer to that icon is possible, the window will "zap back" to it's original location to indicate the operation. If he drops the window there it will be transferred to the other users desktop.
BUG=305068
TEST=visual
Review URL: https://codereview.chromium.org/27042003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@228523 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash/wm/drag_window_resizer.cc')
-rw-r--r-- | ash/wm/drag_window_resizer.cc | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/ash/wm/drag_window_resizer.cc b/ash/wm/drag_window_resizer.cc index 6a1ae1b..92b8755 100644 --- a/ash/wm/drag_window_resizer.cc +++ b/ash/wm/drag_window_resizer.cc @@ -5,8 +5,11 @@ #include "ash/wm/drag_window_resizer.h" #include "ash/display/mouse_cursor_event_filter.h" +#include "ash/root_window_controller.h" #include "ash/screen_ash.h" #include "ash/shell.h" +#include "ash/system/tray/system_tray.h" +#include "ash/system/user/tray_user.h" #include "ash/wm/coordinate_conversion.h" #include "ash/wm/drag_window_controller.h" #include "base/memory/weak_ptr.h" @@ -72,7 +75,14 @@ DragWindowResizer* DragWindowResizer::Create( void DragWindowResizer::Drag(const gfx::Point& location, int event_flags) { base::WeakPtr<DragWindowResizer> resizer(weak_ptr_factory_.GetWeakPtr()); - next_window_resizer_->Drag(location, event_flags); + + // If we are on top of a window to desktop transfer button, we move the window + // temporarily back to where it was initially (showing that we do something). + gfx::Point filtered_location = GetTrayUserItemAtPoint(location) ? + details_.initial_location_in_parent : location; + + next_window_resizer_->Drag(filtered_location, event_flags); + if (!resizer) return; @@ -90,6 +100,9 @@ void DragWindowResizer::Drag(const gfx::Point& location, int event_flags) { } void DragWindowResizer::CompleteDrag(int event_flags) { + if (TryDraggingToNewUser()) + return; + next_window_resizer_->CompleteDrag(event_flags); GetTarget()->layer()->SetOpacity(details_.initial_opacity); @@ -197,5 +210,60 @@ bool DragWindowResizer::ShouldAllowMouseWarp() { GetTarget()->type() == aura::client::WINDOW_TYPE_PANEL); } +TrayUser* DragWindowResizer::GetTrayUserItemAtPoint( + const gfx::Point& point_in_screen) { + // Unit tests might not have an ash shell. + if (!ash::Shell::GetInstance()) + return NULL; + + // Check that this is a drag move operation from a suitable window. + if (details_.window_component != HTCAPTION || + GetTarget()->transient_parent() || + (GetTarget()->type() != aura::client::WINDOW_TYPE_NORMAL && + GetTarget()->type() != aura::client::WINDOW_TYPE_PANEL && + GetTarget()->type() != aura::client::WINDOW_TYPE_POPUP)) + return NULL; + + // We only allow to drag the window onto a tray of it's own RootWindow. + SystemTray* tray = internal::GetRootWindowController( + details_.window->GetRootWindow())->GetSystemTray(); + + // Again - unit tests might not have a tray. + if (!tray) + return NULL; + + const std::vector<internal::TrayUser*> tray_users = tray->GetTrayUserItems(); + if (tray_users.size() <= 1) + return NULL; + + std::vector<internal::TrayUser*>::const_iterator it = tray_users.begin(); + for (; it != tray_users.end(); ++it) { + if ((*it)->CanDropWindowHereToTransferToUser(point_in_screen)) + return *it; + } + return NULL; +} + +bool DragWindowResizer::TryDraggingToNewUser() { + TrayUser* tray_user = GetTrayUserItemAtPoint(last_mouse_location_); + // No need to try dragging if there is no user. + if (!tray_user) + return false; + + // We have to avoid a brief flash caused by the RevertDrag operation. + // To do this, we first set the opacity of our target window to 0, so that no + // matter what the RevertDrag does the window will stay hidden. Then transfer + // the window to the new owner (which will hide it). RevertDrag will then do + // it's thing and return the transparency to its original value. + int old_opacity = GetTarget()->layer()->opacity(); + GetTarget()->layer()->SetOpacity(0); + if (!tray_user->TransferWindowToUser(details_.window)) { + GetTarget()->layer()->SetOpacity(old_opacity); + return false; + } + RevertDrag(); + return true; +} + } // namespace internal } // namespace ash |