Commit fa1b90e7 authored by Xiaoqian Dai's avatar Xiaoqian Dai Committed by Commit Bot

overview gesture: move window hide logic to DragWindowFromShelfController.

Previously it was in HomeLauncherGestureHandler. That means all eligible
windows were hidden before the drag actually started. Move it to its own
class DragWindowFromShelfController so that we only hide window when
drag actually starts. It will also be benificial for the class
DragWindowFromShelfController to be called from other caller.

Bug: 997885
Change-Id: I0cb8285c9505b48db76d4f5e5103ca24ebe1d90a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1872804Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Xiaoqian Dai <xdai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#708008}
parent 786a00fb
......@@ -13,6 +13,7 @@
#include "ash/shell.h"
#include "ash/wallpaper/wallpaper_view.h"
#include "ash/wallpaper/wallpaper_widget_controller.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/overview/overview_constants.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/overview/overview_session.h"
......@@ -124,10 +125,66 @@ class WindowTransformToHomeScreenAnimation
} // namespace
// Hide all visible windows expect the dragged windows or the window showing in
// splitview during dragging.
class DragWindowFromShelfController::WindowsHider
: public aura::WindowObserver {
public:
explicit WindowsHider(aura::Window* dragged_window)
: dragged_window_(dragged_window) {
std::vector<aura::Window*> windows =
Shell::Get()->mru_window_tracker()->BuildMruWindowList(kActiveDesk);
for (auto* window : windows) {
if (window == dragged_window_)
continue;
if (!window->IsVisible())
continue;
if (SplitViewController::Get(window)->IsWindowInSplitView(window))
continue;
hidden_windows_.push_back(window);
{
ScopedAnimationDisabler disabler(window);
// Minimize so that they can show up correctly in overview.
WindowState::Get(window)->Minimize();
window->Hide();
}
window->AddObserver(this);
}
}
~WindowsHider() override {
for (auto* window : hidden_windows_)
window->RemoveObserver(this);
hidden_windows_.clear();
}
void RestoreWindowsVisibility() {
for (auto* window : hidden_windows_) {
window->RemoveObserver(this);
ScopedAnimationDisabler disabler(window);
window->Show();
}
hidden_windows_.clear();
}
// aura::WindowObserver:
void OnWindowDestroying(aura::Window* window) override {
window->RemoveObserver(this);
hidden_windows_.erase(
std::find(hidden_windows_.begin(), hidden_windows_.end(), window));
}
private:
aura::Window* dragged_window_;
std::vector<aura::Window*> hidden_windows_;
DISALLOW_COPY_AND_ASSIGN(WindowsHider);
};
DragWindowFromShelfController::DragWindowFromShelfController(
aura::Window* window,
const std::vector<aura::Window*>& hidden_windows)
: window_(window), hidden_windows_(hidden_windows) {}
aura::Window* window)
: window_(window) {}
DragWindowFromShelfController::~DragWindowFromShelfController() {
CancelDrag();
......@@ -194,10 +251,8 @@ void DragWindowFromShelfController::Drag(const gfx::Point& location_in_screen,
void DragWindowFromShelfController::EndDrag(
const gfx::Point& location_in_screen,
base::Optional<float> velocity_y) {
if (!drag_started_) {
ReshowHiddenWindowsOnDragEnd();
if (!drag_started_)
return;
}
drag_started_ = false;
OverviewController* overview_controller = Shell::Get()->overview_controller();
......@@ -234,10 +289,8 @@ void DragWindowFromShelfController::EndDrag(
}
void DragWindowFromShelfController::CancelDrag() {
if (!drag_started_) {
ReshowHiddenWindowsOnDragEnd();
if (!drag_started_)
return;
}
drag_started_ = false;
// Reset the window's transform to identity transform.
......@@ -269,6 +322,9 @@ void DragWindowFromShelfController::OnDragStarted(
original_backdrop_mode_ = window_->GetProperty(kBackdropWindowMode);
window_->SetProperty(kBackdropWindowMode, BackdropWindowMode::kDisabled);
// Hide all visible windows behind the dragged window during dragging.
windows_hider_ = std::make_unique<WindowsHider>(window_);
// Hide the home launcher until it's eligible to show it.
Shell::Get()->home_screen_controller()->OnWindowDragStarted();
......@@ -336,7 +392,6 @@ void DragWindowFromShelfController::OnDragEnded(
}
WindowState::Get(window_)->DeleteDragDetails();
hidden_windows_.clear();
}
void DragWindowFromShelfController::UpdateDraggedWindow(
......@@ -481,11 +536,7 @@ bool DragWindowFromShelfController::ShouldDropWindowInOverview(
}
void DragWindowFromShelfController::ReshowHiddenWindowsOnDragEnd() {
for (auto* window : hidden_windows_) {
ScopedAnimationDisabler disable(window);
window->Show();
}
hidden_windows_.clear();
windows_hider_->RestoreWindowsVisibility();
}
void DragWindowFromShelfController::ShowOverviewDuringOrAfterDrag() {
......
......@@ -47,9 +47,7 @@ class DragWindowFromShelfController {
// view is active during dragging.
static constexpr float kVelocityToOverviewThreshold = 1000.f;
DragWindowFromShelfController(
aura::Window* window,
const std::vector<aura::Window*>& hidden_windows);
explicit DragWindowFromShelfController(aura::Window* window);
~DragWindowFromShelfController();
// Called during swiping up on the shelf.
......@@ -61,6 +59,8 @@ class DragWindowFromShelfController {
void CancelDrag();
private:
class WindowsHider;
void OnDragStarted(const gfx::Point& location_in_screen);
void OnDragEnded(const gfx::Point& location_in_screen,
bool should_drop_window_in_overview,
......@@ -115,9 +115,9 @@ class DragWindowFromShelfController {
bool drag_started_ = false;
BackdropWindowMode original_backdrop_mode_ = BackdropWindowMode::kAuto;
// The windows that are hidden during window dragging. Depends on different
// Hide all eligible windows during window dragging. Depends on different
// scenarios, we may or may not reshow there windows when drag ends.
std::vector<aura::Window*> hidden_windows_;
std::unique_ptr<WindowsHider> windows_hider_;
// Timer to show and update overview.
base::OneShotTimer show_overview_timer_;
......
......@@ -835,7 +835,7 @@ bool HomeLauncherGestureHandler::SetUpWindows(
}
aura::Window* first_window = nullptr;
if (mode == HomeLauncherGestureHandler::Mode::kDragWindowToHomeOrOverview) {
if (mode == Mode::kDragWindowToHomeOrOverview) {
DCHECK(location_in_screen.has_value());
first_window =
GetWindowForDragToHomeOrOverview(*location_in_screen, windows);
......@@ -884,36 +884,28 @@ bool HomeLauncherGestureHandler::SetUpWindows(
});
}
// In kDragWindowToHomeOrOverview mode, no need to calculate the desired
// opacity and transform for the dragged window and its transient descendants
// and backdrop window and the divider window. No need to hide windows as well
// since DragWindowFromShelfController will handle it itself.
if (mode == Mode::kDragWindowToHomeOrOverview)
return true;
// Hide all visible windows which are behind our window so that when we
// scroll, the home launcher will be visible in kSlideUpToShow case and
// wallpaper will be visible in kDragWindowToHomeOrOverview case. This is only
// needed when swiping up, and not when overview mode is active.
// scroll, the home launcher will be visible in kSlideUpToShow case. This is
// only needed when swiping up, and not when overview mode is active.
hidden_windows_.clear();
if ((mode == Mode::kSlideUpToShow ||
mode == Mode::kDragWindowToHomeOrOverview) &&
!overview_active_on_gesture_start_) {
if (mode == Mode::kSlideUpToShow && !overview_active_on_gesture_start_) {
for (auto* window : windows) {
if (window->IsVisible() &&
(mode == Mode::kSlideUpToShow ||
(mode == Mode::kDragWindowToHomeOrOverview &&
!split_view_controller->IsWindowInSplitView(window)))) {
if (window->IsVisible()) {
hidden_windows_.push_back(window);
window->AddObserver(this);
}
}
// Minimize the hidden windows instead of hiding so that they can show up
// in overview later.
window_util::HideAndMaybeMinimizeWithoutAnimation(
hidden_windows_,
/*minimize=*/(mode == Mode::kDragWindowToHomeOrOverview));
window_util::HideAndMaybeMinimizeWithoutAnimation(hidden_windows_,
/*minimize=*/false);
}
// In kDragWindowToHomeOrOverview mode, no need to calculate the desired
// opacity and transform for the dragged window and its transient descendants
// and backdrop window and the divider window.
if (mode == Mode::kDragWindowToHomeOrOverview)
return true;
// Show |active_window_| if we are swiping down to hide.
if (mode == Mode::kSlideDownToHide) {
ScopedAnimationDisabler disable(GetActiveWindow());
......@@ -975,8 +967,8 @@ bool HomeLauncherGestureHandler::SetUpWindows(
void HomeLauncherGestureHandler::OnDragStarted(const gfx::Point& location) {
if (mode_ == Mode::kDragWindowToHomeOrOverview) {
window_drag_controller_ = std::make_unique<DragWindowFromShelfController>(
GetActiveWindow(), hidden_windows_);
window_drag_controller_ =
std::make_unique<DragWindowFromShelfController>(GetActiveWindow());
} else if (mode_ == Mode::kSwipeHomeToOverview) {
swipe_home_to_overview_controller_ =
std::make_unique<SwipeHomeToOverviewController>();
......
......@@ -498,6 +498,7 @@ TEST_F(HomeLauncherGestureHandlerTest, DraggedActiveWindow) {
// Tests that in kDragWindowToHomeOrOverview mode, we may hide different sets
// of windows in different scenarios.
TEST_F(HomeLauncherGestureHandlerTest, HideWindowDuringWindowDragging) {
UpdateDisplay("400x400");
const gfx::Rect shelf_bounds =
Shelf::ForWindow(Shell::GetPrimaryRootWindow())->GetIdealBounds();
......@@ -510,6 +511,7 @@ TEST_F(HomeLauncherGestureHandlerTest, HideWindowDuringWindowDragging) {
GetGestureHandler()->OnPressEvent(Mode::kDragWindowToHomeOrOverview,
shelf_bounds.CenterPoint());
GetGestureHandler()->OnScrollEvent(gfx::Point(200, 200), 1.f, 1.f);
EXPECT_TRUE(window1->IsVisible());
EXPECT_FALSE(window2->IsVisible());
EXPECT_FALSE(window3->IsVisible());
......@@ -526,6 +528,7 @@ TEST_F(HomeLauncherGestureHandlerTest, HideWindowDuringWindowDragging) {
GetGestureHandler()->OnPressEvent(Mode::kDragWindowToHomeOrOverview,
shelf_bounds.bottom_left());
EXPECT_EQ(GetGestureHandler()->GetActiveWindow(), window1.get());
GetGestureHandler()->OnScrollEvent(gfx::Point(0, 200), 1.f, 1.f);
EXPECT_TRUE(window1->IsVisible());
EXPECT_TRUE(window2->IsVisible());
EXPECT_FALSE(window3->IsVisible());
......@@ -537,6 +540,7 @@ TEST_F(HomeLauncherGestureHandlerTest, HideWindowDuringWindowDragging) {
GetGestureHandler()->OnPressEvent(Mode::kDragWindowToHomeOrOverview,
shelf_bounds.bottom_right());
GetGestureHandler()->OnScrollEvent(gfx::Point(400, 200), 1.f, 1.f);
EXPECT_TRUE(window1->IsVisible());
EXPECT_TRUE(window2->IsVisible());
EXPECT_FALSE(window3->IsVisible());
......@@ -608,8 +612,8 @@ TEST_F(HomeLauncherGestureHandlerTest, MayOrMayNotReShowHiddenWindows) {
// windows.
GetGestureHandler()->OnPressEvent(Mode::kDragWindowToHomeOrOverview,
shelf_bounds.CenterPoint());
EXPECT_FALSE(window2->IsVisible());
GetGestureHandler()->OnScrollEvent(gfx::Point(200, 200), 0.f, 1.f);
EXPECT_FALSE(window2->IsVisible());
GetGestureHandler()->OnReleaseEvent(shelf_bounds.CenterPoint(),
base::nullopt);
EXPECT_TRUE(window2->IsVisible());
......@@ -617,8 +621,8 @@ TEST_F(HomeLauncherGestureHandlerTest, MayOrMayNotReShowHiddenWindows) {
// If fling to homescreen, do not reshow the hidden windows.
GetGestureHandler()->OnPressEvent(Mode::kDragWindowToHomeOrOverview,
shelf_bounds.CenterPoint());
EXPECT_FALSE(window2->IsVisible());
GetGestureHandler()->OnScrollEvent(gfx::Point(200, 200), 0.f, 1.f);
EXPECT_FALSE(window2->IsVisible());
GetGestureHandler()->OnReleaseEvent(
gfx::Point(200, 200),
-DragWindowFromShelfController::kVelocityToHomeScreenThreshold);
......@@ -631,8 +635,8 @@ TEST_F(HomeLauncherGestureHandlerTest, MayOrMayNotReShowHiddenWindows) {
window1->Show();
GetGestureHandler()->OnPressEvent(Mode::kDragWindowToHomeOrOverview,
shelf_bounds.CenterPoint());
EXPECT_FALSE(window2->IsVisible());
GetGestureHandler()->OnScrollEvent(gfx::Point(200, 200), 0.f, 1.f);
EXPECT_FALSE(window2->IsVisible());
OverviewController* overview_controller = Shell::Get()->overview_controller();
EXPECT_TRUE(overview_controller->InOverviewSession());
GetGestureHandler()->OnReleaseEvent(gfx::Point(200, 200), base::nullopt);
......@@ -648,8 +652,8 @@ TEST_F(HomeLauncherGestureHandlerTest, MayOrMayNotReShowHiddenWindows) {
window1->Show();
GetGestureHandler()->OnPressEvent(Mode::kDragWindowToHomeOrOverview,
shelf_bounds.CenterPoint());
EXPECT_FALSE(window2->IsVisible());
GetGestureHandler()->OnScrollEvent(gfx::Point(0, 200), 0.f, 1.f);
EXPECT_FALSE(window2->IsVisible());
EXPECT_TRUE(overview_controller->InOverviewSession());
GetGestureHandler()->OnReleaseEvent(gfx::Point(0, 200), base::nullopt);
EXPECT_TRUE(overview_controller->InOverviewSession());
......@@ -671,14 +675,17 @@ TEST_F(HomeLauncherGestureHandlerTest, MinimizedWindowsShowInOverview) {
GetGestureHandler()->OnPressEvent(Mode::kDragWindowToHomeOrOverview,
shelf_bounds.CenterPoint());
EXPECT_TRUE(window1->IsVisible());
EXPECT_FALSE(window2->IsVisible());
EXPECT_TRUE(WindowState::Get(window2.get())->IsMinimized());
EXPECT_FALSE(window3->IsVisible());
EXPECT_TRUE(WindowState::Get(window3.get())->IsMinimized());
EXPECT_TRUE(window2->IsVisible());
EXPECT_TRUE(window3->IsVisible());
// Drag it far enough so overview should be open behind the dragged window.
GetGestureHandler()->OnScrollEvent(gfx::Point(200, 200), 0.f, 1.f);
OverviewController* overview_controller = Shell::Get()->overview_controller();
EXPECT_TRUE(overview_controller->InOverviewSession());
EXPECT_TRUE(window1->IsVisible());
EXPECT_FALSE(window2->IsVisible());
EXPECT_TRUE(WindowState::Get(window2.get())->IsMinimized());
EXPECT_FALSE(window3->IsVisible());
EXPECT_TRUE(WindowState::Get(window3.get())->IsMinimized());
EXPECT_FALSE(overview_controller->overview_session()->IsWindowInOverview(
window1.get()));
EXPECT_TRUE(overview_controller->overview_session()->IsWindowInOverview(
......
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