From b9aad5d250a2b0933d2eac2836f537bbc2b850a6 Mon Sep 17 00:00:00 2001 From: Reza Bakhshi Laktasaraei Date: Tue, 2 Jun 2026 13:26:01 +0330 Subject: [PATCH] Engaged chat search on typing instead of focus in screen reader mode. In screen reader mode, focusing the dialogs search field no longer opens the suggestions panel or shows the cancel-search button. Search engages only when the user types, stays engaged after clearing the query, and disengages only on explicit Escape or the cancel-search button. Tab and Backspace on an empty query no longer exit search in this mode. Non-screen-reader behavior is unchanged. --- Telegram/SourceFiles/dialogs/dialogs_widget.cpp | 16 +++++++++++++--- Telegram/SourceFiles/dialogs/dialogs_widget.h | 2 ++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index 73664fd5fc..7a2f133ce0 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -44,6 +44,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/controls/swipe_handler.h" #include "ui/painter.h" #include "ui/rect.h" +#include "ui/screen_reader_mode.h" #include "ui/ui_utility.h" #include "lang/lang_keys.h" #include "mainwindow.h" @@ -1773,8 +1774,12 @@ void Widget::processSearchFocusChange() { updateSuggestions(anim::type::normal); } +bool Widget::searchActive() const { + return Ui::ScreenReaderModeActive() ? _searchEngaged : _searchHasFocus; +} + void Widget::updateSuggestions(anim::type animated) { - const auto suggest = (_searchHasFocus || _searchSuggestionsLocked) + const auto suggest = (searchActive() || _searchSuggestionsLocked) && !_searchState.inChat && (_inner->state() == WidgetState::Default); if (anim::Disabled() || !session().data().chatsListLoaded()) { @@ -3363,7 +3368,7 @@ void Widget::listScrollUpdated() { void Widget::updateCancelSearch() { const auto shown = !_searchState.query.isEmpty() || (!_searchState.inChat - && (_searchHasFocus || _searchSuggestionsLocked)); + && (searchActive() || _searchSuggestionsLocked)); _cancelSearch->toggle(shown, anim::type::normal); if (_searchState.inChat) { _cancelSearch->setAccessibleName(shown @@ -3400,6 +3405,9 @@ QString Widget::validateSearchQuery() { void Widget::applySearchUpdate() { auto copy = _searchState; copy.query = validateSearchQuery(); + if (Ui::ScreenReaderModeActive() && !copy.query.isEmpty()) { + _searchEngaged = true; + } applySearchState(std::move(copy)); if (_chooseFromUser->toggled() @@ -4173,7 +4181,8 @@ void Widget::keyPressEvent(QKeyEvent *e) { //} else { // e->ignore(); //} - } else if ((e->key() == Qt::Key_Backspace || e->key() == Qt::Key_Tab) + } else if ((e->key() == Qt::Key_Backspace + || (e->key() == Qt::Key_Tab && !Ui::ScreenReaderModeActive())) && _searchHasFocus && !_searchState.inChat && _searchState.query.isEmpty()) { @@ -4404,6 +4413,7 @@ void Widget::setSearchQuery(const QString &query, int cursorPosition) { } bool Widget::cancelSearch(CancelSearchOptions options) { + _searchEngaged = false; const auto clearingSuggestionsQuery = _suggestions && _suggestions->consumeSearchQuery(QString()); if (clearingSuggestionsQuery) { diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.h b/Telegram/SourceFiles/dialogs/dialogs_widget.h index 9c2bcaea15..81a180e57e 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.h @@ -291,6 +291,7 @@ private: void updateSuggestions(anim::type animated); void processSearchFocusChange(); void closeSuggestions(); + [[nodiscard]] bool searchActive() const; [[nodiscard]] bool redirectToSearchPossible() const; [[nodiscard]] bool redirectKeyToSearch(QKeyEvent *e) const; @@ -373,6 +374,7 @@ private: QString _lastSearchText; bool _searchSuggestionsLocked = false; bool _searchHasFocus = false; + bool _searchEngaged = false; bool _processingSearch = false; rpl::event_stream> _storiesContents;