Commit 0b1fc9b7 authored by Min Chen's avatar Min Chen Committed by Commit Bot

Set the dragged window as active window on window drag ended.

changes in this cl,
- Added overview exit type kWindowDragged for ending overview on window
  drag.
- Set the dragged window as active window on window drag ended, this will
  make sure the dragged window will not lost its activation on overview
  ended.
- Update the non-dragged windows' bounds at the end of animation. Since
  we want no animation if overview ends on window drag, including the
  update bounds animation. Set the animation type to ZERO for all the
  other windows except the dragged window. Then we can only see the update
  bounds animation of the dragged window. All the other windows' bounds
  will be updated at the end of the animation, which can not be seen by
  users.

Bug: 883579
Change-Id: I6a523e6be7caf32757299462cdf6197574768be2
Reviewed-on: https://chromium-review.googlesource.com/1232957
Commit-Queue: Min Chen <minch@chromium.org>
Reviewed-by: default avatarXiaoqian Dai <xdai@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#593715}
parent 38874404
...@@ -78,7 +78,12 @@ class ASH_EXPORT WindowSelector : public display::DisplayObserver, ...@@ -78,7 +78,12 @@ class ASH_EXPORT WindowSelector : public display::DisplayObserver,
// Overview can be closed by swiping up from the shelf. In this mode, the // Overview can be closed by swiping up from the shelf. In this mode, the
// call site will handle shifting the bounds of the windows, so overview // call site will handle shifting the bounds of the windows, so overview
// code does not need to handle any animations. This is an exit only type. // code does not need to handle any animations. This is an exit only type.
kSwipeFromShelf kSwipeFromShelf,
// Overview can be opened by start dragging a window from top or be closed
// if the dragged window restores back to maximized/full-screened. Used as
// an exit type only currently to avoid the update bounds animation of the
// windows in overview grid on overview mode ended.
kWindowDragged
}; };
// Callback which fills out the passed settings object. Used by several // Callback which fills out the passed settings object. Used by several
......
...@@ -291,7 +291,8 @@ bool WindowSelectorController::ToggleOverview( ...@@ -291,7 +291,8 @@ bool WindowSelectorController::ToggleOverview(
return true; return true;
window_selector_->set_enter_exit_overview_type(new_type); window_selector_->set_enter_exit_overview_type(new_type);
if (type != WindowSelector::EnterExitOverviewType::kNormal) { if (type == WindowSelector::EnterExitOverviewType::kWindowsMinimized ||
type == WindowSelector::EnterExitOverviewType::kSwipeFromShelf) {
// Minimize the windows without animations. When the home launcher button // Minimize the windows without animations. When the home launcher button
// is pressed, minimized widgets will get created in their place, and // is pressed, minimized widgets will get created in their place, and
// those widgets will be slid out of overview. Otherwise, // those widgets will be slid out of overview. Otherwise,
......
...@@ -126,6 +126,14 @@ bool IsSnapped(aura::Window* window) { ...@@ -126,6 +126,14 @@ bool IsSnapped(aura::Window* window) {
return wm::GetWindowState(window)->IsSnapped(); return wm::GetWindowState(window)->IsSnapped();
} }
// Returns the window selector if overview mode is active, otherwise returns
// nullptr.
WindowSelector* GetWindowSelector() {
return Shell::Get()->window_selector_controller()->IsSelecting()
? Shell::Get()->window_selector_controller()->window_selector()
: nullptr;
}
} // namespace } // namespace
// The window observer that observes the current tab-dragged window. When it's // The window observer that observes the current tab-dragged window. When it's
...@@ -724,8 +732,7 @@ void SplitViewController::OnOverviewModeStarting() { ...@@ -724,8 +732,7 @@ void SplitViewController::OnOverviewModeStarting() {
void SplitViewController::OnOverviewModeEnding() { void SplitViewController::OnOverviewModeEnding() {
DCHECK(IsSplitViewModeActive()); DCHECK(IsSplitViewModeActive());
WindowSelector* window_selector = WindowSelector* window_selector = GetWindowSelector();
Shell::Get()->window_selector_controller()->window_selector();
// Early exit if overview is ended while swiping up on the shelf to avoid // Early exit if overview is ended while swiping up on the shelf to avoid
// snapping a window or showing a toast. // snapping a window or showing a toast.
if (window_selector->enter_exit_overview_type() == if (window_selector->enter_exit_overview_type() ==
...@@ -1401,8 +1408,7 @@ void SplitViewController::RemoveWindowFromOverviewIfApplicable( ...@@ -1401,8 +1408,7 @@ void SplitViewController::RemoveWindowFromOverviewIfApplicable(
if (!Shell::Get()->window_selector_controller()->IsSelecting()) if (!Shell::Get()->window_selector_controller()->IsSelecting())
return; return;
WindowSelector* window_selector = WindowSelector* window_selector = GetWindowSelector();
Shell::Get()->window_selector_controller()->window_selector();
WindowGrid* current_grid = WindowGrid* current_grid =
window_selector->GetGridWithRootWindow(window->GetRootWindow()); window_selector->GetGridWithRootWindow(window->GetRootWindow());
if (!current_grid) if (!current_grid)
...@@ -1430,10 +1436,9 @@ void SplitViewController::UpdateSnappingWindowTransformedBounds( ...@@ -1430,10 +1436,9 @@ void SplitViewController::UpdateSnappingWindowTransformedBounds(
} }
void SplitViewController::InsertWindowToOverview(aura::Window* window) { void SplitViewController::InsertWindowToOverview(aura::Window* window) {
if (!window || !Shell::Get()->window_selector_controller()->IsSelecting()) if (!window || !GetWindowSelector())
return; return;
Shell::Get()->window_selector_controller()->window_selector()->AddItem( GetWindowSelector()->AddItem(window, /*reposition=*/true, /*animate=*/true);
window, /*reposition=*/true, /*animate=*/true);
} }
void SplitViewController::StartOverview() { void SplitViewController::StartOverview() {
...@@ -1461,13 +1466,8 @@ void SplitViewController::EndWindowDragImpl( ...@@ -1461,13 +1466,8 @@ void SplitViewController::EndWindowDragImpl(
const gfx::Point& last_location_in_screen) { const gfx::Point& last_location_in_screen) {
// If dragged window was in overview before or it has been added to overview // If dragged window was in overview before or it has been added to overview
// window by dropping on the new selector item, do nothing. // window by dropping on the new selector item, do nothing.
WindowSelectorController* window_selector_controller = if (GetWindowSelector() && GetWindowSelector()->IsWindowInOverview(window))
Shell::Get()->window_selector_controller();
if (window_selector_controller->IsSelecting() &&
window_selector_controller->window_selector()->IsWindowInOverview(
window)) {
return; return;
}
const bool was_splitview_active = IsSplitViewModeActive(); const bool was_splitview_active = IsSplitViewModeActive();
if (desired_snap_position == SplitViewController::NONE) { if (desired_snap_position == SplitViewController::NONE) {
...@@ -1486,13 +1486,20 @@ void SplitViewController::EndWindowDragImpl( ...@@ -1486,13 +1486,20 @@ void SplitViewController::EndWindowDragImpl(
SetTransformWithAnimation(window, window->layer()->GetTargetTransform(), SetTransformWithAnimation(window, window->layer()->GetTargetTransform(),
gfx::Transform()); gfx::Transform());
if (window_selector_controller->IsSelecting()) { WindowSelector* window_selector = GetWindowSelector();
window_selector_controller->window_selector() if (window_selector) {
->SetWindowListNotAnimatedWhenExiting(window->GetRootWindow()); window_selector->SetWindowListNotAnimatedWhenExiting(
// End the overview mode if it's active at the moment. The dragged window->GetRootWindow());
// window will be restored back to its previous state before dragging. // Set the overview exit type to kWindowDragged to avoid update bounds
EndOverview(); // animation of the windows in overview grid.
window_selector->set_enter_exit_overview_type(
WindowSelector::EnterExitOverviewType::kWindowDragged);
} }
// Activate the dragged window will end the overview at the same time.The
// dragged window will be restored back to its previous state before
// dragging.
wm::ActivateWindow(window);
DCHECK(!Shell::Get()->window_selector_controller()->IsSelecting());
} }
} else { } else {
// Note SnapWindow() might put the previous window that was snapped at the // Note SnapWindow() might put the previous window that was snapped at the
......
...@@ -2839,6 +2839,51 @@ TEST_F(SplitViewTabDraggingTest, SourceWindowBackgroundTest) { ...@@ -2839,6 +2839,51 @@ TEST_F(SplitViewTabDraggingTest, SourceWindowBackgroundTest) {
EXPECT_TRUE(Shell::Get()->app_list_controller()->IsVisible()); EXPECT_TRUE(Shell::Get()->app_list_controller()->IsVisible());
} }
// Tests that the dragged window should be the active and top window if overview
// ended because of window drag.
TEST_F(SplitViewTabDraggingTest, OverviewEndedOnWindowDrag) {
const gfx::Rect bounds(0, 0, 400, 400);
std::unique_ptr<aura::Window> window1(
CreateWindowWithType(bounds, AppType::BROWSER));
std::unique_ptr<aura::Window> window2(
CreateWindowWithType(bounds, AppType::BROWSER));
split_view_controller()->SnapWindow(window1.get(), SplitViewController::LEFT);
split_view_controller()->SnapWindow(window2.get(),
SplitViewController::RIGHT);
// Drags |window2| to overview.
std::unique_ptr<WindowResizer> resizer =
StartDrag(window2.get(), window2.get());
gfx::Rect new_selector_item_bounds =
GetNewSelectorItemBoundsDuringDrag(window1.get());
DragWindowTo(resizer.get(), new_selector_item_bounds.CenterPoint());
CompleteDrag(std::move(resizer));
WindowSelectorController* selector_controller =
Shell::Get()->window_selector_controller();
EXPECT_TRUE(selector_controller->IsSelecting());
EXPECT_TRUE(selector_controller->window_selector()->IsWindowInOverview(
window2.get()));
EXPECT_EQ(split_view_controller()->state(),
SplitViewController::LEFT_SNAPPED);
// Drags |window1| by a small distance. Both splitview and overview should be
// ended and |window1| is the active window and above |window2|.
resizer = StartDrag(window1.get(), window1.get());
DragWindowTo(resizer.get(), gfx::Point(10, 10));
CompleteDrag(std::move(resizer));
EXPECT_FALSE(selector_controller->IsSelecting());
EXPECT_FALSE(split_view_controller()->IsSplitViewModeActive());
EXPECT_TRUE(wm::GetWindowState(window1.get())->IsMaximized());
EXPECT_TRUE(wm::GetWindowState(window2.get())->IsMaximized());
EXPECT_TRUE(wm::GetWindowState(window1.get())->IsActive());
EXPECT_FALSE(wm::GetWindowState(window2.get())->IsActive());
// |window1| should above |window2|.
const aura::Window::Windows windows = window1->parent()->children();
auto window1_layer = std::find(windows.begin(), windows.end(), window1.get());
auto window2_layer = std::find(windows.begin(), windows.end(), window2.get());
EXPECT_TRUE(window1_layer > window2_layer);
}
class TestWindowDelegateWithWidget : public views::WidgetDelegate { class TestWindowDelegateWithWidget : public views::WidgetDelegate {
public: public:
TestWindowDelegateWithWidget(bool can_activate) TestWindowDelegateWithWidget(bool can_activate)
......
...@@ -85,12 +85,36 @@ void TabletModeWindowManager::WindowStateDestroyed(aura::Window* window) { ...@@ -85,12 +85,36 @@ void TabletModeWindowManager::WindowStateDestroyed(aura::Window* window) {
void TabletModeWindowManager::OnOverviewModeStarting() { void TabletModeWindowManager::OnOverviewModeStarting() {
for (auto& pair : window_state_map_) for (auto& pair : window_state_map_)
SetDeferBoundsUpdates(pair.first, true); SetDeferBoundsUpdates(pair.first, /*defer_bounds_updates=*/true);
}
void TabletModeWindowManager::OnOverviewModeEnding() {
WindowSelector* window_selector =
Shell::Get()->window_selector_controller()->window_selector();
exit_overview_by_window_drag_ =
window_selector->enter_exit_overview_type() ==
WindowSelector::EnterExitOverviewType::kWindowDragged;
} }
void TabletModeWindowManager::OnOverviewModeEnded() { void TabletModeWindowManager::OnOverviewModeEnded() {
for (auto& pair : window_state_map_) for (auto& pair : window_state_map_) {
SetDeferBoundsUpdates(pair.first, false); // We don't want any animation if overview exits because of dragging a
// window from top, including the window update bounds animation. Set the
// animation tween type to ZERO for all the other windows except the dragged
// window(active window). Then the dragged window can still be animated to
// its target bounds but all the other windows' bounds will be updated at
// the end of the animation.
pair.second->set_use_zero_animation_type(
exit_overview_by_window_drag_ &&
!wm::GetWindowState(pair.first)->IsActive());
SetDeferBoundsUpdates(pair.first, /*defer_bounds_updates=*/false);
// SetDeferBoundsUpdates is called with /*defer_bounds_updates=*/false
// hence the window bounds is updated with proper zero animation type
// flag. Reset the flag here so that it does not affect window bounds
// update later.
pair.second->set_use_zero_animation_type(false);
}
} }
void TabletModeWindowManager::OnSplitViewModeEnded() { void TabletModeWindowManager::OnSplitViewModeEnded() {
......
...@@ -59,6 +59,7 @@ class ASH_EXPORT TabletModeWindowManager ...@@ -59,6 +59,7 @@ class ASH_EXPORT TabletModeWindowManager
// ShellObserver: // ShellObserver:
void OnOverviewModeStarting() override; void OnOverviewModeStarting() override;
void OnOverviewModeEnding() override;
void OnOverviewModeEnded() override; void OnOverviewModeEnded() override;
void OnSplitViewModeEnded() override; void OnSplitViewModeEnded() override;
...@@ -146,6 +147,9 @@ class ASH_EXPORT TabletModeWindowManager ...@@ -146,6 +147,9 @@ class ASH_EXPORT TabletModeWindowManager
std::unique_ptr<wm::TabletModeEventHandler> event_handler_; std::unique_ptr<wm::TabletModeEventHandler> event_handler_;
// True if overview exit type is |kWindowDragged|.
bool exit_overview_by_window_drag_ = false;
DISALLOW_COPY_AND_ASSIGN(TabletModeWindowManager); DISALLOW_COPY_AND_ASSIGN(TabletModeWindowManager);
}; };
......
...@@ -174,8 +174,7 @@ TabletModeWindowState::TabletModeWindowState(aura::Window* window, ...@@ -174,8 +174,7 @@ TabletModeWindowState::TabletModeWindowState(aura::Window* window,
TabletModeWindowManager* creator) TabletModeWindowManager* creator)
: window_(window), : window_(window),
creator_(creator), creator_(creator),
current_state_type_(wm::GetWindowState(window)->GetStateType()), current_state_type_(wm::GetWindowState(window)->GetStateType()) {
defer_bounds_updates_(false) {
old_state_.reset(wm::GetWindowState(window) old_state_.reset(wm::GetWindowState(window)
->SetStateObject(std::unique_ptr<State>(this)) ->SetStateObject(std::unique_ptr<State>(this))
.release()); .release());
...@@ -449,6 +448,11 @@ void TabletModeWindowState::UpdateBounds(wm::WindowState* window_state, ...@@ -449,6 +448,11 @@ void TabletModeWindowState::UpdateBounds(wm::WindowState* window_state,
if (!window_state->window()->IsVisible() || !animated) { if (!window_state->window()->IsVisible() || !animated) {
window_state->SetBoundsDirect(bounds_in_parent); window_state->SetBoundsDirect(bounds_in_parent);
} else { } else {
if (use_zero_animation_type_) {
window_state->SetBoundsDirectCrossFade(bounds_in_parent,
gfx::Tween::ZERO);
return;
}
// If we animate (to) tablet mode, we want to use the cross fade to // If we animate (to) tablet mode, we want to use the cross fade to
// avoid flashing. // avoid flashing.
if (window_state->IsMaximized()) if (window_state->IsMaximized())
......
...@@ -47,6 +47,10 @@ class TabletModeWindowState : public wm::WindowState::State { ...@@ -47,6 +47,10 @@ class TabletModeWindowState : public wm::WindowState::State {
wm::WindowState::State* previous_state) override; wm::WindowState::State* previous_state) override;
void DetachState(wm::WindowState* window_state) override; void DetachState(wm::WindowState* window_state) override;
void set_use_zero_animation_type(bool use_zero_animation_type) {
use_zero_animation_type_ = use_zero_animation_type;
}
private: private:
// Updates the window to |new_state_type| and resulting bounds: // Updates the window to |new_state_type| and resulting bounds:
// Either full screen, maximized centered or minimized. If the state does not // Either full screen, maximized centered or minimized. If the state does not
...@@ -87,7 +91,11 @@ class TabletModeWindowState : public wm::WindowState::State { ...@@ -87,7 +91,11 @@ class TabletModeWindowState : public wm::WindowState::State {
mojom::WindowStateType current_state_type_; mojom::WindowStateType current_state_type_;
// If true, do not update bounds. // If true, do not update bounds.
bool defer_bounds_updates_; bool defer_bounds_updates_ = false;
// If true, the animation type will be set to ZERO, which means the bounds
// will be updated at the end of the animation.
bool use_zero_animation_type_ = false;
// If true, the state will not process events. // If true, the state will not process events.
bool ignore_wm_events_ = false; bool ignore_wm_events_ = false;
......
...@@ -629,7 +629,8 @@ void WindowState::SetBoundsDirectAnimated(const gfx::Rect& bounds) { ...@@ -629,7 +629,8 @@ void WindowState::SetBoundsDirectAnimated(const gfx::Rect& bounds) {
SetBoundsDirect(bounds); SetBoundsDirect(bounds);
} }
void WindowState::SetBoundsDirectCrossFade(const gfx::Rect& new_bounds) { void WindowState::SetBoundsDirectCrossFade(const gfx::Rect& new_bounds,
gfx::Tween::Type animation_type) {
// Some test results in invoking CrossFadeToBounds when window is not visible. // Some test results in invoking CrossFadeToBounds when window is not visible.
// No animation is necessary in that case, thus just change the bounds and // No animation is necessary in that case, thus just change the bounds and
// quit. // quit.
...@@ -656,7 +657,7 @@ void WindowState::SetBoundsDirectCrossFade(const gfx::Rect& new_bounds) { ...@@ -656,7 +657,7 @@ void WindowState::SetBoundsDirectCrossFade(const gfx::Rect& new_bounds) {
// Resize the window to the new size, which will force a layout and paint. // Resize the window to the new size, which will force a layout and paint.
SetBoundsDirect(new_bounds); SetBoundsDirect(new_bounds);
CrossFadeAnimation(window_, std::move(old_layer_owner), gfx::Tween::EASE_OUT); CrossFadeAnimation(window_, std::move(old_layer_owner), animation_type);
} }
WindowState* GetActiveWindowState() { WindowState* GetActiveWindowState() {
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "base/optional.h" #include "base/optional.h"
#include "ui/aura/window_observer.h" #include "ui/aura/window_observer.h"
#include "ui/base/ui_base_types.h" #include "ui/base/ui_base_types.h"
#include "ui/gfx/animation/tween.h"
namespace gfx { namespace gfx {
class Rect; class Rect;
...@@ -394,7 +395,9 @@ class ASH_EXPORT WindowState : public aura::WindowObserver { ...@@ -394,7 +395,9 @@ class ASH_EXPORT WindowState : public aura::WindowObserver {
// Sets the window's |bounds| and transition to the new bounds with // Sets the window's |bounds| and transition to the new bounds with
// a cross fade animation. // a cross fade animation.
void SetBoundsDirectCrossFade(const gfx::Rect& bounds); void SetBoundsDirectCrossFade(
const gfx::Rect& bounds,
gfx::Tween::Type animation_type = gfx::Tween::EASE_OUT);
// aura::WindowObserver: // aura::WindowObserver:
void OnWindowPropertyChanged(aura::Window* window, void OnWindowPropertyChanged(aura::Window* window,
......
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