Commit e39ba92c authored by Jacobo Aragunde Pérez's avatar Jacobo Aragunde Pérez Committed by Commit Bot

Change accounts & sync role to be a menu.

The accounts & sync dialog UI is a better fit for the menu accessible
role instead of a dialog, because it contains a list of actionable
buttons instead of a message and a few buttons. What's more, it is
already built using a menu container.

For the dialog to behave like a menu, we need to override the top-level
dialog to become a menu bar, and emit the corresponding events for open
and close to make it discoverable.

Bug: 1098304
Change-Id: I93bb25dc9b790e1f8d0e2c61993d20f191c439c0
AX-relnotes: announce accounts & sync as a menu when opened.
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2494933
Commit-Queue: Jacobo Aragunde Pérez <jaragunde@igalia.com>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Reviewed-by: default avatarJan Krcal <jkrcal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#823244}
parent 31d457df
...@@ -485,7 +485,10 @@ void ProfileMenuViewBase::ShowBubble( ...@@ -485,7 +485,10 @@ void ProfileMenuViewBase::ShowBubble(
bubble = new ProfileMenuView(anchor_button, browser); bubble = new ProfileMenuView(anchor_button, browser);
} }
views::BubbleDialogDelegateView::CreateBubble(bubble)->Show(); views::Widget* widget = views::BubbleDialogDelegateView::CreateBubble(bubble);
bubble->ax_widget_observer_ =
std::make_unique<AXMenuWidgetObserver>(bubble, widget);
widget->Show();
if (is_source_keyboard) if (is_source_keyboard)
bubble->FocusButtonOnKeyboardOpen(); bubble->FocusButtonOnKeyboardOpen();
} }
...@@ -987,11 +990,10 @@ void ProfileMenuViewBase::OnThemeChanged() { ...@@ -987,11 +990,10 @@ void ProfileMenuViewBase::OnThemeChanged() {
} }
ax::mojom::Role ProfileMenuViewBase::GetAccessibleWindowRole() { ax::mojom::Role ProfileMenuViewBase::GetAccessibleWindowRole() {
// Return |ax::mojom::Role::kDialog| which will make screen readers announce // Return |ax::mojom::Role::kMenuBar|, because it fits better the kind of UI
// the following in the listed order: // contained in this dialog. The top-level container in this dialog uses a
// the title of the dialog, labels (if any), the focused View within the // kMenu role to match.
// dialog (if any) return ax::mojom::Role::kMenuBar;
return ax::mojom::Role::kDialog;
} }
bool ProfileMenuViewBase::HandleContextMenu( bool ProfileMenuViewBase::HandleContextMenu(
...@@ -1028,3 +1030,31 @@ void ProfileMenuViewBase::UpdateSyncInfoContainerBackground() { ...@@ -1028,3 +1030,31 @@ void ProfileMenuViewBase::UpdateSyncInfoContainerBackground() {
views::LayoutProvider::Get()->GetCornerRadiusMetric( views::LayoutProvider::Get()->GetCornerRadiusMetric(
views::EMPHASIS_HIGH))); views::EMPHASIS_HIGH)));
} }
// Despite ProfileMenuViewBase being a dialog, we are enforcing it to behave
// like a menu from the accessibility POV because it fits better with a menu UX.
// The dialog exposes the kMenuBar role, and the top-level container is kMenu.
// This class is responsible for emitting menu accessible events when the dialog
// is activated or deactivated.
class ProfileMenuViewBase::AXMenuWidgetObserver : public views::WidgetObserver {
public:
AXMenuWidgetObserver(ProfileMenuViewBase* owner, views::Widget* widget)
: owner_(owner) {
observer_.Add(widget);
}
~AXMenuWidgetObserver() override = default;
void OnWidgetActivationChanged(views::Widget* widget, bool active) override {
if (active) {
owner_->NotifyAccessibilityEvent(ax::mojom::Event::kMenuStart, true);
owner_->NotifyAccessibilityEvent(ax::mojom::Event::kMenuPopupStart, true);
} else {
owner_->NotifyAccessibilityEvent(ax::mojom::Event::kMenuPopupEnd, true);
owner_->NotifyAccessibilityEvent(ax::mojom::Event::kMenuEnd, true);
}
}
private:
ProfileMenuViewBase* owner_;
ScopedObserver<views::Widget, views::WidgetObserver> observer_{this};
};
...@@ -169,6 +169,8 @@ class ProfileMenuViewBase : public content::WebContentsDelegate, ...@@ -169,6 +169,8 @@ class ProfileMenuViewBase : public content::WebContentsDelegate,
} }
private: private:
class AXMenuWidgetObserver;
friend class ProfileMenuViewExtensionsTest; friend class ProfileMenuViewExtensionsTest;
void Reset(); void Reset();
...@@ -222,6 +224,8 @@ class ProfileMenuViewBase : public content::WebContentsDelegate, ...@@ -222,6 +224,8 @@ class ProfileMenuViewBase : public content::WebContentsDelegate,
// Actual heading string would be set by children classes. // Actual heading string would be set by children classes.
base::string16 profile_mgmt_heading_; base::string16 profile_mgmt_heading_;
std::unique_ptr<AXMenuWidgetObserver> ax_widget_observer_;
DISALLOW_COPY_AND_ASSIGN(ProfileMenuViewBase); DISALLOW_COPY_AND_ASSIGN(ProfileMenuViewBase);
}; };
......
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