| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/wm/drag_window_resizer.h" | 5 #include "ash/wm/drag_window_resizer.h" |
| 6 | 6 |
| 7 #include "ash/display/mouse_cursor_event_filter.h" | 7 #include "ash/display/mouse_cursor_event_filter.h" |
| 8 #include "ash/root_window_controller.h" | |
| 9 #include "ash/screen_util.h" | 8 #include "ash/screen_util.h" |
| 10 #include "ash/shell.h" | 9 #include "ash/shell.h" |
| 11 #include "ash/system/tray/system_tray.h" | |
| 12 #include "ash/system/user/tray_user.h" | |
| 13 #include "ash/wm/coordinate_conversion.h" | 10 #include "ash/wm/coordinate_conversion.h" |
| 14 #include "ash/wm/drag_window_controller.h" | 11 #include "ash/wm/drag_window_controller.h" |
| 15 #include "ash/wm/window_state.h" | 12 #include "ash/wm/window_state.h" |
| 16 #include "ash/wm/window_util.h" | 13 #include "ash/wm/window_util.h" |
| 17 #include "base/memory/weak_ptr.h" | 14 #include "base/memory/weak_ptr.h" |
| 18 #include "ui/aura/client/aura_constants.h" | 15 #include "ui/aura/client/aura_constants.h" |
| 19 #include "ui/aura/env.h" | 16 #include "ui/aura/env.h" |
| 20 #include "ui/aura/window.h" | 17 #include "ui/aura/window.h" |
| 21 #include "ui/aura/window_delegate.h" | 18 #include "ui/aura/window_delegate.h" |
| 22 #include "ui/aura/window_event_dispatcher.h" | 19 #include "ui/aura/window_event_dispatcher.h" |
| 23 #include "ui/base/hit_test.h" | 20 #include "ui/base/hit_test.h" |
| 24 #include "ui/base/ui_base_types.h" | 21 #include "ui/base/ui_base_types.h" |
| 25 #include "ui/gfx/screen.h" | 22 #include "ui/gfx/screen.h" |
| 26 #include "ui/views/corewm/window_util.h" | 23 #include "ui/views/corewm/window_util.h" |
| 27 | 24 |
| 28 namespace ash { | 25 namespace ash { |
| 29 namespace internal { | 26 namespace internal { |
| 30 | 27 |
| 31 namespace { | 28 namespace { |
| 32 | 29 |
| 33 // The maximum opacity of the drag phantom window. | 30 // The maximum opacity of the drag phantom window. |
| 34 const float kMaxOpacity = 0.8f; | 31 const float kMaxOpacity = 0.8f; |
| 35 | 32 |
| 36 // The opacity of the window when dragging it over a user item in the tray. | |
| 37 const float kOpacityWhenDraggedOverUserIcon = 0.4f; | |
| 38 | |
| 39 // Returns true if Ash has more than one root window. | 33 // Returns true if Ash has more than one root window. |
| 40 bool HasSecondaryRootWindow() { | 34 bool HasSecondaryRootWindow() { |
| 41 return Shell::GetAllRootWindows().size() > 1; | 35 return Shell::GetAllRootWindows().size() > 1; |
| 42 } | 36 } |
| 43 | 37 |
| 44 // When there are two root windows, returns one of the root windows which is not | 38 // When there are two root windows, returns one of the root windows which is not |
| 45 // |root_window|. Returns NULL if only one root window exists. | 39 // |root_window|. Returns NULL if only one root window exists. |
| 46 aura::Window* GetAnotherRootWindow(aura::Window* root_window) { | 40 aura::Window* GetAnotherRootWindow(aura::Window* root_window) { |
| 47 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); | 41 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
| 48 if (root_windows.size() < 2) | 42 if (root_windows.size() < 2) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 71 | 65 |
| 72 // static | 66 // static |
| 73 DragWindowResizer* DragWindowResizer::Create( | 67 DragWindowResizer* DragWindowResizer::Create( |
| 74 WindowResizer* next_window_resizer, | 68 WindowResizer* next_window_resizer, |
| 75 wm::WindowState* window_state) { | 69 wm::WindowState* window_state) { |
| 76 return new DragWindowResizer(next_window_resizer, window_state); | 70 return new DragWindowResizer(next_window_resizer, window_state); |
| 77 } | 71 } |
| 78 | 72 |
| 79 void DragWindowResizer::Drag(const gfx::Point& location, int event_flags) { | 73 void DragWindowResizer::Drag(const gfx::Point& location, int event_flags) { |
| 80 base::WeakPtr<DragWindowResizer> resizer(weak_ptr_factory_.GetWeakPtr()); | 74 base::WeakPtr<DragWindowResizer> resizer(weak_ptr_factory_.GetWeakPtr()); |
| 81 | |
| 82 // If we are on top of a window to desktop transfer button, we move the window | |
| 83 // temporarily back to where it was initially and make it semi-transparent. | |
| 84 GetTarget()->layer()->SetOpacity( | |
| 85 GetTrayUserItemAtPoint(location) ? kOpacityWhenDraggedOverUserIcon : | |
| 86 details().initial_opacity); | |
| 87 | |
| 88 next_window_resizer_->Drag(location, event_flags); | 75 next_window_resizer_->Drag(location, event_flags); |
| 89 | 76 |
| 90 if (!resizer) | 77 if (!resizer) |
| 91 return; | 78 return; |
| 92 | 79 |
| 93 last_mouse_location_ = location; | 80 last_mouse_location_ = location; |
| 94 // Show a phantom window for dragging in another root window. | 81 // Show a phantom window for dragging in another root window. |
| 95 if (HasSecondaryRootWindow()) { | 82 if (HasSecondaryRootWindow()) { |
| 96 gfx::Point location_in_screen = location; | 83 gfx::Point location_in_screen = location; |
| 97 wm::ConvertPointToScreen(GetTarget()->parent(), &location_in_screen); | 84 wm::ConvertPointToScreen(GetTarget()->parent(), &location_in_screen); |
| 98 const bool in_original_root = | 85 const bool in_original_root = |
| 99 wm::GetRootWindowAt(location_in_screen) == GetTarget()->GetRootWindow(); | 86 wm::GetRootWindowAt(location_in_screen) == GetTarget()->GetRootWindow(); |
| 100 UpdateDragWindow(GetTarget()->bounds(), in_original_root); | 87 UpdateDragWindow(GetTarget()->bounds(), in_original_root); |
| 101 } else { | 88 } else { |
| 102 drag_window_controller_.reset(); | 89 drag_window_controller_.reset(); |
| 103 } | 90 } |
| 104 } | 91 } |
| 105 | 92 |
| 106 void DragWindowResizer::CompleteDrag() { | 93 void DragWindowResizer::CompleteDrag() { |
| 107 if (TryDraggingToNewUser()) | |
| 108 return; | |
| 109 | |
| 110 next_window_resizer_->CompleteDrag(); | 94 next_window_resizer_->CompleteDrag(); |
| 111 | 95 |
| 112 GetTarget()->layer()->SetOpacity(details().initial_opacity); | 96 GetTarget()->layer()->SetOpacity(details().initial_opacity); |
| 113 drag_window_controller_.reset(); | 97 drag_window_controller_.reset(); |
| 114 | 98 |
| 115 // Check if the destination is another display. | 99 // Check if the destination is another display. |
| 116 gfx::Point last_mouse_location_in_screen = last_mouse_location_; | 100 gfx::Point last_mouse_location_in_screen = last_mouse_location_; |
| 117 wm::ConvertPointToScreen(GetTarget()->parent(), | 101 wm::ConvertPointToScreen(GetTarget()->parent(), |
| 118 &last_mouse_location_in_screen); | 102 &last_mouse_location_in_screen); |
| 119 gfx::Screen* screen = Shell::GetScreen(); | 103 gfx::Screen* screen = Shell::GetScreen(); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 } | 204 } |
| 221 } | 205 } |
| 222 | 206 |
| 223 bool DragWindowResizer::ShouldAllowMouseWarp() { | 207 bool DragWindowResizer::ShouldAllowMouseWarp() { |
| 224 return (details().window_component == HTCAPTION) && | 208 return (details().window_component == HTCAPTION) && |
| 225 !views::corewm::GetTransientParent(GetTarget()) && | 209 !views::corewm::GetTransientParent(GetTarget()) && |
| 226 (GetTarget()->type() == ui::wm::WINDOW_TYPE_NORMAL || | 210 (GetTarget()->type() == ui::wm::WINDOW_TYPE_NORMAL || |
| 227 GetTarget()->type() == ui::wm::WINDOW_TYPE_PANEL); | 211 GetTarget()->type() == ui::wm::WINDOW_TYPE_PANEL); |
| 228 } | 212 } |
| 229 | 213 |
| 230 TrayUser* DragWindowResizer::GetTrayUserItemAtPoint( | |
| 231 const gfx::Point& point_in_screen) { | |
| 232 // Unit tests might not have an ash shell. | |
| 233 if (!ash::Shell::GetInstance()) | |
| 234 return NULL; | |
| 235 | |
| 236 // Check that this is a drag move operation from a suitable window. | |
| 237 if (details().window_component != HTCAPTION || | |
| 238 views::corewm::GetTransientParent(GetTarget()) || | |
| 239 (GetTarget()->type() != ui::wm::WINDOW_TYPE_NORMAL && | |
| 240 GetTarget()->type() != ui::wm::WINDOW_TYPE_PANEL && | |
| 241 GetTarget()->type() != ui::wm::WINDOW_TYPE_POPUP)) | |
| 242 return NULL; | |
| 243 | |
| 244 // We only allow to drag the window onto a tray of it's own RootWindow. | |
| 245 SystemTray* tray = internal::GetRootWindowController( | |
| 246 GetTarget()->GetRootWindow())->GetSystemTray(); | |
| 247 | |
| 248 // Again - unit tests might not have a tray. | |
| 249 if (!tray) | |
| 250 return NULL; | |
| 251 | |
| 252 const std::vector<internal::TrayUser*> tray_users = tray->GetTrayUserItems(); | |
| 253 if (tray_users.size() <= 1) | |
| 254 return NULL; | |
| 255 | |
| 256 std::vector<internal::TrayUser*>::const_iterator it = tray_users.begin(); | |
| 257 for (; it != tray_users.end(); ++it) { | |
| 258 if ((*it)->CanDropWindowHereToTransferToUser(point_in_screen)) | |
| 259 return *it; | |
| 260 } | |
| 261 return NULL; | |
| 262 } | |
| 263 | |
| 264 bool DragWindowResizer::TryDraggingToNewUser() { | |
| 265 TrayUser* tray_user = GetTrayUserItemAtPoint(last_mouse_location_); | |
| 266 // No need to try dragging if there is no user. | |
| 267 if (!tray_user) | |
| 268 return false; | |
| 269 | |
| 270 // We have to avoid a brief flash caused by the RevertDrag operation. | |
| 271 // To do this, we first set the opacity of our target window to 0, so that no | |
| 272 // matter what the RevertDrag does the window will stay hidden. Then transfer | |
| 273 // the window to the new owner (which will hide it). RevertDrag will then do | |
| 274 // it's thing and return the transparency to its original value. | |
| 275 int old_opacity = GetTarget()->layer()->opacity(); | |
| 276 GetTarget()->layer()->SetOpacity(0); | |
| 277 GetTarget()->SetBounds(details().initial_bounds_in_parent); | |
| 278 if (!tray_user->TransferWindowToUser(GetTarget())) { | |
| 279 GetTarget()->layer()->SetOpacity(old_opacity); | |
| 280 return false; | |
| 281 } | |
| 282 RevertDrag(); | |
| 283 return true; | |
| 284 } | |
| 285 | |
| 286 } // namespace internal | 214 } // namespace internal |
| 287 } // namespace ash | 215 } // namespace ash |
| OLD | NEW |