Commit db99b0a4 authored by Dana Fried's avatar Dana Fried Committed by Commit Bot

Reset toolbar icon animations when browser is restored.

See attached bug for specific cases addressed.

Needs testing on MacOS.

Bug: 1106506
Change-Id: I65cf6236d618b1cf8ada7b8b4ef07dbd7ed74e12
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2303775Reviewed-by: default avatarCaroline Rising <corising@chromium.org>
Commit-Queue: Dana Fried <dfried@chromium.org>
Cr-Commit-Position: refs/heads/master@{#789553}
parent 5b8f7ad1
......@@ -17,11 +17,56 @@
#include "ui/views/layout/animating_layout_manager.h"
#include "ui/views/layout/flex_layout.h"
#include "ui/views/view_class_properties.h"
#include "ui/views/view_observer.h"
// static
const char ToolbarIconContainerView::kToolbarIconContainerViewClassName[] =
"ToolbarIconContainerView";
// Watches for widget restore (or first show) and resets the animation so icons
// don't spuriously "animate in" when a window is shown or restored. See
// crbug.com/1106506 for more details.
//
// There is currently no signal that is consistent across platforms and
// accessible from the View hierarchy that can tell us if, e.g., a window has
// been restored from a minimized state. While we could theoretically plumb
// state changes through from NativeWidget, we can observe the specific set of
// cases we want by observing the size of the window.
//
// We *cannot* observe the size of the widget itself, as at least on Windows,
// minimizing a window does not set the widget to 0x0, but rather a small,
// Windows 3.1-esque tile (~160x28) and moves it to [-32000, -32000], so far off
// the screen it can't appear on any monitor.
//
// What we can observe is the widget's root view, which is (a) always present
// after the toolbar has been added to its widget and through its entire
// lifetime, and (b) is actually set to zero size when the window is zero size
// or minimized on Windows.
class ToolbarIconContainerView::WidgetRestoreObserver
: public views::ViewObserver {
public:
explicit WidgetRestoreObserver(
ToolbarIconContainerView* toolbar_icon_container_view)
: toolbar_icon_container_view_(toolbar_icon_container_view) {
scoped_observer_.Add(
toolbar_icon_container_view->GetWidget()->GetRootView());
}
void OnViewBoundsChanged(views::View* observed_view) override {
const bool is_collapsed = observed_view->bounds().IsEmpty();
if (is_collapsed != was_collapsed_) {
was_collapsed_ = is_collapsed;
if (!is_collapsed)
toolbar_icon_container_view_->animating_layout_manager()->ResetLayout();
}
}
private:
bool was_collapsed_ = true;
ToolbarIconContainerView* const toolbar_icon_container_view_;
ScopedObserver<views::View, views::ViewObserver> scoped_observer_{this};
};
ToolbarIconContainerView::ToolbarIconContainerView(bool uses_highlight)
: uses_highlight_(uses_highlight) {
views::AnimatingLayoutManager* animating_layout =
......@@ -128,6 +173,12 @@ const char* ToolbarIconContainerView::GetClassName() const {
return kToolbarIconContainerViewClassName;
}
void ToolbarIconContainerView::AddedToWidget() {
// Add an observer to reset the animation if the browser window is restored,
// preventing spurious animation. (See crbug.com/1106506)
restore_observer_ = std::make_unique<WidgetRestoreObserver>(this);
}
void ToolbarIconContainerView::AnimationProgressed(
const gfx::Animation* animation) {
SetHighlightBorder();
......
......@@ -74,12 +74,14 @@ class ToolbarIconContainerView : public views::View,
private:
friend class ToolbarAccountIconContainerViewBrowserTest;
class WidgetRestoreObserver;
// views::View:
void OnMouseEntered(const ui::MouseEvent& event) override;
void OnMouseExited(const ui::MouseEvent& event) override;
gfx::Insets GetInsets() const override;
const char* GetClassName() const override;
void AddedToWidget() override;
// gfx::AnimationDelegate:
void AnimationProgressed(const gfx::Animation* animation) override;
......@@ -108,6 +110,9 @@ class ToolbarIconContainerView : public views::View,
// Fade-in/out animation for the highlight border.
gfx::SlideAnimation highlight_animation_{this};
// Tracks when the widget is restored and resets the layout.
std::unique_ptr<WidgetRestoreObserver> restore_observer_;
base::ObserverList<Observer> observers_;
};
......
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