Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions ui/widgets/dropdown_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
#include "ui/widgets/dropdown_menu.h"

#include "ui/screen_reader_mode.h"

#include <QtGui/QtEvents>

namespace Ui {
Expand All @@ -31,6 +33,7 @@ DropdownMenu::DropdownMenu(QWidget *parent, const style::DropdownMenu &st) : Inn
//}

void DropdownMenu::init() {
InnerDropdown::setShownCallback([this] { showFinish(); });
InnerDropdown::setHiddenCallback([this] { hideFinish(); });

_menu->resizesFromInner(
Expand Down Expand Up @@ -231,6 +234,18 @@ void DropdownMenu::childHiding(DropdownMenu *child) {
}
}

void DropdownMenu::showFinish() {
// A popup menu opens for a screen reader as if from the keyboard: the
// first item is selected, takes the focus and is announced, and the
// arrows go on from there. A dropdown just appeared in the window,
// with nothing selected and nothing to hear. Do the same here, once
// the content is visible - a selected item that is still hidden
// behind the show animation could not hold the focus.
if (ScreenReaderModeActive()) {
_menu->setShowSource(TriggeredSource::Keyboard);
}
}

void DropdownMenu::hideFinish() {
_menu->clearSelection();
if (const auto onstack = _hiddenCallback) {
Expand Down
1 change: 1 addition & 0 deletions ui/widgets/dropdown_menu.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class DropdownMenu : public InnerDropdown {
void childHiding(DropdownMenu *child);

void init();
void showFinish();
void hideFinish();

using TriggeredSource = Menu::TriggeredSource;
Expand Down
15 changes: 13 additions & 2 deletions ui/widgets/inner_dropdown.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ void InnerDropdown::paintEvent(QPaintEvent *e) {
} else if (_showAnimation) {
_showAnimation->paintFrame(p, 0, 0, width(), 1., 1.);
_showAnimation.reset();
showChildren();
showFinished();
} else {
if (!_cache.isNull()) _cache = QPixmap();
const auto inner = rect().marginsRemoved(_st.padding);
Expand Down Expand Up @@ -219,12 +219,16 @@ void InnerDropdown::finishAnimating() {

void InnerDropdown::showFast() {
_hideTimer.cancel();
const auto showing = isHidden() || _hiding || (_showAnimation != nullptr);
finishAnimating();
if (isHidden()) {
showChildren();
saveFocusWidgetAndShow();
}
_hiding = false;
if (showing) {
showFinished();
}
}

void InnerDropdown::hideFast() {
Expand Down Expand Up @@ -367,11 +371,18 @@ void InnerDropdown::opacityAnimationCallback() {
_hiding = false;
hideFinished();
} else if (!_a_show.animating()) {
showChildren();
showFinished();
}
}
}

void InnerDropdown::showFinished() {
showChildren();
if (const auto onstack = _shownCallback) {
onstack();
}
}

void InnerDropdown::showAnimationCallback() {
update();
}
Expand Down
6 changes: 6 additions & 0 deletions ui/widgets/inner_dropdown.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ class InnerDropdown : public RpWidget {
void setHiddenCallback(Fn<void()> callback) {
_hiddenCallback = std::move(callback);
}
// Fired once the dropdown is fully shown, with its content visible.
void setShownCallback(Fn<void()> callback) {
_shownCallback = std::move(callback);
}

bool isHiding() const {
return _hiding && _a_opacity.animating();
Expand Down Expand Up @@ -103,6 +107,7 @@ class InnerDropdown : public RpWidget {
void maybeReturnFocus();
void hideFinished();
void showStarted();
void showFinished();

void scrolled();

Expand All @@ -123,6 +128,7 @@ class InnerDropdown : public RpWidget {
Fn<void()> _showStartCallback;
Fn<void()> _hideStartCallback;
Fn<void()> _hiddenCallback;
Fn<void()> _shownCallback;

object_ptr<ScrollArea> _scroll;

Expand Down
10 changes: 10 additions & 0 deletions ui/widgets/menu/menu_item_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
//
#include "ui/widgets/menu/menu_item_base.h"

#include "ui/screen_reader_mode.h"
#include "ui/widgets/menu/menu.h"

#include <QtGui/QAccessible>
#include <QtGui/QtEvents>

namespace Ui::Menu {
Expand All @@ -30,6 +32,14 @@ void ItemBase::setSelected(
_lastTriggeredSource = source;
_selected = selected;
update();
if (selected
&& focusPolicy() == Qt::NoFocus
&& ScreenReaderModeActive()) {
// The focus policy is granted when the screen reader first
// queries the item. A popup menu is queried as its window
// appears, a menu inside the window may not have been yet.
QAccessible::queryAccessibleInterface(this);
}
if (selected && focusPolicy() != Qt::NoFocus) {
setFocus();
QAccessibleEvent event(this, QAccessible::Focus);
Expand Down