12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/panels/panel_window_resizer.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ash/display/display_controller.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/screen_util.h"
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ash/shelf/shelf.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_types.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_widget.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shell_window_ids.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/wm/panels/panel_layout_manager.h"
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ash/wm/window_state.h"
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ash/wm/window_util.h"
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "base/memory/weak_ptr.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/client/aura_constants.h"
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/aura/client/window_tree_client.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/env.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window_delegate.h"
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/hit_test.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/ui_base_types.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/screen.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h"
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "ui/wm/core/coordinate_conversion.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ash {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kPanelSnapToLauncherDistance = 30;
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
35c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochPanelLayoutManager* GetPanelLayoutManager(aura::Window* panel_container) {
36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(panel_container->id() == kShellWindowId_PanelContainer);
37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return static_cast<PanelLayoutManager*>(panel_container->layout_manager());
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PanelWindowResizer::~PanelWindowResizer() {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PanelWindowResizer*
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PanelWindowResizer::Create(WindowResizer* next_window_resizer,
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           wm::WindowState* window_state) {
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return new PanelWindowResizer(next_window_resizer, window_state);
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PanelWindowResizer::Drag(const gfx::Point& location, int event_flags) {
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  last_location_ = location;
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ::wm::ConvertPointToScreen(GetTarget()->parent(), &last_location_);
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!did_move_or_resize_) {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    did_move_or_resize_ = true;
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    StartedDragging();
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check if the destination has changed displays.
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Screen* screen = Shell::GetScreen();
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const gfx::Display dst_display =
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      screen->GetDisplayNearestPoint(last_location_);
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (dst_display.id() !=
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      screen->GetDisplayNearestWindow(panel_container_->GetRootWindow()).id()) {
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // The panel is being dragged to a new display. If the previous container is
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the current parent of the panel it will be informed of the end of drag
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // when the panel is reparented, otherwise let the previous container know
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // the drag is complete. If we told the panel's parent that the drag was
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // complete it would begin positioning the panel.
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (GetTarget()->parent() != panel_container_)
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetPanelLayoutManager(panel_container_)->FinishDragging();
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    aura::Window* dst_root = Shell::GetInstance()->display_controller()->
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetRootWindowForDisplayId(dst_display.id());
75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    panel_container_ =
76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        Shell::GetContainer(dst_root, kShellWindowId_PanelContainer);
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // The panel's parent already knows that the drag is in progress for this
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // panel.
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (panel_container_ && GetTarget()->parent() != panel_container_)
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      GetPanelLayoutManager(panel_container_)->StartDragging(GetTarget());
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Point offset;
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Rect bounds(CalculateBoundsForDrag(location));
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!(details().bounds_change & WindowResizer::kBoundsChange_Resizes)) {
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    window_state_->drag_details()->should_attach_to_shelf =
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        AttachToLauncher(bounds, &offset);
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Point modified_location(location.x() + offset.x(),
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               location.y() + offset.y());
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::WeakPtr<PanelWindowResizer> resizer(weak_ptr_factory_.GetWeakPtr());
9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  next_window_resizer_->Drag(modified_location, event_flags);
9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!resizer)
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (details().should_attach_to_shelf &&
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      !(details().bounds_change & WindowResizer::kBoundsChange_Resizes)) {
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    UpdateLauncherPosition();
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PanelWindowResizer::CompleteDrag() {
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The root window can change when dragging into a different screen.
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  next_window_resizer_->CompleteDrag();
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FinishDragging();
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PanelWindowResizer::RevertDrag() {
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  next_window_resizer_->RevertDrag();
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window_state_->drag_details()->should_attach_to_shelf = was_attached_;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FinishDragging();
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PanelWindowResizer::PanelWindowResizer(WindowResizer* next_window_resizer,
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                       wm::WindowState* window_state)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : WindowResizer(window_state),
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      next_window_resizer_(next_window_resizer),
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      panel_container_(NULL),
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      initial_panel_container_(NULL),
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      did_move_or_resize_(false),
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      was_attached_(window_state->panel_attached()),
12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      weak_ptr_factory_(this) {
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(details().is_resizable);
125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  panel_container_ = Shell::GetContainer(GetTarget()->GetRootWindow(),
126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                         kShellWindowId_PanelContainer);
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  initial_panel_container_ = panel_container_;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool PanelWindowResizer::AttachToLauncher(const gfx::Rect& bounds,
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                          gfx::Point* offset) {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool should_attach = false;
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (panel_container_) {
134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    PanelLayoutManager* panel_layout_manager =
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetPanelLayoutManager(panel_container_);
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gfx::Rect launcher_bounds = ScreenUtil::ConvertRectFromScreen(
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetTarget()->parent(),
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        panel_layout_manager->shelf()->
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        shelf_widget()->GetWindowBoundsInScreen());
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    switch (panel_layout_manager->shelf()->alignment()) {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case SHELF_ALIGNMENT_BOTTOM:
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (bounds.bottom() >= (launcher_bounds.y() -
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                kPanelSnapToLauncherDistance)) {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          should_attach = true;
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          offset->set_y(launcher_bounds.y() - bounds.height() - bounds.y());
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case SHELF_ALIGNMENT_LEFT:
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (bounds.x() <= (launcher_bounds.right() +
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           kPanelSnapToLauncherDistance)) {
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          should_attach = true;
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          offset->set_x(launcher_bounds.right() - bounds.x());
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case SHELF_ALIGNMENT_RIGHT:
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (bounds.right() >= (launcher_bounds.x() -
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               kPanelSnapToLauncherDistance)) {
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          should_attach = true;
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          offset->set_x(launcher_bounds.x() - bounds.width() - bounds.x());
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case SHELF_ALIGNMENT_TOP:
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (bounds.y() <= (launcher_bounds.bottom() +
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           kPanelSnapToLauncherDistance)) {
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          should_attach = true;
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          offset->set_y(launcher_bounds.bottom() - bounds.y());
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return should_attach;
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PanelWindowResizer::StartedDragging() {
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Tell the panel layout manager that we are dragging this panel before
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // attaching it so that it does not get repositioned.
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (panel_container_)
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GetPanelLayoutManager(panel_container_)->StartDragging(GetTarget());
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!was_attached_) {
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Attach the panel while dragging placing it in front of other panels.
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    window_state_->set_panel_attached(true);
182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // We use root window coordinates to ensure that during the drag the panel
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // is reparented to a container in the root window that has that window.
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    aura::Window* target = GetTarget();
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    aura::Window* target_root = target->GetRootWindow();
186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    aura::Window* old_parent = target->parent();
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    aura::client::ParentWindowWithContext(
1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        target, target_root, target_root->GetBoundsInScreen());
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    wm::ReparentTransientChildrenOfChild(target, old_parent, target->parent());
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PanelWindowResizer::FinishDragging() {
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!did_move_or_resize_)
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (window_state_->panel_attached() != details().should_attach_to_shelf) {
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    window_state_->set_panel_attached(details().should_attach_to_shelf);
198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // We use last known location to ensure that after the drag the panel
199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // is reparented to a container in the root window that has that location.
2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    aura::Window* target = GetTarget();
2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    aura::Window* target_root = target->GetRootWindow();
202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    aura::Window* old_parent = target->parent();
2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    aura::client::ParentWindowWithContext(
2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        target, target_root, gfx::Rect(last_location_, gfx::Size()));
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    wm::ReparentTransientChildrenOfChild(target, old_parent, target->parent());
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // If we started the drag in one root window and moved into another root
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // but then canceled the drag we may need to inform the original layout
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // manager that the drag is finished.
2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (initial_panel_container_ != panel_container_)
2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch     GetPanelLayoutManager(initial_panel_container_)->FinishDragging();
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (panel_container_)
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    GetPanelLayoutManager(panel_container_)->FinishDragging();
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PanelWindowResizer::UpdateLauncherPosition() {
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (panel_container_) {
2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GetPanelLayoutManager(panel_container_)->shelf()->
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        UpdateIconPositionForWindow(GetTarget());
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace aura
225