| 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 |