Commit b913327b authored by Evan Stade's avatar Evan Stade Committed by Commit Bot

Chrome OS tablet mode: Allow window dragging for non-resizable windows

CreateWindowResizer was unintentionally aborting early, before calling
CreateWindowResizerForTabletMode. Thus it applied the resizable check
to windows that shouldn't have gotten it, such as non-resizable ARC
windows in tablet mode.

Bug: 947769
Change-Id: If0863936c8bdb43513fd4b3d8ba39d597275d604
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1565355
Commit-Queue: Evan Stade <estade@chromium.org>
Reviewed-by: default avatarXiaoqian Dai <xdai@chromium.org>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Cr-Commit-Position: refs/heads/master@{#650524}
parent 1b05cf2c
...@@ -30,7 +30,6 @@ class WmToplevelWindowEventHandlerTest : public AshTestBase { ...@@ -30,7 +30,6 @@ class WmToplevelWindowEventHandlerTest : public AshTestBase {
void SetUp() override { void SetUp() override {
AshTestBase::SetUp(); AshTestBase::SetUp();
TabletModeControllerTestApi().EnterTabletMode();
dragged_window_ = CreateTestWindow(); dragged_window_ = CreateTestWindow();
non_dragged_window_ = CreateTestWindow(); non_dragged_window_ = CreateTestWindow();
...@@ -68,7 +67,7 @@ class WmToplevelWindowEventHandlerTest : public AshTestBase { ...@@ -68,7 +67,7 @@ class WmToplevelWindowEventHandlerTest : public AshTestBase {
// the overview mode. // the overview mode.
TEST_F(WmToplevelWindowEventHandlerTest, TEST_F(WmToplevelWindowEventHandlerTest,
TapWindowInOverviewGridDuringWindowDrag) { TapWindowInOverviewGridDuringWindowDrag) {
ASSERT_TRUE(TabletModeControllerTestApi().IsTabletModeStarted()); TabletModeControllerTestApi().EnterTabletMode();
SendGestureEvent(gfx::Point(0, 0), 0, 5, ui::ET_GESTURE_SCROLL_BEGIN); SendGestureEvent(gfx::Point(0, 0), 0, 5, ui::ET_GESTURE_SCROLL_BEGIN);
// Drag the window to the right corner to avoid overlap with // Drag the window to the right corner to avoid overlap with
...@@ -96,8 +95,48 @@ TEST_F(WmToplevelWindowEventHandlerTest, ...@@ -96,8 +95,48 @@ TEST_F(WmToplevelWindowEventHandlerTest,
EXPECT_FALSE(overview_controller->overview_session()); EXPECT_FALSE(overview_controller->overview_session());
} }
// In tablet mode, the window's resizability shouldn't be taken into account
// when dragging from the top. Regression test for https://crbug.com/1444132
TEST_F(WmToplevelWindowEventHandlerTest,
NonResizableWindowsCanBeDraggedInTabletMode) {
TabletModeControllerTestApi().EnterTabletMode();
dragged_window_->SetProperty(aura::client::kResizeBehaviorKey,
ws::mojom::kResizeBehaviorNone);
SendGestureEvent(gfx::Point(0, 0), 0, 5, ui::ET_GESTURE_SCROLL_BEGIN);
SendGestureEvent(gfx::Point(700, 500), 700, 500,
ui::ET_GESTURE_SCROLL_UPDATE);
EXPECT_TRUE(wm::GetWindowState(dragged_window_.get())->is_dragged());
OverviewController* overview_controller = Shell::Get()->overview_controller();
EXPECT_TRUE(overview_controller->IsSelecting());
EXPECT_TRUE(overview_controller->overview_session()->IsWindowInOverview(
non_dragged_window_.get()));
}
// Contrary to tablet mode, in non-tablet mode, non resizable windows cannot be
// dragged.
TEST_F(WmToplevelWindowEventHandlerTest,
NonResizableWindowsCannotBeDraggedInClamshellMode) {
ASSERT_FALSE(TabletModeControllerTestApi().IsTabletModeStarted());
dragged_window_->SetProperty(aura::client::kResizeBehaviorKey,
ws::mojom::kResizeBehaviorNone);
SendGestureEvent(gfx::Point(0, 0), 0, 5, ui::ET_GESTURE_SCROLL_BEGIN);
SendGestureEvent(gfx::Point(700, 500), 700, 500,
ui::ET_GESTURE_SCROLL_UPDATE);
EXPECT_FALSE(wm::GetWindowState(dragged_window_.get())->is_dragged());
OverviewController* overview_controller = Shell::Get()->overview_controller();
EXPECT_FALSE(overview_controller->IsSelecting());
}
// Tests that the window drag will be reverted if the screen is being rotated. // Tests that the window drag will be reverted if the screen is being rotated.
TEST_F(WmToplevelWindowEventHandlerTest, DisplayConfigurationChangeTest) { TEST_F(WmToplevelWindowEventHandlerTest, DisplayConfigurationChangeTest) {
TabletModeControllerTestApi().EnterTabletMode();
int64_t display_id = display::Screen::GetScreen()->GetPrimaryDisplay().id(); int64_t display_id = display::Screen::GetScreen()->GetPrimaryDisplay().id();
display::DisplayManager* display_manager = Shell::Get()->display_manager(); display::DisplayManager* display_manager = Shell::Get()->display_manager();
display::test::ScopedSetInternalDisplayId set_internal(display_manager, display::test::ScopedSetInternalDisplayId set_internal(display_manager,
......
...@@ -97,9 +97,8 @@ std::unique_ptr<WindowResizer> CreateWindowResizerForTabletMode( ...@@ -97,9 +97,8 @@ std::unique_ptr<WindowResizer> CreateWindowResizerForTabletMode(
std::unique_ptr<WindowResizer> window_resizer = std::unique_ptr<WindowResizer> window_resizer =
std::make_unique<TabletModeWindowDragController>( std::make_unique<TabletModeWindowDragController>(
window_state, std::make_unique<TabletModeAppWindowDragDelegate>()); window_state, std::make_unique<TabletModeAppWindowDragDelegate>());
window_resizer = std::make_unique<DragWindowResizer>( return std::make_unique<DragWindowResizer>(std::move(window_resizer),
std::move(window_resizer), window_state); window_state);
return window_resizer;
} }
// Only allow drag that happens on caption or top area. Note: for a maxmized // Only allow drag that happens on caption or top area. Note: for a maxmized
...@@ -125,9 +124,8 @@ std::unique_ptr<WindowResizer> CreateWindowResizerForTabletMode( ...@@ -125,9 +124,8 @@ std::unique_ptr<WindowResizer> CreateWindowResizerForTabletMode(
std::make_unique<TabletModeWindowDragController>( std::make_unique<TabletModeWindowDragController>(
window_state, window_state,
std::make_unique<TabletModeBrowserWindowDragDelegate>()); std::make_unique<TabletModeBrowserWindowDragDelegate>());
window_resizer = std::make_unique<DragWindowResizer>( return std::make_unique<DragWindowResizer>(std::move(window_resizer),
std::move(window_resizer), window_state); window_state);
return window_resizer;
} }
} // namespace } // namespace
...@@ -140,28 +138,14 @@ std::unique_ptr<WindowResizer> CreateWindowResizer( ...@@ -140,28 +138,14 @@ std::unique_ptr<WindowResizer> CreateWindowResizer(
DCHECK(window); DCHECK(window);
wm::WindowState* window_state = wm::GetWindowState(window); wm::WindowState* window_state = wm::GetWindowState(window);
// No need to return a resizer when the window cannot get resized or when a
// resizer already exists for this window.
if ((!window_state->CanResize() && window_component != HTCAPTION) ||
window_state->drag_details()) {
return nullptr;
}
// TODO(varkha): The chaining of window resizers causes some of the logic // A resizer already exists; don't create a new one.
// to be repeated and the logic flow difficult to control. With some windows if (window_state->drag_details())
// classes using reparenting during drag operations it becomes challenging to return nullptr;
// implement proper transition from one resizer to another during or at the
// end of the drag. This also causes http://crbug.com/247085.
// We should have a better way of doing this, perhaps by having a way of
// observing drags or having a generic drag window wrapper which informs a
// layout manager that a drag has started or stopped. It may be possible to
// refactor and eliminate chaining.
std::unique_ptr<WindowResizer> window_resizer;
if (window_state->IsPip()) { if (window_state->IsPip()) {
window_state->CreateDragDetails(point_in_parent, window_component, source); window_state->CreateDragDetails(point_in_parent, window_component, source);
window_resizer = std::make_unique<PipWindowResizer>(window_state); return std::make_unique<PipWindowResizer>(window_state);
return window_resizer;
} }
if (Shell::Get() if (Shell::Get()
...@@ -171,6 +155,10 @@ std::unique_ptr<WindowResizer> CreateWindowResizer( ...@@ -171,6 +155,10 @@ std::unique_ptr<WindowResizer> CreateWindowResizer(
window_component, source); window_component, source);
} }
// No need to return a resizer when the window cannot get resized.
if (!window_state->CanResize() && window_component != HTCAPTION)
return nullptr;
if (!window_state->IsNormalOrSnapped()) if (!window_state->IsNormalOrSnapped())
return nullptr; return nullptr;
...@@ -182,6 +170,17 @@ std::unique_ptr<WindowResizer> CreateWindowResizer( ...@@ -182,6 +170,17 @@ std::unique_ptr<WindowResizer> CreateWindowResizer(
window_state->CreateDragDetails(point_in_parent, window_component, source); window_state->CreateDragDetails(point_in_parent, window_component, source);
const int parent_shell_window_id = const int parent_shell_window_id =
window->parent() ? window->parent()->id() : -1; window->parent() ? window->parent()->id() : -1;
// TODO(varkha): The chaining of window resizers causes some of the logic
// to be repeated and the logic flow difficult to control. With some windows
// classes using reparenting during drag operations it becomes challenging to
// implement proper transition from one resizer to another during or at the
// end of the drag. This also causes http://crbug.com/247085.
// We should have a better way of doing this, perhaps by having a way of
// observing drags or having a generic drag window wrapper which informs a
// layout manager that a drag has started or stopped. It may be possible to
// refactor and eliminate chaining.
std::unique_ptr<WindowResizer> window_resizer;
if (window->parent() && if (window->parent() &&
// TODO(afakhry): Maybe use switchable containers? // TODO(afakhry): Maybe use switchable containers?
(desks_util::IsDeskContainerId(parent_shell_window_id) || (desks_util::IsDeskContainerId(parent_shell_window_id) ||
...@@ -191,9 +190,8 @@ std::unique_ptr<WindowResizer> CreateWindowResizer( ...@@ -191,9 +190,8 @@ std::unique_ptr<WindowResizer> CreateWindowResizer(
} else { } else {
window_resizer.reset(DefaultWindowResizer::Create(window_state)); window_resizer.reset(DefaultWindowResizer::Create(window_state));
} }
window_resizer = std::make_unique<DragWindowResizer>( return std::make_unique<DragWindowResizer>(std::move(window_resizer),
std::move(window_resizer), window_state); window_state);
return window_resizer;
} }
namespace { namespace {
......
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