Commit 3404205b authored by Sammie Quon's avatar Sammie Quon Committed by Commit Bot

Reland "overview: Fix how multi touch works for overview drag."

This is a reland of c6e9dffe

TBR=oshima@chromium.org

Original change's description:
> overview: Fix how multi touch works for overview drag.
>
> Using two fingers was not restricted which brought a bunch of other bugs.
> Only allow one item to be dragged at a time. Still allows switching of
> fingers midway, so we just check the item which requests drag events is
> the same as the current drag item, instead of checking the gesture
> finger id.
>
> Test: ash_unittests WindowSelectorTest.DraggingWithTwoFingers
> Bug: 827435
> Change-Id: I2c897b1b3c483b5df7a98a658f575a6ebd706acd
> Reviewed-on: https://chromium-review.googlesource.com/988294
> Commit-Queue: Sammie Quon <sammiequon@chromium.org>
> Reviewed-by: Mitsuru Oshima <oshima@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#547932}

Bug: 827435
Change-Id: I1cda10e4712f79e458f5b977779809a1ed8255d5
Reviewed-on: https://chromium-review.googlesource.com/996052Reviewed-by: default avatarSammie Quon <sammiequon@chromium.org>
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#548097}
parent 99e83234
......@@ -90,6 +90,7 @@ void OverviewWindowDragController::CompleteDrag(
SnapWindow(snap_position_);
}
}
item_ = nullptr;
}
void OverviewWindowDragController::ActivateDraggedWindow() {
......@@ -117,6 +118,9 @@ void OverviewWindowDragController::ResetGesture() {
window_selector_->PositionWindows(/*animate=*/true);
window_selector_->SetSplitViewDragIndicatorsIndicatorState(
IndicatorState::kNone, gfx::Point());
// This function gets called on long press, which bypasses CompleteDrag but
// stops dragging as well, so reset |item_|.
item_ = nullptr;
}
void OverviewWindowDragController::ResetWindowSelector() {
......
......@@ -963,31 +963,52 @@ float WindowSelectorItem::GetItemScale(const gfx::Size& size) {
void WindowSelectorItem::HandlePressEvent(
const gfx::Point& location_in_screen) {
// We allow switching finger while dragging, but do not allow dragging two or more items.
if (window_selector_->window_drag_controller() &&
window_selector_->window_drag_controller()->item()) {
return;
}
StartDrag();
window_selector_->InitiateDrag(this, location_in_screen);
}
void WindowSelectorItem::HandleReleaseEvent(
const gfx::Point& location_in_screen) {
if (!IsDragItem())
return;
EndDrag();
window_selector_->CompleteDrag(this, location_in_screen);
}
void WindowSelectorItem::HandleDragEvent(const gfx::Point& location_in_screen) {
if (!IsDragItem())
return;
window_selector_->Drag(this, location_in_screen);
}
void WindowSelectorItem::ActivateDraggedWindow() {
DCHECK_EQ(this, window_selector_->window_drag_controller()->item());
if (!IsDragItem())
return;
window_selector_->ActivateDraggedWindow();
}
void WindowSelectorItem::ResetDraggedWindowGesture() {
OnSelectorItemDragEnded();
DCHECK_EQ(this, window_selector_->window_drag_controller()->item());
if (!IsDragItem())
return;
window_selector_->ResetDraggedWindowGesture();
}
bool WindowSelectorItem::IsDragItem() {
return window_selector_->window_drag_controller() &&
window_selector_->window_drag_controller()->item() == this;
}
void WindowSelectorItem::SetShadowBounds(
base::Optional<gfx::Rect> bounds_in_screen) {
if (!IsNewOverviewUi())
......
......@@ -185,6 +185,9 @@ class ASH_EXPORT WindowSelectorItem : public views::ButtonListener,
void ActivateDraggedWindow();
void ResetDraggedWindowGesture();
// Checks if this item is current being dragged.
bool IsDragItem();
// Sets the bounds of the window shadow. If |bounds_in_screen| is nullopt,
// the shadow is hidden.
void SetShadowBounds(base::Optional<gfx::Rect> bounds_in_screen);
......
......@@ -2907,6 +2907,64 @@ TEST_F(WindowSelectorTest, ShadowBounds) {
ToggleOverview();
}
// Verify that attempting to drag with a secondary finger works as expected.
TEST_F(WindowSelectorTest, DraggingWithTwoFingers) {
std::unique_ptr<aura::Window> window1 = CreateTestWindow();
std::unique_ptr<aura::Window> window2 = CreateTestWindow();
// Dragging is only allowed in tablet mode.
RunAllPendingInMessageLoop();
Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
ToggleOverview();
RunAllPendingInMessageLoop();
WindowSelectorItem* item1 = GetWindowItemForWindow(0, window1.get());
WindowSelectorItem* item2 = GetWindowItemForWindow(0, window2.get());
const gfx::Rect original_bounds1 = item1->target_bounds();
const gfx::Rect original_bounds2 = item2->target_bounds();
constexpr int kTouchId1 = 1;
constexpr int kTouchId2 = 2;
// Verify that the bounds of the tapped window expand when touched.
ui::test::EventGenerator& generator = GetEventGenerator();
generator.set_current_location(original_bounds1.CenterPoint());
generator.PressTouchId(kTouchId1);
RunAllPendingInMessageLoop();
EXPECT_GT(item1->target_bounds().width(), original_bounds1.width());
EXPECT_GT(item1->target_bounds().height(), original_bounds1.height());
// Verify that attempting to touch the second window with a second finger does
// nothing to the second window. The first window remains the window to be
// dragged.
generator.set_current_location(original_bounds2.CenterPoint());
generator.PressTouchId(kTouchId2);
RunAllPendingInMessageLoop();
EXPECT_GT(item1->target_bounds().width(), original_bounds1.width());
EXPECT_GT(item1->target_bounds().height(), original_bounds1.height());
EXPECT_EQ(item2->target_bounds(), original_bounds2);
// Verify the first window moves on drag.
gfx::Point last_center_point = item1->target_bounds().CenterPoint();
generator.MoveTouchIdBy(kTouchId1, 40, 40);
RunAllPendingInMessageLoop();
EXPECT_NE(last_center_point, item1->target_bounds().CenterPoint());
EXPECT_EQ(original_bounds2.CenterPoint(),
item2->target_bounds().CenterPoint());
// Verify the first window moves on drag, even if we switch to a second
// finger.
last_center_point = item1->target_bounds().CenterPoint();
generator.ReleaseTouchId(kTouchId2);
generator.PressTouchId(kTouchId2);
generator.MoveTouchIdBy(kTouchId2, 40, 40);
RunAllPendingInMessageLoop();
EXPECT_NE(last_center_point, item1->target_bounds().CenterPoint());
EXPECT_EQ(original_bounds2.CenterPoint(),
item2->target_bounds().CenterPoint());
}
class SplitViewWindowSelectorTest : public WindowSelectorTest {
public:
SplitViewWindowSelectorTest() = default;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment