Index: ash/wm/dock/docked_window_layout_manager.cc |
diff --git a/ash/wm/dock/docked_window_layout_manager.cc b/ash/wm/dock/docked_window_layout_manager.cc |
index 36998df309179e3113ec83e016e32ce7f570c16a..17b7a20759c4e8c88934c867e48dc4a3e67f73ea 100644 |
--- a/ash/wm/dock/docked_window_layout_manager.cc |
+++ b/ash/wm/dock/docked_window_layout_manager.cc |
@@ -4,6 +4,7 @@ |
#include "ash/wm/dock/docked_window_layout_manager.h" |
+#include "ash/ash_switches.h" |
#include "ash/launcher/launcher.h" |
#include "ash/screen_ash.h" |
#include "ash/shelf/shelf_layout_manager.h" |
@@ -14,7 +15,9 @@ |
#include "ash/wm/coordinate_conversion.h" |
#include "ash/wm/window_properties.h" |
#include "ash/wm/window_util.h" |
+#include "ash/wm/workspace/snap_types.h" |
#include "base/auto_reset.h" |
+#include "base/command_line.h" |
#include "third_party/skia/include/core/SkColor.h" |
#include "ui/aura/client/activation_client.h" |
#include "ui/aura/client/aura_constants.h" |
@@ -27,10 +30,12 @@ namespace ash { |
namespace internal { |
// Minimum, maximum width of the dock area and a width of the gap |
+// static |
+const int DockedWindowLayoutManager::kMaxDockWidth = 360; |
+// static |
const int DockedWindowLayoutManager::kMinDockWidth = 200; |
-const int DockedWindowLayoutManager::kMaxDockWidth = 450; |
+// static |
const int DockedWindowLayoutManager::kMinDockGap = 2; |
-const int kWindowIdealSpacing = 4; |
namespace { |
@@ -207,6 +212,7 @@ void DockedWindowLayoutManager::DockDraggedWindow(aura::Window* window) { |
void DockedWindowLayoutManager::UndockDraggedWindow() { |
OnWindowUndocked(); |
Relayout(); |
+ UpdateDockBounds(); |
is_dragged_from_dock_ = false; |
} |
@@ -217,9 +223,13 @@ void DockedWindowLayoutManager::FinishDragging() { |
DCHECK (!is_dragged_window_docked_); |
// Stop observing a window unless it is docked container's child in which |
// case it needs to keep being observed after the drag completes. |
- if (dragged_window_->parent() != dock_container_) |
+ if (dragged_window_->parent() != dock_container_) { |
dragged_window_->RemoveObserver(this); |
+ if (last_active_window_ == dragged_window_) |
+ last_active_window_ = NULL; |
+ } |
dragged_window_ = NULL; |
+ dragged_bounds_ = gfx::Rect(); |
Relayout(); |
UpdateDockBounds(); |
} |
@@ -239,26 +249,20 @@ void DockedWindowLayoutManager::SetLauncher(ash::Launcher* launcher) { |
DockedAlignment DockedWindowLayoutManager::GetAlignmentOfWindow( |
const aura::Window* window) const { |
const gfx::Rect& bounds(window->GetBoundsInScreen()); |
- const gfx::Rect docked_bounds = dock_container_->GetBoundsInScreen(); |
- // Do not allow docking if a window is vertically maximized (as is the case |
- // when it is snapped). |
- const gfx::Rect work_area = |
- Shell::GetScreen()->GetDisplayNearestWindow(dock_container_).work_area(); |
- if (bounds.y() == work_area.y() && bounds.height() == work_area.height()) |
- return DOCKED_ALIGNMENT_NONE; |
- |
- // Do not allow docking on the same side as launcher shelf. |
- ShelfAlignment shelf_alignment = SHELF_ALIGNMENT_BOTTOM; |
- if (launcher_) |
- shelf_alignment = launcher_->alignment(); |
+ // Test overlap with an existing docked area first. |
+ if (docked_bounds_.Intersects(bounds) && |
+ alignment_ != DOCKED_ALIGNMENT_NONE) { |
+ // A window is being added to other docked windows (on the same side). |
+ return alignment_; |
+ } |
- if (bounds.x() == docked_bounds.x() && |
- shelf_alignment != SHELF_ALIGNMENT_LEFT) { |
+ const gfx::Rect container_bounds = dock_container_->GetBoundsInScreen(); |
+ if (bounds.x() <= container_bounds.x() && |
+ bounds.right() > container_bounds.x()) { |
return DOCKED_ALIGNMENT_LEFT; |
- } |
- if (bounds.right() == docked_bounds.right() && |
- shelf_alignment != SHELF_ALIGNMENT_RIGHT) { |
+ } else if (bounds.x() < container_bounds.right() && |
+ bounds.right() >= container_bounds.right()) { |
return DOCKED_ALIGNMENT_RIGHT; |
} |
return DOCKED_ALIGNMENT_NONE; |
@@ -281,6 +285,30 @@ DockedAlignment DockedWindowLayoutManager::CalculateAlignment() const { |
return DOCKED_ALIGNMENT_NONE; |
} |
+bool DockedWindowLayoutManager::CanDockWindow(aura::Window* window, |
+ SnapType edge) { |
+ if (!CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kAshEnableDockedWindows)) { |
+ return false; |
+ } |
+ // Cannot dock on the other size from an existing dock. |
+ const DockedAlignment alignment = CalculateAlignment(); |
+ if ((edge == SNAP_LEFT && alignment == DOCKED_ALIGNMENT_RIGHT) || |
+ (edge == SNAP_RIGHT && alignment == DOCKED_ALIGNMENT_LEFT)) { |
+ return false; |
+ } |
+ |
+ // Do not allow docking on the same side as launcher shelf. |
+ ShelfAlignment shelf_alignment = SHELF_ALIGNMENT_BOTTOM; |
+ if (launcher_) |
+ shelf_alignment = launcher_->alignment(); |
+ if ((edge == SNAP_LEFT && shelf_alignment == SHELF_ALIGNMENT_LEFT) || |
+ (edge == SNAP_RIGHT && shelf_alignment == SHELF_ALIGNMENT_RIGHT)) { |
+ return false; |
+ } |
+ return true; |
+} |
+ |
//////////////////////////////////////////////////////////////////////////////// |
// DockLayoutManager, aura::LayoutManager implementation: |
void DockedWindowLayoutManager::OnWindowResized() { |
@@ -564,6 +592,17 @@ void DockedWindowLayoutManager::Relayout() { |
aura::Window* window = *iter; |
gfx::Rect bounds = window->GetBoundsInScreen(); |
+ DockedAlignment alignment = alignment_; |
+ if (alignment == DOCKED_ALIGNMENT_NONE && window == dragged_window_) { |
+ alignment = GetAlignmentOfWindow(window); |
+ if (alignment == DOCKED_ALIGNMENT_NONE) |
+ bounds.set_size(gfx::Size()); |
+ } |
+ |
+ // Restrict width. |
+ if (bounds.width() > kMaxDockWidth) |
+ bounds.set_width(kMaxDockWidth); |
+ |
// Fan out windows evenly distributing the overlap or remaining free space. |
bounds.set_y(std::max(work_area.y(), |
std::min(work_area.bottom() - bounds.height(), |
@@ -572,7 +611,7 @@ void DockedWindowLayoutManager::Relayout() { |
// All docked windows other than the one currently dragged remain stuck |
// to the screen edge. |
- switch (alignment_) { |
+ switch (alignment) { |
case DOCKED_ALIGNMENT_LEFT: |
bounds.set_x(dock_bounds.x()); |
break; |
@@ -586,6 +625,8 @@ void DockedWindowLayoutManager::Relayout() { |
dragged_bounds_ = bounds; |
continue; |
} |
+ // If the following asserts it is probably because not all the children |
+ // have been removed when dock was closed. |
DCHECK_NE(alignment_, DOCKED_ALIGNMENT_NONE); |
// Keep the dock at least kMinDockWidth when all windows in it overhang. |
docked_width_ = std::min(kMaxDockWidth, |