Commit 0bf44249 authored by Andrew Xu's avatar Andrew Xu Committed by Commit Bot

Animate status area widget when entering/exiting overview

Currently the bounds animation of status area widget is disabled if
the target bounds have the different size from the current bounds.
Based on https://crrev.com/c/2158911, it aims to disable the animation
when tray items are added/removed. However. we do have a scenario where
the status area widget's bounds change meanwhile it does not involve
the tray item's movement: when entering/exiting overview mode in tablet,
the status area widget's height changes.

In this CL, StatusAreaWidget::LayoutInputs has a new attribute to
indicate whether animation is allowed. The animation is banned if the
status area widget's length on the main axis (that is the width for
horizontal shelf or the height for vertical shelf) changes.

Bug: 1079347
Change-Id: I9190168b40af6e88bf774e1f98c7a0de0467be7e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2227099
Commit-Queue: Andrew Xu <andrewxu@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarTim Song <tengs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#775800}
parent 8bd3b460
......@@ -995,6 +995,37 @@ TEST_P(HotseatWidgetTest, HomeToOverviewChangesStateOnce) {
}
}
// Verifies that the hotseat widget and the status area widget are animated to
// the target location when entering overview mode in home launcher
// (https://crbug.com/1079347).
TEST_P(HotseatWidgetTest, VerifyShelfAnimationWhenEnteringOverview) {
GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
TabletModeControllerTestApi().EnterTabletMode();
ui::ScopedAnimationDurationScaleMode non_zero_duration_mode(
ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
HotseatWidget* hotseat_widget = GetPrimaryShelf()->hotseat_widget();
ASSERT_EQ(HotseatState::kShownHomeLauncher, hotseat_widget->state());
ui::LayerAnimator* hotseat_layer_animator =
hotseat_widget->GetNativeView()->layer()->GetAnimator();
ui::LayerAnimator* status_area_layer_animator = GetShelfWidget()
->status_area_widget()
->GetNativeView()
->layer()
->GetAnimator();
ASSERT_FALSE(hotseat_layer_animator->is_animating());
ASSERT_FALSE(status_area_layer_animator->is_animating());
OverviewAnimationWaiter waiter;
StartOverview();
EXPECT_TRUE(hotseat_layer_animator->is_animating());
EXPECT_TRUE(status_area_layer_animator->is_animating());
waiter.Wait();
ASSERT_EQ(HotseatState::kExtended, hotseat_widget->state());
}
// Tests that home -> in-app results in only one state change.
TEST_P(HotseatWidgetTest, HomeToInAppChangesStateOnce) {
GetPrimaryShelf()->SetAutoHideBehavior(shelf_auto_hide_behavior());
......
......@@ -211,10 +211,7 @@ void StatusAreaWidget::UpdateLayout(bool animate) {
if (layout_inputs_ == new_layout_inputs)
return;
// Do not animate size changes, as they only really occur when tray items are
// added and removed. See crbug.com/1067199.
if (layout_inputs_ &&
layout_inputs_->bounds.size() != new_layout_inputs.bounds.size())
if (!new_layout_inputs.should_animate)
animate = false;
for (TrayBackgroundView* tray_button : tray_buttons_)
......@@ -467,9 +464,25 @@ StatusAreaWidget::LayoutInputs StatusAreaWidget::GetLayoutInputs() const {
if (tray_buttons_[i]->GetVisible())
child_visibility_bitmask |= 1 << i;
}
bool should_animate = true;
// Do not animate when tray items are added and removed (See
// crbug.com/1067199).
if (layout_inputs_) {
const bool is_horizontal_alignment = shelf_->IsHorizontalAlignment();
const gfx::Rect current_bounds = layout_inputs_->bounds;
if ((is_horizontal_alignment &&
current_bounds.width() != target_bounds_.width()) ||
(!is_horizontal_alignment &&
current_bounds.height() != target_bounds_.height())) {
should_animate = false;
}
}
return {target_bounds_, CalculateCollapseState(),
shelf_->shelf_layout_manager()->GetOpacity(),
child_visibility_bitmask};
child_visibility_bitmask, should_animate};
}
} // namespace ash
......@@ -156,6 +156,12 @@ class ASH_EXPORT StatusAreaWidget : public SessionObserver,
// Each bit keep track of one child's visibility.
unsigned int child_visibility_bitmask = 0;
// Indicates whether animation is allowed.
bool should_animate = true;
// |should_animate| does not affect the status area widget's target
// layout. So it is not taken into consideration when comparing LayoutInputs
// instances.
bool operator==(const LayoutInputs& other) const {
return bounds == other.bounds && collapse_state == other.collapse_state &&
opacity == other.opacity &&
......
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