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" | 8 #include "ash/root_window_controller.h" |
9 #include "ash/screen_ash.h" | 9 #include "ash/screen_ash.h" |
10 #include "ash/shell.h" | 10 #include "ash/shell.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 return root_windows[1]; | 51 return root_windows[1]; |
52 return root_windows[0]; | 52 return root_windows[0]; |
53 } | 53 } |
54 | 54 |
55 } // namespace | 55 } // namespace |
56 | 56 |
57 // static | 57 // static |
58 DragWindowResizer* DragWindowResizer::instance_ = NULL; | 58 DragWindowResizer* DragWindowResizer::instance_ = NULL; |
59 | 59 |
60 DragWindowResizer::~DragWindowResizer() { | 60 DragWindowResizer::~DragWindowResizer() { |
61 if (GetTarget()) | 61 if (window_state_) |
62 wm::GetWindowState(GetTarget())->set_window_resizer_(NULL); | 62 window_state_->DeleteDragDetails(); |
63 Shell* shell = Shell::GetInstance(); | 63 Shell* shell = Shell::GetInstance(); |
64 shell->mouse_cursor_filter()->set_mouse_warp_mode( | 64 shell->mouse_cursor_filter()->set_mouse_warp_mode( |
65 MouseCursorEventFilter::WARP_ALWAYS); | 65 MouseCursorEventFilter::WARP_ALWAYS); |
66 shell->mouse_cursor_filter()->HideSharedEdgeIndicator(); | 66 shell->mouse_cursor_filter()->HideSharedEdgeIndicator(); |
67 if (instance_ == this) | 67 if (instance_ == this) |
68 instance_ = NULL; | 68 instance_ = NULL; |
69 } | 69 } |
70 | 70 |
71 // static | 71 // static |
72 DragWindowResizer* DragWindowResizer::Create( | 72 DragWindowResizer* DragWindowResizer::Create( |
73 WindowResizer* next_window_resizer, | 73 WindowResizer* next_window_resizer, |
74 aura::Window* window, | 74 wm::WindowState* window_state) { |
75 const gfx::Point& location, | 75 return new DragWindowResizer(next_window_resizer, window_state); |
76 int window_component, | |
77 aura::client::WindowMoveSource source) { | |
78 Details details(window, location, window_component, source); | |
79 return details.is_resizable ? | |
80 new DragWindowResizer(next_window_resizer, details) : NULL; | |
81 } | 76 } |
82 | 77 |
83 void DragWindowResizer::Drag(const gfx::Point& location, int event_flags) { | 78 void DragWindowResizer::Drag(const gfx::Point& location, int event_flags) { |
84 base::WeakPtr<DragWindowResizer> resizer(weak_ptr_factory_.GetWeakPtr()); | 79 base::WeakPtr<DragWindowResizer> resizer(weak_ptr_factory_.GetWeakPtr()); |
85 | 80 |
86 // If we are on top of a window to desktop transfer button, we move the window | 81 // If we are on top of a window to desktop transfer button, we move the window |
87 // temporarily back to where it was initially and make it semi-transparent. | 82 // temporarily back to where it was initially and make it semi-transparent. |
88 GetTarget()->layer()->SetOpacity( | 83 GetTarget()->layer()->SetOpacity( |
89 GetTrayUserItemAtPoint(location) ? kOpacityWhenDraggedOverUserIcon : | 84 GetTrayUserItemAtPoint(location) ? kOpacityWhenDraggedOverUserIcon : |
90 details_.initial_opacity); | 85 details().initial_opacity); |
91 | 86 |
92 next_window_resizer_->Drag(location, event_flags); | 87 next_window_resizer_->Drag(location, event_flags); |
93 | 88 |
94 if (!resizer) | 89 if (!resizer) |
95 return; | 90 return; |
96 | 91 |
97 last_mouse_location_ = location; | 92 last_mouse_location_ = location; |
98 // Show a phantom window for dragging in another root window. | 93 // Show a phantom window for dragging in another root window. |
99 if (HasSecondaryRootWindow()) { | 94 if (HasSecondaryRootWindow()) { |
100 gfx::Point location_in_screen = location; | 95 gfx::Point location_in_screen = location; |
101 wm::ConvertPointToScreen(GetTarget()->parent(), &location_in_screen); | 96 wm::ConvertPointToScreen(GetTarget()->parent(), &location_in_screen); |
102 const bool in_original_root = | 97 const bool in_original_root = |
103 wm::GetRootWindowAt(location_in_screen) == GetTarget()->GetRootWindow(); | 98 wm::GetRootWindowAt(location_in_screen) == GetTarget()->GetRootWindow(); |
104 UpdateDragWindow(GetTarget()->bounds(), in_original_root); | 99 UpdateDragWindow(GetTarget()->bounds(), in_original_root); |
105 } else { | 100 } else { |
106 drag_window_controller_.reset(); | 101 drag_window_controller_.reset(); |
107 } | 102 } |
108 } | 103 } |
109 | 104 |
110 void DragWindowResizer::CompleteDrag() { | 105 void DragWindowResizer::CompleteDrag() { |
111 if (TryDraggingToNewUser()) | 106 if (TryDraggingToNewUser()) |
112 return; | 107 return; |
113 | 108 |
114 next_window_resizer_->CompleteDrag(); | 109 next_window_resizer_->CompleteDrag(); |
115 | 110 |
116 GetTarget()->layer()->SetOpacity(details_.initial_opacity); | 111 GetTarget()->layer()->SetOpacity(details().initial_opacity); |
117 drag_window_controller_.reset(); | 112 drag_window_controller_.reset(); |
118 | 113 |
119 // Check if the destination is another display. | 114 // Check if the destination is another display. |
120 gfx::Point last_mouse_location_in_screen = last_mouse_location_; | 115 gfx::Point last_mouse_location_in_screen = last_mouse_location_; |
121 wm::ConvertPointToScreen(GetTarget()->parent(), | 116 wm::ConvertPointToScreen(GetTarget()->parent(), |
122 &last_mouse_location_in_screen); | 117 &last_mouse_location_in_screen); |
123 gfx::Screen* screen = Shell::GetScreen(); | 118 gfx::Screen* screen = Shell::GetScreen(); |
124 const gfx::Display dst_display = | 119 const gfx::Display dst_display = |
125 screen->GetDisplayNearestPoint(last_mouse_location_in_screen); | 120 screen->GetDisplayNearestPoint(last_mouse_location_in_screen); |
126 | 121 |
(...skipping 23 matching lines...) Expand all Loading... |
150 last_mouse_location_in_screen.x() - dst_bounds.width()); | 145 last_mouse_location_in_screen.x() - dst_bounds.width()); |
151 } | 146 } |
152 GetTarget()->SetBoundsInScreen(dst_bounds, dst_display); | 147 GetTarget()->SetBoundsInScreen(dst_bounds, dst_display); |
153 } | 148 } |
154 } | 149 } |
155 | 150 |
156 void DragWindowResizer::RevertDrag() { | 151 void DragWindowResizer::RevertDrag() { |
157 next_window_resizer_->RevertDrag(); | 152 next_window_resizer_->RevertDrag(); |
158 | 153 |
159 drag_window_controller_.reset(); | 154 drag_window_controller_.reset(); |
160 GetTarget()->layer()->SetOpacity(details_.initial_opacity); | 155 GetTarget()->layer()->SetOpacity(details().initial_opacity); |
161 } | |
162 | |
163 aura::Window* DragWindowResizer::GetTarget() { | |
164 return next_window_resizer_->GetTarget(); | |
165 } | |
166 | |
167 const gfx::Point& DragWindowResizer::GetInitialLocation() const { | |
168 return details_.initial_location_in_parent; | |
169 } | 156 } |
170 | 157 |
171 DragWindowResizer::DragWindowResizer(WindowResizer* next_window_resizer, | 158 DragWindowResizer::DragWindowResizer(WindowResizer* next_window_resizer, |
172 const Details& details) | 159 wm::WindowState* window_state) |
173 : next_window_resizer_(next_window_resizer), | 160 : WindowResizer(window_state), |
174 details_(details), | 161 next_window_resizer_(next_window_resizer), |
175 weak_ptr_factory_(this) { | 162 weak_ptr_factory_(this) { |
176 // The pointer should be confined in one display during resizing a window | 163 // The pointer should be confined in one display during resizing a window |
177 // because the window cannot span two displays at the same time anyway. The | 164 // because the window cannot span two displays at the same time anyway. The |
178 // exception is window/tab dragging operation. During that operation, | 165 // exception is window/tab dragging operation. During that operation, |
179 // |mouse_warp_mode_| should be set to WARP_DRAG so that the user could move a | 166 // |mouse_warp_mode_| should be set to WARP_DRAG so that the user could move a |
180 // window/tab to another display. | 167 // window/tab to another display. |
181 MouseCursorEventFilter* mouse_cursor_filter = | 168 MouseCursorEventFilter* mouse_cursor_filter = |
182 Shell::GetInstance()->mouse_cursor_filter(); | 169 Shell::GetInstance()->mouse_cursor_filter(); |
183 mouse_cursor_filter->set_mouse_warp_mode( | 170 mouse_cursor_filter->set_mouse_warp_mode( |
184 ShouldAllowMouseWarp() ? | 171 ShouldAllowMouseWarp() ? |
185 MouseCursorEventFilter::WARP_DRAG : MouseCursorEventFilter::WARP_NONE); | 172 MouseCursorEventFilter::WARP_DRAG : MouseCursorEventFilter::WARP_NONE); |
186 if (ShouldAllowMouseWarp()) { | 173 if (ShouldAllowMouseWarp()) |
187 mouse_cursor_filter->ShowSharedEdgeIndicator( | 174 mouse_cursor_filter->ShowSharedEdgeIndicator(GetTarget()->GetRootWindow()); |
188 details.window->GetRootWindow()); | |
189 } | |
190 instance_ = this; | 175 instance_ = this; |
191 } | 176 } |
192 | 177 |
193 void DragWindowResizer::UpdateDragWindow(const gfx::Rect& bounds, | 178 void DragWindowResizer::UpdateDragWindow(const gfx::Rect& bounds, |
194 bool in_original_root) { | 179 bool in_original_root) { |
195 if (details_.window_component != HTCAPTION || !ShouldAllowMouseWarp()) | 180 if (details().window_component != HTCAPTION || !ShouldAllowMouseWarp()) |
196 return; | 181 return; |
197 | 182 |
198 // It's available. Show a phantom window on the display if needed. | 183 // It's available. Show a phantom window on the display if needed. |
199 aura::Window* another_root = | 184 aura::Window* another_root = |
200 GetAnotherRootWindow(GetTarget()->GetRootWindow()); | 185 GetAnotherRootWindow(GetTarget()->GetRootWindow()); |
201 const gfx::Rect root_bounds_in_screen(another_root->GetBoundsInScreen()); | 186 const gfx::Rect root_bounds_in_screen(another_root->GetBoundsInScreen()); |
202 const gfx::Rect bounds_in_screen = | 187 const gfx::Rect bounds_in_screen = |
203 ScreenAsh::ConvertRectToScreen(GetTarget()->parent(), bounds); | 188 ScreenAsh::ConvertRectToScreen(GetTarget()->parent(), bounds); |
204 gfx::Rect bounds_in_another_root = | 189 gfx::Rect bounds_in_another_root = |
205 gfx::IntersectRects(root_bounds_in_screen, bounds_in_screen); | 190 gfx::IntersectRects(root_bounds_in_screen, bounds_in_screen); |
(...skipping 19 matching lines...) Expand all Loading... |
225 in_original_root ? 1 : (kMaxOpacity * (1 - fraction_in_another_window)); | 210 in_original_root ? 1 : (kMaxOpacity * (1 - fraction_in_another_window)); |
226 drag_window_controller_->SetOpacity(phantom_opacity); | 211 drag_window_controller_->SetOpacity(phantom_opacity); |
227 GetTarget()->layer()->SetOpacity(window_opacity); | 212 GetTarget()->layer()->SetOpacity(window_opacity); |
228 } else { | 213 } else { |
229 drag_window_controller_.reset(); | 214 drag_window_controller_.reset(); |
230 GetTarget()->layer()->SetOpacity(1.0f); | 215 GetTarget()->layer()->SetOpacity(1.0f); |
231 } | 216 } |
232 } | 217 } |
233 | 218 |
234 bool DragWindowResizer::ShouldAllowMouseWarp() { | 219 bool DragWindowResizer::ShouldAllowMouseWarp() { |
235 return (details_.window_component == HTCAPTION) && | 220 return (details().window_component == HTCAPTION) && |
236 !views::corewm::GetTransientParent(GetTarget()) && | 221 !views::corewm::GetTransientParent(GetTarget()) && |
237 (GetTarget()->type() == ui::wm::WINDOW_TYPE_NORMAL || | 222 (GetTarget()->type() == ui::wm::WINDOW_TYPE_NORMAL || |
238 GetTarget()->type() == ui::wm::WINDOW_TYPE_PANEL); | 223 GetTarget()->type() == ui::wm::WINDOW_TYPE_PANEL); |
239 } | 224 } |
240 | 225 |
241 TrayUser* DragWindowResizer::GetTrayUserItemAtPoint( | 226 TrayUser* DragWindowResizer::GetTrayUserItemAtPoint( |
242 const gfx::Point& point_in_screen) { | 227 const gfx::Point& point_in_screen) { |
243 // Unit tests might not have an ash shell. | 228 // Unit tests might not have an ash shell. |
244 if (!ash::Shell::GetInstance()) | 229 if (!ash::Shell::GetInstance()) |
245 return NULL; | 230 return NULL; |
246 | 231 |
247 // Check that this is a drag move operation from a suitable window. | 232 // Check that this is a drag move operation from a suitable window. |
248 if (details_.window_component != HTCAPTION || | 233 if (details().window_component != HTCAPTION || |
249 views::corewm::GetTransientParent(GetTarget()) || | 234 views::corewm::GetTransientParent(GetTarget()) || |
250 (GetTarget()->type() != ui::wm::WINDOW_TYPE_NORMAL && | 235 (GetTarget()->type() != ui::wm::WINDOW_TYPE_NORMAL && |
251 GetTarget()->type() != ui::wm::WINDOW_TYPE_PANEL && | 236 GetTarget()->type() != ui::wm::WINDOW_TYPE_PANEL && |
252 GetTarget()->type() != ui::wm::WINDOW_TYPE_POPUP)) | 237 GetTarget()->type() != ui::wm::WINDOW_TYPE_POPUP)) |
253 return NULL; | 238 return NULL; |
254 | 239 |
255 // We only allow to drag the window onto a tray of it's own RootWindow. | 240 // We only allow to drag the window onto a tray of it's own RootWindow. |
256 SystemTray* tray = internal::GetRootWindowController( | 241 SystemTray* tray = internal::GetRootWindowController( |
257 details_.window->GetRootWindow())->GetSystemTray(); | 242 GetTarget()->GetRootWindow())->GetSystemTray(); |
258 | 243 |
259 // Again - unit tests might not have a tray. | 244 // Again - unit tests might not have a tray. |
260 if (!tray) | 245 if (!tray) |
261 return NULL; | 246 return NULL; |
262 | 247 |
263 const std::vector<internal::TrayUser*> tray_users = tray->GetTrayUserItems(); | 248 const std::vector<internal::TrayUser*> tray_users = tray->GetTrayUserItems(); |
264 if (tray_users.size() <= 1) | 249 if (tray_users.size() <= 1) |
265 return NULL; | 250 return NULL; |
266 | 251 |
267 std::vector<internal::TrayUser*>::const_iterator it = tray_users.begin(); | 252 std::vector<internal::TrayUser*>::const_iterator it = tray_users.begin(); |
(...skipping 10 matching lines...) Expand all Loading... |
278 if (!tray_user) | 263 if (!tray_user) |
279 return false; | 264 return false; |
280 | 265 |
281 // We have to avoid a brief flash caused by the RevertDrag operation. | 266 // We have to avoid a brief flash caused by the RevertDrag operation. |
282 // To do this, we first set the opacity of our target window to 0, so that no | 267 // To do this, we first set the opacity of our target window to 0, so that no |
283 // matter what the RevertDrag does the window will stay hidden. Then transfer | 268 // matter what the RevertDrag does the window will stay hidden. Then transfer |
284 // the window to the new owner (which will hide it). RevertDrag will then do | 269 // the window to the new owner (which will hide it). RevertDrag will then do |
285 // it's thing and return the transparency to its original value. | 270 // it's thing and return the transparency to its original value. |
286 int old_opacity = GetTarget()->layer()->opacity(); | 271 int old_opacity = GetTarget()->layer()->opacity(); |
287 GetTarget()->layer()->SetOpacity(0); | 272 GetTarget()->layer()->SetOpacity(0); |
288 GetTarget()->SetBounds(details_.initial_bounds_in_parent); | 273 GetTarget()->SetBounds(details().initial_bounds_in_parent); |
289 if (!tray_user->TransferWindowToUser(details_.window)) { | 274 if (!tray_user->TransferWindowToUser(GetTarget())) { |
290 GetTarget()->layer()->SetOpacity(old_opacity); | 275 GetTarget()->layer()->SetOpacity(old_opacity); |
291 return false; | 276 return false; |
292 } | 277 } |
293 RevertDrag(); | 278 RevertDrag(); |
294 return true; | 279 return true; |
295 } | 280 } |
296 | 281 |
297 } // namespace internal | 282 } // namespace internal |
298 } // namespace ash | 283 } // namespace ash |
OLD | NEW |