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

Unified Diff: ash/wm/workspace/snap_sizer.cc

Issue 23431009: Windows docking should get triggered by pressing against the screen edge (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Windows docking should get triggered by pressing against the screen edge (comments) Created 7 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: ash/wm/workspace/snap_sizer.cc
diff --git a/ash/wm/workspace/snap_sizer.cc b/ash/wm/workspace/snap_sizer.cc
index 11b59470fcd87d5be27e934cc992feac57b7c90a..309b9ca80e79696a763a9e62fd6a8d62ae1953a1 100644
--- a/ash/wm/workspace/snap_sizer.cc
+++ b/ash/wm/workspace/snap_sizer.cc
@@ -6,10 +6,17 @@
#include <cmath>
+#include "ash/ash_switches.h"
+#include "ash/launcher/launcher.h"
#include "ash/screen_ash.h"
+#include "ash/shell.h"
+#include "ash/shell_window_ids.h"
+#include "ash/wm/dock/docked_window_layout_manager.h"
#include "ash/wm/property_util.h"
+#include "ash/wm/window_properties.h"
#include "ash/wm/window_resizer.h"
#include "ash/wm/window_util.h"
+#include "base/command_line.h"
#include "ui/aura/window.h"
#include "ui/gfx/screen.h"
@@ -38,28 +45,37 @@ const int kPixelsBeforeAdjust = 100;
const int kMinimumScreenPercent = 90;
// Create the list of possible width for the current screen configuration:
-// Fill the |usable_width_| list with items from |kIdealWidth| which fit on
-// the screen and supplement it with the 'half of screen' size. Furthermore,
-// add an entry for 90% of the screen size if it is smaller then the biggest
-// value in the |kIdealWidth| list (to get a step between the values).
-std::vector<int> BuildIdealWidthList(aura::Window* window) {
+// Returns a list that for windows that can be snapped (|allow_snap| set)
+// includes items from |kIdealWidth| which fit on the screen and supplement it
+// with the 'half of screen' size. Furthermore, add an entry for 90% of the
+// screen size if it is smaller then the biggest value in the |kIdealWidth|
+// list (to get a step between the values).
+// When a window can be docked (|allow_dock| set) a zero-width is added as the
+// last value to facilitate showing a docking guide.
+std::vector<int> BuildIdealWidthList(aura::Window* window,
+ bool allow_snap,
+ bool allow_dock) {
std::vector<int> ideal_width_list;
- gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window));
- int half_size = work_area.width() / 2;
- int maximum_width = (kMinimumScreenPercent * work_area.width()) / 100;
- for (size_t i = 0; i < arraysize(kIdealWidth); i++) {
- if (maximum_width >= kIdealWidth[i]) {
- if (i && !ideal_width_list.size() && maximum_width != kIdealWidth[i])
- ideal_width_list.push_back(maximum_width);
- if (half_size > kIdealWidth[i])
- ideal_width_list.push_back(half_size);
- if (half_size >= kIdealWidth[i])
- half_size = 0;
- ideal_width_list.push_back(kIdealWidth[i]);
+ if (allow_snap) {
+ gfx::Rect work_area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window));
+ int half_size = work_area.width() / 2;
+ int maximum_width = (kMinimumScreenPercent * work_area.width()) / 100;
+ for (size_t i = 0; i < arraysize(kIdealWidth); i++) {
+ if (maximum_width >= kIdealWidth[i]) {
+ if (i && !ideal_width_list.size() && maximum_width != kIdealWidth[i])
+ ideal_width_list.push_back(maximum_width);
+ if (half_size > kIdealWidth[i])
+ ideal_width_list.push_back(half_size);
+ if (half_size >= kIdealWidth[i])
+ half_size = 0;
+ ideal_width_list.push_back(kIdealWidth[i]);
+ }
}
+ if (half_size)
+ ideal_width_list.push_back(half_size);
}
- if (half_size)
- ideal_width_list.push_back(half_size);
+ if (allow_dock)
+ ideal_width_list.push_back(0);
return ideal_width_list;
}
@@ -79,13 +95,30 @@ SnapSizer::SnapSizer(aura::Window* window,
last_adjust_x_(start.x()),
last_update_x_(start.x()),
start_x_(start.x()),
- input_type_(input_type),
- usable_width_(BuildIdealWidthList(window)) {
+ input_type_(input_type) {
+ aura::Window* dock_container = Shell::GetContainer(
+ window_->GetRootWindow(), kShellWindowId_DockedContainer);
+ dock_layout_ = static_cast<DockedWindowLayoutManager*>(
+ dock_container->layout_manager());
+ bool allow_dock =
+ input_type_ == internal::SnapSizer::WORKSPACE_DRAG_INPUT &&
+ CanDockWindow(window_, edge_);
+ bool allow_snap = !allow_dock ||
+ (wm::CanSnapWindow(window_) &&
+ !dock_layout_->is_dragged_window_docked() &&
+ window->bounds().width() > DockedWindowLayoutManager::kMaxDockWidth);
+ usable_width_ = BuildIdealWidthList(window, allow_snap, allow_dock);
DCHECK(!usable_width_.empty());
+ UpdateDockedState();
target_bounds_ = GetTargetBounds();
}
SnapSizer::~SnapSizer() {
+ // Normally when a drag is completed CompleteDrag will be called making
+ // the following a no-op. updating state is necessary when a window gets
+ // snapped in and out during the drag.
+ if (dock_layout_->is_dragged_window_docked())
+ dock_layout_->UndockDraggedWindow();
}
void SnapSizer::SnapWindow(aura::Window* window, SnapSizer::Edge edge) {
@@ -136,6 +169,7 @@ void SnapSizer::Update(const gfx::Point& location) {
CalculateIncrement(location.x(), last_adjust_x_));
}
}
+ UpdateDockedState();
last_update_x_ = location.x();
time_last_update_ = base::TimeTicks::Now();
}
@@ -157,6 +191,7 @@ gfx::Rect SnapSizer::GetSnapBounds(const gfx::Rect& bounds) {
void SnapSizer::SelectDefaultSizeAndDisableResize() {
resize_disabled_ = true;
size_index_ = 0;
+ UpdateDockedState();
target_bounds_ = GetTargetBounds();
}
@@ -177,6 +212,11 @@ gfx::Rect SnapSizer::GetTargetBoundsForSize(size_t size_index) const {
width = usable_width_[size_index];
}
+ if (width == 0) {
+ return ScreenAsh::ConvertRectFromScreen(window_->parent(),
+ dock_layout_->dragged_bounds());
+ }
+
if (edge_ == LEFT_EDGE) {
int x = work_area.x();
int mid_x = x + width;
@@ -187,6 +227,38 @@ gfx::Rect SnapSizer::GetTargetBoundsForSize(size_t size_index) const {
return gfx::Rect(x , y, max_x - x, max_y - y);
}
+bool SnapSizer::ShouldDockWindow() const {
+ // TODO(varkha): use dedicated state.
+ return (usable_width_[size_index_] == 0);
+}
+
+// static
+bool SnapSizer::CanDockWindow(aura::Window* window, SnapSizer::Edge edge) {
+ if (!CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kAshEnableDockedWindows)) {
+ return false;
+ }
+ // Cannot dock on the other size from an existing dock.
+ aura::Window* dock_container = Shell::GetContainer(
+ window->GetRootWindow(), kShellWindowId_DockedContainer);
+ DockedWindowLayoutManager* dock_layout =
+ static_cast<DockedWindowLayoutManager*>(dock_container->layout_manager());
+ const DockedAlignment alignment = dock_layout->CalculateAlignment();
+ if ((edge == LEFT_EDGE && alignment == DOCKED_ALIGNMENT_RIGHT) ||
+ (edge == RIGHT_EDGE && alignment == DOCKED_ALIGNMENT_LEFT)) {
+ return false;
+ }
+
+ // Do not allow docking on the same side as launcher shelf.
+ Launcher* shelf = Launcher::ForWindow(window);
+ if (shelf &&
+ ((edge == LEFT_EDGE && shelf->alignment() == SHELF_ALIGNMENT_LEFT) ||
+ (edge == RIGHT_EDGE && shelf->alignment() == SHELF_ALIGNMENT_RIGHT))) {
+ return false;
+ }
+ return true;
+}
+
int SnapSizer::CalculateIncrement(int x, int reference_x) const {
if (AlongEdge(x))
return 1;
@@ -219,9 +291,21 @@ gfx::Rect SnapSizer::GetTargetBounds() const {
}
bool SnapSizer::AlongEdge(int x) const {
- gfx::Rect area(ScreenAsh::GetDisplayBoundsInParent(window_));
+ gfx::Rect area(ScreenAsh::GetDisplayWorkAreaBoundsInParent(window_));
return (x <= area.x()) || (x >= area.right() - 1);
}
+void SnapSizer::UpdateDockedState() {
+ if (ShouldDockWindow() &&
+ dock_layout_->GetAlignmentOfWindow(window_) != DOCKED_ALIGNMENT_NONE) {
+ if (!dock_layout_->is_dragged_window_docked())
+ dock_layout_->DockDraggedWindow(window_);
+ target_bounds_ = GetTargetBounds();
+ } else {
+ if (dock_layout_->is_dragged_window_docked())
+ dock_layout_->UndockDraggedWindow();
+ }
+}
+
} // namespace internal
} // namespace ash

Powered by Google App Engine
This is Rietveld 408576698