diff options
author | Doris Verria <[email protected]> | 2024-09-24 14:12:02 +0200 |
---|---|---|
committer | Doris Verria <[email protected]> | 2024-10-03 01:05:34 +0200 |
commit | 926d3287aba9fe2b67c25d0c0c5b606f3f41803e (patch) | |
tree | 16e8201015bf652ca8ed42157968976dceaf5805 | |
parent | 0563862e23eda4a7b8def8c8afacf732b9a992ef (diff) |
QWidgetWindow::setFocusToTarget: Respect focus policies and proxies
When calling QWidgetWindowPrivate::setFocusToTarget with Prev or Next
target parameter, we were just setting focus to the
next/prevInFocusChain() of the window's focusWidget(). This will bypass
focus proxies and focus policies of the widget, which is wrong as it
can end up giving eg: tab focus to a widget that does not have such
focus policy.
To fix, we should instead call QWidget::focusNextPrevChild which
determines the right next/prev in the TAB focus chain. As this is a
protected member of QWidget, implement a "wrapper" for it in
QWidgetWindow which is a friend class of QWidget.
Pick-to: 6.8
Task-number: QTBUG-121789
Change-Id: I1f4f5d85e7552926580906fdef6f0a456fe7486c
Reviewed-by: Axel Spoerl <[email protected]>
Reviewed-by: MohammadHossein Qanbari <[email protected]>
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 31 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow_p.h | 2 |
2 files changed, 18 insertions, 15 deletions
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index e2f1776780d..e489749214f 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -82,31 +82,26 @@ public: QWidget *widget = q->widget(); if (!widget) return; - QWidget *newFocusWidget = nullptr; switch (target) { - case FocusTarget::First: - newFocusWidget = q->getFocusWidget(QWidgetWindow::FirstFocusWidget); - break; - case FocusTarget::Last: - newFocusWidget = q->getFocusWidget(QWidgetWindow::LastFocusWidget); - break; + case FocusTarget::Prev: case FocusTarget::Next: { QWidget *focusWidget = widget->focusWidget() ? widget->focusWidget() : widget; - newFocusWidget = focusWidget->nextInFocusChain() ? focusWidget->nextInFocusChain() : focusWidget; - break; + q->focusNextPrevChild(focusWidget, target == FocusTarget::Next); + return; } - case FocusTarget::Prev: { - QWidget *focusWidget = widget->focusWidget() ? widget->focusWidget() : widget; - newFocusWidget = focusWidget->previousInFocusChain() ? focusWidget->previousInFocusChain() : focusWidget; + case FocusTarget::First: + case FocusTarget::Last: { + QWidgetWindow::FocusWidgets fw = target == FocusTarget::First + ? QWidgetWindow::FirstFocusWidget + : QWidgetWindow::LastFocusWidget; + if (QWidget *newFocusWidget = q->getFocusWidget(fw)) + newFocusWidget->setFocus(reason); break; } default: break; } - - if (newFocusWidget) - newFocusWidget->setFocus(reason); } QRectF closestAcceptableGeometry(const QRectF &rect) const override; @@ -233,6 +228,12 @@ void QWidgetWindow::setNativeWindowVisibility(bool visible) d->QWindowPrivate::setVisible(visible); } +void QWidgetWindow::focusNextPrevChild(QWidget *widget, bool next) +{ + Q_ASSERT(widget); + widget->focusNextPrevChild(next); +} + static inline bool shouldBePropagatedToWidget(QEvent *event) { switch (event->type()) { diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h index 0ee6b71a795..bd4983b8065 100644 --- a/src/widgets/kernel/qwidgetwindow_p.h +++ b/src/widgets/kernel/qwidgetwindow_p.h @@ -46,6 +46,8 @@ public: QObject *focusObject() const override; void setNativeWindowVisibility(bool visible); + static void focusNextPrevChild(QWidget *widget, bool next); + protected: bool event(QEvent *) override; |