Commit ad7e5862 authored by Tatsuhisa Yamaguchi's avatar Tatsuhisa Yamaguchi Committed by Commit Bot

Unified: Anchor system tray bubble to the shelf rect.

The design spec states tray bubble should be anchored to:
- right-bottom (when the shelf is positioned to the bottom or right)
- or left-bottom (when the shelf is positioned to the left)
corner of the workspace.

The bubble went to wrong positions when changing the device mode
between tablet and laptop, or rotating the screen, while the system
tray bubble is opened. This change is a fix for it.


Bug: 864939, 812536
Change-Id: I1392a2d96c72e06c4e8e159f22901720da72747a
Reviewed-on: https://chromium-review.googlesource.com/1246082
Commit-Queue: Tatsuhisa Yamaguchi <yamaguchi@chromium.org>
Reviewed-by: default avatarYoshiki Iguchi <yoshiki@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594630}
parent ca393e72
......@@ -209,7 +209,7 @@ int Shelf::GetDockedMagnifierHeight() const {
: 0;
}
gfx::Rect Shelf::GetIdealBounds() {
gfx::Rect Shelf::GetIdealBounds() const {
return shelf_layout_manager_->GetIdealBounds();
}
......@@ -298,6 +298,21 @@ TrayBackgroundView* Shelf::GetSystemTrayAnchor() const {
return GetStatusAreaWidget()->GetSystemTrayAnchor();
}
gfx::Rect Shelf::GetSystemTrayAnchorRect() const {
gfx::Rect shelf_bounds = GetIdealBounds();
switch (alignment_) {
case SHELF_ALIGNMENT_BOTTOM:
case SHELF_ALIGNMENT_BOTTOM_LOCKED:
return gfx::Rect(shelf_bounds.right(), shelf_bounds.y(), 0, 0);
case SHELF_ALIGNMENT_LEFT:
return gfx::Rect(shelf_bounds.right(), shelf_bounds.bottom(), 0, 0);
case SHELF_ALIGNMENT_RIGHT:
return gfx::Rect(shelf_bounds.x(), shelf_bounds.bottom(), 0, 0);
}
NOTREACHED();
return gfx::Rect();
}
bool Shelf::ShouldHideOnSecondaryDisplay(session_manager::SessionState state) {
if (Shell::GetPrimaryRootWindowController()->shelf() == this)
return false;
......
......@@ -102,7 +102,7 @@ class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver {
int GetDockedMagnifierHeight() const;
// Returns the ideal bounds of the shelf assuming it is visible.
gfx::Rect GetIdealBounds();
gfx::Rect GetIdealBounds() const;
gfx::Rect GetUserWorkAreaBounds() const;
......@@ -140,6 +140,12 @@ class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver {
// bubble will be anchored. See also: StatusAreaWidget::GetSystemTrayAnchor()
TrayBackgroundView* GetSystemTrayAnchor() const;
// Get the anchor rect that the system tray bubble and the notification center
// bubble will be anchored.
// x() and y() designates anchor point, but width() and height() are dummy.
// See also: BubbleDialogDelegateView::GetBubbleBounds()
gfx::Rect GetSystemTrayAnchorRect() const;
void set_is_tablet_mode_animation_running(bool value) {
is_tablet_mode_animation_running_ = value;
}
......
......@@ -210,7 +210,7 @@ bool ShelfLayoutManager::IsVisible() const {
state_.auto_hide_state == SHELF_AUTO_HIDE_SHOWN));
}
gfx::Rect ShelfLayoutManager::GetIdealBounds() {
gfx::Rect ShelfLayoutManager::GetIdealBounds() const {
const int shelf_size = ShelfConstants::shelf_size();
aura::Window* shelf_window = shelf_widget_->GetNativeWindow();
gfx::Rect rect(screen_util::GetDisplayBoundsInParent(shelf_window));
......
......@@ -80,7 +80,7 @@ class ASH_EXPORT ShelfLayoutManager
bool IsVisible() const;
// Returns the ideal bounds of the shelf assuming it is visible.
gfx::Rect GetIdealBounds();
gfx::Rect GetIdealBounds() const;
// Returns the preferred size of the shelf for the target visibility state.
gfx::Size GetPreferredSize();
......
......@@ -231,6 +231,11 @@ TrayBubbleView::TrayBubbleView(const InitParams& init_params)
auto layout = std::make_unique<BottomAlignedBoxLayout>(this);
layout->SetDefaultFlex(1);
layout_ = SetLayoutManager(std::move(layout));
if (init_params.anchor_mode == AnchorMode::kRect) {
SetAnchorView(nullptr);
SetAnchorRect(init_params.anchor_rect);
}
}
TrayBubbleView::~TrayBubbleView() {
......@@ -306,9 +311,20 @@ void TrayBubbleView::ResetDelegate() {
}
void TrayBubbleView::ChangeAnchorView(views::View* anchor_view) {
DCHECK(params_.anchor_mode == AnchorMode::kView);
BubbleDialogDelegateView::SetAnchorView(anchor_view);
}
void TrayBubbleView::ChangeAnchorRect(const gfx::Rect& rect) {
DCHECK(params_.anchor_mode == AnchorMode::kRect);
BubbleDialogDelegateView::SetAnchorRect(rect);
}
void TrayBubbleView::ChangeAnchorAlignment(
TrayBubbleView::AnchorAlignment alignment) {
SetArrow(GetArrowAlignment(alignment));
}
int TrayBubbleView::GetDialogButtons() const {
return ui::DIALOG_BUTTON_NONE;
}
......
......@@ -12,6 +12,7 @@
#include "base/optional.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/events/event.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/bubble/bubble_dialog_delegate_view.h"
#include "ui/views/mouse_watcher.h"
......@@ -85,12 +86,23 @@ class ASH_EXPORT TrayBubbleView : public views::BubbleDialogDelegateView,
DISALLOW_COPY_AND_ASSIGN(Delegate);
};
// Anchor mode being set at creation.
enum class AnchorMode {
// Anchor to |anchor_view|. This is the default.
kView,
// Anchor to |anchor_rect|. Used for anchoring to the shelf.
kRect
};
struct ASH_EXPORT InitParams {
InitParams();
InitParams(const InitParams& other);
Delegate* delegate = nullptr;
gfx::NativeWindow parent_window = nullptr;
View* anchor_view = nullptr;
AnchorMode anchor_mode = AnchorMode::kView;
// Only used if anchor_mode == AnchorMode::kRect.
gfx::Rect anchor_rect;
AnchorAlignment anchor_alignment = ANCHOR_ALIGNMENT_BOTTOM;
int min_width = 0;
int max_width = 0;
......@@ -135,8 +147,16 @@ class ASH_EXPORT TrayBubbleView : public views::BubbleDialogDelegateView,
void ResetDelegate();
// Anchors the bubble to |anchor_view|.
// Only eligible if anchor_mode == AnchorMode::kView.
void ChangeAnchorView(views::View* anchor_view);
// Anchors the bubble to |anchor_rect|. Exclusive with ChangeAnchorView().
// Only eligible if anchor_mode == AnchorMode::kRect.
void ChangeAnchorRect(const gfx::Rect& anchor_rect);
// Change anchor alignment mode when anchoring either the rect or view.
void ChangeAnchorAlignment(AnchorAlignment alignment);
Delegate* delegate() { return delegate_; }
void set_gesture_dragging(bool dragging) { is_gesture_dragging_ = dragging; }
......
......@@ -76,6 +76,8 @@ UnifiedSystemTrayBubble::UnifiedSystemTrayBubble(UnifiedSystemTray* tray,
init_params.parent_window = tray->GetBubbleWindowContainer();
init_params.anchor_view =
tray->shelf()->GetSystemTrayAnchor()->GetBubbleAnchor();
init_params.anchor_mode = TrayBubbleView::AnchorMode::kRect;
init_params.anchor_rect = tray->shelf()->GetSystemTrayAnchorRect();
init_params.corner_radius = kUnifiedTrayCornerRadius;
init_params.has_shadow = false;
init_params.show_by_click = show_by_click;
......@@ -294,22 +296,8 @@ void UnifiedSystemTrayBubble::UpdateBubbleBounds() {
int max_height = CalculateMaxHeight();
unified_view_->SetMaxHeight(max_height);
bubble_view_->SetMaxHeight(max_height);
// If the bubble is open while switching to and from tablet mode, change the
// bubble anchor if needed. The new anchor view may also have a translation
// applied to it so shift the bubble bounds so that it appears in the correct
// location.
bubble_view_->ChangeAnchorView(
tray_->shelf()->GetSystemTrayAnchor()->GetBubbleAnchor());
gfx::Rect bounds =
bubble_view_->GetWidget()->GetNativeWindow()->GetBoundsInScreen();
const gfx::Vector2dF translation = tray_->shelf()
->GetSystemTrayAnchor()
->layer()
->transform()
.To2dTranslation();
bounds.set_x(bounds.x() - translation.x());
bounds.set_y(bounds.y() - translation.y());
bubble_view_->GetWidget()->GetNativeWindow()->SetBounds(bounds);
bubble_view_->ChangeAnchorAlignment(tray_->GetAnchorAlignment());
bubble_view_->ChangeAnchorRect(tray_->shelf()->GetSystemTrayAnchorRect());
}
void UnifiedSystemTrayBubble::CreateBlurLayerForAnimation() {
......
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