From 0f8abea17431d2f98ac41e48eca1266cca66664a Mon Sep 17 00:00:00 2001 From: Reza Bakhshi Laktasaraei Date: Thu, 3 Sep 2026 04:39:43 +0330 Subject: [PATCH] Tell a field's Tab handler when the default order is wanted The fields of a box pass Tab on to one another - question, answers and back to the question - with the buttons around them never focusable, so nothing was lost. In screen reader mode those buttons are Tab stops, and the ring closed on the fields keeps the keyboard from ever reaching them. Every box wrote the same escape by hand. Let the field decide instead: the request it fires for Tab now says whether the default focus order is wanted - in screen reader mode it is - and a handler that would only pass the focus on to another field leaves such a request alone, while one that uses Tab for something else, like accepting a suggestion, goes ahead as usual. --- ui/widgets/fields/input_field.cpp | 6 +++++- ui/widgets/fields/input_field.h | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ui/widgets/fields/input_field.cpp b/ui/widgets/fields/input_field.cpp index 38c530eca..80e045b59 100644 --- a/ui/widgets/fields/input_field.cpp +++ b/ui/widgets/fields/input_field.cpp @@ -25,6 +25,7 @@ #include "ui/painter.h" #include "ui/qt_object_factory.h" #include "ui/integration.h" +#include "ui/screen_reader_mode.h" #include "styles/style_widgets.h" #include "styles/palette.h" @@ -4378,7 +4379,10 @@ void InputField::keyPressEventInner(QKeyEvent *e) { e->ignore(); } else { const auto forward = (key == Qt::Key_Tab) && !shift; - auto request = TabbedRequest{ .backward = !forward }; + auto request = TabbedRequest{ + .backward = !forward, + .defaultOrder = ScreenReaderModeActive(), + }; _tabbed.fire(&request); if (!request.handled && !focusNextPrevChild(forward)) { e->ignore(); diff --git a/ui/widgets/fields/input_field.h b/ui/widgets/fields/input_field.h index 28cc3cf56..bd2e8072f 100644 --- a/ui/widgets/fields/input_field.h +++ b/ui/widgets/fields/input_field.h @@ -152,6 +152,14 @@ class InputField : public RpWidget { struct TabbedRequest { bool backward = false; bool handled = false; + + // Set when Tab should follow the default focus order instead: in + // screen reader mode the buttons and settings around the fields + // are Tab stops, and a handler that would only pass the focus on + // to another field is expected to leave the request alone. One + // that uses Tab for something else - accepting a suggestion - + // goes ahead as usual. + bool defaultOrder = false; }; static const QString kTagBold; static const QString kTagItalic;