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

Do not do animation when entering overview because of window dragging.

If overview mode is opened behind the current dragged window, we should
not do the animation when entering overview.

Bug: 823769
Test: None
Change-Id: I1d89bcdc27ea784449698183e026aa63f1c2cf2c
Reviewed-on: https://chromium-review.googlesource.com/1157289
Commit-Queue: Xiaoqian Dai <xdai@chromium.org>
Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#579877}
parent 3543f253
......@@ -177,9 +177,11 @@ class NewSelectorItemView : public views::View {
};
// Creates |new_selector_item_widget_|. It's created when a window (not from
// overview) is dragged around and destroyed when the drag ends.
// overview) is dragged around and destroyed when the drag ends. If |animate|
// is true, do the opacity animation for the new selector item.
std::unique_ptr<views::Widget> CreateNewSelectorItemWidget(
aura::Window* dragged_window) {
aura::Window* dragged_window,
bool animate) {
views::Widget::InitParams params;
params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS;
params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
......@@ -197,14 +199,16 @@ std::unique_ptr<views::Widget> CreateNewSelectorItemWidget(
widget->SetContentsView(new NewSelectorItemView());
widget->Show();
widget->SetOpacity(0.f);
ui::ScopedLayerAnimationSettings animation_settings(
widget->GetNativeWindow()->layer()->GetAnimator());
animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
kNewSelectorItemTransitionMilliseconds));
animation_settings.SetTweenType(gfx::Tween::EASE_IN);
animation_settings.SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
if (animate) {
widget->SetOpacity(0.f);
ui::ScopedLayerAnimationSettings animation_settings(
widget->GetNativeWindow()->layer()->GetAnimator());
animation_settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
kNewSelectorItemTransitionMilliseconds));
animation_settings.SetTweenType(gfx::Tween::EASE_IN);
animation_settings.SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
}
widget->SetOpacity(1.f);
return widget;
}
......@@ -476,7 +480,7 @@ WindowSelectorItem* WindowGrid::GetWindowSelectorItemContaining(
return nullptr;
}
void WindowGrid::AddItem(aura::Window* window, bool reposition) {
void WindowGrid::AddItem(aura::Window* window, bool reposition, bool animate) {
DCHECK(!GetWindowSelectorItemContaining(window));
window_observer_.Add(window);
......@@ -486,7 +490,7 @@ void WindowGrid::AddItem(aura::Window* window, bool reposition) {
window_list_.back()->PrepareForOverview();
if (reposition)
PositionWindows(/*animate=*/true);
PositionWindows(animate);
}
void WindowGrid::RemoveItem(WindowSelectorItem* selector_item,
......@@ -577,12 +581,14 @@ void WindowGrid::OnSelectorItemDragEnded() {
window_selector_item->OnSelectorItemDragEnded();
}
void WindowGrid::OnWindowDragStarted(aura::Window* dragged_window) {
void WindowGrid::OnWindowDragStarted(aura::Window* dragged_window,
bool animate) {
DCHECK_EQ(dragged_window->GetRootWindow(), root_window_);
DCHECK(!new_selector_item_widget_);
new_selector_item_widget_ = CreateNewSelectorItemWidget(dragged_window);
new_selector_item_widget_ =
CreateNewSelectorItemWidget(dragged_window, animate);
window_selector_->AddItem(new_selector_item_widget_->GetNativeWindow(),
/*reposition=*/true);
/*reposition=*/true, animate);
// Stack the newly added window item below |dragged_window|.
DCHECK_EQ(dragged_window->parent(),
......@@ -664,8 +670,10 @@ void WindowGrid::OnWindowDragEnded(aura::Window* dragged_window,
// add it to overview without repositioning the grid. It will be done at the
// end of this function.
if (SelectedWindow()) {
if (IsNewSelectorItemWindow(SelectedWindow()->GetWindow()))
window_selector_->AddItem(dragged_window, /*reposition=*/false);
if (IsNewSelectorItemWindow(SelectedWindow()->GetWindow())) {
window_selector_->AddItem(dragged_window, /*reposition=*/false,
/*animate=*/false);
}
SelectedWindow()->set_selected(false);
selection_widget_.reset();
}
......
......@@ -92,8 +92,9 @@ class ASH_EXPORT WindowGrid : public aura::WindowObserver,
// Adds |window| to the grid. Intended to be used by split view. |window|
// cannot already be on the grid. If |reposition| is true, reposition all
// window items in the grid after adding the item.
void AddItem(aura::Window* window, bool reposition);
// window items in the grid after adding the item. If |animate| is true,
// reposition with animation.
void AddItem(aura::Window* window, bool reposition, bool animate);
// Removes |selector_item| from the grid. If |reprosition| is ture, reposition
// all window items in the grid after removing the item.
......@@ -131,7 +132,7 @@ class ASH_EXPORT WindowGrid : public aura::WindowObserver,
// Called when a window's tab(s) start/continue/end being dragged around in
// WindowGrid.
void OnWindowDragStarted(aura::Window* dragged_window);
void OnWindowDragStarted(aura::Window* dragged_window, bool animate);
void OnWindowDragContinued(aura::Window* dragged_window,
const gfx::Point& location_in_screen,
IndicatorState indicator_state);
......@@ -142,22 +143,6 @@ class ASH_EXPORT WindowGrid : public aura::WindowObserver,
// item.
bool IsNewSelectorItemWindow(aura::Window* window) const;
// Returns true if the grid has no more windows.
bool empty() const { return window_list_.empty(); }
// Returns how many window selector items are in the grid.
size_t size() const { return window_list_.size(); }
// Returns true if the selection widget is active.
bool is_selecting() const { return selection_widget_ != nullptr; }
// Returns the root window in which the grid displays the windows.
const aura::Window* root_window() const { return root_window_; }
const std::vector<std::unique_ptr<WindowSelectorItem>>& window_list() const {
return window_list_;
}
// aura::WindowObserver:
void OnWindowDestroying(aura::Window* window) override;
// TODO(flackr): Handle window bounds changed in WindowSelectorItem.
......@@ -174,22 +159,6 @@ class ASH_EXPORT WindowGrid : public aura::WindowObserver,
gfx::Rect GetNoItemsIndicatorLabelBoundsForTesting() const;
WindowSelector* window_selector() { return window_selector_; }
void set_window_animation_observer(
base::WeakPtr<OverviewWindowAnimationObserver> observer) {
window_animation_observer_ = observer;
}
base::WeakPtr<OverviewWindowAnimationObserver> window_animation_observer() {
return window_animation_observer_;
}
const gfx::Rect bounds() const { return bounds_; }
views::Widget* new_selector_item_widget_for_testing() {
return new_selector_item_widget_.get();
}
// Sets |should_animate_when_entering_| and |should_animate_when_exiting_|
// of the selector items of the windows based on where the first MRU window
// covering the available workspace is found. Also sets the
......@@ -221,6 +190,38 @@ class ASH_EXPORT WindowGrid : public aura::WindowObserver,
// Clears |nudge_data_|.
void EndNudge();
// Returns true if the grid has no more windows.
bool empty() const { return window_list_.empty(); }
// Returns how many window selector items are in the grid.
size_t size() const { return window_list_.size(); }
// Returns true if the selection widget is active.
bool is_selecting() const { return selection_widget_ != nullptr; }
// Returns the root window in which the grid displays the windows.
const aura::Window* root_window() const { return root_window_; }
const std::vector<std::unique_ptr<WindowSelectorItem>>& window_list() const {
return window_list_;
}
WindowSelector* window_selector() { return window_selector_; }
void set_window_animation_observer(
base::WeakPtr<OverviewWindowAnimationObserver> observer) {
window_animation_observer_ = observer;
}
base::WeakPtr<OverviewWindowAnimationObserver> window_animation_observer() {
return window_animation_observer_;
}
const gfx::Rect bounds() const { return bounds_; }
views::Widget* new_selector_item_widget_for_testing() {
return new_selector_item_widget_.get();
}
private:
class ShieldView;
friend class WindowSelectorTest;
......
......@@ -206,6 +206,20 @@ views::Widget* CreateTextFilter(views::TextfieldController* controller,
return widget;
}
// Gets the window that's currently being dragged in |root_window|. Returns
// nullptr if there is no such window.
aura::Window* GetDraggedWindow(
const aura::Window* root_window,
const std::vector<aura::Window*>& mru_window_list) {
for (auto* window : mru_window_list) {
if (wm::GetWindowState(window)->is_dragged() &&
window->GetRootWindow() == root_window) {
return window;
}
}
return nullptr;
}
} // namespace
// static
......@@ -286,15 +300,27 @@ void WindowSelector::Init(const WindowList& windows,
base::AutoReset<bool> auto_restoring_minimized_windows(
&restoring_minimized_windows_, true);
WindowList mru_window_list =
Shell::Get()->mru_window_tracker()->BuildMruWindowList();
// Do not call PrepareForOverview until all items are added to window_list_
// as we don't want to cause any window updates until all windows in
// overview are observed. See http://crbug.com/384495.
for (std::unique_ptr<WindowGrid>& window_grid : grid_list_) {
window_grid->SetWindowListAnimationStates(/*selected_item=*/nullptr,
OverviewTransition::kEnter);
window_grid->PrepareForOverview();
window_grid->PositionWindows(/*animate=*/true, /*ignore_item=*/nullptr,
OverviewTransition::kEnter);
// Check if there is any window that's being dragged in the grid. If so,
// do not do the animation when entering overview.
aura::Window* dragged_window =
GetDraggedWindow(window_grid->root_window(), mru_window_list);
if (dragged_window) {
window_grid->PositionWindows(/*animate=*/false);
} else {
window_grid->SetWindowListAnimationStates(/*selected_item=*/nullptr,
OverviewTransition::kEnter);
window_grid->PositionWindows(/*animate=*/true, /*ignore_item=*/nullptr,
OverviewTransition::kEnter);
}
}
// Image used for text filter textfield.
......@@ -519,13 +545,15 @@ WindowGrid* WindowSelector::GetGridWithRootWindow(aura::Window* root_window) {
return nullptr;
}
void WindowSelector::AddItem(aura::Window* window, bool reposition) {
void WindowSelector::AddItem(aura::Window* window,
bool reposition,
bool animate) {
// Early exit if a grid already contains |window|.
WindowGrid* grid = GetGridWithRootWindow(window->GetRootWindow());
if (!grid || grid->GetWindowSelectorItemContaining(window))
return;
grid->AddItem(window, reposition);
grid->AddItem(window, reposition, animate);
++num_items_;
// Transfer focus from |window| to the text widget, to match the behavior of
......@@ -605,12 +633,13 @@ void WindowSelector::ResetDraggedWindowGesture() {
window_drag_controller_->ResetGesture();
}
void WindowSelector::OnWindowDragStarted(aura::Window* dragged_window) {
void WindowSelector::OnWindowDragStarted(aura::Window* dragged_window,
bool animate) {
WindowGrid* target_grid =
GetGridWithRootWindow(dragged_window->GetRootWindow());
if (!target_grid)
return;
target_grid->OnWindowDragStarted(dragged_window);
target_grid->OnWindowDragStarted(dragged_window, animate);
}
void WindowSelector::OnWindowDragContinued(aura::Window* dragged_window,
......
......@@ -110,14 +110,15 @@ class ASH_EXPORT WindowSelector : public display::DisplayObserver,
// Add |window| to the grid in |grid_list_| with the same root window. Does
// nothing if the grid already contains |window|. And if |reposition| is true,
// re-position all windows in the target window grid. This may be called in
// two scenarioes: 1) when a item in split view mode was previously snapped
// but should now be returned to the window grid (e.g. split view divider
// dragged to either edge, or a window is snapped to a postion that already
// has a snapped window); 2) when a window (not from overview) is dragged
// while overview is open and the window is dropped on the new selector item,
// the dragged window is then added to the overview.
void AddItem(aura::Window* window, bool reposition);
// re-position all windows in the target window grid. If |animate| is true,
// re-position with animation. This function may be called in two scenarioes:
// 1) when a item in split view mode was previously snapped but should now be
// returned to the window grid (e.g. split view divider dragged to either
// edge, or a window is snapped to a postion that already has a snapped
// window); 2) when a window (not from overview) is dragged while overview is
// open and the window is dropped on the new selector item, the dragged window
// is then added to the overview.
void AddItem(aura::Window* window, bool reposition, bool animate);
// Removes the window selector item from the overview window grid. And if
// |reposition| is true, re-position all windows in the target window grid.
......@@ -144,7 +145,7 @@ class ASH_EXPORT WindowSelector : public display::DisplayObserver,
// Called when a window's tab(s) start/continue/end being dragged around if
// overview mode is active.
// TODO(xdai): Currently it doesn't work for multi-display scenario.
void OnWindowDragStarted(aura::Window* dragged_window);
void OnWindowDragStarted(aura::Window* dragged_window, bool animate);
void OnWindowDragContinued(aura::Window* dragged_window,
const gfx::Point& location_in_screen,
IndicatorState indicator_state);
......
......@@ -1414,7 +1414,7 @@ void SplitViewController::InsertWindowToOverview(aura::Window* window) {
if (!window || !Shell::Get()->window_selector_controller()->IsSelecting())
return;
Shell::Get()->window_selector_controller()->window_selector()->AddItem(
window, /*reposition=*/true);
window, /*reposition=*/true, /*animate=*/true);
}
void SplitViewController::StartOverview() {
......
......@@ -117,7 +117,8 @@ void TabletModeAppWindowDragController::EndWindowDrag(
if (event->type() == ui::ET_SCROLL_FLING_START &&
event->details().velocity_y() > kFlingToOverviewThreshold) {
Shell::Get()->window_selector_controller()->window_selector()->AddItem(
drag_delegate_->dragged_window(), /*reposition=*/true);
drag_delegate_->dragged_window(), /*reposition=*/true,
/*animate=*/true);
}
drag_delegate_->EndWindowDrag(result, location_in_screen);
}
......
......@@ -54,17 +54,24 @@ void TabletModeWindowDragDelegate::StartWindowDrag(
original_backdrop_mode_ = dragged_window_->GetProperty(kBackdropWindowMode);
dragged_window_->SetProperty(kBackdropWindowMode,
BackdropWindowMode::kDisabled);
WindowSelectorController* controller =
Shell::Get()->window_selector_controller();
bool was_overview_open = controller->IsSelecting();
// If the dragged window is one of the snapped windows, SplitViewController
// might open overview in the dragged window side of the screen.
split_view_controller_->OnWindowDragStarted(dragged_window_);
if (ShouldOpenOverviewWhenDragStarts()) {
WindowSelectorController* controller =
Shell::Get()->window_selector_controller();
if (!controller->IsSelecting())
controller->ToggleOverview();
}
if (ShouldOpenOverviewWhenDragStarts() && !controller->IsSelecting())
controller->ToggleOverview();
if (GetWindowSelector())
GetWindowSelector()->OnWindowDragStarted(dragged_window_);
if (controller->IsSelecting()) {
// Only do animation if overview was open before the drag started. If the
// overview is opened because of the window drag, do not do animation.
GetWindowSelector()->OnWindowDragStarted(dragged_window_,
/*animate=*/was_overview_open);
}
}
void TabletModeWindowDragDelegate::ContinueWindowDrag(
......
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