Commit 6b7d5bc7 authored by Mitsuru Oshima's avatar Mitsuru Oshima Committed by Commit Bot

Overview optimizations

This is 2nd attempt to land: crrev.com/c/1304973
[2] are the difference from above CL.

*[2] Added null check in OnStartingAnimationComplete.
* Pause occusion tracker during overview animation
 [2] wait 5000ms when exiting overview before resume
       because a user may re-enter overview
 [2] wait 50ms when entering overview before resume
       because it can take 2 frame to finish draing the frame
       after animation observer is called.
* Activate the text filter after animation
* [2]Animate shelf after overview animation.
* [2] Improve blur animation:
 Use Compositor's AnimationObesrver to drive animation
 Progress only by 2 to reduce the frequency.
* Don't animate backdrop window during overview animation.
* Fix the bounds change issue in WindowGrid. It shouldn't change
the parent window's bounds.

  in both clamshell and tabletmode.
  The web contents should load after animations without backdrop animation.
  No gap at the bottom of the screen after exiting overview mode.

Bug: 898077, 897387
Test: no functional change. Manually tested visual change by entering/exiting overview mode
Change-Id: I0e606af2ad2f8871108e17e6147e51d0b68b5ee6
Reviewed-on: https://chromium-review.googlesource.com/c/1316828Reviewed-by: default avatarXiaoqian Dai <xdai@chromium.org>
Commit-Queue: Mitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605114}
parent 05d610bf
......@@ -487,12 +487,13 @@ void ShelfLayoutManager::OnAppListVisibilityChanged(bool shown,
MaybeUpdateShelfBackground(AnimationChangeType::IMMEDIATE);
}
void ShelfLayoutManager::OnOverviewModeStarting() {
void ShelfLayoutManager::OnOverviewModeStartingAnimationComplete(
bool canceled) {
UpdateVisibilityState();
MaybeUpdateShelfBackground(AnimationChangeType::ANIMATE);
}
void ShelfLayoutManager::OnOverviewModeEnded() {
void ShelfLayoutManager::OnOverviewModeEndingAnimationComplete(bool canceled) {
UpdateVisibilityState();
MaybeUpdateShelfBackground(AnimationChangeType::ANIMATE);
}
......
......@@ -164,8 +164,8 @@ class ASH_EXPORT ShelfLayoutManager
void OnPinnedStateChanged(aura::Window* pinned_window) override;
void OnAppListVisibilityChanged(bool shown,
aura::Window* root_window) override;
void OnOverviewModeStarting() override;
void OnOverviewModeEnded() override;
void OnOverviewModeStartingAnimationComplete(bool canceled) override;
void OnOverviewModeEndingAnimationComplete(bool canceled) override;
void OnSplitViewModeStarted() override;
void OnSplitViewModeEnded() override;
......
......@@ -13,6 +13,7 @@
#include "ash/shell.h"
#include "ash/wm/overview/cleanup_animation_observer.h"
#include "ash/wm/overview/scoped_overview_animation_settings.h"
#include "ash/wm/overview/start_animation_observer.h"
#include "ash/wm/overview/window_selector_controller.h"
#include "ash/wm/splitview/split_view_controller.h"
#include "ash/wm/window_state.h"
......@@ -139,8 +140,14 @@ void FadeInWidgetAndMaybeSlideOnEnter(views::Widget* widget,
ScopedOverviewAnimationSettings scoped_overview_animation_settings(
animation_type, window);
window->layer()->SetOpacity(1.0f);
if (slide)
if (slide) {
window->SetTransform(original_transform);
auto start_observer = std::make_unique<StartAnimationObserver>();
scoped_overview_animation_settings.AddObserver(start_observer.get());
Shell::Get()->window_selector_controller()->AddStartAnimationObserver(
std::move(start_observer));
}
}
void FadeOutWidgetAndMaybeSlideOnExit(std::unique_ptr<views::Widget> widget,
......
......@@ -509,6 +509,9 @@ void WindowGrid::RemoveItem(WindowSelectorItem* selector_item,
window_observer_.Remove(selector_item->GetWindow());
window_state_observer_.Remove(
wm::GetWindowState(selector_item->GetWindow()));
// Erase from the list first because deleting WindowSelectorItem can
// lead to iterating through the |window_list_|.
std::unique_ptr<WindowSelectorItem> tmp = std::move(*iter);
window_list_.erase(iter);
}
......@@ -734,7 +737,11 @@ void WindowGrid::OnWindowDestroying(aura::Window* window) {
const bool needs_repositioning = !((*iter)->animating_to_close());
size_t removed_index = iter - window_list_.begin();
// Erase from the list first because deleting WindowSelectorItem can
// lead to iterating through the |window_list_|.
std::unique_ptr<WindowSelectorItem> tmp = std::move(*iter);
window_list_.erase(iter);
tmp.reset();
if (empty()) {
selection_widget_.reset();
......@@ -1101,7 +1108,6 @@ void WindowGrid::InitShieldWidget() {
aura::Window* parent_window = widget_window->parent();
const gfx::Rect bounds = ash::screen_util::SnapBoundsToDisplayEdge(
parent_window->bounds(), parent_window);
parent_window->SetBounds(bounds);
widget_window->SetBounds(bounds);
widget_window->SetName("OverviewModeShield");
......
......@@ -50,6 +50,7 @@
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/wm/core/coordinate_conversion.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/public/activation_client.h"
......@@ -104,6 +105,27 @@ struct WindowSelectorItemForRoot {
const aura::Window* root_window;
};
// A WidgetDelegate to specify the initialy focused view.
class TextFilterWidgetDelegate : public views::WidgetDelegate {
public:
TextFilterWidgetDelegate(views::Widget* widget, views::View* initial_focus)
: widget_(widget), initial_focus_(initial_focus) {}
~TextFilterWidgetDelegate() override = default;
// WidgetDelegate:
void DeleteDelegate() override { delete this; }
views::Widget* GetWidget() override { return widget_; }
const views::Widget* GetWidget() const override { return widget_; }
bool ShouldAdvanceFocusToTopLevelWidget() const override { return true; }
views::View* GetInitiallyFocusedView() override { return initial_focus_; }
private:
views::Widget* widget_;
views::View* initial_focus_;
DISALLOW_COPY_AND_ASSIGN(TextFilterWidgetDelegate);
};
// Triggers a shelf visibility update on all root window controllers.
void UpdateShelfVisibility() {
for (aura::Window* root : Shell::GetAllRootWindows())
......@@ -196,6 +218,9 @@ views::Widget* CreateTextFilter(views::TextfieldController* controller,
params.name = "OverviewModeTextFilter";
*text_filter_bottom = params.bounds.bottom() + kTextFieldBottomMargin;
params.parent = root_window->GetChildById(kShellWindowId_StatusContainer);
views::Textfield* textfield = new views::Textfield();
params.delegate = new TextFilterWidgetDelegate(widget, textfield);
widget->Init(params);
// Use |container| to specify the padding surrounding the text and to give
......@@ -215,7 +240,6 @@ views::Widget* CreateTextFilter(views::TextfieldController* controller,
vertical_padding, kTextFilterCornerRadius),
kTextFilterHorizontalPadding));
views::Textfield* textfield = new views::Textfield();
textfield->set_controller(controller);
textfield->SetBorder(views::NullBorder());
textfield->SetBackgroundColor(kTextFilterBackgroundColor);
......@@ -239,8 +263,6 @@ views::Widget* CreateTextFilter(views::TextfieldController* controller,
aura::Window* text_filter_widget_window = widget->GetNativeWindow();
text_filter_widget_window->layer()->SetOpacity(0);
text_filter_widget_window->SetTransform(transform);
widget->Show();
textfield->RequestFocus();
return widget;
}
......@@ -722,6 +744,14 @@ void WindowSelector::UpdateMaskAndShadow(bool show) {
}
}
void WindowSelector::OnStartingAnimationComplete(bool canceled) {
if (!canceled) {
UpdateMaskAndShadow(!canceled);
if (text_filter_widget_)
text_filter_widget_->Show();
}
}
void WindowSelector::OnDisplayRemoved(const display::Display& display) {
// TODO(flackr): Keep window selection active on remaining displays.
CancelSelection();
......
......@@ -217,6 +217,9 @@ class ASH_EXPORT WindowSelector : public display::DisplayObserver,
// Shows or hides all the window selector items' mask and shadow.
void UpdateMaskAndShadow(bool show);
// Called when the overview mode starting animation completes.
void OnStartingAnimationComplete(bool canceled);
WindowSelectorDelegate* delegate() { return delegate_; }
SplitViewDragIndicators* split_view_drag_indicators() {
......
......@@ -12,7 +12,9 @@
#include "ash/wm/overview/window_selector.h"
#include "ash/wm/overview/window_selector_delegate.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "ui/aura/window_occlusion_tracker.h"
namespace ash {
class WindowSelector;
......@@ -97,6 +99,10 @@ class ASH_EXPORT WindowSelectorController : public WindowSelectorDelegate {
// Dispatched when window selection begins.
void OnSelectionStarted();
void OnStartingAnimationComplete(bool canceled);
void OnEndingAnimationComplete(bool canceled);
void ResetPauser();
// Collection of DelayedAnimationObserver objects that own widgets that may be
// still animating after overview mode ends. If shell needs to shut down while
// those animations are in progress, the animations are shut down and the
......@@ -106,6 +112,9 @@ class ASH_EXPORT WindowSelectorController : public WindowSelectorDelegate {
// notify shell that the starting animations have been completed.
std::vector<std::unique_ptr<DelayedAnimationObserver>> start_animations_;
std::unique_ptr<aura::WindowOcclusionTracker::ScopedPause>
occlusion_tracker_pauser_;
std::unique_ptr<WindowSelector> window_selector_;
base::Time last_selection_time_;
......@@ -116,6 +125,10 @@ class ASH_EXPORT WindowSelectorController : public WindowSelectorDelegate {
// Animates the blurring if necessary.
std::unique_ptr<OverviewBlurController> overview_blur_controller_;
base::CancelableOnceClosure reset_pauser_task_;
base::WeakPtrFactory<WindowSelectorController> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(WindowSelectorController);
};
......
......@@ -586,7 +586,6 @@ void WindowSelectorItem::SlideWindowIn() {
// called if we see the home launcher on enter (all windows are minimized).
DCHECK(item_widget_);
DCHECK(transform_window_.minimized_widget());
FadeInWidgetAndMaybeSlideOnEnter(item_widget_.get(),
OVERVIEW_ANIMATION_ENTER_FROM_HOME_LAUNCHER,
/*slide=*/true);
......@@ -1177,7 +1176,6 @@ void WindowSelectorItem::CreateWindowLabel(const base::string16& title) {
caption_container_view_ = new CaptionContainerView(
this, image_view, label_view_, cannot_snap_label_view_, close_button_);
UpdateCannotSnapWarningVisibility();
item_widget_->SetContentsView(caption_container_view_);
item_widget_->Show();
item_widget_->SetOpacity(0);
......
......@@ -15,9 +15,11 @@
#include "ash/public/cpp/app_types.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/screen_util.h"
#include "ash/shell.h"
#include "ash/wallpaper/wallpaper_controller.h"
#include "ash/wm/overview/window_selector_controller.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "ash/wm/workspace/backdrop_delegate.h"
#include "base/auto_reset.h"
......@@ -68,7 +70,7 @@ class BackdropEventHandler : public ui::EventHandler {
} // namespace
BackdropController::BackdropController(aura::Window* container)
: container_(container), in_restacking_(false) {
: container_(container) {
DCHECK(container_);
Shell::Get()->AddShellObserver(this);
Shell::Get()->accessibility_controller()->AddObserver(this);
......@@ -101,6 +103,10 @@ void BackdropController::OnWindowStackingChanged(aura::Window* window) {
UpdateBackdrop();
}
void BackdropController::OnDisplayMetricsChanged() {
UpdateBackdrop();
}
void BackdropController::OnPostWindowStateTypeChange(
wm::WindowState* window_state,
mojom::WindowStateType old_type) {
......@@ -117,8 +123,8 @@ void BackdropController::UpdateBackdrop() {
// No need to continue update for recursive calls or in overview mode.
WindowSelectorController* window_selector_controller =
Shell::Get()->window_selector_controller();
if (in_restacking_ || (window_selector_controller &&
window_selector_controller->IsSelecting())) {
if (pause_update_ || (window_selector_controller &&
window_selector_controller->IsSelecting())) {
return;
}
......@@ -129,12 +135,14 @@ void BackdropController::UpdateBackdrop() {
return;
}
// We are changing the order of windows which will cause recursion.
base::AutoReset<bool> lock(&in_restacking_, true);
base::AutoReset<bool> lock(&pause_update_, true);
EnsureBackdropWidget();
UpdateAccessibilityMode();
if (window == backdrop_window_ && backdrop_->IsVisible())
if (window == backdrop_window_ && backdrop_->IsVisible()) {
Layout();
return;
}
if (window->GetRootWindow() != backdrop_window_->GetRootWindow())
return;
......@@ -148,11 +156,20 @@ void BackdropController::UpdateBackdrop() {
}
void BackdropController::OnOverviewModeStarting() {
if (backdrop_window_)
backdrop_window_->SetProperty(aura::client::kAnimationsDisabledKey, true);
Hide();
}
void BackdropController::OnOverviewModeEnded() {
void BackdropController::OnOverviewModeEnding() {
pause_update_ = true;
}
void BackdropController::OnOverviewModeEndingAnimationComplete(bool canceled) {
pause_update_ = false;
UpdateBackdrop();
if (backdrop_window_)
backdrop_window_->ClearProperty(aura::client::kAnimationsDisabledKey);
}
void BackdropController::OnAppListVisibilityChanged(bool shown,
......@@ -209,6 +226,8 @@ void BackdropController::EnsureBackdropWidget() {
::wm::SetWindowVisibilityAnimationType(
backdrop_window_, ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
backdrop_window_->layer()->SetColor(SK_ColorBLACK);
wm::GetWindowState(backdrop_window_)->set_allow_set_bounds_direct(true);
}
void BackdropController::UpdateAccessibilityMode() {
......@@ -265,11 +284,7 @@ bool BackdropController::WindowShouldHaveBackdrop(aura::Window* window) {
}
void BackdropController::Show() {
// Makes sure that the backdrop has the correct bounds if it should not be
// fullscreen size.
backdrop_->SetFullscreen(BackdropShouldFullscreen());
if (!BackdropShouldFullscreen())
backdrop_->SetBounds(GetBackdropBounds());
Layout();
backdrop_->Show();
}
......@@ -315,4 +330,21 @@ gfx::Rect BackdropController::GetBackdropBounds() {
snapped_window, snap_position);
}
void BackdropController::Layout() {
// Makes sure that the backdrop has the correct bounds if it should not be
// fullscreen size.
backdrop_->SetFullscreen(BackdropShouldFullscreen());
if (backdrop_->IsFullscreen()) {
// TODO(oshima): The size of solid color layer can be smaller than texture's
// layer with fractional scale (crbug.com/9000220). Use adjusted bounds so
// that it can cover texture layer. Fix the bug and remove this.
auto* window = backdrop_window_;
gfx::Rect bounds = screen_util::GetDisplayBoundsInParent(window);
backdrop_window_->SetBounds(
screen_util::SnapBoundsToDisplayEdge(bounds, window));
} else {
backdrop_->SetBounds(GetBackdropBounds());
}
}
} // namespace ash
......@@ -57,6 +57,7 @@ class BackdropController : public ShellObserver,
void OnWindowStackingChanged(aura::Window* window);
void OnPostWindowStateTypeChange(wm::WindowState* window_state,
mojom::WindowStateType old_type);
void OnDisplayMetricsChanged();
void SetBackdropDelegate(std::unique_ptr<BackdropDelegate> delegate);
......@@ -68,7 +69,8 @@ class BackdropController : public ShellObserver,
// ShellObserver:
void OnOverviewModeStarting() override;
void OnOverviewModeEnded() override;
void OnOverviewModeEnding() override;
void OnOverviewModeEndingAnimationComplete(bool canceled) override;
void OnAppListVisibilityChanged(bool shown,
aura::Window* root_window) override;
void OnSplitViewModeStarting() override;
......@@ -92,6 +94,8 @@ class BackdropController : public ShellObserver,
void UpdateAccessibilityMode();
void Layout();
// Returns the current visible top level window in the container.
aura::Window* GetTopmostWindowWithBackdrop();
......@@ -130,8 +134,10 @@ class BackdropController : public ShellObserver,
std::unique_ptr<ui::EventHandler> backdrop_event_handler_;
ui::EventHandler* original_event_handler_ = nullptr;
// If true, the |RestackOrHideWindow| might recurse.
bool in_restacking_ = false;
// If true, skip updating background. Used to avoid recursive update
// when updating the window stack, or delay hiding the backdrop
// in overview mode.
bool pause_update_ = false;
DISALLOW_COPY_AND_ASSIGN(BackdropController);
};
......
......@@ -387,6 +387,7 @@ void WorkspaceLayoutManager::OnDisplayMetricsChanged(
const wm::WMEvent event(wm::WM_EVENT_WORKAREA_BOUNDS_CHANGED);
AdjustAllWindowsBoundsForWorkAreaChange(&event);
}
backdrop_controller_->OnDisplayMetricsChanged();
}
//////////////////////////////////////////////////////////////////////////////
......
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