diff --git a/ash/BUILD.gn b/ash/BUILD.gn index ce7acd9c04fe2..53603a60f5fc8 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn @@ -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", diff --git a/ash/public/cpp/shelf_config.h b/ash/public/cpp/shelf_config.h index 111e186ecc1b0..c5e9f075edb84 100644 --- a/ash/public/cpp/shelf_config.h +++ b/ash/public/cpp/shelf_config.h @@ -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_; diff --git a/ash/shelf/shelf_config.cc b/ash/shelf/shelf_config.cc index 2ff3680cdf197..a9e14c0b6f28f 100644 --- a/ash/shelf/shelf_config.cc +++ b/ash/shelf/shelf_config.cc @@ -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(); diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index b3a1ff9d0366c..ea4db255b21f5 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc @@ -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) diff --git a/ash/wm/tablet_mode/tablet_mode_event_handler.cc b/ash/wm/tablet_mode/tablet_mode_event_handler.cc deleted file mode 100644 index 46d51856debbd..0000000000000 --- a/ash/wm/tablet_mode/tablet_mode_event_handler.cc +++ /dev/null @@ -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 diff --git a/ash/wm/tablet_mode/tablet_mode_event_handler.h b/ash/wm/tablet_mode/tablet_mode_event_handler.h deleted file mode 100644 index a7b7a450cd278..0000000000000 --- a/ash/wm/tablet_mode/tablet_mode_event_handler.h +++ /dev/null @@ -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_ diff --git a/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.cc b/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.cc new file mode 100644 index 0000000000000..afa303638b03e --- /dev/null +++ b/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.cc @@ -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 diff --git a/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.h b/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.h new file mode 100644 index 0000000000000..4ff560f00c8f8 --- /dev/null +++ b/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler.h @@ -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_ diff --git a/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler_unittest.cc b/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler_unittest.cc new file mode 100644 index 0000000000000..c369eb7257d93 --- /dev/null +++ b/ash/wm/tablet_mode/tablet_mode_toggle_fullscreen_event_handler_unittest.cc @@ -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 diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager.cc b/ash/wm/tablet_mode/tablet_mode_window_manager.cc index b144ef8a86d48..94cc436ebfc09 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_manager.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_manager.cc @@ -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() { diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager.h b/ash/wm/tablet_mode/tablet_mode_window_manager.h index 4666ea88f704c..cb1b3726bb051 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_manager.h +++ b/ash/wm/tablet_mode/tablet_mode_window_manager.h @@ -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; diff --git a/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc b/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc index d44f3754426a3..e0ae20897a713 100644 --- a/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc +++ b/ash/wm/tablet_mode/tablet_mode_window_manager_unittest.cc @@ -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).