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