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 |