tablet: Change tap on edge to exit non-immersive fullscreen to swipe.
Non-immersive fullscreen mode (i.e. youtube video pressed with app fullscreen button) is too easy to exit by accident by tapping on the top/bottom edge. This CL changes that logic to be a swipe instead. The swipe is same logic as shelf swipe but needs to be started on the edge. Also moved tests to a new file. Test: added tests Bug: 497784 Change-Id: Id197d1109d39d89467d844d8b82c72f9a3547540 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2138552 Reviewed-by: Xiaoqian Dai <xdai@chromium.org> Reviewed-by: Xiyuan Xia <xiyuan@chromium.org> Commit-Queue: Sammie Quon <sammiequon@chromium.org> Cr-Commit-Position: refs/heads/master@{#757586}
This commit is contained in:
ash
@@ -1366,8 +1366,8 @@ component("ash") {
|
||||
"wm/tablet_mode/scoped_skip_user_session_blocked_check.h",
|
||||
"wm/tablet_mode/tablet_mode_browser_window_drag_delegate.cc",
|
||||
"wm/tablet_mode/tablet_mode_controller.cc",
|
||||
"wm/tablet_mode/tablet_mode_event_handler.cc",
|
||||
"wm/tablet_mode/tablet_mode_event_handler.h",
|
||||
"wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.cc",
|
||||
"wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.h",
|
||||
"wm/tablet_mode/tablet_mode_window_drag_delegate.cc",
|
||||
"wm/tablet_mode/tablet_mode_window_drag_metrics.cc",
|
||||
"wm/tablet_mode/tablet_mode_window_drag_metrics.h",
|
||||
@@ -2094,6 +2094,7 @@ test("ash_unittests") {
|
||||
"wm/system_modal_container_layout_manager_unittest.cc",
|
||||
"wm/tablet_mode/accelerometer_test_data_literals.cc",
|
||||
"wm/tablet_mode/tablet_mode_controller_unittest.cc",
|
||||
"wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler_unittest.cc",
|
||||
"wm/tablet_mode/tablet_mode_window_manager_unittest.cc",
|
||||
"wm/toplevel_window_event_handler_unittest.cc",
|
||||
"wm/video_detector_unittest.cc",
|
||||
|
@@ -116,6 +116,10 @@ class ASH_EXPORT ShelfConfig : public TabletModeObserver,
|
||||
// Returns whether we are within an app.
|
||||
bool is_in_app() const;
|
||||
|
||||
// The threshold relative to the size of the shelf that is used to determine
|
||||
// if the shelf visibility should change during a drag.
|
||||
float drag_hide_ratio_threshold() const;
|
||||
|
||||
int app_icon_group_margin() const { return app_icon_group_margin_; }
|
||||
SkColor shelf_control_permanent_highlight_background() const {
|
||||
return shelf_control_permanent_highlight_background_;
|
||||
|
@@ -36,7 +36,11 @@ constexpr int kControlButtonsShownReasonCount = 1 << 4;
|
||||
|
||||
// When any edge of the primary display is less than or equal to this threshold,
|
||||
// dense shelf will be active.
|
||||
const int kDenseShelfScreenSizeThreshold = 600;
|
||||
constexpr int kDenseShelfScreenSizeThreshold = 600;
|
||||
|
||||
// Drags on the shelf that are greater than this number times the shelf size
|
||||
// will trigger shelf visibility changes.
|
||||
constexpr float kDragHideRatioThreshold = 0.4f;
|
||||
|
||||
// Records the histogram value tracking the reason shelf control buttons are
|
||||
// shown in tablet mode.
|
||||
@@ -305,6 +309,10 @@ bool ShelfConfig::is_in_app() const {
|
||||
(!is_app_list_visible_ || is_virtual_keyboard_shown_);
|
||||
}
|
||||
|
||||
float ShelfConfig::drag_hide_ratio_threshold() const {
|
||||
return kDragHideRatioThreshold;
|
||||
}
|
||||
|
||||
void ShelfConfig::UpdateConfig(bool app_list_visible) {
|
||||
const gfx::Rect screen_size =
|
||||
display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
|
||||
|
@@ -2508,13 +2508,13 @@ bool ShelfLayoutManager::ShouldChangeVisibilityAfterDrag(
|
||||
// The visibility of the shelf changes only if the shelf was dragged X%
|
||||
// along the correct axis. If the shelf was already visible, then the
|
||||
// direction of the drag does not matter.
|
||||
const float kDragHideThreshold = 0.4f;
|
||||
const gfx::Rect bounds = GetIdealBounds();
|
||||
const float drag_ratio =
|
||||
fabs(drag_amount_) /
|
||||
(shelf_->IsHorizontalAlignment() ? bounds.height() : bounds.width());
|
||||
|
||||
return IsSwipingCorrectDirection() && drag_ratio > kDragHideThreshold;
|
||||
return IsSwipingCorrectDirection() &&
|
||||
drag_ratio > ShelfConfig::Get()->drag_hide_ratio_threshold();
|
||||
}
|
||||
|
||||
if (event_in_screen.type() == ui::ET_SCROLL_FLING_START)
|
||||
|
@@ -1,73 +0,0 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ash/wm/tablet_mode/tablet_mode_event_handler.h"
|
||||
|
||||
#include "ash/session/session_controller_impl.h"
|
||||
#include "ash/shell.h"
|
||||
#include "ash/wm/window_state.h"
|
||||
#include "ash/wm/window_util.h"
|
||||
#include "ash/wm/wm_event.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/events/event.h"
|
||||
|
||||
namespace ash {
|
||||
namespace {
|
||||
|
||||
// The height of the area in which a touch operation leads to exiting the
|
||||
// full screen mode.
|
||||
const int kLeaveFullScreenAreaHeightInPixel = 2;
|
||||
|
||||
} // namespace
|
||||
|
||||
TabletModeEventHandler::TabletModeEventHandler() {
|
||||
Shell::Get()->AddPreTargetHandler(this);
|
||||
}
|
||||
|
||||
TabletModeEventHandler::~TabletModeEventHandler() {
|
||||
Shell::Get()->RemovePreTargetHandler(this);
|
||||
}
|
||||
|
||||
void TabletModeEventHandler::OnTouchEvent(ui::TouchEvent* event) {
|
||||
if (ToggleFullscreen(*event))
|
||||
event->StopPropagation();
|
||||
}
|
||||
|
||||
bool TabletModeEventHandler::ToggleFullscreen(const ui::TouchEvent& event) {
|
||||
if (event.type() != ui::ET_TOUCH_PRESSED)
|
||||
return false;
|
||||
|
||||
const SessionControllerImpl* controller = Shell::Get()->session_controller();
|
||||
|
||||
if (controller->IsScreenLocked() ||
|
||||
controller->GetSessionState() != session_manager::SessionState::ACTIVE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the active window (from the primary screen) to un-fullscreen.
|
||||
aura::Window* window = window_util::GetActiveWindow();
|
||||
if (!window)
|
||||
return false;
|
||||
|
||||
WindowState* window_state = WindowState::Get(window);
|
||||
if (!window_state->IsFullscreen() || window_state->IsInImmersiveFullscreen())
|
||||
return false;
|
||||
|
||||
// Test that the touch happened in the top or bottom lines.
|
||||
int y = event.y();
|
||||
if (y >= kLeaveFullScreenAreaHeightInPixel &&
|
||||
y < (window->bounds().height() - kLeaveFullScreenAreaHeightInPixel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do not exit fullscreen in kiosk app mode.
|
||||
if (Shell::Get()->session_controller()->IsRunningInAppMode())
|
||||
return false;
|
||||
|
||||
WMEvent toggle_fullscreen(WM_EVENT_TOGGLE_FULLSCREEN);
|
||||
WindowState::Get(window)->OnWMEvent(&toggle_fullscreen);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ash
|
@@ -1,37 +0,0 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ASH_WM_TABLET_MODE_TABLET_MODE_EVENT_HANDLER_H_
|
||||
#define ASH_WM_TABLET_MODE_TABLET_MODE_EVENT_HANDLER_H_
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "ui/events/event_handler.h"
|
||||
|
||||
namespace ui {
|
||||
class TouchEvent;
|
||||
}
|
||||
|
||||
namespace ash {
|
||||
|
||||
// TabletModeEventHandler handles toggling fullscreen when appropriate.
|
||||
// TabletModeEventHandler installs event handlers in an environment specific
|
||||
// way, e.g. EventHandler for aura.
|
||||
class TabletModeEventHandler : public ui::EventHandler {
|
||||
public:
|
||||
TabletModeEventHandler();
|
||||
~TabletModeEventHandler() override;
|
||||
|
||||
private:
|
||||
// ui::EventHandler:
|
||||
void OnTouchEvent(ui::TouchEvent* event) override;
|
||||
|
||||
// Returns true if a toggle happened.
|
||||
bool ToggleFullscreen(const ui::TouchEvent& event);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(TabletModeEventHandler);
|
||||
};
|
||||
|
||||
} // namespace ash
|
||||
|
||||
#endif // ASH_WM_TABLET_MODE_TABLET_MODE_EVENT_HANDLER_H_
|
@@ -0,0 +1,139 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.h"
|
||||
|
||||
#include "ash/public/cpp/shelf_config.h"
|
||||
#include "ash/session/session_controller_impl.h"
|
||||
#include "ash/shell.h"
|
||||
#include "ash/wm/window_state.h"
|
||||
#include "ash/wm/window_util.h"
|
||||
#include "ash/wm/wm_event.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/events/event.h"
|
||||
|
||||
namespace ash {
|
||||
namespace {
|
||||
|
||||
// The height of the area in which a touch operation leads to exiting the
|
||||
// full screen mode.
|
||||
constexpr int kLeaveFullScreenAreaHeightInPixel = 2;
|
||||
|
||||
} // namespace
|
||||
|
||||
TabletModeToggleFullscreenEventHandler::
|
||||
TabletModeToggleFullscreenEventHandler() {
|
||||
Shell::Get()->AddPreTargetHandler(this);
|
||||
}
|
||||
|
||||
TabletModeToggleFullscreenEventHandler::
|
||||
~TabletModeToggleFullscreenEventHandler() {
|
||||
ResetDragData();
|
||||
Shell::Get()->RemovePreTargetHandler(this);
|
||||
}
|
||||
|
||||
void TabletModeToggleFullscreenEventHandler::OnTouchEvent(
|
||||
ui::TouchEvent* event) {
|
||||
if (ProcessEvent(*event)) {
|
||||
event->SetHandled();
|
||||
event->StopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
void TabletModeToggleFullscreenEventHandler::OnWindowDestroying(
|
||||
aura::Window* window) {
|
||||
DCHECK(drag_data_);
|
||||
DCHECK_EQ(drag_data_->window, window);
|
||||
ResetDragData();
|
||||
}
|
||||
|
||||
bool TabletModeToggleFullscreenEventHandler::ProcessEvent(
|
||||
const ui::TouchEvent& event) {
|
||||
switch (event.type()) {
|
||||
case ui::ET_TOUCH_PRESSED: {
|
||||
DCHECK(!drag_data_);
|
||||
|
||||
aura::Window* active_window = window_util::GetActiveWindow();
|
||||
if (!active_window || !CanToggleFullscreen(active_window))
|
||||
return false;
|
||||
|
||||
const int y = event.y();
|
||||
// For touch press events only process the ones on the top or bottom
|
||||
// lines.
|
||||
if (y >= kLeaveFullScreenAreaHeightInPixel &&
|
||||
y < (active_window->bounds().height() -
|
||||
kLeaveFullScreenAreaHeightInPixel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
drag_data_ = DragData{y, active_window};
|
||||
active_window->AddObserver(this);
|
||||
return true;
|
||||
}
|
||||
case ui::ET_TOUCH_RELEASED: {
|
||||
if (!drag_data_)
|
||||
return false;
|
||||
|
||||
// Toggle fullscreen if dragged enough and the window can still be
|
||||
// fullscreened.
|
||||
const int drag_threshold =
|
||||
ShelfConfig::Get()->shelf_size() *
|
||||
ShelfConfig::Get()->drag_hide_ratio_threshold();
|
||||
if (abs(event.y() - drag_data_->start_y_location) > drag_threshold &&
|
||||
CanToggleFullscreen(drag_data_->window)) {
|
||||
WMEvent toggle_fullscreen(WM_EVENT_TOGGLE_FULLSCREEN);
|
||||
WindowState::Get(drag_data_->window)->OnWMEvent(&toggle_fullscreen);
|
||||
}
|
||||
|
||||
ResetDragData();
|
||||
return true;
|
||||
}
|
||||
case ui::ET_TOUCH_MOVED:
|
||||
return drag_data_.has_value();
|
||||
case ui::ET_TOUCH_CANCELLED: {
|
||||
const bool drag_in_progress = drag_data_.has_value();
|
||||
ResetDragData();
|
||||
return drag_in_progress;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TabletModeToggleFullscreenEventHandler::CanToggleFullscreen(
|
||||
const aura::Window* window) {
|
||||
DCHECK(window);
|
||||
|
||||
const SessionControllerImpl* controller = Shell::Get()->session_controller();
|
||||
if (controller->IsScreenLocked() ||
|
||||
controller->GetSessionState() != session_manager::SessionState::ACTIVE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the active window (from the primary screen) to un-fullscreen.
|
||||
aura::Window* active_window = window_util::GetActiveWindow();
|
||||
if (window != active_window)
|
||||
return false;
|
||||
|
||||
const WindowState* window_state = WindowState::Get(window);
|
||||
if (!window_state->IsFullscreen() || window_state->IsInImmersiveFullscreen())
|
||||
return false;
|
||||
|
||||
// Do not exit fullscreen in kiosk app mode.
|
||||
if (Shell::Get()->session_controller()->IsRunningInAppMode())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TabletModeToggleFullscreenEventHandler::ResetDragData() {
|
||||
if (drag_data_)
|
||||
drag_data_->window->RemoveObserver(this);
|
||||
drag_data_.reset();
|
||||
}
|
||||
|
||||
} // namespace ash
|
@@ -0,0 +1,57 @@
|
||||
// Copyright 2016 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ASH_WM_TABLET_MODE_TABLET_MODE_TOGGLE_FULLSCREEN_EVENT_HANDLER_H_
|
||||
#define ASH_WM_TABLET_MODE_TABLET_MODE_TOGGLE_FULLSCREEN_EVENT_HANDLER_H_
|
||||
|
||||
#include "ui/aura/window_observer.h"
|
||||
#include "ui/events/event_handler.h"
|
||||
|
||||
namespace ui {
|
||||
class TouchEvent;
|
||||
}
|
||||
|
||||
namespace ash {
|
||||
|
||||
// TabletModeToggleFullscreenEventHandler handles toggling fullscreen when
|
||||
// appropriate. TabletModeToggleFullscreenEventHandler installs event handlers
|
||||
// in an environment specific way, e.g. EventHandler for aura.
|
||||
class TabletModeToggleFullscreenEventHandler : public ui::EventHandler,
|
||||
public aura::WindowObserver {
|
||||
public:
|
||||
TabletModeToggleFullscreenEventHandler();
|
||||
TabletModeToggleFullscreenEventHandler(
|
||||
const TabletModeToggleFullscreenEventHandler&) = delete;
|
||||
TabletModeToggleFullscreenEventHandler& operator=(
|
||||
const TabletModeToggleFullscreenEventHandler&) = delete;
|
||||
~TabletModeToggleFullscreenEventHandler() override;
|
||||
|
||||
private:
|
||||
struct DragData {
|
||||
int start_y_location;
|
||||
aura::Window* window;
|
||||
};
|
||||
|
||||
// ui::EventHandler:
|
||||
void OnTouchEvent(ui::TouchEvent* event) override;
|
||||
|
||||
// aura::WindowObserver:
|
||||
void OnWindowDestroying(aura::Window* window) override;
|
||||
|
||||
bool ProcessEvent(const ui::TouchEvent& event);
|
||||
|
||||
// Returns true if |window| can be fullscreen toggled.
|
||||
bool CanToggleFullscreen(const aura::Window* window);
|
||||
|
||||
// Resets |drag_data_| and remove the WindowObserver.
|
||||
void ResetDragData();
|
||||
|
||||
// Valid if a processable drag is in progress. Contains the event initial
|
||||
// location and the window that was active when the drag started.
|
||||
base::Optional<DragData> drag_data_;
|
||||
};
|
||||
|
||||
} // namespace ash
|
||||
|
||||
#endif // ASH_WM_TABLET_MODE_TABLET_MODE_TOGGLE_FULLSCREEN_EVENT_HANDLER_H_
|
@@ -0,0 +1,171 @@
|
||||
// Copyright 2020 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.h"
|
||||
|
||||
#include "ash/public/cpp/window_properties.h"
|
||||
#include "ash/test/ash_test_base.h"
|
||||
#include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h"
|
||||
#include "ash/wm/window_state.h"
|
||||
#include "ash/wm/wm_event.h"
|
||||
#include "ui/aura/window.h"
|
||||
|
||||
namespace ash {
|
||||
|
||||
class TabletModeToggleFullscreenEventHandlerTest : public AshTestBase {
|
||||
public:
|
||||
TabletModeToggleFullscreenEventHandlerTest() = default;
|
||||
TabletModeToggleFullscreenEventHandlerTest(
|
||||
const TabletModeToggleFullscreenEventHandlerTest&) = delete;
|
||||
TabletModeToggleFullscreenEventHandlerTest& operator=(
|
||||
const TabletModeToggleFullscreenEventHandlerTest&) = delete;
|
||||
~TabletModeToggleFullscreenEventHandlerTest() override = default;
|
||||
|
||||
// AshTestBase:
|
||||
void SetUp() override {
|
||||
AshTestBase::SetUp();
|
||||
|
||||
UpdateDisplay("800x600");
|
||||
TabletModeControllerTestApi().EnterTabletMode();
|
||||
|
||||
background_window_ = CreateTestWindow(gfx::Rect(200, 200));
|
||||
foreground_window_ = CreateTestWindow(gfx::Rect(200, 200));
|
||||
ToggleFullscreen(foreground_window_.get(), /*immersive=*/false);
|
||||
ToggleFullscreen(background_window_.get(), /*immersive=*/false);
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
background_window_.reset();
|
||||
foreground_window_.reset();
|
||||
AshTestBase::TearDown();
|
||||
}
|
||||
|
||||
void ToggleFullscreen(aura::Window* window, bool immersive) {
|
||||
WMEvent toggle_fullscreen(WM_EVENT_TOGGLE_FULLSCREEN);
|
||||
WindowState::Get(window)->OnWMEvent(&toggle_fullscreen);
|
||||
window->SetProperty(kImmersiveIsActive, immersive);
|
||||
}
|
||||
|
||||
bool IsFullscreen(aura::Window* window) const {
|
||||
return WindowState::Get(window)->IsFullscreen();
|
||||
}
|
||||
|
||||
void GenerateSwipe(int start_y, int end_y) {
|
||||
GetEventGenerator()->GestureScrollSequence(
|
||||
gfx::Point(400, start_y), gfx::Point(400, end_y),
|
||||
base::TimeDelta::FromMilliseconds(100), 3);
|
||||
}
|
||||
|
||||
aura::Window* foreground_window() { return foreground_window_.get(); }
|
||||
aura::Window* background_window() { return background_window_.get(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<aura::Window> foreground_window_;
|
||||
std::unique_ptr<aura::Window> background_window_;
|
||||
};
|
||||
|
||||
TEST_F(TabletModeToggleFullscreenEventHandlerTest, SwipeFromTop) {
|
||||
ASSERT_TRUE(IsFullscreen(foreground_window()));
|
||||
ASSERT_TRUE(IsFullscreen(background_window()));
|
||||
|
||||
// Try swiping from a point not on the edge. Verify that we do not exit
|
||||
// fullscreen.
|
||||
GenerateSwipe(100, 200);
|
||||
ASSERT_TRUE(IsFullscreen(foreground_window()));
|
||||
ASSERT_TRUE(IsFullscreen(background_window()));
|
||||
|
||||
// Try a tiny swipe that is on the edge. Verify that we do not exit
|
||||
// fullscreen.
|
||||
GenerateSwipe(1, 5);
|
||||
ASSERT_TRUE(IsFullscreen(foreground_window()));
|
||||
ASSERT_TRUE(IsFullscreen(background_window()));
|
||||
|
||||
// Test that a normal swipe on the edge will exit fullscreen on the active
|
||||
// window.
|
||||
GenerateSwipe(1, 50);
|
||||
EXPECT_FALSE(IsFullscreen(foreground_window()));
|
||||
EXPECT_TRUE(IsFullscreen(background_window()));
|
||||
|
||||
// Test that a second swipe will not do anything..
|
||||
GenerateSwipe(1, 50);
|
||||
EXPECT_FALSE(IsFullscreen(foreground_window()));
|
||||
EXPECT_TRUE(IsFullscreen(background_window()));
|
||||
}
|
||||
|
||||
TEST_F(TabletModeToggleFullscreenEventHandlerTest, SwipeFromBottom) {
|
||||
ASSERT_TRUE(IsFullscreen(foreground_window()));
|
||||
ASSERT_TRUE(IsFullscreen(background_window()));
|
||||
|
||||
// Try swiping from a point not on the edge. Verify that we do not exit
|
||||
// fullscreen.
|
||||
GenerateSwipe(500, 400);
|
||||
ASSERT_TRUE(IsFullscreen(foreground_window()));
|
||||
ASSERT_TRUE(IsFullscreen(background_window()));
|
||||
|
||||
// Try a tiny swipe that is on the edge. Verify that we do not exit
|
||||
// fullscreen.
|
||||
GenerateSwipe(599, 594);
|
||||
ASSERT_TRUE(IsFullscreen(foreground_window()));
|
||||
ASSERT_TRUE(IsFullscreen(background_window()));
|
||||
|
||||
// Test that a normal swipe on the edge will exit fullscreen on the active
|
||||
// window.
|
||||
GenerateSwipe(599, 549);
|
||||
EXPECT_FALSE(IsFullscreen(foreground_window()));
|
||||
EXPECT_TRUE(IsFullscreen(background_window()));
|
||||
}
|
||||
|
||||
// Tests that tapping on the edge does not exit fullscreen.
|
||||
TEST_F(TabletModeToggleFullscreenEventHandlerTest, TapOnEdge) {
|
||||
ASSERT_TRUE(IsFullscreen(foreground_window()));
|
||||
|
||||
// Tap on the top edge.
|
||||
GetEventGenerator()->set_current_screen_location(gfx::Point(400, 1));
|
||||
GetEventGenerator()->PressTouch();
|
||||
GetEventGenerator()->ReleaseTouch();
|
||||
EXPECT_TRUE(IsFullscreen(foreground_window()));
|
||||
|
||||
// Tap on the bottom edge.
|
||||
GetEventGenerator()->set_current_screen_location(gfx::Point(400, 50));
|
||||
GetEventGenerator()->PressTouch();
|
||||
GetEventGenerator()->ReleaseTouch();
|
||||
EXPECT_TRUE(IsFullscreen(foreground_window()));
|
||||
}
|
||||
|
||||
TEST_F(TabletModeToggleFullscreenEventHandlerTest,
|
||||
SwipeImmersiveFullscreenWindow) {
|
||||
// Switch from non-immersive fullscreen to immersive fullscreen mode.
|
||||
ToggleFullscreen(foreground_window(), /*immersive=*/true);
|
||||
ToggleFullscreen(foreground_window(), /*immersive=*/true);
|
||||
ASSERT_TRUE(IsFullscreen(foreground_window()));
|
||||
|
||||
// Test that a normal swipe on the top edge will not exit immersive
|
||||
// fullscreen.
|
||||
GenerateSwipe(1, 50);
|
||||
EXPECT_TRUE(IsFullscreen(foreground_window()));
|
||||
EXPECT_TRUE(IsFullscreen(background_window()));
|
||||
|
||||
// Test that a normal swipe on the top edge will not exit immersive
|
||||
// fullscreen.
|
||||
GenerateSwipe(599, 549);
|
||||
EXPECT_TRUE(IsFullscreen(foreground_window()));
|
||||
EXPECT_TRUE(IsFullscreen(background_window()));
|
||||
}
|
||||
|
||||
// Tests that if a window is un-fullscreened during a drag, it remains
|
||||
// un-fullscreened on touch release.
|
||||
TEST_F(TabletModeToggleFullscreenEventHandlerTest, ToggleFullscreenDuringDrag) {
|
||||
ASSERT_TRUE(IsFullscreen(foreground_window()));
|
||||
|
||||
GetEventGenerator()->set_current_screen_location(gfx::Point(400, 1));
|
||||
GetEventGenerator()->PressTouch();
|
||||
ToggleFullscreen(foreground_window(), /*immersive=*/false);
|
||||
EXPECT_FALSE(IsFullscreen(foreground_window()));
|
||||
|
||||
GetEventGenerator()->set_current_screen_location(gfx::Point(400, 50));
|
||||
GetEventGenerator()->ReleaseTouch();
|
||||
EXPECT_FALSE(IsFullscreen(foreground_window()));
|
||||
}
|
||||
|
||||
} // namespace ash
|
@@ -23,7 +23,7 @@
|
||||
#include "ash/wm/splitview/split_view_controller.h"
|
||||
#include "ash/wm/splitview/split_view_utils.h"
|
||||
#include "ash/wm/tablet_mode/scoped_skip_user_session_blocked_check.h"
|
||||
#include "ash/wm/tablet_mode/tablet_mode_event_handler.h"
|
||||
#include "ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.h"
|
||||
#include "ash/wm/tablet_mode/tablet_mode_window_state.h"
|
||||
#include "ash/wm/window_state.h"
|
||||
#include "ash/wm/window_util.h"
|
||||
@@ -158,7 +158,7 @@ void TabletModeWindowManager::Init() {
|
||||
Shell::Get()->overview_controller()->AddObserver(this);
|
||||
accounts_since_entering_tablet_.insert(
|
||||
Shell::Get()->session_controller()->GetActiveAccountId());
|
||||
event_handler_ = std::make_unique<TabletModeEventHandler>();
|
||||
event_handler_ = std::make_unique<TabletModeToggleFullscreenEventHandler>();
|
||||
}
|
||||
|
||||
void TabletModeWindowManager::Shutdown() {
|
||||
|
@@ -29,7 +29,7 @@ class Window;
|
||||
|
||||
namespace ash {
|
||||
class TabletModeController;
|
||||
class TabletModeEventHandler;
|
||||
class TabletModeToggleFullscreenEventHandler;
|
||||
class TabletModeWindowState;
|
||||
|
||||
// A window manager which - when created - will force all windows into maximized
|
||||
@@ -184,7 +184,7 @@ class ASH_EXPORT TabletModeWindowManager : public aura::WindowObserver,
|
||||
// All accounts that have been active at least once since tablet mode started.
|
||||
base::flat_set<AccountId> accounts_since_entering_tablet_;
|
||||
|
||||
std::unique_ptr<TabletModeEventHandler> event_handler_;
|
||||
std::unique_ptr<TabletModeToggleFullscreenEventHandler> event_handler_;
|
||||
|
||||
// True when tablet mode is about to end.
|
||||
bool is_exiting_ = false;
|
||||
|
@@ -1318,215 +1318,6 @@ TEST_P(TabletModeWindowManagerTest, TryToDesktopSizeDragUnmaximizable) {
|
||||
EXPECT_EQ(first_dragged_origin.y() + 5, window->bounds().y());
|
||||
}
|
||||
|
||||
// Test that an edge swipe from the top will end full screen mode.
|
||||
TEST_P(TabletModeWindowManagerTest, ExitFullScreenWithEdgeSwipeFromTop) {
|
||||
gfx::Rect rect(10, 10, 200, 50);
|
||||
std::unique_ptr<aura::Window> background_window(
|
||||
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
|
||||
std::unique_ptr<aura::Window> foreground_window(
|
||||
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
|
||||
WindowState* background_window_state =
|
||||
WindowState::Get(background_window.get());
|
||||
WindowState* foreground_window_state =
|
||||
WindowState::Get(foreground_window.get());
|
||||
wm::ActivateWindow(foreground_window.get());
|
||||
CreateTabletModeWindowManager();
|
||||
|
||||
// Fullscreen both windows.
|
||||
WMEvent event(WM_EVENT_TOGGLE_FULLSCREEN);
|
||||
background_window_state->OnWMEvent(&event);
|
||||
foreground_window_state->OnWMEvent(&event);
|
||||
EXPECT_TRUE(background_window_state->IsFullscreen());
|
||||
EXPECT_TRUE(foreground_window_state->IsFullscreen());
|
||||
EXPECT_EQ(foreground_window.get(), window_util::GetActiveWindow());
|
||||
|
||||
// Do an edge swipe top into screen.
|
||||
ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
|
||||
generator.GestureScrollSequence(gfx::Point(50, 0), gfx::Point(50, 100),
|
||||
base::TimeDelta::FromMilliseconds(20), 10);
|
||||
|
||||
EXPECT_FALSE(foreground_window_state->IsFullscreen());
|
||||
EXPECT_TRUE(background_window_state->IsFullscreen());
|
||||
|
||||
// Do a second edge swipe top into screen.
|
||||
generator.GestureScrollSequence(gfx::Point(50, 0), gfx::Point(50, 100),
|
||||
base::TimeDelta::FromMilliseconds(20), 10);
|
||||
|
||||
EXPECT_FALSE(foreground_window_state->IsFullscreen());
|
||||
EXPECT_TRUE(background_window_state->IsFullscreen());
|
||||
|
||||
DestroyTabletModeWindowManager();
|
||||
}
|
||||
|
||||
// Test that an edge swipe from the bottom will end full screen mode.
|
||||
TEST_P(TabletModeWindowManagerTest, ExitFullScreenWithEdgeSwipeFromBottom) {
|
||||
gfx::Rect rect(10, 10, 200, 50);
|
||||
std::unique_ptr<aura::Window> background_window(
|
||||
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
|
||||
std::unique_ptr<aura::Window> foreground_window(
|
||||
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
|
||||
WindowState* background_window_state =
|
||||
WindowState::Get(background_window.get());
|
||||
WindowState* foreground_window_state =
|
||||
WindowState::Get(foreground_window.get());
|
||||
wm::ActivateWindow(foreground_window.get());
|
||||
CreateTabletModeWindowManager();
|
||||
|
||||
// Fullscreen both windows.
|
||||
WMEvent event(WM_EVENT_TOGGLE_FULLSCREEN);
|
||||
background_window_state->OnWMEvent(&event);
|
||||
foreground_window_state->OnWMEvent(&event);
|
||||
EXPECT_TRUE(background_window_state->IsFullscreen());
|
||||
EXPECT_TRUE(foreground_window_state->IsFullscreen());
|
||||
EXPECT_EQ(foreground_window.get(), window_util::GetActiveWindow());
|
||||
|
||||
// Do an edge swipe bottom into screen.
|
||||
ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
|
||||
int y = Shell::GetPrimaryRootWindow()->bounds().bottom();
|
||||
generator.GestureScrollSequence(gfx::Point(50, y), gfx::Point(50, y - 100),
|
||||
base::TimeDelta::FromMilliseconds(20), 10);
|
||||
|
||||
EXPECT_FALSE(foreground_window_state->IsFullscreen());
|
||||
EXPECT_TRUE(background_window_state->IsFullscreen());
|
||||
|
||||
DestroyTabletModeWindowManager();
|
||||
}
|
||||
|
||||
// Test that an edge touch press at the top will end full screen mode.
|
||||
TEST_P(TabletModeWindowManagerTest, ExitFullScreenWithEdgeTouchAtTop) {
|
||||
gfx::Rect rect(10, 10, 200, 50);
|
||||
std::unique_ptr<aura::Window> background_window(
|
||||
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
|
||||
std::unique_ptr<aura::Window> foreground_window(
|
||||
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
|
||||
WindowState* background_window_state =
|
||||
WindowState::Get(background_window.get());
|
||||
WindowState* foreground_window_state =
|
||||
WindowState::Get(foreground_window.get());
|
||||
wm::ActivateWindow(foreground_window.get());
|
||||
CreateTabletModeWindowManager();
|
||||
|
||||
// Fullscreen both windows.
|
||||
WMEvent event(WM_EVENT_TOGGLE_FULLSCREEN);
|
||||
background_window_state->OnWMEvent(&event);
|
||||
foreground_window_state->OnWMEvent(&event);
|
||||
EXPECT_TRUE(background_window_state->IsFullscreen());
|
||||
EXPECT_TRUE(foreground_window_state->IsFullscreen());
|
||||
EXPECT_EQ(foreground_window.get(), window_util::GetActiveWindow());
|
||||
|
||||
// Touch tap on the top edge.
|
||||
ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
|
||||
generator.GestureTapAt(gfx::Point(100, 0));
|
||||
EXPECT_FALSE(foreground_window_state->IsFullscreen());
|
||||
EXPECT_TRUE(background_window_state->IsFullscreen());
|
||||
|
||||
// Try the same again and see that nothing changes.
|
||||
generator.GestureTapAt(gfx::Point(100, 0));
|
||||
EXPECT_FALSE(foreground_window_state->IsFullscreen());
|
||||
EXPECT_TRUE(background_window_state->IsFullscreen());
|
||||
|
||||
DestroyTabletModeWindowManager();
|
||||
}
|
||||
|
||||
// Test that an edge touch press at the bottom will end full screen mode.
|
||||
TEST_P(TabletModeWindowManagerTest, ExitFullScreenWithEdgeTouchAtBottom) {
|
||||
gfx::Rect rect(10, 10, 200, 50);
|
||||
std::unique_ptr<aura::Window> background_window(
|
||||
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
|
||||
std::unique_ptr<aura::Window> foreground_window(
|
||||
CreateWindow(aura::client::WINDOW_TYPE_NORMAL, rect));
|
||||
WindowState* background_window_state =
|
||||
WindowState::Get(background_window.get());
|
||||
WindowState* foreground_window_state =
|
||||
WindowState::Get(foreground_window.get());
|
||||
wm::ActivateWindow(foreground_window.get());
|
||||
CreateTabletModeWindowManager();
|
||||
|
||||
// Fullscreen both windows.
|
||||
WMEvent event(WM_EVENT_TOGGLE_FULLSCREEN);
|
||||
background_window_state->OnWMEvent(&event);
|
||||
foreground_window_state->OnWMEvent(&event);
|
||||
EXPECT_TRUE(background_window_state->IsFullscreen());
|
||||
EXPECT_TRUE(foreground_window_state->IsFullscreen());
|
||||
EXPECT_EQ(foreground_window.get(), window_util::GetActiveWindow());
|
||||
|
||||
// Touch tap on the bottom edge.
|
||||
ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
|
||||
generator.GestureTapAt(
|
||||
gfx::Point(100, Shell::GetPrimaryRootWindow()->bounds().bottom() - 1));
|
||||
EXPECT_FALSE(foreground_window_state->IsFullscreen());
|
||||
EXPECT_TRUE(background_window_state->IsFullscreen());
|
||||
|
||||
// Try the same again and see that nothing changes.
|
||||
generator.GestureTapAt(
|
||||
gfx::Point(100, Shell::GetPrimaryRootWindow()->bounds().bottom() - 1));
|
||||
EXPECT_FALSE(foreground_window_state->IsFullscreen());
|
||||
EXPECT_TRUE(background_window_state->IsFullscreen());
|
||||
|
||||
DestroyTabletModeWindowManager();
|
||||
}
|
||||
|
||||
// Test that an edge swipe from the top on an immersive mode window will not end
|
||||
// full screen mode.
|
||||
TEST_P(TabletModeWindowManagerTest, NoExitImmersiveModeWithEdgeSwipeFromTop) {
|
||||
std::unique_ptr<aura::Window> window(CreateWindow(
|
||||
aura::client::WINDOW_TYPE_NORMAL, gfx::Rect(10, 10, 200, 50)));
|
||||
WindowState* window_state = WindowState::Get(window.get());
|
||||
wm::ActivateWindow(window.get());
|
||||
CreateTabletModeWindowManager();
|
||||
|
||||
// Fullscreen the window.
|
||||
WMEvent event(WM_EVENT_TOGGLE_FULLSCREEN);
|
||||
window_state->OnWMEvent(&event);
|
||||
EXPECT_TRUE(window_state->IsFullscreen());
|
||||
EXPECT_FALSE(window_state->IsInImmersiveFullscreen());
|
||||
EXPECT_EQ(window.get(), window_util::GetActiveWindow());
|
||||
|
||||
window->SetProperty(kImmersiveIsActive, true);
|
||||
|
||||
// Do an edge swipe top into screen.
|
||||
ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
|
||||
generator.GestureScrollSequence(gfx::Point(50, 0), gfx::Point(50, 100),
|
||||
base::TimeDelta::FromMilliseconds(20), 10);
|
||||
|
||||
// It should have not exited full screen or immersive mode.
|
||||
EXPECT_TRUE(window_state->IsFullscreen());
|
||||
EXPECT_TRUE(window_state->IsInImmersiveFullscreen());
|
||||
|
||||
DestroyTabletModeWindowManager();
|
||||
}
|
||||
|
||||
// Test that an edge swipe from the bottom will not end immersive mode.
|
||||
TEST_P(TabletModeWindowManagerTest,
|
||||
NoExitImmersiveModeWithEdgeSwipeFromBottom) {
|
||||
std::unique_ptr<aura::Window> window(CreateWindow(
|
||||
aura::client::WINDOW_TYPE_NORMAL, gfx::Rect(10, 10, 200, 50)));
|
||||
WindowState* window_state = WindowState::Get(window.get());
|
||||
wm::ActivateWindow(window.get());
|
||||
CreateTabletModeWindowManager();
|
||||
|
||||
// Fullscreen the window.
|
||||
WMEvent event(WM_EVENT_TOGGLE_FULLSCREEN);
|
||||
window_state->OnWMEvent(&event);
|
||||
EXPECT_TRUE(window_state->IsFullscreen());
|
||||
EXPECT_FALSE(window_state->IsInImmersiveFullscreen());
|
||||
EXPECT_EQ(window.get(), window_util::GetActiveWindow());
|
||||
window->SetProperty(kImmersiveIsActive, true);
|
||||
EXPECT_TRUE(window_state->IsInImmersiveFullscreen());
|
||||
|
||||
// Do an edge swipe bottom into screen.
|
||||
ui::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
|
||||
int y = Shell::GetPrimaryRootWindow()->bounds().bottom();
|
||||
generator.GestureScrollSequence(gfx::Point(50, y), gfx::Point(50, y - 100),
|
||||
base::TimeDelta::FromMilliseconds(20), 10);
|
||||
|
||||
// The window should still be full screen and immersive.
|
||||
EXPECT_TRUE(window_state->IsFullscreen());
|
||||
EXPECT_TRUE(window_state->IsInImmersiveFullscreen());
|
||||
|
||||
DestroyTabletModeWindowManager();
|
||||
}
|
||||
|
||||
// Tests that windows with the always-on-top property are not managed by
|
||||
// the TabletModeWindowManager while tablet mode is engaged (i.e.,
|
||||
// they remain free-floating).
|
||||
|
Reference in New Issue
Block a user