Commit 42198a57 authored by Toni Barzic's avatar Toni Barzic Committed by Commit Bot

Update logic for calculating drag handle anchor bounds

Drag handle is used as an anchor for in-app to home contextual nudge,
and for login shelf swipe contextual nudge. By default, anchor bounds
are derived from the anchor's bounds in screen. This generally works,
but due to the way shelf widget (who owns the drag handled) bounds are
animated, relying on bounds in screen could end up misplacing the
contextual nudge widget when bounds change.

The shelf widget is animated by setting it's target bounds, and then
animating a transform that matches the current shelf position to the
identity transform. This means that when the widget bounds are set, the
widget might have non-identity transform. GetBoundsInScreen will take
that transform into account, and cause the nudge widget to be positioned
relative to the current widget position, instead of the target one.

This updates the logic for calculating drag handle anchor bounds to
ignore the shelf widget transforms. Additionally, it is changed to
ignore the drag handle's transform as well - the drag handle gets
translated using a transform when in-app to home  nudge is shown, but
the nudge bounds are set relative to the handle bounds with no
transform, and in addition have the identical transform set.

BUG=1058615

Change-Id: I1e398cf2e0d149c0bb9b2bea22651196a26b89fa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2091271
Commit-Queue: Toni Baržić <tbarzic@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#747823}
parent 221e6558
......@@ -16,6 +16,7 @@
#include "base/timer/timer.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/wm/core/coordinate_conversion.h"
namespace ash {
......@@ -145,6 +146,27 @@ void DragHandle::OnGestureEvent(ui::GestureEvent* event) {
}
}
gfx::Rect DragHandle::GetAnchorBoundsInScreen() const {
gfx::Rect anchor_bounds = ConvertRectToWidget(GetLocalBounds());
// Ignore any transform set on the drag handle - drag handle is used as an
// anchor for contextual nudges, and their bounds are set relative to the
// handle bounds without transform (for example, for in-app to home nudge both
// drag handle and the nudge will have non-indentity, identical transforms).
gfx::Point origin_in_screen = anchor_bounds.origin();
layer()->transform().TransformPointReverse(&origin_in_screen);
// If the parent widget has a transform set, it should be ignored as well (the
// transform is set during shelf widget animations, and will animate to
// identity transform), so the nudge bounds are set relative to the target
// shelf bounds.
aura::Window* const widget_window = GetWidget()->GetNativeWindow();
origin_in_screen += widget_window->bounds().origin().OffsetFromOrigin();
wm::ConvertPointToScreen(widget_window->parent(), &origin_in_screen);
anchor_bounds.set_origin(origin_in_screen);
return anchor_bounds;
}
void DragHandle::ShowDragHandleTooltip() {
DCHECK(!drag_handle_nudge_);
drag_handle_nudge_ = new ContextualNudge(
......
......@@ -43,6 +43,7 @@ class ASH_EXPORT DragHandle : public views::View,
// views::View:
void OnGestureEvent(ui::GestureEvent* event) override;
gfx::Rect GetAnchorBoundsInScreen() const override;
bool ShowingNudge() { return showing_nudge_; }
......@@ -58,6 +59,10 @@ class ASH_EXPORT DragHandle : public views::View,
return hide_drag_handle_nudge_timer_.IsRunning();
}
ContextualNudge* drag_handle_nudge_for_testing() {
return drag_handle_nudge_;
}
private:
// Animates tooltip for drag handle gesture.
void ShowDragHandleTooltip();
......
......@@ -220,4 +220,64 @@ TEST_F(DragHandleContextualNudgeTest, DragHandleNudgeShownOnTap) {
->has_hide_drag_handle_timer_for_testing());
}
// Tests that the drag handle nudge is horizontally centered in screen, and
// drawn above the shelf drag handle, even after display bounds are updated.
TEST_F(DragHandleContextualNudgeTest, DragHandleNudgeBoundsInScreen) {
UpdateDisplay("675x1200");
TabletModeControllerTestApi().EnterTabletMode();
views::Widget* widget = CreateTestWidget();
widget->Maximize();
ShelfWidget* const shelf_widget = GetShelfWidget();
DragHandle* const drag_handle = shelf_widget->GetDragHandle();
EXPECT_TRUE(drag_handle->GetVisible());
ASSERT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
drag_handle->fire_show_drag_handle_timer_for_testing();
EXPECT_TRUE(drag_handle->ShowingNudge());
// Calculates absolute difference between horizontal margins of |inner| rect
// within |outer| rect.
auto margin_diff = [](const gfx::Rect& inner, const gfx::Rect& outer) -> int {
const int left = inner.x() - outer.x();
EXPECT_GE(left, 0);
const int right = outer.right() - inner.right();
EXPECT_GE(right, 0);
return std::abs(left - right);
};
// Verify that nudge widget is centered in shelf.
gfx::Rect shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
gfx::Rect nudge_bounds = drag_handle->drag_handle_nudge_for_testing()
->label()
->GetBoundsInScreen();
EXPECT_LE(margin_diff(nudge_bounds, shelf_bounds), 1);
// Verify that the nudge vertical bounds - within the shelf bounds, and above
// the drag handle.
gfx::Rect drag_handle_bounds = drag_handle->GetBoundsInScreen();
EXPECT_LE(shelf_bounds.y(), nudge_bounds.y());
EXPECT_LE(nudge_bounds.bottom(), drag_handle_bounds.y());
// Change the display bounds, and verify the updated drag handle bounds.
UpdateDisplay("1200x675");
EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->ShowingNudge());
// Verify that nudge widget is centered in shelf.
shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
nudge_bounds = drag_handle->drag_handle_nudge_for_testing()
->label()
->GetBoundsInScreen();
EXPECT_LE(margin_diff(nudge_bounds, shelf_bounds), 1);
// Verify that the nudge vertical bounds - within the shelf bounds, and above
// the drag handle.
drag_handle_bounds = drag_handle->GetBoundsInScreen();
EXPECT_LE(shelf_bounds.y(), nudge_bounds.y());
EXPECT_LE(nudge_bounds.bottom(), drag_handle_bounds.y());
}
} // namespace ash
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