| 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/workspace/multi_window_resize_controller.h" | 5 #include "ash/wm/workspace/multi_window_resize_controller.h" |
| 6 | 6 |
| 7 #include "ash/public/cpp/shell_window_ids.h" | 7 #include "ash/public/cpp/shell_window_ids.h" |
| 8 #include "ash/root_window_controller.h" | 8 #include "ash/root_window_controller.h" |
| 9 #include "ash/wm/window_state_aura.h" |
| 9 #include "ash/wm/workspace/workspace_window_resizer.h" | 10 #include "ash/wm/workspace/workspace_window_resizer.h" |
| 10 #include "ash/wm_window.h" | 11 #include "ash/wm_window.h" |
| 12 #include "ui/aura/window.h" |
| 13 #include "ui/aura/window_delegate.h" |
| 11 #include "ui/base/cursor/cursor.h" | 14 #include "ui/base/cursor/cursor.h" |
| 12 #include "ui/base/hit_test.h" | 15 #include "ui/base/hit_test.h" |
| 13 #include "ui/display/screen.h" | 16 #include "ui/display/screen.h" |
| 14 #include "ui/gfx/canvas.h" | 17 #include "ui/gfx/canvas.h" |
| 15 #include "ui/gfx/image/image.h" | 18 #include "ui/gfx/image/image.h" |
| 16 #include "ui/views/view.h" | 19 #include "ui/views/view.h" |
| 17 #include "ui/views/widget/widget.h" | 20 #include "ui/views/widget/widget.h" |
| 18 #include "ui/views/widget/widget_delegate.h" | 21 #include "ui/views/widget/widget_delegate.h" |
| 19 #include "ui/wm/core/compound_event_filter.h" | 22 #include "ui/wm/core/compound_event_filter.h" |
| 23 #include "ui/wm/core/coordinate_conversion.h" |
| 24 #include "ui/wm/core/window_animations.h" |
| 20 | 25 |
| 21 namespace ash { | 26 namespace ash { |
| 22 namespace { | 27 namespace { |
| 23 | 28 |
| 24 // Delay before showing. | 29 // Delay before showing. |
| 25 const int kShowDelayMS = 400; | 30 const int kShowDelayMS = 400; |
| 26 | 31 |
| 27 // Delay before hiding. | 32 // Delay before hiding. |
| 28 const int kHideDelayMS = 500; | 33 const int kHideDelayMS = 500; |
| 29 | 34 |
| 30 // Padding from the bottom/right edge the resize widget is shown at. | 35 // Padding from the bottom/right edge the resize widget is shown at. |
| 31 const int kResizeWidgetPadding = 15; | 36 const int kResizeWidgetPadding = 15; |
| 32 | 37 |
| 33 bool ContainsX(WmWindow* window, int x) { | 38 gfx::Point ConvertPointFromScreen(aura::Window* window, |
| 34 return x >= 0 && x <= window->GetBounds().width(); | 39 const gfx::Point& point) { |
| 40 gfx::Point result(point); |
| 41 ::wm::ConvertPointFromScreen(window, &result); |
| 42 return result; |
| 35 } | 43 } |
| 36 | 44 |
| 37 bool ContainsScreenX(WmWindow* window, int x_in_screen) { | 45 gfx::Point ConvertPointToTarget(aura::Window* source, |
| 46 aura::Window* target, |
| 47 const gfx::Point& point) { |
| 48 gfx::Point result(point); |
| 49 aura::Window::ConvertPointToTarget(source, target, &result); |
| 50 return result; |
| 51 } |
| 52 |
| 53 gfx::Rect ConvertRectToScreen(aura::Window* source, const gfx::Rect& rect) { |
| 54 gfx::Rect result(rect); |
| 55 ::wm::ConvertRectToScreen(source, &result); |
| 56 return result; |
| 57 } |
| 58 |
| 59 bool ContainsX(aura::Window* window, int x) { |
| 60 return x >= 0 && x <= window->bounds().width(); |
| 61 } |
| 62 |
| 63 bool ContainsScreenX(aura::Window* window, int x_in_screen) { |
| 38 gfx::Point window_loc = | 64 gfx::Point window_loc = |
| 39 window->ConvertPointFromScreen(gfx::Point(x_in_screen, 0)); | 65 ConvertPointFromScreen(window, gfx::Point(x_in_screen, 0)); |
| 40 return ContainsX(window, window_loc.x()); | 66 return ContainsX(window, window_loc.x()); |
| 41 } | 67 } |
| 42 | 68 |
| 43 bool ContainsY(WmWindow* window, int y) { | 69 bool ContainsY(aura::Window* window, int y) { |
| 44 return y >= 0 && y <= window->GetBounds().height(); | 70 return y >= 0 && y <= window->bounds().height(); |
| 45 } | 71 } |
| 46 | 72 |
| 47 bool ContainsScreenY(WmWindow* window, int y_in_screen) { | 73 bool ContainsScreenY(aura::Window* window, int y_in_screen) { |
| 48 gfx::Point window_loc = | 74 gfx::Point window_loc = |
| 49 window->ConvertPointFromScreen(gfx::Point(0, y_in_screen)); | 75 ConvertPointFromScreen(window, gfx::Point(0, y_in_screen)); |
| 50 return ContainsY(window, window_loc.y()); | 76 return ContainsY(window, window_loc.y()); |
| 51 } | 77 } |
| 52 | 78 |
| 53 bool Intersects(int x1, int max_1, int x2, int max_2) { | 79 bool Intersects(int x1, int max_1, int x2, int max_2) { |
| 54 return x2 <= max_1 && max_2 > x1; | 80 return x2 <= max_1 && max_2 > x1; |
| 55 } | 81 } |
| 56 | 82 |
| 57 } // namespace | 83 } // namespace |
| 58 | 84 |
| 59 // View contained in the widget. Passes along mouse events to the | 85 // View contained in the widget. Passes along mouse events to the |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 direction == other.direction; | 198 direction == other.direction; |
| 173 } | 199 } |
| 174 | 200 |
| 175 MultiWindowResizeController::MultiWindowResizeController() {} | 201 MultiWindowResizeController::MultiWindowResizeController() {} |
| 176 | 202 |
| 177 MultiWindowResizeController::~MultiWindowResizeController() { | 203 MultiWindowResizeController::~MultiWindowResizeController() { |
| 178 window_resizer_.reset(); | 204 window_resizer_.reset(); |
| 179 Hide(); | 205 Hide(); |
| 180 } | 206 } |
| 181 | 207 |
| 182 void MultiWindowResizeController::Show(WmWindow* window, | 208 void MultiWindowResizeController::Show(aura::Window* window, |
| 183 int component, | 209 int component, |
| 184 const gfx::Point& point_in_window) { | 210 const gfx::Point& point_in_window) { |
| 185 // When the resize widget is showing we ignore Show() requests. Instead we | 211 // When the resize widget is showing we ignore Show() requests. Instead we |
| 186 // only care about mouse movements from MouseWatcher. This is necessary as | 212 // only care about mouse movements from MouseWatcher. This is necessary as |
| 187 // WorkspaceEventHandler only sees mouse movements over the windows, not all | 213 // WorkspaceEventHandler only sees mouse movements over the windows, not all |
| 188 // windows or over the desktop. | 214 // windows or over the desktop. |
| 189 if (resize_widget_) | 215 if (resize_widget_) |
| 190 return; | 216 return; |
| 191 | 217 |
| 192 ResizeWindows windows(DetermineWindows(window, component, point_in_window)); | 218 ResizeWindows windows(DetermineWindows(window, component, point_in_window)); |
| 193 if (IsShowing() && windows_.Equals(windows)) | 219 if (IsShowing() && windows_.Equals(windows)) |
| 194 return; | 220 return; |
| 195 | 221 |
| 196 Hide(); | 222 Hide(); |
| 197 if (!windows.is_valid()) { | 223 if (!windows.is_valid()) { |
| 198 windows_ = ResizeWindows(); | 224 windows_ = ResizeWindows(); |
| 199 return; | 225 return; |
| 200 } | 226 } |
| 201 | 227 |
| 202 windows_ = windows; | 228 windows_ = windows; |
| 203 windows_.window1->aura_window()->AddObserver(this); | 229 windows_.window1->AddObserver(this); |
| 204 windows_.window2->aura_window()->AddObserver(this); | 230 windows_.window2->AddObserver(this); |
| 205 show_location_in_parent_ = | 231 show_location_in_parent_ = |
| 206 window->ConvertPointToTarget(window->GetParent(), point_in_window); | 232 ConvertPointToTarget(window, window->parent(), point_in_window); |
| 207 show_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kShowDelayMS), | 233 show_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kShowDelayMS), |
| 208 this, | 234 this, |
| 209 &MultiWindowResizeController::ShowIfValidMouseLocation); | 235 &MultiWindowResizeController::ShowIfValidMouseLocation); |
| 210 } | 236 } |
| 211 | 237 |
| 212 void MultiWindowResizeController::Hide() { | 238 void MultiWindowResizeController::Hide() { |
| 213 if (window_resizer_) | 239 if (window_resizer_) |
| 214 return; // Ignore hides while actively resizing. | 240 return; // Ignore hides while actively resizing. |
| 215 | 241 |
| 216 if (windows_.window1) { | 242 if (windows_.window1) { |
| 217 windows_.window1->aura_window()->RemoveObserver(this); | 243 windows_.window1->RemoveObserver(this); |
| 218 windows_.window1 = NULL; | 244 windows_.window1 = nullptr; |
| 219 } | 245 } |
| 220 if (windows_.window2) { | 246 if (windows_.window2) { |
| 221 windows_.window2->aura_window()->RemoveObserver(this); | 247 windows_.window2->RemoveObserver(this); |
| 222 windows_.window2 = NULL; | 248 windows_.window2 = nullptr; |
| 223 } | 249 } |
| 224 | 250 |
| 225 show_timer_.Stop(); | 251 show_timer_.Stop(); |
| 226 | 252 |
| 227 if (!resize_widget_) | 253 if (!resize_widget_) |
| 228 return; | 254 return; |
| 229 | 255 |
| 230 for (size_t i = 0; i < windows_.other_windows.size(); ++i) | 256 for (size_t i = 0; i < windows_.other_windows.size(); ++i) |
| 231 windows_.other_windows[i]->aura_window()->RemoveObserver(this); | 257 windows_.other_windows[i]->RemoveObserver(this); |
| 232 mouse_watcher_.reset(); | 258 mouse_watcher_.reset(); |
| 233 resize_widget_.reset(); | 259 resize_widget_.reset(); |
| 234 windows_ = ResizeWindows(); | 260 windows_ = ResizeWindows(); |
| 235 } | 261 } |
| 236 | 262 |
| 237 void MultiWindowResizeController::MouseMovedOutOfHost() { | 263 void MultiWindowResizeController::MouseMovedOutOfHost() { |
| 238 Hide(); | 264 Hide(); |
| 239 } | 265 } |
| 240 | 266 |
| 241 void MultiWindowResizeController::OnWindowDestroying(aura::Window* window) { | 267 void MultiWindowResizeController::OnWindowDestroying(aura::Window* window) { |
| 242 // Have to explicitly reset the WindowResizer, otherwise Hide() does nothing. | 268 // Have to explicitly reset the WindowResizer, otherwise Hide() does nothing. |
| 243 window_resizer_.reset(); | 269 window_resizer_.reset(); |
| 244 Hide(); | 270 Hide(); |
| 245 } | 271 } |
| 246 | 272 |
| 247 MultiWindowResizeController::ResizeWindows | 273 MultiWindowResizeController::ResizeWindows |
| 248 MultiWindowResizeController::DetermineWindowsFromScreenPoint( | 274 MultiWindowResizeController::DetermineWindowsFromScreenPoint( |
| 249 WmWindow* window) const { | 275 aura::Window* window) const { |
| 250 gfx::Point mouse_location( | 276 gfx::Point mouse_location( |
| 251 display::Screen::GetScreen()->GetCursorScreenPoint()); | 277 display::Screen::GetScreen()->GetCursorScreenPoint()); |
| 252 mouse_location = window->ConvertPointFromScreen(mouse_location); | 278 mouse_location = ConvertPointFromScreen(window, mouse_location); |
| 253 const int component = window->GetNonClientComponent(mouse_location); | 279 const int component = |
| 280 window->delegate() |
| 281 ? window->delegate()->GetNonClientComponent(mouse_location) |
| 282 : HTNOWHERE; |
| 254 return DetermineWindows(window, component, mouse_location); | 283 return DetermineWindows(window, component, mouse_location); |
| 255 } | 284 } |
| 256 | 285 |
| 257 void MultiWindowResizeController::CreateMouseWatcher() { | 286 void MultiWindowResizeController::CreateMouseWatcher() { |
| 258 mouse_watcher_.reset( | 287 mouse_watcher_.reset( |
| 259 new views::MouseWatcher(new ResizeMouseWatcherHost(this), this)); | 288 new views::MouseWatcher(new ResizeMouseWatcherHost(this), this)); |
| 260 mouse_watcher_->set_notify_on_exit_time( | 289 mouse_watcher_->set_notify_on_exit_time( |
| 261 base::TimeDelta::FromMilliseconds(kHideDelayMS)); | 290 base::TimeDelta::FromMilliseconds(kHideDelayMS)); |
| 262 mouse_watcher_->Start(); | 291 mouse_watcher_->Start(); |
| 263 } | 292 } |
| 264 | 293 |
| 265 MultiWindowResizeController::ResizeWindows | 294 MultiWindowResizeController::ResizeWindows |
| 266 MultiWindowResizeController::DetermineWindows(WmWindow* window, | 295 MultiWindowResizeController::DetermineWindows(aura::Window* window, |
| 267 int window_component, | 296 int window_component, |
| 268 const gfx::Point& point) const { | 297 const gfx::Point& point) const { |
| 269 ResizeWindows result; | 298 ResizeWindows result; |
| 270 gfx::Point point_in_parent = | 299 gfx::Point point_in_parent = |
| 271 window->ConvertPointToTarget(window->GetParent(), point); | 300 ConvertPointToTarget(window, window->parent(), point); |
| 272 switch (window_component) { | 301 switch (window_component) { |
| 273 case HTRIGHT: | 302 case HTRIGHT: |
| 274 result.direction = LEFT_RIGHT; | 303 result.direction = LEFT_RIGHT; |
| 275 result.window1 = window; | 304 result.window1 = window; |
| 276 result.window2 = FindWindowByEdge( | 305 result.window2 = FindWindowByEdge( |
| 277 window, HTLEFT, window->GetBounds().right(), point_in_parent.y()); | 306 window, HTLEFT, window->bounds().right(), point_in_parent.y()); |
| 278 break; | 307 break; |
| 279 case HTLEFT: | 308 case HTLEFT: |
| 280 result.direction = LEFT_RIGHT; | 309 result.direction = LEFT_RIGHT; |
| 281 result.window1 = FindWindowByEdge( | 310 result.window1 = FindWindowByEdge(window, HTRIGHT, window->bounds().x(), |
| 282 window, HTRIGHT, window->GetBounds().x(), point_in_parent.y()); | 311 point_in_parent.y()); |
| 283 result.window2 = window; | 312 result.window2 = window; |
| 284 break; | 313 break; |
| 285 case HTTOP: | 314 case HTTOP: |
| 286 result.direction = TOP_BOTTOM; | 315 result.direction = TOP_BOTTOM; |
| 287 result.window1 = FindWindowByEdge(window, HTBOTTOM, point_in_parent.x(), | 316 result.window1 = FindWindowByEdge(window, HTBOTTOM, point_in_parent.x(), |
| 288 window->GetBounds().y()); | 317 window->bounds().y()); |
| 289 result.window2 = window; | 318 result.window2 = window; |
| 290 break; | 319 break; |
| 291 case HTBOTTOM: | 320 case HTBOTTOM: |
| 292 result.direction = TOP_BOTTOM; | 321 result.direction = TOP_BOTTOM; |
| 293 result.window1 = window; | 322 result.window1 = window; |
| 294 result.window2 = FindWindowByEdge(window, HTTOP, point_in_parent.x(), | 323 result.window2 = FindWindowByEdge(window, HTTOP, point_in_parent.x(), |
| 295 window->GetBounds().bottom()); | 324 window->bounds().bottom()); |
| 296 break; | 325 break; |
| 297 default: | 326 default: |
| 298 break; | 327 break; |
| 299 } | 328 } |
| 300 return result; | 329 return result; |
| 301 } | 330 } |
| 302 | 331 |
| 303 WmWindow* MultiWindowResizeController::FindWindowByEdge( | 332 aura::Window* MultiWindowResizeController::FindWindowByEdge( |
| 304 WmWindow* window_to_ignore, | 333 aura::Window* window_to_ignore, |
| 305 int edge_want, | 334 int edge_want, |
| 306 int x_in_parent, | 335 int x_in_parent, |
| 307 int y_in_parent) const { | 336 int y_in_parent) const { |
| 308 WmWindow* parent = window_to_ignore->GetParent(); | 337 aura::Window* parent = window_to_ignore->parent(); |
| 309 std::vector<WmWindow*> windows = parent->GetChildren(); | 338 const aura::Window::Windows& windows = parent->children(); |
| 310 for (auto i = windows.rbegin(); i != windows.rend(); ++i) { | 339 for (auto i = windows.rbegin(); i != windows.rend(); ++i) { |
| 311 WmWindow* window = *i; | 340 aura::Window* window = *i; |
| 312 if (window == window_to_ignore || !window->IsVisible()) | 341 if (window == window_to_ignore || !window->IsVisible()) |
| 313 continue; | 342 continue; |
| 314 | 343 |
| 315 // Ignore windows without a non-client area. | 344 // Ignore windows without a non-client area. |
| 316 if (!window->HasNonClientArea()) | 345 if (!window->delegate()) |
| 317 continue; | 346 continue; |
| 318 | 347 |
| 319 gfx::Point p = parent->ConvertPointToTarget( | 348 gfx::Point p = ConvertPointToTarget(parent, window, |
| 320 window, gfx::Point(x_in_parent, y_in_parent)); | 349 gfx::Point(x_in_parent, y_in_parent)); |
| 321 switch (edge_want) { | 350 switch (edge_want) { |
| 322 case HTLEFT: | 351 case HTLEFT: |
| 323 if (ContainsY(window, p.y()) && p.x() == 0) | 352 if (ContainsY(window, p.y()) && p.x() == 0) |
| 324 return window; | 353 return window; |
| 325 break; | 354 break; |
| 326 case HTRIGHT: | 355 case HTRIGHT: |
| 327 if (ContainsY(window, p.y()) && p.x() == window->GetBounds().width()) | 356 if (ContainsY(window, p.y()) && p.x() == window->bounds().width()) |
| 328 return window; | 357 return window; |
| 329 break; | 358 break; |
| 330 case HTTOP: | 359 case HTTOP: |
| 331 if (ContainsX(window, p.x()) && p.y() == 0) | 360 if (ContainsX(window, p.x()) && p.y() == 0) |
| 332 return window; | 361 return window; |
| 333 break; | 362 break; |
| 334 case HTBOTTOM: | 363 case HTBOTTOM: |
| 335 if (ContainsX(window, p.x()) && p.y() == window->GetBounds().height()) | 364 if (ContainsX(window, p.x()) && p.y() == window->bounds().height()) |
| 336 return window; | 365 return window; |
| 337 break; | 366 break; |
| 338 default: | 367 default: |
| 339 NOTREACHED(); | 368 NOTREACHED(); |
| 340 } | 369 } |
| 341 // Window doesn't contain the edge, but if window contains |point| | 370 // Window doesn't contain the edge, but if window contains |point| |
| 342 // it's obscuring any other window that could be at the location. | 371 // it's obscuring any other window that could be at the location. |
| 343 if (window->GetBounds().Contains(x_in_parent, y_in_parent)) | 372 if (window->bounds().Contains(x_in_parent, y_in_parent)) |
| 344 return NULL; | 373 return NULL; |
| 345 } | 374 } |
| 346 return NULL; | 375 return NULL; |
| 347 } | 376 } |
| 348 | 377 |
| 349 WmWindow* MultiWindowResizeController::FindWindowTouching( | 378 aura::Window* MultiWindowResizeController::FindWindowTouching( |
| 350 WmWindow* window, | 379 aura::Window* window, |
| 351 Direction direction) const { | 380 Direction direction) const { |
| 352 int right = window->GetBounds().right(); | 381 int right = window->bounds().right(); |
| 353 int bottom = window->GetBounds().bottom(); | 382 int bottom = window->bounds().bottom(); |
| 354 WmWindow* parent = window->GetParent(); | 383 aura::Window* parent = window->parent(); |
| 355 std::vector<WmWindow*> windows = parent->GetChildren(); | 384 const aura::Window::Windows& windows = parent->children(); |
| 356 for (auto i = windows.rbegin(); i != windows.rend(); ++i) { | 385 for (auto i = windows.rbegin(); i != windows.rend(); ++i) { |
| 357 WmWindow* other = *i; | 386 aura::Window* other = *i; |
| 358 if (other == window || !other->IsVisible()) | 387 if (other == window || !other->IsVisible()) |
| 359 continue; | 388 continue; |
| 360 switch (direction) { | 389 switch (direction) { |
| 361 case TOP_BOTTOM: | 390 case TOP_BOTTOM: |
| 362 if (other->GetBounds().y() == bottom && | 391 if (other->bounds().y() == bottom && |
| 363 Intersects(other->GetBounds().x(), other->GetBounds().right(), | 392 Intersects(other->bounds().x(), other->bounds().right(), |
| 364 window->GetBounds().x(), window->GetBounds().right())) { | 393 window->bounds().x(), window->bounds().right())) { |
| 365 return other; | 394 return other; |
| 366 } | 395 } |
| 367 break; | 396 break; |
| 368 case LEFT_RIGHT: | 397 case LEFT_RIGHT: |
| 369 if (other->GetBounds().x() == right && | 398 if (other->bounds().x() == right && |
| 370 Intersects(other->GetBounds().y(), other->GetBounds().bottom(), | 399 Intersects(other->bounds().y(), other->bounds().bottom(), |
| 371 window->GetBounds().y(), window->GetBounds().bottom())) { | 400 window->bounds().y(), window->bounds().bottom())) { |
| 372 return other; | 401 return other; |
| 373 } | 402 } |
| 374 break; | 403 break; |
| 375 default: | 404 default: |
| 376 NOTREACHED(); | 405 NOTREACHED(); |
| 377 } | 406 } |
| 378 } | 407 } |
| 379 return NULL; | 408 return NULL; |
| 380 } | 409 } |
| 381 | 410 |
| 382 void MultiWindowResizeController::FindWindowsTouching( | 411 void MultiWindowResizeController::FindWindowsTouching( |
| 383 WmWindow* start, | 412 aura::Window* start, |
| 384 Direction direction, | 413 Direction direction, |
| 385 std::vector<WmWindow*>* others) const { | 414 aura::Window::Windows* others) const { |
| 386 while (start) { | 415 while (start) { |
| 387 start = FindWindowTouching(start, direction); | 416 start = FindWindowTouching(start, direction); |
| 388 if (start) | 417 if (start) |
| 389 others->push_back(start); | 418 others->push_back(start); |
| 390 } | 419 } |
| 391 } | 420 } |
| 392 | 421 |
| 393 void MultiWindowResizeController::ShowIfValidMouseLocation() { | 422 void MultiWindowResizeController::ShowIfValidMouseLocation() { |
| 394 if (DetermineWindowsFromScreenPoint(windows_.window1).Equals(windows_) || | 423 if (DetermineWindowsFromScreenPoint(windows_.window1).Equals(windows_) || |
| 395 DetermineWindowsFromScreenPoint(windows_.window2).Equals(windows_)) { | 424 DetermineWindowsFromScreenPoint(windows_.window2).Equals(windows_)) { |
| 396 ShowNow(); | 425 ShowNow(); |
| 397 } else { | 426 } else { |
| 398 Hide(); | 427 Hide(); |
| 399 } | 428 } |
| 400 } | 429 } |
| 401 | 430 |
| 402 void MultiWindowResizeController::ShowNow() { | 431 void MultiWindowResizeController::ShowNow() { |
| 403 DCHECK(!resize_widget_.get()); | 432 DCHECK(!resize_widget_.get()); |
| 404 DCHECK(windows_.is_valid()); | 433 DCHECK(windows_.is_valid()); |
| 405 show_timer_.Stop(); | 434 show_timer_.Stop(); |
| 406 resize_widget_.reset(new views::Widget); | 435 resize_widget_.reset(new views::Widget); |
| 407 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); | 436 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); |
| 408 params.name = "MultiWindowResizeController"; | 437 params.name = "MultiWindowResizeController"; |
| 409 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 438 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
| 410 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 439 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
| 411 windows_.window1->GetRootWindowController() | 440 RootWindowController::ForWindow(windows_.window1) |
| 412 ->ConfigureWidgetInitParamsForContainer( | 441 ->ConfigureWidgetInitParamsForContainer( |
| 413 resize_widget_.get(), kShellWindowId_AlwaysOnTopContainer, ¶ms); | 442 resize_widget_.get(), kShellWindowId_AlwaysOnTopContainer, ¶ms); |
| 414 ResizeView* view = new ResizeView(this, windows_.direction); | 443 ResizeView* view = new ResizeView(this, windows_.direction); |
| 415 resize_widget_->set_focus_on_creation(false); | 444 resize_widget_->set_focus_on_creation(false); |
| 416 resize_widget_->Init(params); | 445 resize_widget_->Init(params); |
| 417 WmWindow::Get(resize_widget_->GetNativeWindow()) | 446 ::wm::SetWindowVisibilityAnimationType( |
| 418 ->SetVisibilityAnimationType(::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); | 447 resize_widget_->GetNativeWindow(), |
| 448 ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); |
| 419 resize_widget_->SetContentsView(view); | 449 resize_widget_->SetContentsView(view); |
| 420 show_bounds_in_screen_ = windows_.window1->GetParent()->ConvertRectToScreen( | 450 show_bounds_in_screen_ = ConvertRectToScreen( |
| 451 windows_.window1->parent(), |
| 421 CalculateResizeWidgetBounds(show_location_in_parent_)); | 452 CalculateResizeWidgetBounds(show_location_in_parent_)); |
| 422 resize_widget_->SetBounds(show_bounds_in_screen_); | 453 resize_widget_->SetBounds(show_bounds_in_screen_); |
| 423 resize_widget_->Show(); | 454 resize_widget_->Show(); |
| 424 CreateMouseWatcher(); | 455 CreateMouseWatcher(); |
| 425 } | 456 } |
| 426 | 457 |
| 427 bool MultiWindowResizeController::IsShowing() const { | 458 bool MultiWindowResizeController::IsShowing() const { |
| 428 return resize_widget_.get() || show_timer_.IsRunning(); | 459 return resize_widget_.get() || show_timer_.IsRunning(); |
| 429 } | 460 } |
| 430 | 461 |
| 431 void MultiWindowResizeController::StartResize( | 462 void MultiWindowResizeController::StartResize( |
| 432 const gfx::Point& location_in_screen) { | 463 const gfx::Point& location_in_screen) { |
| 433 DCHECK(!window_resizer_.get()); | 464 DCHECK(!window_resizer_.get()); |
| 434 DCHECK(windows_.is_valid()); | 465 DCHECK(windows_.is_valid()); |
| 435 gfx::Point location_in_parent = | 466 gfx::Point location_in_parent = |
| 436 windows_.window2->GetParent()->ConvertPointFromScreen(location_in_screen); | 467 ConvertPointFromScreen(windows_.window2->parent(), location_in_screen); |
| 437 std::vector<WmWindow*> windows; | 468 aura::Window::Windows windows; |
| 438 windows.push_back(windows_.window2); | 469 windows.push_back(windows_.window2); |
| 439 DCHECK(windows_.other_windows.empty()); | 470 DCHECK(windows_.other_windows.empty()); |
| 440 FindWindowsTouching(windows_.window2, windows_.direction, | 471 FindWindowsTouching(windows_.window2, windows_.direction, |
| 441 &windows_.other_windows); | 472 &windows_.other_windows); |
| 442 for (size_t i = 0; i < windows_.other_windows.size(); ++i) { | 473 for (size_t i = 0; i < windows_.other_windows.size(); ++i) { |
| 443 windows_.other_windows[i]->aura_window()->AddObserver(this); | 474 windows_.other_windows[i]->AddObserver(this); |
| 444 windows.push_back(windows_.other_windows[i]); | 475 windows.push_back(windows_.other_windows[i]); |
| 445 } | 476 } |
| 446 int component = windows_.direction == LEFT_RIGHT ? HTRIGHT : HTBOTTOM; | 477 int component = windows_.direction == LEFT_RIGHT ? HTRIGHT : HTBOTTOM; |
| 447 wm::WindowState* window_state = windows_.window1->GetWindowState(); | 478 wm::WindowState* window_state = wm::GetWindowState(windows_.window1); |
| 448 window_state->CreateDragDetails(location_in_parent, component, | 479 window_state->CreateDragDetails(location_in_parent, component, |
| 449 aura::client::WINDOW_MOVE_SOURCE_MOUSE); | 480 aura::client::WINDOW_MOVE_SOURCE_MOUSE); |
| 450 window_resizer_.reset(WorkspaceWindowResizer::Create(window_state, windows)); | 481 window_resizer_.reset(WorkspaceWindowResizer::Create( |
| 482 window_state, WmWindow::FromAuraWindows(windows))); |
| 451 | 483 |
| 452 // Do not hide the resize widget while a drag is active. | 484 // Do not hide the resize widget while a drag is active. |
| 453 mouse_watcher_.reset(); | 485 mouse_watcher_.reset(); |
| 454 } | 486 } |
| 455 | 487 |
| 456 void MultiWindowResizeController::Resize(const gfx::Point& location_in_screen, | 488 void MultiWindowResizeController::Resize(const gfx::Point& location_in_screen, |
| 457 int event_flags) { | 489 int event_flags) { |
| 458 gfx::Point location_in_parent = | 490 gfx::Point location_in_parent = |
| 459 windows_.window1->GetParent()->ConvertPointFromScreen(location_in_screen); | 491 ConvertPointFromScreen(windows_.window1->parent(), location_in_screen); |
| 460 window_resizer_->Drag(location_in_parent, event_flags); | 492 window_resizer_->Drag(location_in_parent, event_flags); |
| 461 gfx::Rect bounds = windows_.window1->GetParent()->ConvertRectToScreen( | 493 gfx::Rect bounds = |
| 462 CalculateResizeWidgetBounds(location_in_parent)); | 494 ConvertRectToScreen(windows_.window1->parent(), |
| 495 CalculateResizeWidgetBounds(location_in_parent)); |
| 463 | 496 |
| 464 if (windows_.direction == LEFT_RIGHT) | 497 if (windows_.direction == LEFT_RIGHT) |
| 465 bounds.set_y(show_bounds_in_screen_.y()); | 498 bounds.set_y(show_bounds_in_screen_.y()); |
| 466 else | 499 else |
| 467 bounds.set_x(show_bounds_in_screen_.x()); | 500 bounds.set_x(show_bounds_in_screen_.x()); |
| 468 resize_widget_->SetBounds(bounds); | 501 resize_widget_->SetBounds(bounds); |
| 469 } | 502 } |
| 470 | 503 |
| 471 void MultiWindowResizeController::CompleteResize() { | 504 void MultiWindowResizeController::CompleteResize() { |
| 472 window_resizer_->CompleteDrag(); | 505 window_resizer_->CompleteDrag(); |
| 473 window_resizer_->GetTarget()->GetWindowState()->DeleteDragDetails(); | 506 window_resizer_->GetTarget()->GetWindowState()->DeleteDragDetails(); |
| 474 window_resizer_.reset(); | 507 window_resizer_.reset(); |
| 475 | 508 |
| 476 // Mouse may still be over resizer, if not hide. | 509 // Mouse may still be over resizer, if not hide. |
| 477 gfx::Point screen_loc = display::Screen::GetScreen()->GetCursorScreenPoint(); | 510 gfx::Point screen_loc = display::Screen::GetScreen()->GetCursorScreenPoint(); |
| 478 if (!resize_widget_->GetWindowBoundsInScreen().Contains(screen_loc)) { | 511 if (!resize_widget_->GetWindowBoundsInScreen().Contains(screen_loc)) { |
| 479 Hide(); | 512 Hide(); |
| 480 } else { | 513 } else { |
| 481 // If the mouse is over the resizer we need to remove observers on any of | 514 // If the mouse is over the resizer we need to remove observers on any of |
| 482 // the |other_windows|. If we start another resize we'll recalculate the | 515 // the |other_windows|. If we start another resize we'll recalculate the |
| 483 // |other_windows| and invoke AddObserver() as necessary. | 516 // |other_windows| and invoke AddObserver() as necessary. |
| 484 for (size_t i = 0; i < windows_.other_windows.size(); ++i) | 517 for (size_t i = 0; i < windows_.other_windows.size(); ++i) |
| 485 windows_.other_windows[i]->aura_window()->RemoveObserver(this); | 518 windows_.other_windows[i]->RemoveObserver(this); |
| 486 windows_.other_windows.clear(); | 519 windows_.other_windows.clear(); |
| 487 | 520 |
| 488 CreateMouseWatcher(); | 521 CreateMouseWatcher(); |
| 489 } | 522 } |
| 490 } | 523 } |
| 491 | 524 |
| 492 void MultiWindowResizeController::CancelResize() { | 525 void MultiWindowResizeController::CancelResize() { |
| 493 if (!window_resizer_) | 526 if (!window_resizer_) |
| 494 return; // Happens if window was destroyed and we nuked the WindowResizer. | 527 return; // Happens if window was destroyed and we nuked the WindowResizer. |
| 495 window_resizer_->RevertDrag(); | 528 window_resizer_->RevertDrag(); |
| 496 window_resizer_->GetTarget()->GetWindowState()->DeleteDragDetails(); | 529 window_resizer_->GetTarget()->GetWindowState()->DeleteDragDetails(); |
| 497 window_resizer_.reset(); | 530 window_resizer_.reset(); |
| 498 Hide(); | 531 Hide(); |
| 499 } | 532 } |
| 500 | 533 |
| 501 gfx::Rect MultiWindowResizeController::CalculateResizeWidgetBounds( | 534 gfx::Rect MultiWindowResizeController::CalculateResizeWidgetBounds( |
| 502 const gfx::Point& location_in_parent) const { | 535 const gfx::Point& location_in_parent) const { |
| 503 gfx::Size pref = resize_widget_->GetContentsView()->GetPreferredSize(); | 536 gfx::Size pref = resize_widget_->GetContentsView()->GetPreferredSize(); |
| 504 int x = 0, y = 0; | 537 int x = 0, y = 0; |
| 505 if (windows_.direction == LEFT_RIGHT) { | 538 if (windows_.direction == LEFT_RIGHT) { |
| 506 x = windows_.window1->GetBounds().right() - pref.width() / 2; | 539 x = windows_.window1->bounds().right() - pref.width() / 2; |
| 507 y = location_in_parent.y() + kResizeWidgetPadding; | 540 y = location_in_parent.y() + kResizeWidgetPadding; |
| 508 if (y + pref.height() / 2 > windows_.window1->GetBounds().bottom() && | 541 if (y + pref.height() / 2 > windows_.window1->bounds().bottom() && |
| 509 y + pref.height() / 2 > windows_.window2->GetBounds().bottom()) { | 542 y + pref.height() / 2 > windows_.window2->bounds().bottom()) { |
| 510 y = location_in_parent.y() - kResizeWidgetPadding - pref.height(); | 543 y = location_in_parent.y() - kResizeWidgetPadding - pref.height(); |
| 511 } | 544 } |
| 512 } else { | 545 } else { |
| 513 x = location_in_parent.x() + kResizeWidgetPadding; | 546 x = location_in_parent.x() + kResizeWidgetPadding; |
| 514 if (x + pref.height() / 2 > windows_.window1->GetBounds().right() && | 547 if (x + pref.height() / 2 > windows_.window1->bounds().right() && |
| 515 x + pref.height() / 2 > windows_.window2->GetBounds().right()) { | 548 x + pref.height() / 2 > windows_.window2->bounds().right()) { |
| 516 x = location_in_parent.x() - kResizeWidgetPadding - pref.width(); | 549 x = location_in_parent.x() - kResizeWidgetPadding - pref.width(); |
| 517 } | 550 } |
| 518 y = windows_.window1->GetBounds().bottom() - pref.height() / 2; | 551 y = windows_.window1->bounds().bottom() - pref.height() / 2; |
| 519 } | 552 } |
| 520 return gfx::Rect(x, y, pref.width(), pref.height()); | 553 return gfx::Rect(x, y, pref.width(), pref.height()); |
| 521 } | 554 } |
| 522 | 555 |
| 523 bool MultiWindowResizeController::IsOverResizeWidget( | 556 bool MultiWindowResizeController::IsOverResizeWidget( |
| 524 const gfx::Point& location_in_screen) const { | 557 const gfx::Point& location_in_screen) const { |
| 525 return resize_widget_->GetWindowBoundsInScreen().Contains(location_in_screen); | 558 return resize_widget_->GetWindowBoundsInScreen().Contains(location_in_screen); |
| 526 } | 559 } |
| 527 | 560 |
| 528 bool MultiWindowResizeController::IsOverWindows( | 561 bool MultiWindowResizeController::IsOverWindows( |
| 529 const gfx::Point& location_in_screen) const { | 562 const gfx::Point& location_in_screen) const { |
| 530 if (IsOverResizeWidget(location_in_screen)) | 563 if (IsOverResizeWidget(location_in_screen)) |
| 531 return true; | 564 return true; |
| 532 | 565 |
| 533 if (windows_.direction == TOP_BOTTOM) { | 566 if (windows_.direction == TOP_BOTTOM) { |
| 534 if (!ContainsScreenX(windows_.window1, location_in_screen.x()) || | 567 if (!ContainsScreenX(windows_.window1, location_in_screen.x()) || |
| 535 !ContainsScreenX(windows_.window2, location_in_screen.x())) { | 568 !ContainsScreenX(windows_.window2, location_in_screen.x())) { |
| 536 return false; | 569 return false; |
| 537 } | 570 } |
| 538 } else { | 571 } else { |
| 539 if (!ContainsScreenY(windows_.window1, location_in_screen.y()) || | 572 if (!ContainsScreenY(windows_.window1, location_in_screen.y()) || |
| 540 !ContainsScreenY(windows_.window2, location_in_screen.y())) { | 573 !ContainsScreenY(windows_.window2, location_in_screen.y())) { |
| 541 return false; | 574 return false; |
| 542 } | 575 } |
| 543 } | 576 } |
| 544 | 577 |
| 545 // Check whether |location_in_screen| is in the event target's resize region. | 578 // Check whether |location_in_screen| is in the event target's resize region. |
| 546 // This is tricky because a window's resize region can extend outside a | 579 // This is tricky because a window's resize region can extend outside a |
| 547 // window's bounds. | 580 // window's bounds. |
| 548 WmWindow* target = | 581 aura::Window* target = RootWindowController::ForWindow(windows_.window1) |
| 549 windows_.window1->GetRootWindowController()->FindEventTarget( | 582 ->FindEventTarget(location_in_screen); |
| 550 location_in_screen); | |
| 551 if (target == windows_.window1) { | 583 if (target == windows_.window1) { |
| 552 return IsOverComponent( | 584 return IsOverComponent( |
| 553 windows_.window1, location_in_screen, | 585 windows_.window1, location_in_screen, |
| 554 windows_.direction == TOP_BOTTOM ? HTBOTTOM : HTRIGHT); | 586 windows_.direction == TOP_BOTTOM ? HTBOTTOM : HTRIGHT); |
| 555 } | 587 } |
| 556 if (target == windows_.window2) { | 588 if (target == windows_.window2) { |
| 557 return IsOverComponent(windows_.window2, location_in_screen, | 589 return IsOverComponent(windows_.window2, location_in_screen, |
| 558 windows_.direction == TOP_BOTTOM ? HTTOP : HTLEFT); | 590 windows_.direction == TOP_BOTTOM ? HTTOP : HTLEFT); |
| 559 } | 591 } |
| 560 return false; | 592 return false; |
| 561 } | 593 } |
| 562 | 594 |
| 563 bool MultiWindowResizeController::IsOverComponent( | 595 bool MultiWindowResizeController::IsOverComponent( |
| 564 WmWindow* window, | 596 aura::Window* window, |
| 565 const gfx::Point& location_in_screen, | 597 const gfx::Point& location_in_screen, |
| 566 int component) const { | 598 int component) const { |
| 567 gfx::Point window_loc = window->ConvertPointFromScreen(location_in_screen); | 599 gfx::Point window_loc = ConvertPointFromScreen(window, location_in_screen); |
| 568 return window->GetNonClientComponent(window_loc) == component; | 600 const int window_component = |
| 601 window->delegate() ? window->delegate()->GetNonClientComponent(window_loc) |
| 602 : HTNOWHERE; |
| 603 return window_component == component; |
| 569 } | 604 } |
| 570 | 605 |
| 571 } // namespace ash | 606 } // namespace ash |
| OLD | NEW |