From cde91dd71a89d1f82bc87dabe95643cc93853e50 Mon Sep 17 00:00:00 2001 From: Pan Zhang Date: Fri, 13 Mar 2026 16:32:51 +0800 Subject: animatedheightwidget: prevent viewport scrolling The search field moves upwards and becomes obscured when pressing navigation keys like the down arrow. This happens because the underlying QScrollArea processes keyboard navigation events, shifting the visible viewport even when scrollbars are completely hidden and disabled. Move the event filter from the contents container directly to the QScrollArea (m_contentsContainerParent) and its viewport. Update the filter to intercept Qt::Key_Up and Qt::Key_Down events, preventing the scroll area from handling these inputs. BUG: 510469 --- src/animatedheightwidget.cpp | 20 ++++++++++++++++---- src/animatedheightwidget.h | 5 +++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/animatedheightwidget.cpp b/src/animatedheightwidget.cpp index c89863b25..ed7e6bdc6 100644 --- a/src/animatedheightwidget.cpp +++ b/src/animatedheightwidget.cpp @@ -33,6 +33,11 @@ AnimatedHeightWidget::AnimatedHeightWidget(QWidget *parent) m_contentsContainerParent->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_contentsContainerParent->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_contentsContainerParent->setWidgetResizable(true); + // Prevent the internal scroll area from reacting to navigation keys and + // scrolling the contents (scrollbars are hidden but scrolling still changes + // the visible region). + m_contentsContainerParent->installEventFilter(this); + m_contentsContainerParent->viewport()->installEventFilter(this); // Disables manual scrolling, for example with mouse scrollwheel. m_contentsContainerParent->verticalScrollBar()->setEnabled(false); m_contentsContainerParent->horizontalScrollBar()->setEnabled(false); @@ -88,7 +93,6 @@ QWidget *AnimatedHeightWidget::prepareContentsContainer(QWidget *contentsContain contentsContainer->setParent(m_contentsContainerParent); m_contentsContainerParent->setWidget(contentsContainer); m_contentsContainerParent->setFocusProxy(contentsContainer); - contentsContainer->installEventFilter(this); return contentsContainer; } @@ -99,12 +103,20 @@ bool AnimatedHeightWidget::isAnimationRunning() const bool AnimatedHeightWidget::eventFilter(QObject *obj, QEvent *event) { - if (event->type() == QEvent::KeyPress) { + if ((obj == m_contentsContainerParent || obj == m_contentsContainerParent->viewport()) && event->type() == QEvent::KeyPress) { auto *keyEvent = static_cast(event); - // Ignore PageUp/PageDown to prevent QScrollArea (invisible scrollbar) from scrolling - if (keyEvent->key() == Qt::Key_PageUp || keyEvent->key() == Qt::Key_PageDown) { + // Ignore navigation keys to prevent the internal QScrollArea (with + // invisible scrollbars) from scrolling and visually moving child bars + // such as the search bar. + switch (keyEvent->key()) { + case Qt::Key_Up: + case Qt::Key_Down: + case Qt::Key_PageUp: + case Qt::Key_PageDown: keyEvent->accept(); return true; + default: + break; } } return QWidget::eventFilter(obj, event); diff --git a/src/animatedheightwidget.h b/src/animatedheightwidget.h index 3933df93f..92701bd25 100644 --- a/src/animatedheightwidget.h +++ b/src/animatedheightwidget.h @@ -57,8 +57,9 @@ protected: protected: /** - * Ignore PageUp/PageDown key events to prevent the internal QScrollArea - * (with an invisible scrollbar) from scrolling while editing inside child widgets. + * Ignore Up/Down/PageUp/PageDown key events for the internal QScrollArea + * (with an invisible scrollbar) to prevent it from scrolling and moving the + * visible region of contained widgets such as the search bar. */ bool eventFilter(QObject *obj, QEvent *event) override; -- cgit v1.3