Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(336)

Side by Side Diff: ash/wm/workspace/multi_window_resize_controller.cc

Issue 771543002: Improve the logic for hiding the multi-window resize handle (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fix_multi_window
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698