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 @@ ...@@ -4,6 +4,7 @@
#include "ash/system/message_center/ash_message_popup_collection.h" #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_config.h"
#include "ash/public/cpp/shelf_types.h" #include "ash/public/cpp/shelf_types.h"
#include "ash/public/cpp/shell_window_ids.h" #include "ash/public/cpp/shell_window_ids.h"
...@@ -37,6 +38,8 @@ AshMessagePopupCollection::~AshMessagePopupCollection() { ...@@ -37,6 +38,8 @@ AshMessagePopupCollection::~AshMessagePopupCollection() {
if (screen_) if (screen_)
screen_->RemoveObserver(this); screen_->RemoveObserver(this);
shelf_->RemoveObserver(this); shelf_->RemoveObserver(this);
for (views::Widget* widget : tracked_widgets_)
widget->RemoveObserver(this);
} }
void AshMessagePopupCollection::StartObserving( void AshMessagePopupCollection::StartObserving(
...@@ -115,6 +118,13 @@ void AshMessagePopupCollection::ConfigureWidgetInitParamsForContainer( ...@@ -115,6 +118,13 @@ void AshMessagePopupCollection::ConfigureWidgetInitParamsForContainer(
// On ash, popups go in the status container. // On ash, popups go in the status container.
init_params->parent = shelf_->GetWindow()->GetRootWindow()->GetChildById( init_params->parent = shelf_->GetWindow()->GetRootWindow()->GetChildById(
kShellWindowId_StatusContainer); 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 { bool AshMessagePopupCollection::IsPrimaryDisplayForNotification() const {
...@@ -159,4 +169,22 @@ void AshMessagePopupCollection::OnDisplayMetricsChanged( ...@@ -159,4 +169,22 @@ void AshMessagePopupCollection::OnDisplayMetricsChanged(
UpdateWorkArea(); 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 } // namespace ash
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "ui/display/display_observer.h" #include "ui/display/display_observer.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
#include "ui/message_center/views/message_popup_collection.h" #include "ui/message_center/views/message_popup_collection.h"
#include "ui/views/widget/widget_observer.h"
namespace display { namespace display {
class Screen; class Screen;
...@@ -30,7 +31,8 @@ class Shelf; ...@@ -30,7 +31,8 @@ class Shelf;
class ASH_EXPORT AshMessagePopupCollection class ASH_EXPORT AshMessagePopupCollection
: public message_center::MessagePopupCollection, : public message_center::MessagePopupCollection,
public ShelfObserver, public ShelfObserver,
public display::DisplayObserver { public display::DisplayObserver,
public views::WidgetObserver {
public: public:
explicit AshMessagePopupCollection(Shelf* shelf); explicit AshMessagePopupCollection(Shelf* shelf);
~AshMessagePopupCollection() override; ~AshMessagePopupCollection() override;
...@@ -42,7 +44,7 @@ class ASH_EXPORT AshMessagePopupCollection ...@@ -42,7 +44,7 @@ class ASH_EXPORT AshMessagePopupCollection
// bubble) so that notification toasts can avoid it. // bubble) so that notification toasts can avoid it.
void SetTrayBubbleHeight(int height); void SetTrayBubbleHeight(int height);
// Overridden from message_center::MessagePopupCollection: // message_center::MessagePopupCollection:
int GetToastOriginX(const gfx::Rect& toast_bounds) const override; int GetToastOriginX(const gfx::Rect& toast_bounds) const override;
int GetBaseline() const override; int GetBaseline() const override;
gfx::Rect GetWorkArea() const override; gfx::Rect GetWorkArea() const override;
...@@ -72,15 +74,21 @@ class ASH_EXPORT AshMessagePopupCollection ...@@ -72,15 +74,21 @@ class ASH_EXPORT AshMessagePopupCollection
// ShelfObserver: // ShelfObserver:
void OnShelfWorkAreaInsetsChanged() override; void OnShelfWorkAreaInsetsChanged() override;
// Overridden from display::DisplayObserver: // display::DisplayObserver:
void OnDisplayMetricsChanged(const display::Display& display, void OnDisplayMetricsChanged(const display::Display& display,
uint32_t metrics) override; uint32_t metrics) override;
// views::WidgetObserver:
void OnWidgetClosing(views::Widget* widget) override;
void OnWidgetActivationChanged(views::Widget* widget, bool active) override;
display::Screen* screen_; display::Screen* screen_;
gfx::Rect work_area_; gfx::Rect work_area_;
Shelf* shelf_; Shelf* shelf_;
int tray_bubble_height_; int tray_bubble_height_;
std::set<views::Widget*> tracked_widgets_;
DISALLOW_COPY_AND_ASSIGN(AshMessagePopupCollection); DISALLOW_COPY_AND_ASSIGN(AshMessagePopupCollection);
}; };
......
...@@ -192,6 +192,12 @@ void MessagePopupView::OnWorkAreaChanged() { ...@@ -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, void MessagePopupView::OnWidgetActivationChanged(views::Widget* widget,
bool active) { bool active) {
is_active_ = active; is_active_ = active;
......
...@@ -55,6 +55,7 @@ class MESSAGE_CENTER_EXPORT MessagePopupView : public views::WidgetDelegateView, ...@@ -55,6 +55,7 @@ class MESSAGE_CENTER_EXPORT MessagePopupView : public views::WidgetDelegateView,
const char* GetClassName() const override; const char* GetClassName() const override;
void OnDisplayChanged() override; void OnDisplayChanged() override;
void OnWorkAreaChanged() override; void OnWorkAreaChanged() override;
void OnFocus() override;
// views::WidgetObserver: // views::WidgetObserver:
void OnWidgetActivationChanged(views::Widget* widget, bool active) override; 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