| 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_util.h" | 7 #include "ash/screen_util.h" |
| 8 #include "ash/shell.h" | 8 #include "ash/shell.h" |
| 9 #include "ash/shell_window_ids.h" | 9 #include "ash/shell_window_ids.h" |
| 10 #include "ash/wm/window_animations.h" | 10 #include "ash/wm/window_animations.h" |
| 11 #include "ash/wm/workspace/workspace_event_handler.h" | 11 #include "ash/wm/workspace/workspace_event_handler.h" |
| 12 #include "ash/wm/workspace/workspace_window_resizer.h" | 12 #include "ash/wm/workspace/workspace_window_resizer.h" |
| 13 #include "grit/ash_resources.h" | 13 #include "grit/ash_resources.h" |
| 14 #include "ui/aura/client/screen_position_client.h" | 14 #include "ui/aura/client/screen_position_client.h" |
| 15 #include "ui/aura/window.h" | 15 #include "ui/aura/window.h" |
| 16 #include "ui/aura/window_delegate.h" | 16 #include "ui/aura/window_delegate.h" |
| 17 #include "ui/aura/window_event_dispatcher.h" | 17 #include "ui/aura/window_event_dispatcher.h" |
| 18 #include "ui/base/hit_test.h" | 18 #include "ui/base/hit_test.h" |
| 19 #include "ui/base/resource/resource_bundle.h" | 19 #include "ui/base/resource/resource_bundle.h" |
| 20 #include "ui/events/event_targeter.h" | |
| 21 #include "ui/gfx/canvas.h" | 20 #include "ui/gfx/canvas.h" |
| 22 #include "ui/gfx/image/image.h" | 21 #include "ui/gfx/image/image.h" |
| 23 #include "ui/gfx/screen.h" | 22 #include "ui/gfx/screen.h" |
| 24 #include "ui/views/view.h" | 23 #include "ui/views/view.h" |
| 25 #include "ui/views/widget/widget.h" | 24 #include "ui/views/widget/widget.h" |
| 26 #include "ui/views/widget/widget_delegate.h" | 25 #include "ui/views/widget/widget_delegate.h" |
| 27 #include "ui/wm/core/compound_event_filter.h" | 26 #include "ui/wm/core/compound_event_filter.h" |
| 28 #include "ui/wm/core/coordinate_conversion.h" | 27 #include "ui/wm/core/coordinate_conversion.h" |
| 29 | 28 |
| 30 using aura::Window; | 29 using aura::Window; |
| 31 | 30 |
| 32 namespace ash { | 31 namespace ash { |
| 33 namespace { | 32 namespace { |
| 34 | 33 |
| 35 // Delay before showing. | 34 // Delay before showing. |
| 36 const int kShowDelayMS = 400; | 35 const int kShowDelayMS = 400; |
| 37 | 36 |
| 38 // Delay before hiding. | 37 // Delay before hiding. |
| 39 const int kHideDelayMS = 500; | 38 const int kHideDelayMS = 500; |
| 40 | 39 |
| 41 // Padding from the bottom/right edge the resize widget is shown at. | 40 // Padding from the bottom/right edge the resize widget is shown at. |
| 42 const int kResizeWidgetPadding = 15; | 41 const int kResizeWidgetPadding = 15; |
| 43 | 42 |
| 44 bool ContainsX(Window* window, int x) { | 43 bool ContainsX(Window* window, int x) { |
| 45 return x >= 0 && x <= window->bounds().width(); | 44 return window->bounds().x() <= x && window->bounds().right() >= x; |
| 46 } | |
| 47 | |
| 48 bool ContainsScreenX(Window* window, int x_in_screen) { | |
| 49 gfx::Point window_loc(x_in_screen, 0); | |
| 50 ::wm::ConvertPointFromScreen(window, &window_loc); | |
| 51 return ContainsX(window, window_loc.x()); | |
| 52 } | 45 } |
| 53 | 46 |
| 54 bool ContainsY(Window* window, int y) { | 47 bool ContainsY(Window* window, int y) { |
| 55 return y >= 0 && y <= window->bounds().height(); | 48 return window->bounds().y() <= y && window->bounds().bottom() >= y; |
| 56 } | |
| 57 | |
| 58 bool ContainsScreenY(Window* window, int y_in_screen) { | |
| 59 gfx::Point window_loc(0, y_in_screen); | |
| 60 ::wm::ConvertPointFromScreen(window, &window_loc); | |
| 61 return ContainsY(window, window_loc.y()); | |
| 62 } | 49 } |
| 63 | 50 |
| 64 bool Intersects(int x1, int max_1, int x2, int max_2) { | 51 bool Intersects(int x1, int max_1, int x2, int max_2) { |
| 65 return x2 <= max_1 && max_2 > x1; | 52 return x2 <= max_1 && max_2 > x1; |
| 66 } | 53 } |
| 67 | 54 |
| 68 } // namespace | 55 } // namespace |
| 69 | 56 |
| 70 // View contained in the widget. Passes along mouse events to the | 57 // View contained in the widget. Passes along mouse events to the |
| 71 // MultiWindowResizeController so that it can start/stop the resize loop. | 58 // MultiWindowResizeController so that it can start/stop the resize loop. |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 int component, | 154 int component, |
| 168 const gfx::Point& point_in_window) { | 155 const gfx::Point& point_in_window) { |
| 169 // When the resize widget is showing we ignore Show() requests. Instead we | 156 // When the resize widget is showing we ignore Show() requests. Instead we |
| 170 // only care about mouse movements from MouseWatcher. This is necessary as | 157 // only care about mouse movements from MouseWatcher. This is necessary as |
| 171 // WorkspaceEventHandler only sees mouse movements over the windows, not all | 158 // WorkspaceEventHandler only sees mouse movements over the windows, not all |
| 172 // windows or over the desktop. | 159 // windows or over the desktop. |
| 173 if (resize_widget_) | 160 if (resize_widget_) |
| 174 return; | 161 return; |
| 175 | 162 |
| 176 ResizeWindows windows(DetermineWindows(window, component, point_in_window)); | 163 ResizeWindows windows(DetermineWindows(window, component, point_in_window)); |
| 177 if (IsShowing() && windows_.Equals(windows)) | 164 if (IsShowing()) { |
| 165 if (windows_.Equals(windows)) |
| 166 return; // Over the same windows. |
| 167 DelayedHide(); |
| 168 } |
| 169 |
| 170 if (!windows.is_valid()) |
| 178 return; | 171 return; |
| 179 | |
| 180 Hide(); | 172 Hide(); |
| 181 windows_ = windows; | 173 windows_ = windows; |
| 182 if (!windows.is_valid()) | |
| 183 return; | |
| 184 | |
| 185 windows_.window1->AddObserver(this); | 174 windows_.window1->AddObserver(this); |
| 186 windows_.window2->AddObserver(this); | 175 windows_.window2->AddObserver(this); |
| 187 show_location_in_parent_ = point_in_window; | 176 show_location_in_parent_ = point_in_window; |
| 188 Window::ConvertPointToTarget( | 177 Window::ConvertPointToTarget( |
| 189 window, window->parent(), &show_location_in_parent_); | 178 window, window->parent(), &show_location_in_parent_); |
| 179 if (show_timer_.IsRunning()) |
| 180 return; |
| 190 show_timer_.Start( | 181 show_timer_.Start( |
| 191 FROM_HERE, base::TimeDelta::FromMilliseconds(kShowDelayMS), | 182 FROM_HERE, base::TimeDelta::FromMilliseconds(kShowDelayMS), |
| 192 this, &MultiWindowResizeController::ShowIfValidMouseLocation); | 183 this, &MultiWindowResizeController::ShowIfValidMouseLocation); |
| 193 } | 184 } |
| 194 | 185 |
| 195 void MultiWindowResizeController::Hide() { | 186 void MultiWindowResizeController::Hide() { |
| 187 hide_timer_.Stop(); |
| 196 if (window_resizer_) | 188 if (window_resizer_) |
| 197 return; // Ignore hides while actively resizing. | 189 return; // Ignore hides while actively resizing. |
| 198 | 190 |
| 199 if (windows_.window1) { | 191 if (windows_.window1) { |
| 200 windows_.window1->RemoveObserver(this); | 192 windows_.window1->RemoveObserver(this); |
| 201 windows_.window1 = NULL; | 193 windows_.window1 = NULL; |
| 202 } | 194 } |
| 203 if (windows_.window2) { | 195 if (windows_.window2) { |
| 204 windows_.window2->RemoveObserver(this); | 196 windows_.window2->RemoveObserver(this); |
| 205 windows_.window2 = NULL; | 197 windows_.window2 = NULL; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 232 MultiWindowResizeController::DetermineWindowsFromScreenPoint( | 224 MultiWindowResizeController::DetermineWindowsFromScreenPoint( |
| 233 aura::Window* window) const { | 225 aura::Window* window) const { |
| 234 gfx::Point mouse_location( | 226 gfx::Point mouse_location( |
| 235 gfx::Screen::GetScreenFor(window)->GetCursorScreenPoint()); | 227 gfx::Screen::GetScreenFor(window)->GetCursorScreenPoint()); |
| 236 ::wm::ConvertPointFromScreen(window, &mouse_location); | 228 ::wm::ConvertPointFromScreen(window, &mouse_location); |
| 237 const int component = | 229 const int component = |
| 238 window->delegate()->GetNonClientComponent(mouse_location); | 230 window->delegate()->GetNonClientComponent(mouse_location); |
| 239 return DetermineWindows(window, component, mouse_location); | 231 return DetermineWindows(window, component, mouse_location); |
| 240 } | 232 } |
| 241 | 233 |
| 242 void MultiWindowResizeController::CreateMouseWatcher() { | |
| 243 mouse_watcher_.reset(new views::MouseWatcher( | |
| 244 new ResizeMouseWatcherHost(this), this)); | |
| 245 mouse_watcher_->set_notify_on_exit_time( | |
| 246 base::TimeDelta::FromMilliseconds(kHideDelayMS)); | |
| 247 mouse_watcher_->Start(); | |
| 248 } | |
| 249 | |
| 250 MultiWindowResizeController::ResizeWindows | 234 MultiWindowResizeController::ResizeWindows |
| 251 MultiWindowResizeController::DetermineWindows( | 235 MultiWindowResizeController::DetermineWindows( |
| 252 Window* window, | 236 Window* window, |
| 253 int window_component, | 237 int window_component, |
| 254 const gfx::Point& point) const { | 238 const gfx::Point& point) const { |
| 255 ResizeWindows result; | 239 ResizeWindows result; |
| 256 gfx::Point point_in_parent(point); | 240 gfx::Point point_in_parent(point); |
| 257 Window::ConvertPointToTarget(window, window->parent(), &point_in_parent); | 241 Window::ConvertPointToTarget(window, window->parent(), &point_in_parent); |
| 258 switch (window_component) { | 242 switch (window_component) { |
| 259 case HTRIGHT: | 243 case HTRIGHT: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 282 break; | 266 break; |
| 283 default: | 267 default: |
| 284 break; | 268 break; |
| 285 } | 269 } |
| 286 return result; | 270 return result; |
| 287 } | 271 } |
| 288 | 272 |
| 289 Window* MultiWindowResizeController::FindWindowByEdge( | 273 Window* MultiWindowResizeController::FindWindowByEdge( |
| 290 Window* window_to_ignore, | 274 Window* window_to_ignore, |
| 291 int edge_want, | 275 int edge_want, |
| 292 int x_in_parent, | 276 int x, |
| 293 int y_in_parent) const { | 277 int y) const { |
| 294 Window* parent = window_to_ignore->parent(); | 278 Window* parent = window_to_ignore->parent(); |
| 295 const Window::Windows& windows(parent->children()); | 279 const Window::Windows& windows(parent->children()); |
| 296 for (Window::Windows::const_reverse_iterator i = windows.rbegin(); | 280 for (Window::Windows::const_reverse_iterator i = windows.rbegin(); |
| 297 i != windows.rend(); ++i) { | 281 i != windows.rend(); ++i) { |
| 298 Window* window = *i; | 282 Window* window = *i; |
| 299 if (window == window_to_ignore || !window->IsVisible()) | 283 if (window == window_to_ignore || !window->IsVisible()) |
| 300 continue; | 284 continue; |
| 301 | |
| 302 // Ignore windows without a delegate. A delegate is necessary to query the | |
| 303 // non-client component. | |
| 304 if (!window->delegate()) | |
| 305 continue; | |
| 306 | |
| 307 gfx::Point p(x_in_parent, y_in_parent); | |
| 308 aura::Window::ConvertPointToTarget(parent, window, &p); | |
| 309 switch (edge_want) { | 285 switch (edge_want) { |
| 310 case HTLEFT: | 286 case HTLEFT: |
| 311 if (ContainsY(window, p.y()) && p.x() == 0) | 287 if (ContainsY(window, y) && window->bounds().x() == x) |
| 312 return window; | 288 return window; |
| 313 break; | 289 break; |
| 314 case HTRIGHT: | 290 case HTRIGHT: |
| 315 if (ContainsY(window, p.y()) && p.x() == window->bounds().width()) | 291 if (ContainsY(window, y) && window->bounds().right() == x) |
| 316 return window; | 292 return window; |
| 317 break; | 293 break; |
| 318 case HTTOP: | 294 case HTTOP: |
| 319 if (ContainsX(window, p.x()) && p.y() == 0) | 295 if (ContainsX(window, x) && window->bounds().y() == y) |
| 320 return window; | 296 return window; |
| 321 break; | 297 break; |
| 322 case HTBOTTOM: | 298 case HTBOTTOM: |
| 323 if (ContainsX(window, p.x()) && p.y() == window->bounds().height()) | 299 if (ContainsX(window, x) && window->bounds().bottom() == y) |
| 324 return window; | 300 return window; |
| 325 break; | 301 break; |
| 326 default: | 302 default: |
| 327 NOTREACHED(); | 303 NOTREACHED(); |
| 328 } | 304 } |
| 329 // Window doesn't contain the edge, but if window contains |point| | 305 // Window doesn't contain the edge, but if window contains |point| |
| 330 // it's obscuring any other window that could be at the location. | 306 // it's obscuring any other window that could be at the location. |
| 331 if (window->bounds().Contains(x_in_parent, y_in_parent)) | 307 if (window->bounds().Contains(x, y)) |
| 332 return NULL; | 308 return NULL; |
| 333 } | 309 } |
| 334 return NULL; | 310 return NULL; |
| 335 } | 311 } |
| 336 | 312 |
| 337 aura::Window* MultiWindowResizeController::FindWindowTouching( | 313 aura::Window* MultiWindowResizeController::FindWindowTouching( |
| 338 aura::Window* window, | 314 aura::Window* window, |
| 339 Direction direction) const { | 315 Direction direction) const { |
| 340 int right = window->bounds().right(); | 316 int right = window->bounds().right(); |
| 341 int bottom = window->bounds().bottom(); | 317 int bottom = window->bounds().bottom(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 372 aura::Window* start, | 348 aura::Window* start, |
| 373 Direction direction, | 349 Direction direction, |
| 374 std::vector<aura::Window*>* others) const { | 350 std::vector<aura::Window*>* others) const { |
| 375 while (start) { | 351 while (start) { |
| 376 start = FindWindowTouching(start, direction); | 352 start = FindWindowTouching(start, direction); |
| 377 if (start) | 353 if (start) |
| 378 others->push_back(start); | 354 others->push_back(start); |
| 379 } | 355 } |
| 380 } | 356 } |
| 381 | 357 |
| 358 void MultiWindowResizeController::DelayedHide() { |
| 359 if (hide_timer_.IsRunning()) |
| 360 return; |
| 361 |
| 362 hide_timer_.Start(FROM_HERE, |
| 363 base::TimeDelta::FromMilliseconds(kHideDelayMS), |
| 364 this, &MultiWindowResizeController::Hide); |
| 365 } |
| 366 |
| 382 void MultiWindowResizeController::ShowIfValidMouseLocation() { | 367 void MultiWindowResizeController::ShowIfValidMouseLocation() { |
| 383 if (DetermineWindowsFromScreenPoint(windows_.window1).Equals(windows_) || | 368 if (DetermineWindowsFromScreenPoint(windows_.window1).Equals(windows_) || |
| 384 DetermineWindowsFromScreenPoint(windows_.window2).Equals(windows_)) { | 369 DetermineWindowsFromScreenPoint(windows_.window2).Equals(windows_)) { |
| 385 ShowNow(); | 370 ShowNow(); |
| 386 } else { | 371 } else { |
| 387 Hide(); | 372 Hide(); |
| 388 } | 373 } |
| 389 } | 374 } |
| 390 | 375 |
| 391 void MultiWindowResizeController::ShowNow() { | 376 void MultiWindowResizeController::ShowNow() { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 404 ::wm::SetWindowVisibilityAnimationType( | 389 ::wm::SetWindowVisibilityAnimationType( |
| 405 resize_widget_->GetNativeWindow(), | 390 resize_widget_->GetNativeWindow(), |
| 406 ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); | 391 ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE); |
| 407 resize_widget_->GetNativeWindow()->SetName("MultiWindowResizeController"); | 392 resize_widget_->GetNativeWindow()->SetName("MultiWindowResizeController"); |
| 408 resize_widget_->SetContentsView(view); | 393 resize_widget_->SetContentsView(view); |
| 409 show_bounds_in_screen_ = ScreenUtil::ConvertRectToScreen( | 394 show_bounds_in_screen_ = ScreenUtil::ConvertRectToScreen( |
| 410 windows_.window1->parent(), | 395 windows_.window1->parent(), |
| 411 CalculateResizeWidgetBounds(show_location_in_parent_)); | 396 CalculateResizeWidgetBounds(show_location_in_parent_)); |
| 412 resize_widget_->SetBounds(show_bounds_in_screen_); | 397 resize_widget_->SetBounds(show_bounds_in_screen_); |
| 413 resize_widget_->Show(); | 398 resize_widget_->Show(); |
| 414 CreateMouseWatcher(); | 399 mouse_watcher_.reset(new views::MouseWatcher( |
| 400 new ResizeMouseWatcherHost(this), |
| 401 this)); |
| 402 mouse_watcher_->set_notify_on_exit_time( |
| 403 base::TimeDelta::FromMilliseconds(kHideDelayMS)); |
| 404 mouse_watcher_->Start(); |
| 415 } | 405 } |
| 416 | 406 |
| 417 bool MultiWindowResizeController::IsShowing() const { | 407 bool MultiWindowResizeController::IsShowing() const { |
| 418 return resize_widget_.get() || show_timer_.IsRunning(); | 408 return resize_widget_.get() || show_timer_.IsRunning(); |
| 419 } | 409 } |
| 420 | 410 |
| 421 void MultiWindowResizeController::StartResize( | 411 void MultiWindowResizeController::StartResize( |
| 422 const gfx::Point& location_in_screen) { | 412 const gfx::Point& location_in_screen) { |
| 423 DCHECK(!window_resizer_.get()); | 413 DCHECK(!window_resizer_.get()); |
| 424 DCHECK(windows_.is_valid()); | 414 DCHECK(windows_.is_valid()); |
| 415 hide_timer_.Stop(); |
| 425 gfx::Point location_in_parent(location_in_screen); | 416 gfx::Point location_in_parent(location_in_screen); |
| 426 aura::client::GetScreenPositionClient(windows_.window2->GetRootWindow())-> | 417 aura::client::GetScreenPositionClient(windows_.window2->GetRootWindow())-> |
| 427 ConvertPointFromScreen(windows_.window2->parent(), &location_in_parent); | 418 ConvertPointFromScreen(windows_.window2->parent(), &location_in_parent); |
| 428 std::vector<aura::Window*> windows; | 419 std::vector<aura::Window*> windows; |
| 429 windows.push_back(windows_.window2); | 420 windows.push_back(windows_.window2); |
| 430 DCHECK(windows_.other_windows.empty()); | 421 DCHECK(windows_.other_windows.empty()); |
| 431 FindWindowsTouching(windows_.window2, windows_.direction, | 422 FindWindowsTouching(windows_.window2, windows_.direction, |
| 432 &windows_.other_windows); | 423 &windows_.other_windows); |
| 433 for (size_t i = 0; i < windows_.other_windows.size(); ++i) { | 424 for (size_t i = 0; i < windows_.other_windows.size(); ++i) { |
| 434 windows_.other_windows[i]->AddObserver(this); | 425 windows_.other_windows[i]->AddObserver(this); |
| 435 windows.push_back(windows_.other_windows[i]); | 426 windows.push_back(windows_.other_windows[i]); |
| 436 } | 427 } |
| 437 int component = windows_.direction == LEFT_RIGHT ? HTRIGHT : HTBOTTOM; | 428 int component = windows_.direction == LEFT_RIGHT ? HTRIGHT : HTBOTTOM; |
| 438 wm::WindowState* window_state = wm::GetWindowState(windows_.window1); | 429 wm::WindowState* window_state = wm::GetWindowState(windows_.window1); |
| 439 window_state->CreateDragDetails(windows_.window1, | 430 window_state->CreateDragDetails(windows_.window1, |
| 440 location_in_parent, | 431 location_in_parent, |
| 441 component, | 432 component, |
| 442 aura::client::WINDOW_MOVE_SOURCE_MOUSE); | 433 aura::client::WINDOW_MOVE_SOURCE_MOUSE); |
| 443 window_resizer_.reset(WorkspaceWindowResizer::Create(window_state, windows)); | 434 window_resizer_.reset(WorkspaceWindowResizer::Create(window_state, windows)); |
| 444 | |
| 445 // Do not hide the resize widget while a drag is active. | |
| 446 mouse_watcher_.reset(); | |
| 447 } | 435 } |
| 448 | 436 |
| 449 void MultiWindowResizeController::Resize(const gfx::Point& location_in_screen, | 437 void MultiWindowResizeController::Resize(const gfx::Point& location_in_screen, |
| 450 int event_flags) { | 438 int event_flags) { |
| 451 gfx::Point location_in_parent(location_in_screen); | 439 gfx::Point location_in_parent(location_in_screen); |
| 452 aura::client::GetScreenPositionClient(windows_.window1->GetRootWindow())-> | 440 aura::client::GetScreenPositionClient(windows_.window1->GetRootWindow())-> |
| 453 ConvertPointFromScreen(windows_.window1->parent(), &location_in_parent); | 441 ConvertPointFromScreen(windows_.window1->parent(), &location_in_parent); |
| 454 window_resizer_->Drag(location_in_parent, event_flags); | 442 window_resizer_->Drag(location_in_parent, event_flags); |
| 455 gfx::Rect bounds = ScreenUtil::ConvertRectToScreen( | 443 gfx::Rect bounds = ScreenUtil::ConvertRectToScreen( |
| 456 windows_.window1->parent(), | 444 windows_.window1->parent(), |
| (...skipping 15 matching lines...) Expand all Loading... |
| 472 gfx::Point screen_loc = Shell::GetScreen()->GetCursorScreenPoint(); | 460 gfx::Point screen_loc = Shell::GetScreen()->GetCursorScreenPoint(); |
| 473 if (!resize_widget_->GetWindowBoundsInScreen().Contains(screen_loc)) { | 461 if (!resize_widget_->GetWindowBoundsInScreen().Contains(screen_loc)) { |
| 474 Hide(); | 462 Hide(); |
| 475 } else { | 463 } else { |
| 476 // If the mouse is over the resizer we need to remove observers on any of | 464 // If the mouse is over the resizer we need to remove observers on any of |
| 477 // the |other_windows|. If we start another resize we'll recalculate the | 465 // the |other_windows|. If we start another resize we'll recalculate the |
| 478 // |other_windows| and invoke AddObserver() as necessary. | 466 // |other_windows| and invoke AddObserver() as necessary. |
| 479 for (size_t i = 0; i < windows_.other_windows.size(); ++i) | 467 for (size_t i = 0; i < windows_.other_windows.size(); ++i) |
| 480 windows_.other_windows[i]->RemoveObserver(this); | 468 windows_.other_windows[i]->RemoveObserver(this); |
| 481 windows_.other_windows.clear(); | 469 windows_.other_windows.clear(); |
| 482 | |
| 483 CreateMouseWatcher(); | |
| 484 } | 470 } |
| 485 } | 471 } |
| 486 | 472 |
| 487 void MultiWindowResizeController::CancelResize() { | 473 void MultiWindowResizeController::CancelResize() { |
| 488 if (!window_resizer_) | 474 if (!window_resizer_) |
| 489 return; // Happens if window was destroyed and we nuked the WindowResizer. | 475 return; // Happens if window was destroyed and we nuked the WindowResizer. |
| 490 window_resizer_->RevertDrag(); | 476 window_resizer_->RevertDrag(); |
| 491 wm::GetWindowState(window_resizer_->GetTarget())->DeleteDragDetails(); | 477 wm::GetWindowState(window_resizer_->GetTarget())->DeleteDragDetails(); |
| 492 window_resizer_.reset(); | 478 window_resizer_.reset(); |
| 493 Hide(); | 479 Hide(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 510 x + pref.height() / 2 > windows_.window2->bounds().right()) { | 496 x + pref.height() / 2 > windows_.window2->bounds().right()) { |
| 511 x = location_in_parent.x() - kResizeWidgetPadding - pref.width(); | 497 x = location_in_parent.x() - kResizeWidgetPadding - pref.width(); |
| 512 } | 498 } |
| 513 y = windows_.window1->bounds().bottom() - pref.height() / 2; | 499 y = windows_.window1->bounds().bottom() - pref.height() / 2; |
| 514 } | 500 } |
| 515 return gfx::Rect(x, y, pref.width(), pref.height()); | 501 return gfx::Rect(x, y, pref.width(), pref.height()); |
| 516 } | 502 } |
| 517 | 503 |
| 518 bool MultiWindowResizeController::IsOverWindows( | 504 bool MultiWindowResizeController::IsOverWindows( |
| 519 const gfx::Point& location_in_screen) const { | 505 const gfx::Point& location_in_screen) const { |
| 506 if (window_resizer_) |
| 507 return true; // Ignore hides while actively resizing. |
| 508 |
| 520 if (resize_widget_->GetWindowBoundsInScreen().Contains(location_in_screen)) | 509 if (resize_widget_->GetWindowBoundsInScreen().Contains(location_in_screen)) |
| 521 return true; | 510 return true; |
| 522 | 511 |
| 512 int hit1, hit2; |
| 523 if (windows_.direction == TOP_BOTTOM) { | 513 if (windows_.direction == TOP_BOTTOM) { |
| 524 if (!ContainsScreenX(windows_.window1, location_in_screen.x()) || | 514 hit1 = HTBOTTOM; |
| 525 !ContainsScreenX(windows_.window2, location_in_screen.x())) { | 515 hit2 = HTTOP; |
| 526 return false; | |
| 527 } | |
| 528 } else { | 516 } else { |
| 529 if (!ContainsScreenY(windows_.window1, location_in_screen.y()) || | 517 hit1 = HTRIGHT; |
| 530 !ContainsScreenY(windows_.window2, location_in_screen.y())) { | 518 hit2 = HTLEFT; |
| 531 return false; | |
| 532 } | |
| 533 } | 519 } |
| 534 | 520 |
| 535 // Check whether |location_in_screen| is in the event target's resize region. | 521 return IsOverWindow(windows_.window1, location_in_screen, hit1) || |
| 536 // This is tricky because a window's resize region can extend outside a | 522 IsOverWindow(windows_.window2, location_in_screen, hit2); |
| 537 // window's bounds. | |
| 538 gfx::Point location_in_root(location_in_screen); | |
| 539 aura::Window* root = windows_.window1->GetRootWindow(); | |
| 540 ::wm::ConvertPointFromScreen(root, &location_in_root); | |
| 541 ui::MouseEvent test_event(ui::ET_MOUSE_MOVED, location_in_root, | |
| 542 location_in_root, ui::EF_NONE, ui::EF_NONE); | |
| 543 ui::EventTarget* event_handler = static_cast<ui::EventTarget*>(root) | |
| 544 ->GetEventTargeter() | |
| 545 ->FindTargetForEvent(root, &test_event); | |
| 546 if (event_handler == windows_.window1) { | |
| 547 return IsOverComponent( | |
| 548 windows_.window1, | |
| 549 location_in_screen, | |
| 550 windows_.direction == TOP_BOTTOM ? HTBOTTOM : HTRIGHT); | |
| 551 } else if (event_handler == windows_.window2) { | |
| 552 return IsOverComponent( | |
| 553 windows_.window2, | |
| 554 location_in_screen, | |
| 555 windows_.direction == TOP_BOTTOM ? HTTOP : HTLEFT); | |
| 556 } | |
| 557 return false; | |
| 558 } | 523 } |
| 559 | 524 |
| 560 bool MultiWindowResizeController::IsOverComponent( | 525 bool MultiWindowResizeController::IsOverWindow( |
| 561 aura::Window* window, | 526 aura::Window* window, |
| 562 const gfx::Point& location_in_screen, | 527 const gfx::Point& location_in_screen, |
| 563 int component) const { | 528 int component) const { |
| 529 if (!window->delegate()) |
| 530 return false; |
| 531 |
| 564 gfx::Point window_loc(location_in_screen); | 532 gfx::Point window_loc(location_in_screen); |
| 565 ::wm::ConvertPointFromScreen(window, &window_loc); | 533 aura::Window::ConvertPointToTarget( |
| 566 return window->delegate()->GetNonClientComponent(window_loc) == component; | 534 window->GetRootWindow(), window, &window_loc); |
| 535 return window->ContainsPoint(window_loc) && |
| 536 window->delegate()->GetNonClientComponent(window_loc) == component; |
| 567 } | 537 } |
| 568 | 538 |
| 569 } // namespace ash | 539 } // namespace ash |
| OLD | NEW |