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 |