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 |