| 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/screen_ash.h" |
| 7 #include "ash/shell.h" | 8 #include "ash/shell.h" |
| 8 #include "ash/shell_window_ids.h" | 9 #include "ash/shell_window_ids.h" |
| 9 #include "ash/wm/window_animations.h" | 10 #include "ash/wm/window_animations.h" |
| 10 #include "ash/wm/workspace/workspace_event_filter.h" | 11 #include "ash/wm/workspace/workspace_event_filter.h" |
| 11 #include "ash/wm/workspace/workspace_window_resizer.h" | 12 #include "ash/wm/workspace/workspace_window_resizer.h" |
| 12 #include "grit/ui_resources.h" | 13 #include "grit/ui_resources.h" |
| 14 #include "ui/aura/client/screen_position_client.h" |
| 13 #include "ui/aura/event_filter.h" | 15 #include "ui/aura/event_filter.h" |
| 14 #include "ui/aura/root_window.h" | 16 #include "ui/aura/root_window.h" |
| 15 #include "ui/aura/shared/compound_event_filter.h" | 17 #include "ui/aura/shared/compound_event_filter.h" |
| 16 #include "ui/aura/window.h" | 18 #include "ui/aura/window.h" |
| 17 #include "ui/aura/window_delegate.h" | 19 #include "ui/aura/window_delegate.h" |
| 18 #include "ui/base/hit_test.h" | 20 #include "ui/base/hit_test.h" |
| 19 #include "ui/base/resource/resource_bundle.h" | 21 #include "ui/base/resource/resource_bundle.h" |
| 20 #include "ui/gfx/canvas.h" | 22 #include "ui/gfx/canvas.h" |
| 21 #include "ui/gfx/image/image.h" | 23 #include "ui/gfx/image/image.h" |
| 22 #include "ui/gfx/screen.h" | 24 #include "ui/gfx/screen.h" |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 111 }; | 113 }; |
| 112 | 114 |
| 113 // MouseWatcherHost implementation for MultiWindowResizeController. Forwards | 115 // MouseWatcherHost implementation for MultiWindowResizeController. Forwards |
| 114 // Contains() to MultiWindowResizeController. | 116 // Contains() to MultiWindowResizeController. |
| 115 class MultiWindowResizeController::ResizeMouseWatcherHost : | 117 class MultiWindowResizeController::ResizeMouseWatcherHost : |
| 116 public views::MouseWatcherHost { | 118 public views::MouseWatcherHost { |
| 117 public: | 119 public: |
| 118 ResizeMouseWatcherHost(MultiWindowResizeController* host) : host_(host) {} | 120 ResizeMouseWatcherHost(MultiWindowResizeController* host) : host_(host) {} |
| 119 | 121 |
| 120 // MouseWatcherHost overrides: | 122 // MouseWatcherHost overrides: |
| 121 virtual bool Contains(const gfx::Point& screen_point, | 123 virtual bool Contains(const gfx::Point& point_in_screen, |
| 122 MouseEventType type) OVERRIDE { | 124 MouseEventType type) OVERRIDE { |
| 123 return host_->IsOverWindows(screen_point); | 125 return host_->IsOverWindows(point_in_screen); |
| 124 } | 126 } |
| 125 | 127 |
| 126 private: | 128 private: |
| 127 MultiWindowResizeController* host_; | 129 MultiWindowResizeController* host_; |
| 128 | 130 |
| 129 DISALLOW_COPY_AND_ASSIGN(ResizeMouseWatcherHost); | 131 DISALLOW_COPY_AND_ASSIGN(ResizeMouseWatcherHost); |
| 130 }; | 132 }; |
| 131 | 133 |
| 132 MultiWindowResizeController::ResizeWindows::ResizeWindows() | 134 MultiWindowResizeController::ResizeWindows::ResizeWindows() |
| 133 : window1(NULL), | 135 : window1(NULL), |
| (...skipping 15 matching lines...) Expand all Loading... |
| 149 : resize_widget_(NULL), | 151 : resize_widget_(NULL), |
| 150 grid_size_(0) { | 152 grid_size_(0) { |
| 151 } | 153 } |
| 152 | 154 |
| 153 MultiWindowResizeController::~MultiWindowResizeController() { | 155 MultiWindowResizeController::~MultiWindowResizeController() { |
| 154 Hide(); | 156 Hide(); |
| 155 } | 157 } |
| 156 | 158 |
| 157 void MultiWindowResizeController::Show(Window* window, | 159 void MultiWindowResizeController::Show(Window* window, |
| 158 int component, | 160 int component, |
| 159 const gfx::Point& point) { | 161 const gfx::Point& point_in_window) { |
| 160 // When the resize widget is showing we ignore Show() requests. Instead we | 162 // When the resize widget is showing we ignore Show() requests. Instead we |
| 161 // only care about mouse movements from MouseWatcher. This is necessary as | 163 // only care about mouse movements from MouseWatcher. This is necessary as |
| 162 // WorkspaceEventFilter only sees mouse movements over the windows, not all | 164 // WorkspaceEventFilter only sees mouse movements over the windows, not all |
| 163 // windows or over the desktop. | 165 // windows or over the desktop. |
| 164 if (resize_widget_) | 166 if (resize_widget_) |
| 165 return; | 167 return; |
| 166 | 168 |
| 167 ResizeWindows windows(DetermineWindows(window, component, point)); | 169 ResizeWindows windows(DetermineWindows(window, component, point_in_window)); |
| 168 if (IsShowing()) { | 170 if (IsShowing()) { |
| 169 if (windows_.Equals(windows)) | 171 if (windows_.Equals(windows)) |
| 170 return; // Over the same windows. | 172 return; // Over the same windows. |
| 171 DelayedHide(); | 173 DelayedHide(); |
| 172 } | 174 } |
| 173 | 175 |
| 174 if (!windows.is_valid()) | 176 if (!windows.is_valid()) |
| 175 return; | 177 return; |
| 176 Hide(); | 178 Hide(); |
| 177 windows_ = windows; | 179 windows_ = windows; |
| 178 windows_.window1->AddObserver(this); | 180 windows_.window1->AddObserver(this); |
| 179 windows_.window2->AddObserver(this); | 181 windows_.window2->AddObserver(this); |
| 180 show_location_ = point; | 182 show_location_in_parent_ = point_in_window; |
| 181 Window::ConvertPointToWindow(window, window->parent(), &show_location_); | 183 Window::ConvertPointToWindow( |
| 184 window, window->parent(), &show_location_in_parent_); |
| 182 if (show_timer_.IsRunning()) | 185 if (show_timer_.IsRunning()) |
| 183 return; | 186 return; |
| 184 show_timer_.Start(FROM_HERE, | 187 show_timer_.Start(FROM_HERE, |
| 185 base::TimeDelta::FromMilliseconds(kShowDelayMS), | 188 base::TimeDelta::FromMilliseconds(kShowDelayMS), |
| 186 this, &MultiWindowResizeController::ShowNow); | 189 this, &MultiWindowResizeController::ShowNow); |
| 187 } | 190 } |
| 188 | 191 |
| 189 void MultiWindowResizeController::Hide() { | 192 void MultiWindowResizeController::Hide() { |
| 190 hide_timer_.Stop(); | 193 hide_timer_.Stop(); |
| 191 if (window_resizer_.get()) | 194 if (window_resizer_.get()) |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 params.can_activate = false; | 365 params.can_activate = false; |
| 363 ResizeView* view = new ResizeView(this, windows_.direction); | 366 ResizeView* view = new ResizeView(this, windows_.direction); |
| 364 params.delegate = new views::WidgetDelegateView; | 367 params.delegate = new views::WidgetDelegateView; |
| 365 resize_widget_->set_focus_on_creation(false); | 368 resize_widget_->set_focus_on_creation(false); |
| 366 resize_widget_->Init(params); | 369 resize_widget_->Init(params); |
| 367 SetWindowVisibilityAnimationType( | 370 SetWindowVisibilityAnimationType( |
| 368 resize_widget_->GetNativeWindow(), | 371 resize_widget_->GetNativeWindow(), |
| 369 WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); | 372 WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); |
| 370 resize_widget_->GetNativeWindow()->SetName("MultiWindowResizeController"); | 373 resize_widget_->GetNativeWindow()->SetName("MultiWindowResizeController"); |
| 371 resize_widget_->SetContentsView(view); | 374 resize_widget_->SetContentsView(view); |
| 372 show_bounds_ = CalculateResizeWidgetBounds(show_location_); | 375 show_bounds_in_screen_ = ScreenAsh::ConvertRectToScreen( |
| 373 resize_widget_->SetBounds(show_bounds_); | 376 windows_.window1->parent(), |
| 377 CalculateResizeWidgetBounds(show_location_in_parent_)); |
| 378 resize_widget_->SetBounds(show_bounds_in_screen_); |
| 374 resize_widget_->Show(); | 379 resize_widget_->Show(); |
| 375 mouse_watcher_.reset(new views::MouseWatcher( | 380 mouse_watcher_.reset(new views::MouseWatcher( |
| 376 new ResizeMouseWatcherHost(this), | 381 new ResizeMouseWatcherHost(this), |
| 377 this)); | 382 this)); |
| 378 mouse_watcher_->set_notify_on_exit_time( | 383 mouse_watcher_->set_notify_on_exit_time( |
| 379 base::TimeDelta::FromMilliseconds(kHideDelayMS)); | 384 base::TimeDelta::FromMilliseconds(kHideDelayMS)); |
| 380 mouse_watcher_->Start(); | 385 mouse_watcher_->Start(); |
| 381 } | 386 } |
| 382 | 387 |
| 383 bool MultiWindowResizeController::IsShowing() const { | 388 bool MultiWindowResizeController::IsShowing() const { |
| 384 return resize_widget_ || show_timer_.IsRunning(); | 389 return resize_widget_ || show_timer_.IsRunning(); |
| 385 } | 390 } |
| 386 | 391 |
| 387 void MultiWindowResizeController::StartResize( | 392 void MultiWindowResizeController::StartResize( |
| 388 const gfx::Point& screen_location) { | 393 const gfx::Point& location_in_screen) { |
| 389 DCHECK(!window_resizer_.get()); | 394 DCHECK(!window_resizer_.get()); |
| 390 DCHECK(windows_.is_valid()); | 395 DCHECK(windows_.is_valid()); |
| 391 hide_timer_.Stop(); | 396 hide_timer_.Stop(); |
| 392 gfx::Point parent_location(screen_location); | 397 gfx::Point location_in_parent(location_in_screen); |
| 393 aura::Window::ConvertPointToWindow( | 398 aura::client::GetScreenPositionClient(windows_.window2->GetRootWindow())-> |
| 394 windows_.window1->GetRootWindow(), windows_.window1->parent(), | 399 ConvertPointFromScreen(windows_.window2->parent(), &location_in_parent); |
| 395 &parent_location); | |
| 396 std::vector<aura::Window*> windows; | 400 std::vector<aura::Window*> windows; |
| 397 windows.push_back(windows_.window2); | 401 windows.push_back(windows_.window2); |
| 398 FindWindowsTouching(windows_.window2, windows_.direction, | 402 FindWindowsTouching(windows_.window2, windows_.direction, |
| 399 &windows_.other_windows); | 403 &windows_.other_windows); |
| 400 for (size_t i = 0; i < windows_.other_windows.size(); ++i) { | 404 for (size_t i = 0; i < windows_.other_windows.size(); ++i) { |
| 401 windows_.other_windows[i]->AddObserver(this); | 405 windows_.other_windows[i]->AddObserver(this); |
| 402 windows.push_back(windows_.other_windows[i]); | 406 windows.push_back(windows_.other_windows[i]); |
| 403 } | 407 } |
| 404 int component = windows_.direction == LEFT_RIGHT ? HTRIGHT : HTBOTTOM; | 408 int component = windows_.direction == LEFT_RIGHT ? HTRIGHT : HTBOTTOM; |
| 405 window_resizer_.reset(WorkspaceWindowResizer::Create( | 409 window_resizer_.reset(WorkspaceWindowResizer::Create( |
| 406 windows_.window1, parent_location, component, windows)); | 410 windows_.window1, location_in_parent, component, windows)); |
| 407 } | 411 } |
| 408 | 412 |
| 409 void MultiWindowResizeController::Resize(const gfx::Point& screen_location, | 413 void MultiWindowResizeController::Resize(const gfx::Point& location_in_screen, |
| 410 int event_flags) { | 414 int event_flags) { |
| 411 gfx::Point parent_location(screen_location); | 415 gfx::Point location_in_parent(location_in_screen); |
| 412 aura::Window::ConvertPointToWindow(windows_.window1->GetRootWindow(), | 416 aura::client::GetScreenPositionClient(windows_.window1->GetRootWindow())-> |
| 413 windows_.window1->parent(), | 417 ConvertPointFromScreen(windows_.window1->parent(), &location_in_parent); |
| 414 &parent_location); | 418 window_resizer_->Drag(location_in_parent, event_flags); |
| 415 window_resizer_->Drag(parent_location, event_flags); | 419 gfx::Rect bounds = ScreenAsh::ConvertRectToScreen( |
| 416 gfx::Rect bounds = CalculateResizeWidgetBounds(parent_location); | 420 windows_.window1->parent(), |
| 421 CalculateResizeWidgetBounds(location_in_parent)); |
| 422 |
| 417 if (windows_.direction == LEFT_RIGHT) | 423 if (windows_.direction == LEFT_RIGHT) |
| 418 bounds.set_y(show_bounds_.y()); | 424 bounds.set_y(show_bounds_in_screen_.y()); |
| 419 else | 425 else |
| 420 bounds.set_x(show_bounds_.x()); | 426 bounds.set_x(show_bounds_in_screen_.x()); |
| 421 resize_widget_->SetBounds(bounds); | 427 resize_widget_->SetBounds(bounds); |
| 422 } | 428 } |
| 423 | 429 |
| 424 void MultiWindowResizeController::CompleteResize(int event_flags) { | 430 void MultiWindowResizeController::CompleteResize(int event_flags) { |
| 425 window_resizer_->CompleteDrag(event_flags); | 431 window_resizer_->CompleteDrag(event_flags); |
| 426 window_resizer_.reset(); | 432 window_resizer_.reset(); |
| 427 | 433 |
| 428 // Mouse may still be over resizer, if not hide. | 434 // Mouse may still be over resizer, if not hide. |
| 429 gfx::Point screen_loc = gfx::Screen::GetCursorScreenPoint(); | 435 gfx::Point screen_loc = gfx::Screen::GetCursorScreenPoint(); |
| 430 if (!resize_widget_->GetWindowBoundsInScreen().Contains(screen_loc)) | 436 if (!resize_widget_->GetWindowBoundsInScreen().Contains(screen_loc)) |
| 431 Hide(); | 437 Hide(); |
| 432 } | 438 } |
| 433 | 439 |
| 434 void MultiWindowResizeController::CancelResize() { | 440 void MultiWindowResizeController::CancelResize() { |
| 435 if (!window_resizer_.get()) | 441 if (!window_resizer_.get()) |
| 436 return; // Happens if window was destroyed and we nuked the WindowResizer. | 442 return; // Happens if window was destroyed and we nuked the WindowResizer. |
| 437 window_resizer_->RevertDrag(); | 443 window_resizer_->RevertDrag(); |
| 438 window_resizer_.reset(); | 444 window_resizer_.reset(); |
| 439 Hide(); | 445 Hide(); |
| 440 } | 446 } |
| 441 | 447 |
| 442 gfx::Rect MultiWindowResizeController::CalculateResizeWidgetBounds( | 448 gfx::Rect MultiWindowResizeController::CalculateResizeWidgetBounds( |
| 443 const gfx::Point& location) const { | 449 const gfx::Point& location_in_parent) const { |
| 444 gfx::Size pref = resize_widget_->GetContentsView()->GetPreferredSize(); | 450 gfx::Size pref = resize_widget_->GetContentsView()->GetPreferredSize(); |
| 445 int x = 0, y = 0; | 451 int x = 0, y = 0; |
| 446 if (windows_.direction == LEFT_RIGHT) { | 452 if (windows_.direction == LEFT_RIGHT) { |
| 447 x = windows_.window1->bounds().right() - pref.width() / 2; | 453 x = windows_.window1->bounds().right() - pref.width() / 2; |
| 448 y = location.y() + kResizeWidgetPadding; | 454 y = location_in_parent.y() + kResizeWidgetPadding; |
| 449 if (y + pref.height() / 2 > windows_.window1->bounds().bottom() && | 455 if (y + pref.height() / 2 > windows_.window1->bounds().bottom() && |
| 450 y + pref.height() / 2 > windows_.window2->bounds().bottom()) { | 456 y + pref.height() / 2 > windows_.window2->bounds().bottom()) { |
| 451 y = location.y() - kResizeWidgetPadding - pref.height(); | 457 y = location_in_parent.y() - kResizeWidgetPadding - pref.height(); |
| 452 } | 458 } |
| 453 } else { | 459 } else { |
| 454 x = location.x() + kResizeWidgetPadding; | 460 x = location_in_parent.x() + kResizeWidgetPadding; |
| 455 if (x + pref.height() / 2 > windows_.window1->bounds().right() && | 461 if (x + pref.height() / 2 > windows_.window1->bounds().right() && |
| 456 x + pref.height() / 2 > windows_.window2->bounds().right()) { | 462 x + pref.height() / 2 > windows_.window2->bounds().right()) { |
| 457 x = location.x() - kResizeWidgetPadding - pref.width(); | 463 x = location_in_parent.x() - kResizeWidgetPadding - pref.width(); |
| 458 } | 464 } |
| 459 y = windows_.window1->bounds().bottom() - pref.height() / 2; | 465 y = windows_.window1->bounds().bottom() - pref.height() / 2; |
| 460 } | 466 } |
| 461 return gfx::Rect(x, y, pref.width(), pref.height()); | 467 return gfx::Rect(x, y, pref.width(), pref.height()); |
| 462 } | 468 } |
| 463 | 469 |
| 464 bool MultiWindowResizeController::IsOverWindows( | 470 bool MultiWindowResizeController::IsOverWindows( |
| 465 const gfx::Point& screen_location) const { | 471 const gfx::Point& location_in_screen) const { |
| 466 if (window_resizer_.get()) | 472 if (window_resizer_.get()) |
| 467 return true; // Ignore hides while actively resizing. | 473 return true; // Ignore hides while actively resizing. |
| 468 | 474 |
| 469 if (resize_widget_->GetWindowBoundsInScreen().Contains(screen_location)) | 475 if (resize_widget_->GetWindowBoundsInScreen().Contains(location_in_screen)) |
| 470 return true; | 476 return true; |
| 471 | 477 |
| 472 int hit1, hit2; | 478 int hit1, hit2; |
| 473 if (windows_.direction == TOP_BOTTOM) { | 479 if (windows_.direction == TOP_BOTTOM) { |
| 474 hit1 = HTBOTTOM; | 480 hit1 = HTBOTTOM; |
| 475 hit2 = HTTOP; | 481 hit2 = HTTOP; |
| 476 } else { | 482 } else { |
| 477 hit1 = HTRIGHT; | 483 hit1 = HTRIGHT; |
| 478 hit2 = HTLEFT; | 484 hit2 = HTLEFT; |
| 479 } | 485 } |
| 480 | 486 |
| 481 return IsOverWindow(windows_.window1, screen_location, hit1) || | 487 return IsOverWindow(windows_.window1, location_in_screen, hit1) || |
| 482 IsOverWindow(windows_.window2, screen_location, hit2); | 488 IsOverWindow(windows_.window2, location_in_screen, hit2); |
| 483 } | 489 } |
| 484 | 490 |
| 485 bool MultiWindowResizeController::IsOverWindow( | 491 bool MultiWindowResizeController::IsOverWindow( |
| 486 aura::Window* window, | 492 aura::Window* window, |
| 487 const gfx::Point& screen_location, | 493 const gfx::Point& location_in_screen, |
| 488 int component) const { | 494 int component) const { |
| 489 if (!window->delegate()) | 495 if (!window->delegate()) |
| 490 return false; | 496 return false; |
| 491 | 497 |
| 492 gfx::Point window_loc(screen_location); | 498 gfx::Point window_loc(location_in_screen); |
| 493 aura::Window::ConvertPointToWindow( | 499 aura::Window::ConvertPointToWindow( |
| 494 window->GetRootWindow(), window, &window_loc); | 500 window->GetRootWindow(), window, &window_loc); |
| 495 return window->HitTest(window_loc) && | 501 return window->HitTest(window_loc) && |
| 496 window->delegate()->GetNonClientComponent(window_loc) == component; | 502 window->delegate()->GetNonClientComponent(window_loc) == component; |
| 497 } | 503 } |
| 498 | 504 |
| 499 } // namespace internal | 505 } // namespace internal |
| 500 } // namespace ash | 506 } // namespace ash |
| OLD | NEW |