Commit b0be4dc6 authored by Tim Song's avatar Tim Song Committed by Commit Bot

Ash Tray: Make notification pop-ups focusable through ctrl + forward/back.

Each pop-up is contained in its own Widget, which we need to add to ash's
FocusCycler.

TEST=manually verified
BUG=1007027

Change-Id: I330465bc4a63c5ac26951b8bebfb2ee7f2700327
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1832669
Commit-Queue: Tim Song <tengs@chromium.org>
Reviewed-by: default avatarAhmed Mehfooz <amehfooz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#704060}
parent 39c765b9
......@@ -4,6 +4,7 @@
#include "ash/system/message_center/ash_message_popup_collection.h"
#include "ash/focus_cycler.h"
#include "ash/public/cpp/shelf_config.h"
#include "ash/public/cpp/shelf_types.h"
#include "ash/public/cpp/shell_window_ids.h"
......@@ -37,6 +38,8 @@ AshMessagePopupCollection::~AshMessagePopupCollection() {
if (screen_)
screen_->RemoveObserver(this);
shelf_->RemoveObserver(this);
for (views::Widget* widget : tracked_widgets_)
widget->RemoveObserver(this);
}
void AshMessagePopupCollection::StartObserving(
......@@ -115,6 +118,13 @@ void AshMessagePopupCollection::ConfigureWidgetInitParamsForContainer(
// On ash, popups go in the status container.
init_params->parent = shelf_->GetWindow()->GetRootWindow()->GetChildById(
kShellWindowId_StatusContainer);
// Make the widget activatable so it can receive focus when cycling through
// windows (i.e. pressing ctrl + forward/back).
init_params->activatable = views::Widget::InitParams::ACTIVATABLE_YES;
Shell::Get()->focus_cycler()->AddWidget(widget);
widget->AddObserver(this);
tracked_widgets_.insert(widget);
}
bool AshMessagePopupCollection::IsPrimaryDisplayForNotification() const {
......@@ -159,4 +169,22 @@ void AshMessagePopupCollection::OnDisplayMetricsChanged(
UpdateWorkArea();
}
///////////////////////////////////////////////////////////////////////////////
// views::WidgetObserver:
void AshMessagePopupCollection::OnWidgetClosing(views::Widget* widget) {
Shell::Get()->focus_cycler()->RemoveWidget(widget);
widget->RemoveObserver(this);
tracked_widgets_.erase(widget);
}
void AshMessagePopupCollection::OnWidgetActivationChanged(views::Widget* widget,
bool active) {
// Note: Each pop-up is contained in it's own widget and we need to manually
// focus the contained MessageView when the widget is activated through the
// FocusCycler.
if (active && Shell::Get()->focus_cycler()->widget_activating() == widget)
widget->GetFocusManager()->SetFocusedView(widget->GetContentsView());
}
} // namespace ash
......@@ -15,6 +15,7 @@
#include "ui/display/display_observer.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/message_center/views/message_popup_collection.h"
#include "ui/views/widget/widget_observer.h"
namespace display {
class Screen;
......@@ -30,7 +31,8 @@ class Shelf;
class ASH_EXPORT AshMessagePopupCollection
: public message_center::MessagePopupCollection,
public ShelfObserver,
public display::DisplayObserver {
public display::DisplayObserver,
public views::WidgetObserver {
public:
explicit AshMessagePopupCollection(Shelf* shelf);
~AshMessagePopupCollection() override;
......@@ -42,7 +44,7 @@ class ASH_EXPORT AshMessagePopupCollection
// bubble) so that notification toasts can avoid it.
void SetTrayBubbleHeight(int height);
// Overridden from message_center::MessagePopupCollection:
// message_center::MessagePopupCollection:
int GetToastOriginX(const gfx::Rect& toast_bounds) const override;
int GetBaseline() const override;
gfx::Rect GetWorkArea() const override;
......@@ -72,15 +74,21 @@ class ASH_EXPORT AshMessagePopupCollection
// ShelfObserver:
void OnShelfWorkAreaInsetsChanged() override;
// Overridden from display::DisplayObserver:
// display::DisplayObserver:
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t metrics) override;
// views::WidgetObserver:
void OnWidgetClosing(views::Widget* widget) override;
void OnWidgetActivationChanged(views::Widget* widget, bool active) override;
display::Screen* screen_;
gfx::Rect work_area_;
Shelf* shelf_;
int tray_bubble_height_;
std::set<views::Widget*> tracked_widgets_;
DISALLOW_COPY_AND_ASSIGN(AshMessagePopupCollection);
};
......
......@@ -192,6 +192,12 @@ void MessagePopupView::OnWorkAreaChanged() {
}
}
void MessagePopupView::OnFocus() {
// This view is just a container, so advance focus to the underlying
// MessageView.
GetFocusManager()->SetFocusedView(message_view_);
}
void MessagePopupView::OnWidgetActivationChanged(views::Widget* widget,
bool active) {
is_active_ = active;
......
......@@ -55,6 +55,7 @@ class MESSAGE_CENTER_EXPORT MessagePopupView : public views::WidgetDelegateView,
const char* GetClassName() const override;
void OnDisplayChanged() override;
void OnWorkAreaChanged() override;
void OnFocus() override;
// views::WidgetObserver:
void OnWidgetActivationChanged(views::Widget* widget, bool active) override;
......
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