summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoris Verria <[email protected]>2024-09-24 14:12:02 +0200
committerDoris Verria <[email protected]>2024-10-03 01:05:34 +0200
commit926d3287aba9fe2b67c25d0c0c5b606f3f41803e (patch)
tree16e8201015bf652ca8ed42157968976dceaf5805
parent0563862e23eda4a7b8def8c8afacf732b9a992ef (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.cpp31
-rw-r--r--src/widgets/kernel/qwidgetwindow_p.h2
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;