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

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

Issue 121153003: Prevents panels attached to shelf from docking (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Prevents panels attached to shelf from docking (comments+rebased) Created 6 years, 11 months 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/workspace_window_resizer.h" 5 #include "ash/wm/workspace/workspace_window_resizer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 // classes using reparenting during drag operations it becomes challenging to 60 // classes using reparenting during drag operations it becomes challenging to
61 // implement proper transition from one resizer to another during or at the 61 // implement proper transition from one resizer to another during or at the
62 // end of the drag. This also causes http://crbug.com/247085. 62 // end of the drag. This also causes http://crbug.com/247085.
63 // It seems the only thing the panel or dock resizer needs to do is notify the 63 // It seems the only thing the panel or dock resizer needs to do is notify the
64 // layout manager when a docked window is being dragged. We should have a 64 // layout manager when a docked window is being dragged. We should have a
65 // better way of doing this, perhaps by having a way of observing drags or 65 // better way of doing this, perhaps by having a way of observing drags or
66 // having a generic drag window wrapper which informs a layout manager that a 66 // having a generic drag window wrapper which informs a layout manager that a
67 // drag has started or stopped. 67 // drag has started or stopped.
68 // It may be possible to refactor and eliminate chaining. 68 // It may be possible to refactor and eliminate chaining.
69 WindowResizer* window_resizer = NULL; 69 WindowResizer* window_resizer = NULL;
70
71 if (!window_state->IsNormalShowState()) {
72 if (window->parent() &&
73 (window->parent()->id() == internal::kShellWindowId_DefaultContainer ||
74 window->parent()->id() == internal::kShellWindowId_DockedContainer ||
75 window->parent()->id() == internal::kShellWindowId_PanelContainer)) {
76 // Allow dragging maximized windows only when dragged by a tab.
77 if (!window_component != HTCAPTION || !window_state->is_dragged())
78 return scoped_ptr<WindowResizer>();
79 } else {
80 return scoped_ptr<WindowResizer>();
81 }
82 }
83
84 scoped_ptr<DragDetails> details(new DragDetails(
85 window, point_in_parent, window_component, source));
86 if (!details->is_resizable)
87 return scoped_ptr<WindowResizer>();
88 window_state->set_drag_details(details.release());
89
70 if (window->parent() && 90 if (window->parent() &&
71 (window->parent()->id() == internal::kShellWindowId_DefaultContainer || 91 (window->parent()->id() == internal::kShellWindowId_DefaultContainer ||
72 window->parent()->id() == internal::kShellWindowId_DockedContainer || 92 window->parent()->id() == internal::kShellWindowId_DockedContainer ||
73 window->parent()->id() == internal::kShellWindowId_PanelContainer)) { 93 window->parent()->id() == internal::kShellWindowId_PanelContainer)) {
74 // Allow dragging maximized windows if it's not tracked by workspace. This
75 // is set by tab dragging code.
76 if (!window_state->IsNormalShowState() &&
77 (window_component != HTCAPTION ||
78 !window_state->is_dragged())) {
79 return scoped_ptr<WindowResizer>();
80 }
81 window_resizer = internal::WorkspaceWindowResizer::Create( 94 window_resizer = internal::WorkspaceWindowResizer::Create(
82 window, 95 window_state,
83 point_in_parent,
84 window_component,
85 source,
86 std::vector<aura::Window*>()); 96 std::vector<aura::Window*>());
87 } else if (window_state->IsNormalShowState()) { 97 } else {
88 window_resizer = DefaultWindowResizer::Create( 98 window_resizer = DefaultWindowResizer::Create(window_state);
89 window, point_in_parent, window_component, source);
90 } 99 }
91 if (window_resizer) { 100 if (window_resizer) {
92 window_resizer = internal::DragWindowResizer::Create( 101 window_resizer = internal::DragWindowResizer::Create(window_resizer,
93 window_resizer, window, point_in_parent, window_component, source); 102 window_state);
94 } 103 }
95 if (window_resizer && window->type() == ui::wm::WINDOW_TYPE_PANEL) { 104 if (window_resizer && window->type() == ui::wm::WINDOW_TYPE_PANEL)
96 window_resizer = PanelWindowResizer::Create( 105 window_resizer = PanelWindowResizer::Create(window_resizer, window_state);
97 window_resizer, window, point_in_parent, window_component, source);
98 }
99 if (switches::UseDockedWindows() && 106 if (switches::UseDockedWindows() &&
100 window_resizer && window->parent() && 107 window_resizer && window->parent() &&
101 !views::corewm::GetTransientParent(window) && 108 !views::corewm::GetTransientParent(window) &&
102 (window->parent()->id() == internal::kShellWindowId_DefaultContainer || 109 (window->parent()->id() == internal::kShellWindowId_DefaultContainer ||
103 window->parent()->id() == internal::kShellWindowId_DockedContainer || 110 window->parent()->id() == internal::kShellWindowId_DockedContainer ||
104 window->parent()->id() == internal::kShellWindowId_PanelContainer)) { 111 window->parent()->id() == internal::kShellWindowId_PanelContainer)) {
105 window_resizer = internal::DockedWindowResizer::Create( 112 window_resizer = internal::DockedWindowResizer::Create(window_resizer,
106 window_resizer, window, point_in_parent, window_component, source); 113 window_state);
107 } 114 }
108 window_state->set_window_resizer_(window_resizer); 115 window_state->drag_details()->window_resizer = window_resizer;
109 return make_scoped_ptr<WindowResizer>(window_resizer); 116 return make_scoped_ptr<WindowResizer>(window_resizer);
110 } 117 }
111 118
112 namespace internal { 119 namespace internal {
113 120
114 namespace { 121 namespace {
115 122
116 // Snapping distance used instead of WorkspaceWindowResizer::kScreenEdgeInset 123 // Snapping distance used instead of WorkspaceWindowResizer::kScreenEdgeInset
117 // when resizing a window using touchscreen. 124 // when resizing a window using touchscreen.
118 const int kScreenEdgeInsetForTouchResize = 32; 125 const int kScreenEdgeInsetForTouchResize = 32;
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 if (did_lock_cursor_) { 355 if (did_lock_cursor_) {
349 Shell* shell = Shell::GetInstance(); 356 Shell* shell = Shell::GetInstance();
350 shell->cursor_manager()->UnlockCursor(); 357 shell->cursor_manager()->UnlockCursor();
351 } 358 }
352 if (instance_ == this) 359 if (instance_ == this)
353 instance_ = NULL; 360 instance_ = NULL;
354 } 361 }
355 362
356 // static 363 // static
357 WorkspaceWindowResizer* WorkspaceWindowResizer::Create( 364 WorkspaceWindowResizer* WorkspaceWindowResizer::Create(
358 aura::Window* window, 365 wm::WindowState* window_state,
359 const gfx::Point& location_in_parent,
360 int window_component,
361 aura::client::WindowMoveSource source,
362 const std::vector<aura::Window*>& attached_windows) { 366 const std::vector<aura::Window*>& attached_windows) {
363 Details details(window, location_in_parent, window_component, source); 367 return new WorkspaceWindowResizer(window_state, attached_windows);
364 return details.is_resizable ?
365 new WorkspaceWindowResizer(details, attached_windows) : NULL;
366 } 368 }
367 369
368 void WorkspaceWindowResizer::Drag(const gfx::Point& location_in_parent, 370 void WorkspaceWindowResizer::Drag(const gfx::Point& location_in_parent,
369 int event_flags) { 371 int event_flags) {
370 last_mouse_location_ = location_in_parent; 372 last_mouse_location_ = location_in_parent;
371 373
372 int sticky_size; 374 int sticky_size;
373 if (event_flags & ui::EF_CONTROL_DOWN) { 375 if (event_flags & ui::EF_CONTROL_DOWN) {
374 sticky_size = 0; 376 sticky_size = 0;
375 } else if (CommandLine::ForCurrentProcess()->HasSwitch( 377 } else if (CommandLine::ForCurrentProcess()->HasSwitch(
376 switches::kAshEnableStickyEdges)) { 378 switches::kAshEnableStickyEdges)) {
377 sticky_size = kStickyDistancePixels; 379 sticky_size = kStickyDistancePixels;
378 } else if ((details_.bounds_change & kBoundsChange_Resizes) && 380 } else if ((details().bounds_change & kBoundsChange_Resizes) &&
379 details_.source == aura::client::WINDOW_MOVE_SOURCE_TOUCH) { 381 details().source == aura::client::WINDOW_MOVE_SOURCE_TOUCH) {
380 sticky_size = kScreenEdgeInsetForTouchResize; 382 sticky_size = kScreenEdgeInsetForTouchResize;
381 } else { 383 } else {
382 sticky_size = kScreenEdgeInset; 384 sticky_size = kScreenEdgeInset;
383 } 385 }
384 // |bounds| is in |window()->parent()|'s coordinates. 386 // |bounds| is in |GetTarget()->parent()|'s coordinates.
385 gfx::Rect bounds = CalculateBoundsForDrag(details_, location_in_parent); 387 gfx::Rect bounds = CalculateBoundsForDrag(location_in_parent);
386 if (window_state()->IsNormalShowState()) 388 if (window_state()->IsNormalShowState())
387 AdjustBoundsForMainWindow(sticky_size, &bounds); 389 AdjustBoundsForMainWindow(sticky_size, &bounds);
388 390
389 if (bounds != window()->bounds()) { 391 if (bounds != GetTarget()->bounds()) {
390 if (!did_move_or_resize_) { 392 if (!did_move_or_resize_) {
391 if (!details_.restore_bounds.IsEmpty()) 393 if (!details().restore_bounds.IsEmpty())
392 window_state()->ClearRestoreBounds(); 394 window_state()->ClearRestoreBounds();
393 RestackWindows(); 395 RestackWindows();
394 } 396 }
395 did_move_or_resize_ = true; 397 did_move_or_resize_ = true;
396 } 398 }
397 399
398 gfx::Point location_in_screen = location_in_parent; 400 gfx::Point location_in_screen = location_in_parent;
399 wm::ConvertPointToScreen(window()->parent(), &location_in_screen); 401 wm::ConvertPointToScreen(GetTarget()->parent(), &location_in_screen);
400 402
401 aura::Window* root = NULL; 403 aura::Window* root = NULL;
402 gfx::Display display = 404 gfx::Display display =
403 ScreenAsh::FindDisplayContainingPoint(location_in_screen); 405 ScreenAsh::FindDisplayContainingPoint(location_in_screen);
404 // Track the last screen that the pointer was on to keep the snap phantom 406 // Track the last screen that the pointer was on to keep the snap phantom
405 // window there. 407 // window there.
406 if (display.is_valid()) { 408 if (display.is_valid()) {
407 root = Shell::GetInstance()->display_controller()-> 409 root = Shell::GetInstance()->display_controller()->
408 GetRootWindowForDisplayId(display.id()); 410 GetRootWindowForDisplayId(display.id());
409 } 411 }
410 if (!attached_windows_.empty()) 412 if (!attached_windows_.empty())
411 LayoutAttachedWindows(&bounds); 413 LayoutAttachedWindows(&bounds);
412 if (bounds != window()->bounds()) { 414 if (bounds != GetTarget()->bounds()) {
413 // SetBounds needs to be called to update the layout which affects where the 415 // SetBounds needs to be called to update the layout which affects where the
414 // phantom window is drawn. Keep track if the window was destroyed during 416 // phantom window is drawn. Keep track if the window was destroyed during
415 // the drag and quit early if so. 417 // the drag and quit early if so.
416 base::WeakPtr<WorkspaceWindowResizer> resizer( 418 base::WeakPtr<WorkspaceWindowResizer> resizer(
417 weak_ptr_factory_.GetWeakPtr()); 419 weak_ptr_factory_.GetWeakPtr());
418 window()->SetBounds(bounds); 420 GetTarget()->SetBounds(bounds);
419 if (!resizer) 421 if (!resizer)
420 return; 422 return;
421 } 423 }
422 const bool in_original_root = !root || root == window()->GetRootWindow(); 424 const bool in_original_root = !root || root == GetTarget()->GetRootWindow();
423 // Hide a phantom window for snapping if the cursor is in another root window. 425 // Hide a phantom window for snapping if the cursor is in another root window.
424 if (in_original_root) { 426 if (in_original_root) {
425 UpdateSnapPhantomWindow(location_in_parent, bounds); 427 UpdateSnapPhantomWindow(location_in_parent, bounds);
426 } else { 428 } else {
427 snap_type_ = SNAP_NONE; 429 snap_type_ = SNAP_NONE;
428 snap_phantom_window_controller_.reset(); 430 snap_phantom_window_controller_.reset();
429 snap_sizer_.reset(); 431 snap_sizer_.reset();
430 SetDraggedWindowDocked(false); 432 SetDraggedWindowDocked(false);
431 } 433 }
432 } 434 }
433 435
434 void WorkspaceWindowResizer::CompleteDrag() { 436 void WorkspaceWindowResizer::CompleteDrag() {
435 window_state()->set_bounds_changed_by_user(true); 437 window_state()->set_bounds_changed_by_user(true);
436 snap_phantom_window_controller_.reset(); 438 snap_phantom_window_controller_.reset();
437 if (!did_move_or_resize_ || details_.window_component != HTCAPTION) 439 if (!did_move_or_resize_ || details().window_component != HTCAPTION)
438 return; 440 return;
439 441
440 bool snapped = false; 442 bool snapped = false;
441 // When the window is not in the normal show state, we do not snap the window. 443 // When the window is not in the normal show state, we do not snap the window.
442 // This happens when the user minimizes or maximizes the window by keyboard 444 // This happens when the user minimizes or maximizes the window by keyboard
443 // shortcut while dragging it. If the window is the result of dragging a tab 445 // shortcut while dragging it. If the window is the result of dragging a tab
444 // out of a maximized window, it's already in the normal show state when this 446 // out of a maximized window, it's already in the normal show state when this
445 // is called, so it does not matter. 447 // is called, so it does not matter.
446 if (window_state()->IsNormalShowState() && 448 if (window_state()->IsNormalShowState() &&
447 (window()->type() != ui::wm::WINDOW_TYPE_PANEL || 449 (GetTarget()->type() != ui::wm::WINDOW_TYPE_PANEL ||
448 !window_state()->panel_attached() || 450 !window_state()->panel_attached() ||
449 dock_layout_->is_dragged_window_docked()) && 451 dock_layout_->is_dragged_window_docked()) &&
450 (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT)) { 452 (snap_type_ == SNAP_LEFT || snap_type_ == SNAP_RIGHT)) {
451 if (!window_state()->HasRestoreBounds()) { 453 if (!window_state()->HasRestoreBounds()) {
452 gfx::Rect initial_bounds = ScreenAsh::ConvertRectToScreen( 454 gfx::Rect initial_bounds = ScreenAsh::ConvertRectToScreen(
453 window()->parent(), details_.initial_bounds_in_parent); 455 GetTarget()->parent(), details().initial_bounds_in_parent);
454 window_state()->SetRestoreBoundsInScreen( 456 window_state()->SetRestoreBoundsInScreen(
455 details_.restore_bounds.IsEmpty() ? 457 details().restore_bounds.IsEmpty() ?
456 initial_bounds : 458 initial_bounds :
457 details_.restore_bounds); 459 details().restore_bounds);
458 } 460 }
459 DCHECK(snap_sizer_); 461 DCHECK(snap_sizer_);
460 if (window_state()->CanResize() && 462 if (window_state()->CanResize() &&
461 !dock_layout_->is_dragged_window_docked()) { 463 !dock_layout_->is_dragged_window_docked()) {
462 snap_sizer_->SnapWindowToTargetBounds(); 464 snap_sizer_->SnapWindowToTargetBounds();
463 snapped = true; 465 snapped = true;
464 } 466 }
465 } 467 }
466 if (window_state()->IsSnapped() && !snapped) 468 if (window_state()->IsSnapped() && !snapped)
467 window_state()->Restore(); 469 window_state()->Restore();
468 } 470 }
469 471
470 void WorkspaceWindowResizer::RevertDrag() { 472 void WorkspaceWindowResizer::RevertDrag() {
471 window_state()->set_bounds_changed_by_user(initial_bounds_changed_by_user_); 473 window_state()->set_bounds_changed_by_user(initial_bounds_changed_by_user_);
472 snap_phantom_window_controller_.reset(); 474 snap_phantom_window_controller_.reset();
473 475
474 if (!did_move_or_resize_) 476 if (!did_move_or_resize_)
475 return; 477 return;
476 478
477 window()->SetBounds(details_.initial_bounds_in_parent); 479 GetTarget()->SetBounds(details().initial_bounds_in_parent);
478 if (!details_.restore_bounds.IsEmpty()) { 480 if (!details().restore_bounds.IsEmpty()) {
479 window_state()->SetRestoreBoundsInScreen(details_.restore_bounds); 481 window_state()->SetRestoreBoundsInScreen(details().restore_bounds);
480 } 482 }
481 483
482 if (details_.window_component == HTRIGHT) { 484 if (details().window_component == HTRIGHT) {
483 int last_x = details_.initial_bounds_in_parent.right(); 485 int last_x = details().initial_bounds_in_parent.right();
484 for (size_t i = 0; i < attached_windows_.size(); ++i) { 486 for (size_t i = 0; i < attached_windows_.size(); ++i) {
485 gfx::Rect bounds(attached_windows_[i]->bounds()); 487 gfx::Rect bounds(attached_windows_[i]->bounds());
486 bounds.set_x(last_x); 488 bounds.set_x(last_x);
487 bounds.set_width(initial_size_[i]); 489 bounds.set_width(initial_size_[i]);
488 attached_windows_[i]->SetBounds(bounds); 490 attached_windows_[i]->SetBounds(bounds);
489 last_x = attached_windows_[i]->bounds().right(); 491 last_x = attached_windows_[i]->bounds().right();
490 } 492 }
491 } else { 493 } else {
492 int last_y = details_.initial_bounds_in_parent.bottom(); 494 int last_y = details().initial_bounds_in_parent.bottom();
493 for (size_t i = 0; i < attached_windows_.size(); ++i) { 495 for (size_t i = 0; i < attached_windows_.size(); ++i) {
494 gfx::Rect bounds(attached_windows_[i]->bounds()); 496 gfx::Rect bounds(attached_windows_[i]->bounds());
495 bounds.set_y(last_y); 497 bounds.set_y(last_y);
496 bounds.set_height(initial_size_[i]); 498 bounds.set_height(initial_size_[i]);
497 attached_windows_[i]->SetBounds(bounds); 499 attached_windows_[i]->SetBounds(bounds);
498 last_y = attached_windows_[i]->bounds().bottom(); 500 last_y = attached_windows_[i]->bounds().bottom();
499 } 501 }
500 } 502 }
501 } 503 }
502 504
503 aura::Window* WorkspaceWindowResizer::GetTarget() {
504 return details_.window;
505 }
506
507 const gfx::Point& WorkspaceWindowResizer::GetInitialLocation() const {
508 return details_.initial_location_in_parent;
509 }
510
511 WorkspaceWindowResizer::WorkspaceWindowResizer( 505 WorkspaceWindowResizer::WorkspaceWindowResizer(
512 const Details& details, 506 wm::WindowState* window_state,
513 const std::vector<aura::Window*>& attached_windows) 507 const std::vector<aura::Window*>& attached_windows)
514 : details_(details), 508 : WindowResizer(window_state),
515 attached_windows_(attached_windows), 509 attached_windows_(attached_windows),
516 did_lock_cursor_(false), 510 did_lock_cursor_(false),
517 did_move_or_resize_(false), 511 did_move_or_resize_(false),
518 initial_bounds_changed_by_user_( 512 initial_bounds_changed_by_user_(window_state_->bounds_changed_by_user()),
519 details.window_state->bounds_changed_by_user()),
520 total_min_(0), 513 total_min_(0),
521 total_initial_size_(0), 514 total_initial_size_(0),
522 snap_type_(SNAP_NONE), 515 snap_type_(SNAP_NONE),
523 num_mouse_moves_since_bounds_change_(0), 516 num_mouse_moves_since_bounds_change_(0),
524 magnetism_window_(NULL), 517 magnetism_window_(NULL),
525 weak_ptr_factory_(this) { 518 weak_ptr_factory_(this) {
526 DCHECK(details_.is_resizable); 519 DCHECK(details().is_resizable);
527 520
528 // A mousemove should still show the cursor even if the window is 521 // A mousemove should still show the cursor even if the window is
529 // being moved or resized with touch, so do not lock the cursor. 522 // being moved or resized with touch, so do not lock the cursor.
530 if (details.source != aura::client::WINDOW_MOVE_SOURCE_TOUCH) { 523 if (details().source != aura::client::WINDOW_MOVE_SOURCE_TOUCH) {
531 Shell* shell = Shell::GetInstance(); 524 Shell* shell = Shell::GetInstance();
532 shell->cursor_manager()->LockCursor(); 525 shell->cursor_manager()->LockCursor();
533 did_lock_cursor_ = true; 526 did_lock_cursor_ = true;
534 } 527 }
535 528
536 aura::Window* dock_container = Shell::GetContainer( 529 aura::Window* dock_container = Shell::GetContainer(
537 window()->GetRootWindow(), kShellWindowId_DockedContainer); 530 GetTarget()->GetRootWindow(), kShellWindowId_DockedContainer);
538 dock_layout_ = static_cast<DockedWindowLayoutManager*>( 531 dock_layout_ = static_cast<DockedWindowLayoutManager*>(
539 dock_container->layout_manager()); 532 dock_container->layout_manager());
540 533
541 // Only support attaching to the right/bottom. 534 // Only support attaching to the right/bottom.
542 DCHECK(attached_windows_.empty() || 535 DCHECK(attached_windows_.empty() ||
543 (details.window_component == HTRIGHT || 536 (details().window_component == HTRIGHT ||
544 details.window_component == HTBOTTOM)); 537 details().window_component == HTBOTTOM));
545 538
546 // TODO: figure out how to deal with window going off the edge. 539 // TODO: figure out how to deal with window going off the edge.
547 540
548 // Calculate sizes so that we can maintain the ratios if we need to resize. 541 // Calculate sizes so that we can maintain the ratios if we need to resize.
549 int total_available = 0; 542 int total_available = 0;
550 for (size_t i = 0; i < attached_windows_.size(); ++i) { 543 for (size_t i = 0; i < attached_windows_.size(); ++i) {
551 gfx::Size min(attached_windows_[i]->delegate()->GetMinimumSize()); 544 gfx::Size min(attached_windows_[i]->delegate()->GetMinimumSize());
552 int initial_size = PrimaryAxisSize(attached_windows_[i]->bounds().size()); 545 int initial_size = PrimaryAxisSize(attached_windows_[i]->bounds().size());
553 initial_size_.push_back(initial_size); 546 initial_size_.push_back(initial_size);
554 // If current size is smaller than the min, use the current size as the min. 547 // If current size is smaller than the min, use the current size as the min.
(...skipping 11 matching lines...) Expand all
566 const gfx::Rect& bounds) const { 559 const gfx::Rect& bounds) const {
567 if (snap_phantom_window_controller_.get() && 560 if (snap_phantom_window_controller_.get() &&
568 snap_phantom_window_controller_->IsShowing()) { 561 snap_phantom_window_controller_->IsShowing()) {
569 return snap_phantom_window_controller_->bounds_in_screen(); 562 return snap_phantom_window_controller_->bounds_in_screen();
570 } 563 }
571 return bounds; 564 return bounds;
572 } 565 }
573 566
574 void WorkspaceWindowResizer::LayoutAttachedWindows( 567 void WorkspaceWindowResizer::LayoutAttachedWindows(
575 gfx::Rect* bounds) { 568 gfx::Rect* bounds) {
576 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window())); 569 gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(GetTarget()));
577 int initial_size = PrimaryAxisSize(details_.initial_bounds_in_parent.size()); 570 int initial_size = PrimaryAxisSize(details().initial_bounds_in_parent.size());
578 int current_size = PrimaryAxisSize(bounds->size()); 571 int current_size = PrimaryAxisSize(bounds->size());
579 int start = PrimaryAxisCoordinate(bounds->right(), bounds->bottom()); 572 int start = PrimaryAxisCoordinate(bounds->right(), bounds->bottom());
580 int end = PrimaryAxisCoordinate(work_area.right(), work_area.bottom()); 573 int end = PrimaryAxisCoordinate(work_area.right(), work_area.bottom());
581 574
582 int delta = current_size - initial_size; 575 int delta = current_size - initial_size;
583 int available_size = end - start; 576 int available_size = end - start;
584 std::vector<int> sizes; 577 std::vector<int> sizes;
585 int leftovers = CalculateAttachedSizes(delta, available_size, &sizes); 578 int leftovers = CalculateAttachedSizes(delta, available_size, &sizes);
586 579
587 // leftovers > 0 means that the attached windows can't grow to compensate for 580 // leftovers > 0 means that the attached windows can't grow to compensate for
588 // the shrinkage of the main window. This line causes the attached windows to 581 // the shrinkage of the main window. This line causes the attached windows to
589 // be moved so they are still flush against the main window, rather than the 582 // be moved so they are still flush against the main window, rather than the
590 // main window being prevented from shrinking. 583 // main window being prevented from shrinking.
591 leftovers = std::min(0, leftovers); 584 leftovers = std::min(0, leftovers);
592 // Reallocate any leftover pixels back into the main window. This is 585 // Reallocate any leftover pixels back into the main window. This is
593 // necessary when, for example, the main window shrinks, but none of the 586 // necessary when, for example, the main window shrinks, but none of the
594 // attached windows can grow without exceeding their max size constraints. 587 // attached windows can grow without exceeding their max size constraints.
595 // Adding the pixels back to the main window effectively prevents the main 588 // Adding the pixels back to the main window effectively prevents the main
596 // window from resizing too far. 589 // window from resizing too far.
597 if (details_.window_component == HTRIGHT) 590 if (details().window_component == HTRIGHT)
598 bounds->set_width(bounds->width() + leftovers); 591 bounds->set_width(bounds->width() + leftovers);
599 else 592 else
600 bounds->set_height(bounds->height() + leftovers); 593 bounds->set_height(bounds->height() + leftovers);
601 594
602 DCHECK_EQ(attached_windows_.size(), sizes.size()); 595 DCHECK_EQ(attached_windows_.size(), sizes.size());
603 int last = PrimaryAxisCoordinate(bounds->right(), bounds->bottom()); 596 int last = PrimaryAxisCoordinate(bounds->right(), bounds->bottom());
604 for (size_t i = 0; i < attached_windows_.size(); ++i) { 597 for (size_t i = 0; i < attached_windows_.size(); ++i) {
605 gfx::Rect attached_bounds(attached_windows_[i]->bounds()); 598 gfx::Rect attached_bounds(attached_windows_[i]->bounds());
606 if (details_.window_component == HTRIGHT) { 599 if (details().window_component == HTRIGHT) {
607 attached_bounds.set_x(last); 600 attached_bounds.set_x(last);
608 attached_bounds.set_width(sizes[i]); 601 attached_bounds.set_width(sizes[i]);
609 } else { 602 } else {
610 attached_bounds.set_y(last); 603 attached_bounds.set_y(last);
611 attached_bounds.set_height(sizes[i]); 604 attached_bounds.set_height(sizes[i]);
612 } 605 }
613 attached_windows_[i]->SetBounds(attached_bounds); 606 attached_windows_[i]->SetBounds(attached_bounds);
614 last += sizes[i]; 607 last += sizes[i];
615 } 608 }
616 } 609 }
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 int min = PrimaryAxisSize(delegate->GetMinimumSize()); 699 int min = PrimaryAxisSize(delegate->GetMinimumSize());
707 int max = PrimaryAxisSize(delegate->GetMaximumSize()); 700 int max = PrimaryAxisSize(delegate->GetMaximumSize());
708 701
709 sizes->push_back(WindowSize(initial_size, min, max)); 702 sizes->push_back(WindowSize(initial_size, min, max));
710 } 703 }
711 } 704 }
712 705
713 void WorkspaceWindowResizer::MagneticallySnapToOtherWindows(gfx::Rect* bounds) { 706 void WorkspaceWindowResizer::MagneticallySnapToOtherWindows(gfx::Rect* bounds) {
714 if (UpdateMagnetismWindow(*bounds, kAllMagnetismEdges)) { 707 if (UpdateMagnetismWindow(*bounds, kAllMagnetismEdges)) {
715 gfx::Point point = OriginForMagneticAttach( 708 gfx::Point point = OriginForMagneticAttach(
716 ScreenAsh::ConvertRectToScreen(window()->parent(), *bounds), 709 ScreenAsh::ConvertRectToScreen(GetTarget()->parent(), *bounds),
717 magnetism_window_->GetBoundsInScreen(), 710 magnetism_window_->GetBoundsInScreen(),
718 magnetism_edge_); 711 magnetism_edge_);
719 aura::client::GetScreenPositionClient(window()->GetRootWindow())-> 712 aura::client::GetScreenPositionClient(GetTarget()->GetRootWindow())->
720 ConvertPointFromScreen(window()->parent(), &point); 713 ConvertPointFromScreen(GetTarget()->parent(), &point);
721 bounds->set_origin(point); 714 bounds->set_origin(point);
722 } 715 }
723 } 716 }
724 717
725 void WorkspaceWindowResizer::MagneticallySnapResizeToOtherWindows( 718 void WorkspaceWindowResizer::MagneticallySnapResizeToOtherWindows(
726 gfx::Rect* bounds) { 719 gfx::Rect* bounds) {
727 const uint32 edges = WindowComponentToMagneticEdge(details_.window_component); 720 const uint32 edges = WindowComponentToMagneticEdge(
721 details().window_component);
728 if (UpdateMagnetismWindow(*bounds, edges)) { 722 if (UpdateMagnetismWindow(*bounds, edges)) {
729 *bounds = ScreenAsh::ConvertRectFromScreen( 723 *bounds = ScreenAsh::ConvertRectFromScreen(
730 window()->parent(), 724 GetTarget()->parent(),
731 BoundsForMagneticResizeAttach( 725 BoundsForMagneticResizeAttach(
732 ScreenAsh::ConvertRectToScreen(window()->parent(), *bounds), 726 ScreenAsh::ConvertRectToScreen(GetTarget()->parent(), *bounds),
733 magnetism_window_->GetBoundsInScreen(), 727 magnetism_window_->GetBoundsInScreen(),
734 magnetism_edge_)); 728 magnetism_edge_));
735 } 729 }
736 } 730 }
737 731
738 bool WorkspaceWindowResizer::UpdateMagnetismWindow(const gfx::Rect& bounds, 732 bool WorkspaceWindowResizer::UpdateMagnetismWindow(const gfx::Rect& bounds,
739 uint32 edges) { 733 uint32 edges) {
740 // |bounds| are in coordinates of original window's parent. 734 // |bounds| are in coordinates of original window's parent.
741 gfx::Rect bounds_in_screen = 735 gfx::Rect bounds_in_screen =
742 ScreenAsh::ConvertRectToScreen(window()->parent(), bounds); 736 ScreenAsh::ConvertRectToScreen(GetTarget()->parent(), bounds);
743 MagnetismMatcher matcher(bounds_in_screen, edges); 737 MagnetismMatcher matcher(bounds_in_screen, edges);
744 738
745 // If we snapped to a window then check it first. That way we don't bounce 739 // If we snapped to a window then check it first. That way we don't bounce
746 // around when close to multiple edges. 740 // around when close to multiple edges.
747 if (magnetism_window_) { 741 if (magnetism_window_) {
748 if (window_tracker_.Contains(magnetism_window_) && 742 if (window_tracker_.Contains(magnetism_window_) &&
749 matcher.ShouldAttach(magnetism_window_->GetBoundsInScreen(), 743 matcher.ShouldAttach(magnetism_window_->GetBoundsInScreen(),
750 &magnetism_edge_)) { 744 &magnetism_edge_)) {
751 return true; 745 return true;
752 } 746 }
753 window_tracker_.Remove(magnetism_window_); 747 window_tracker_.Remove(magnetism_window_);
754 magnetism_window_ = NULL; 748 magnetism_window_ = NULL;
755 } 749 }
756 750
757 // Avoid magnetically snapping windows that are not resizable. 751 // Avoid magnetically snapping windows that are not resizable.
758 // TODO(oshima): change this to window.type() == TYPE_NORMAL. 752 // TODO(oshima): change this to window.type() == TYPE_NORMAL.
759 if (!window_state()->CanResize()) 753 if (!window_state()->CanResize())
760 return false; 754 return false;
761 755
762 aura::Window::Windows root_windows = Shell::GetAllRootWindows(); 756 aura::Window::Windows root_windows = Shell::GetAllRootWindows();
763 for (aura::Window::Windows::iterator iter = root_windows.begin(); 757 for (aura::Window::Windows::iterator iter = root_windows.begin();
764 iter != root_windows.end(); ++iter) { 758 iter != root_windows.end(); ++iter) {
765 const aura::Window* root_window = *iter; 759 const aura::Window* root_window = *iter;
766 // Test all children from the desktop in each root window. 760 // Test all children from the desktop in each root window.
767 const aura::Window::Windows& children = Shell::GetContainer( 761 const aura::Window::Windows& children = Shell::GetContainer(
768 root_window, kShellWindowId_DefaultContainer)->children(); 762 root_window, kShellWindowId_DefaultContainer)->children();
769 for (aura::Window::Windows::const_reverse_iterator i = children.rbegin(); 763 for (aura::Window::Windows::const_reverse_iterator i = children.rbegin();
770 i != children.rend() && !matcher.AreEdgesObscured(); ++i) { 764 i != children.rend() && !matcher.AreEdgesObscured(); ++i) {
771 wm::WindowState* other_state = wm::GetWindowState(*i); 765 wm::WindowState* other_state = wm::GetWindowState(*i);
772 if (other_state->window() == window() || 766 if (other_state->window() == GetTarget() ||
773 !other_state->window()->IsVisible() || 767 !other_state->window()->IsVisible() ||
774 !other_state->IsNormalShowState() || 768 !other_state->IsNormalShowState() ||
775 !other_state->CanResize()) { 769 !other_state->CanResize()) {
776 continue; 770 continue;
777 } 771 }
778 if (matcher.ShouldAttach( 772 if (matcher.ShouldAttach(
779 other_state->window()->GetBoundsInScreen(), &magnetism_edge_)) { 773 other_state->window()->GetBoundsInScreen(), &magnetism_edge_)) {
780 magnetism_window_ = other_state->window(); 774 magnetism_window_ = other_state->window();
781 window_tracker_.Add(magnetism_window_); 775 window_tracker_.Add(magnetism_window_);
782 return true; 776 return true;
783 } 777 }
784 } 778 }
785 } 779 }
786 return false; 780 return false;
787 } 781 }
788 782
789 void WorkspaceWindowResizer::AdjustBoundsForMainWindow( 783 void WorkspaceWindowResizer::AdjustBoundsForMainWindow(
790 int sticky_size, 784 int sticky_size,
791 gfx::Rect* bounds) { 785 gfx::Rect* bounds) {
792 gfx::Point last_mouse_location_in_screen = last_mouse_location_; 786 gfx::Point last_mouse_location_in_screen = last_mouse_location_;
793 wm::ConvertPointToScreen(window()->parent(), &last_mouse_location_in_screen); 787 wm::ConvertPointToScreen(GetTarget()->parent(),
788 &last_mouse_location_in_screen);
794 gfx::Display display = Shell::GetScreen()->GetDisplayNearestPoint( 789 gfx::Display display = Shell::GetScreen()->GetDisplayNearestPoint(
795 last_mouse_location_in_screen); 790 last_mouse_location_in_screen);
796 gfx::Rect work_area = 791 gfx::Rect work_area =
797 ScreenAsh::ConvertRectFromScreen(window()->parent(), display.work_area()); 792 ScreenAsh::ConvertRectFromScreen(GetTarget()->parent(),
798 if (details_.window_component == HTCAPTION) { 793 display.work_area());
794 if (details().window_component == HTCAPTION) {
799 // Adjust the bounds to the work area where the mouse cursor is located. 795 // Adjust the bounds to the work area where the mouse cursor is located.
800 // Always keep kMinOnscreenHeight or the window height (whichever is less) 796 // Always keep kMinOnscreenHeight or the window height (whichever is less)
801 // on the bottom. 797 // on the bottom.
802 int max_y = work_area.bottom() - std::min(kMinOnscreenHeight, 798 int max_y = work_area.bottom() - std::min(kMinOnscreenHeight,
803 bounds->height()); 799 bounds->height());
804 if (bounds->y() > max_y) { 800 if (bounds->y() > max_y) {
805 bounds->set_y(max_y); 801 bounds->set_y(max_y);
806 } else if (bounds->y() <= work_area.y()) { 802 } else if (bounds->y() <= work_area.y()) {
807 // Don't allow dragging above the top of the display until the mouse 803 // Don't allow dragging above the top of the display until the mouse
808 // cursor reaches the work area above if any. 804 // cursor reaches the work area above if any.
(...skipping 10 matching lines...) Expand all
819 } 815 }
820 } else if (sticky_size > 0) { 816 } else if (sticky_size > 0) {
821 MagneticallySnapResizeToOtherWindows(bounds); 817 MagneticallySnapResizeToOtherWindows(bounds);
822 if (!magnetism_window_ && sticky_size > 0) 818 if (!magnetism_window_ && sticky_size > 0)
823 StickToWorkAreaOnResize(work_area, sticky_size, bounds); 819 StickToWorkAreaOnResize(work_area, sticky_size, bounds);
824 } 820 }
825 821
826 if (attached_windows_.empty()) 822 if (attached_windows_.empty())
827 return; 823 return;
828 824
829 if (details_.window_component == HTRIGHT) { 825 if (details().window_component == HTRIGHT) {
830 bounds->set_width(std::min(bounds->width(), 826 bounds->set_width(std::min(bounds->width(),
831 work_area.right() - total_min_ - bounds->x())); 827 work_area.right() - total_min_ - bounds->x()));
832 } else { 828 } else {
833 DCHECK_EQ(HTBOTTOM, details_.window_component); 829 DCHECK_EQ(HTBOTTOM, details().window_component);
834 bounds->set_height(std::min(bounds->height(), 830 bounds->set_height(std::min(bounds->height(),
835 work_area.bottom() - total_min_ - bounds->y())); 831 work_area.bottom() - total_min_ - bounds->y()));
836 } 832 }
837 } 833 }
838 834
839 bool WorkspaceWindowResizer::StickToWorkAreaOnMove( 835 bool WorkspaceWindowResizer::StickToWorkAreaOnMove(
840 const gfx::Rect& work_area, 836 const gfx::Rect& work_area,
841 int sticky_size, 837 int sticky_size,
842 gfx::Rect* bounds) const { 838 gfx::Rect* bounds) const {
843 const int left_edge = work_area.x(); 839 const int left_edge = work_area.x();
(...skipping 19 matching lines...) Expand all
863 bounds->set_y(bottom_edge - bounds->height()); 859 bounds->set_y(bottom_edge - bounds->height());
864 updated = true; 860 updated = true;
865 } 861 }
866 return updated; 862 return updated;
867 } 863 }
868 864
869 void WorkspaceWindowResizer::StickToWorkAreaOnResize( 865 void WorkspaceWindowResizer::StickToWorkAreaOnResize(
870 const gfx::Rect& work_area, 866 const gfx::Rect& work_area,
871 int sticky_size, 867 int sticky_size,
872 gfx::Rect* bounds) const { 868 gfx::Rect* bounds) const {
873 const uint32 edges = WindowComponentToMagneticEdge(details_.window_component); 869 const uint32 edges = WindowComponentToMagneticEdge(
870 details().window_component);
874 const int left_edge = work_area.x(); 871 const int left_edge = work_area.x();
875 const int right_edge = work_area.right(); 872 const int right_edge = work_area.right();
876 const int top_edge = work_area.y(); 873 const int top_edge = work_area.y();
877 const int bottom_edge = work_area.bottom(); 874 const int bottom_edge = work_area.bottom();
878 if (edges & MAGNETISM_EDGE_TOP && 875 if (edges & MAGNETISM_EDGE_TOP &&
879 ShouldStickToEdge(bounds->y() - top_edge, sticky_size)) { 876 ShouldStickToEdge(bounds->y() - top_edge, sticky_size)) {
880 bounds->set_height(bounds->bottom() - top_edge); 877 bounds->set_height(bounds->bottom() - top_edge);
881 bounds->set_y(top_edge); 878 bounds->set_y(top_edge);
882 } 879 }
883 if (edges & MAGNETISM_EDGE_LEFT && 880 if (edges & MAGNETISM_EDGE_LEFT &&
884 ShouldStickToEdge(bounds->x() - left_edge, sticky_size)) { 881 ShouldStickToEdge(bounds->x() - left_edge, sticky_size)) {
885 bounds->set_width(bounds->right() - left_edge); 882 bounds->set_width(bounds->right() - left_edge);
886 bounds->set_x(left_edge); 883 bounds->set_x(left_edge);
887 } 884 }
888 if (edges & MAGNETISM_EDGE_BOTTOM && 885 if (edges & MAGNETISM_EDGE_BOTTOM &&
889 ShouldStickToEdge(bottom_edge - bounds->bottom(), sticky_size)) { 886 ShouldStickToEdge(bottom_edge - bounds->bottom(), sticky_size)) {
890 bounds->set_height(bottom_edge - bounds->y()); 887 bounds->set_height(bottom_edge - bounds->y());
891 } 888 }
892 if (edges & MAGNETISM_EDGE_RIGHT && 889 if (edges & MAGNETISM_EDGE_RIGHT &&
893 ShouldStickToEdge(right_edge - bounds->right(), sticky_size)) { 890 ShouldStickToEdge(right_edge - bounds->right(), sticky_size)) {
894 bounds->set_width(right_edge - bounds->x()); 891 bounds->set_width(right_edge - bounds->x());
895 } 892 }
896 } 893 }
897 894
898 int WorkspaceWindowResizer::PrimaryAxisSize(const gfx::Size& size) const { 895 int WorkspaceWindowResizer::PrimaryAxisSize(const gfx::Size& size) const {
899 return PrimaryAxisCoordinate(size.width(), size.height()); 896 return PrimaryAxisCoordinate(size.width(), size.height());
900 } 897 }
901 898
902 int WorkspaceWindowResizer::PrimaryAxisCoordinate(int x, int y) const { 899 int WorkspaceWindowResizer::PrimaryAxisCoordinate(int x, int y) const {
903 switch (details_.window_component) { 900 switch (details().window_component) {
904 case HTRIGHT: 901 case HTRIGHT:
905 return x; 902 return x;
906 case HTBOTTOM: 903 case HTBOTTOM:
907 return y; 904 return y;
908 default: 905 default:
909 NOTREACHED(); 906 NOTREACHED();
910 } 907 }
911 return 0; 908 return 0;
912 } 909 }
913 910
914 void WorkspaceWindowResizer::UpdateSnapPhantomWindow(const gfx::Point& location, 911 void WorkspaceWindowResizer::UpdateSnapPhantomWindow(const gfx::Point& location,
915 const gfx::Rect& bounds) { 912 const gfx::Rect& bounds) {
916 if (!did_move_or_resize_ || details_.window_component != HTCAPTION) 913 if (!did_move_or_resize_ || details().window_component != HTCAPTION)
917 return; 914 return;
918 915
919 SnapType last_type = snap_type_; 916 SnapType last_type = snap_type_;
920 snap_type_ = GetSnapType(location); 917 snap_type_ = GetSnapType(location);
921 if (snap_type_ == SNAP_NONE || snap_type_ != last_type) { 918 if (snap_type_ == SNAP_NONE || snap_type_ != last_type) {
922 snap_phantom_window_controller_.reset(); 919 snap_phantom_window_controller_.reset();
923 snap_sizer_.reset(); 920 snap_sizer_.reset();
924 if (snap_type_ == SNAP_NONE) { 921 if (snap_type_ == SNAP_NONE) {
925 SetDraggedWindowDocked(false); 922 SetDraggedWindowDocked(false);
926 return; 923 return;
927 } 924 }
928 } 925 }
929 const bool can_dock = dock_layout_->CanDockWindow(window(), snap_type_); 926 const bool can_dock = dock_layout_->CanDockWindow(GetTarget(), snap_type_);
930 const bool can_snap = window_state()->CanSnap(); 927 const bool can_snap = window_state()->CanSnap();
931 if (!can_snap && !can_dock) { 928 if (!can_snap && !can_dock) {
932 snap_type_ = SNAP_NONE; 929 snap_type_ = SNAP_NONE;
933 snap_phantom_window_controller_.reset(); 930 snap_phantom_window_controller_.reset();
934 snap_sizer_.reset(); 931 snap_sizer_.reset();
935 SetDraggedWindowDocked(false); 932 SetDraggedWindowDocked(false);
936 return; 933 return;
937 } 934 }
938 SnapSizer::Edge edge = (snap_type_ == SNAP_LEFT) ? 935 SnapSizer::Edge edge = (snap_type_ == SNAP_LEFT) ?
939 SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE; 936 SnapSizer::LEFT_EDGE : SnapSizer::RIGHT_EDGE;
940 if (!snap_sizer_) { 937 if (!snap_sizer_) {
941 snap_sizer_.reset(new SnapSizer(window_state(), 938 snap_sizer_.reset(new SnapSizer(window_state(),
942 location, 939 location,
943 edge, 940 edge,
944 internal::SnapSizer::OTHER_INPUT)); 941 internal::SnapSizer::OTHER_INPUT));
945 } else { 942 } else {
946 snap_sizer_->Update(location); 943 snap_sizer_->Update(location);
947 } 944 }
948 945
949 // Update phantom window with snapped or docked guide bounds. 946 // Update phantom window with snapped or docked guide bounds.
950 // Windows that cannot be snapped or are less wide than kMaxDockWidth can get 947 // Windows that cannot be snapped or are less wide than kMaxDockWidth can get
951 // docked without going through a snapping sequence. 948 // docked without going through a snapping sequence.
952 gfx::Rect phantom_bounds; 949 gfx::Rect phantom_bounds;
953 if (can_snap && 950 if (can_snap && (!can_dock || GetTarget()->bounds().width() >
954 (!can_dock || 951 DockedWindowLayoutManager::kMaxDockWidth)) {
955 window()->bounds().width() > DockedWindowLayoutManager::kMaxDockWidth))
956 phantom_bounds = snap_sizer_->target_bounds(); 952 phantom_bounds = snap_sizer_->target_bounds();
953 }
957 const bool should_dock = can_dock && 954 const bool should_dock = can_dock &&
958 (phantom_bounds.IsEmpty() || 955 (phantom_bounds.IsEmpty() ||
959 snap_sizer_->end_of_sequence() || 956 snap_sizer_->end_of_sequence() ||
960 dock_layout_->is_dragged_window_docked()); 957 dock_layout_->is_dragged_window_docked());
961 SetDraggedWindowDocked(should_dock); 958 SetDraggedWindowDocked(should_dock);
962 snap_type_ = GetSnapType(location); 959 snap_type_ = GetSnapType(location);
963 if (dock_layout_->is_dragged_window_docked()) { 960 if (dock_layout_->is_dragged_window_docked()) {
964 phantom_bounds = ScreenAsh::ConvertRectFromScreen( 961 phantom_bounds = ScreenAsh::ConvertRectFromScreen(
965 window()->parent(), dock_layout_->dragged_bounds()); 962 GetTarget()->parent(), dock_layout_->dragged_bounds());
966 } 963 }
967 964
968 if (phantom_bounds.IsEmpty()) { 965 if (phantom_bounds.IsEmpty()) {
969 snap_phantom_window_controller_.reset(); 966 snap_phantom_window_controller_.reset();
970 return; 967 return;
971 } 968 }
972 969
973 if (!snap_phantom_window_controller_) { 970 if (!snap_phantom_window_controller_) {
974 snap_phantom_window_controller_.reset( 971 snap_phantom_window_controller_.reset(
975 new PhantomWindowController(window())); 972 new PhantomWindowController(GetTarget()));
976 } 973 }
977 snap_phantom_window_controller_->Show(ScreenAsh::ConvertRectToScreen( 974 snap_phantom_window_controller_->Show(ScreenAsh::ConvertRectToScreen(
978 window()->parent(), phantom_bounds)); 975 GetTarget()->parent(), phantom_bounds));
979 } 976 }
980 977
981 void WorkspaceWindowResizer::RestackWindows() { 978 void WorkspaceWindowResizer::RestackWindows() {
982 if (attached_windows_.empty()) 979 if (attached_windows_.empty())
983 return; 980 return;
984 // Build a map from index in children to window, returning if there is a 981 // Build a map from index in children to window, returning if there is a
985 // window with a different parent. 982 // window with a different parent.
986 typedef std::map<size_t, aura::Window*> IndexToWindowMap; 983 typedef std::map<size_t, aura::Window*> IndexToWindowMap;
987 IndexToWindowMap map; 984 IndexToWindowMap map;
988 aura::Window* parent = window()->parent(); 985 aura::Window* parent = GetTarget()->parent();
989 const aura::Window::Windows& windows(parent->children()); 986 const aura::Window::Windows& windows(parent->children());
990 map[std::find(windows.begin(), windows.end(), window()) - 987 map[std::find(windows.begin(), windows.end(), GetTarget()) -
991 windows.begin()] = window(); 988 windows.begin()] = GetTarget();
992 for (std::vector<aura::Window*>::const_iterator i = 989 for (std::vector<aura::Window*>::const_iterator i =
993 attached_windows_.begin(); i != attached_windows_.end(); ++i) { 990 attached_windows_.begin(); i != attached_windows_.end(); ++i) {
994 if ((*i)->parent() != parent) 991 if ((*i)->parent() != parent)
995 return; 992 return;
996 size_t index = 993 size_t index =
997 std::find(windows.begin(), windows.end(), *i) - windows.begin(); 994 std::find(windows.begin(), windows.end(), *i) - windows.begin();
998 map[index] = *i; 995 map[index] = *i;
999 } 996 }
1000 997
1001 // Reorder the windows starting at the topmost. 998 // Reorder the windows starting at the topmost.
1002 parent->StackChildAtTop(map.rbegin()->second); 999 parent->StackChildAtTop(map.rbegin()->second);
1003 for (IndexToWindowMap::const_reverse_iterator i = map.rbegin(); 1000 for (IndexToWindowMap::const_reverse_iterator i = map.rbegin();
1004 i != map.rend(); ) { 1001 i != map.rend(); ) {
1005 aura::Window* window = i->second; 1002 aura::Window* window = i->second;
1006 ++i; 1003 ++i;
1007 if (i != map.rend()) 1004 if (i != map.rend())
1008 parent->StackChildBelow(i->second, window); 1005 parent->StackChildBelow(i->second, window);
1009 } 1006 }
1010 } 1007 }
1011 1008
1012 SnapType WorkspaceWindowResizer::GetSnapType( 1009 SnapType WorkspaceWindowResizer::GetSnapType(
1013 const gfx::Point& location) const { 1010 const gfx::Point& location) const {
1014 // TODO: this likely only wants total display area, not the area of a single 1011 // TODO: this likely only wants total display area, not the area of a single
1015 // display. 1012 // display.
1016 gfx::Rect area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window())); 1013 gfx::Rect area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(GetTarget()));
1017 if (details_.source == aura::client::WINDOW_MOVE_SOURCE_TOUCH) { 1014 if (details().source == aura::client::WINDOW_MOVE_SOURCE_TOUCH) {
1018 // Increase tolerance for touch-snapping near the screen edges. This is only 1015 // Increase tolerance for touch-snapping near the screen edges. This is only
1019 // necessary when the work area left or right edge is same as screen edge. 1016 // necessary when the work area left or right edge is same as screen edge.
1020 gfx::Rect display_bounds(ScreenAsh::GetDisplayBoundsInParent(window())); 1017 gfx::Rect display_bounds(ScreenAsh::GetDisplayBoundsInParent(GetTarget()));
1021 int inset_left = 0; 1018 int inset_left = 0;
1022 if (area.x() == display_bounds.x()) 1019 if (area.x() == display_bounds.x())
1023 inset_left = kScreenEdgeInsetForTouchResize; 1020 inset_left = kScreenEdgeInsetForTouchResize;
1024 int inset_right = 0; 1021 int inset_right = 0;
1025 if (area.right() == display_bounds.right()) 1022 if (area.right() == display_bounds.right())
1026 inset_right = kScreenEdgeInsetForTouchResize; 1023 inset_right = kScreenEdgeInsetForTouchResize;
1027 area.Inset(inset_left, 0, inset_right, 0); 1024 area.Inset(inset_left, 0, inset_right, 0);
1028 } 1025 }
1029 if (location.x() <= area.x()) 1026 if (location.x() <= area.x())
1030 return SNAP_LEFT; 1027 return SNAP_LEFT;
1031 if (location.x() >= area.right() - 1) 1028 if (location.x() >= area.right() - 1)
1032 return SNAP_RIGHT; 1029 return SNAP_RIGHT;
1033 return SNAP_NONE; 1030 return SNAP_NONE;
1034 } 1031 }
1035 1032
1036 void WorkspaceWindowResizer::SetDraggedWindowDocked(bool should_dock) { 1033 void WorkspaceWindowResizer::SetDraggedWindowDocked(bool should_dock) {
1037 if (should_dock && 1034 if (should_dock &&
1038 dock_layout_->GetAlignmentOfWindow(window()) != DOCKED_ALIGNMENT_NONE) { 1035 dock_layout_->GetAlignmentOfWindow(GetTarget()) !=
1036 DOCKED_ALIGNMENT_NONE) {
1039 if (!dock_layout_->is_dragged_window_docked()) { 1037 if (!dock_layout_->is_dragged_window_docked()) {
1040 window_state()->set_bounds_changed_by_user(false); 1038 window_state()->set_bounds_changed_by_user(false);
1041 dock_layout_->DockDraggedWindow(window()); 1039 dock_layout_->DockDraggedWindow(GetTarget());
1042 } 1040 }
1043 } else { 1041 } else {
1044 if (dock_layout_->is_dragged_window_docked()) { 1042 if (dock_layout_->is_dragged_window_docked()) {
1045 dock_layout_->UndockDraggedWindow(); 1043 dock_layout_->UndockDraggedWindow();
1046 window_state()->set_bounds_changed_by_user(true); 1044 window_state()->set_bounds_changed_by_user(true);
1047 } 1045 }
1048 } 1046 }
1049 } 1047 }
1050 1048
1051 } // namespace internal 1049 } // namespace internal
1052 } // namespace ash 1050 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698