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. Task-number: QTBUG-121789 Change-Id: I1f4f5d85e7552926580906fdef6f0a456fe7486c Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: MohammadHossein Qanbari <mohammad.qanbari@qt.io> (cherry picked from commit 926d3287aba9fe2b67c25d0c0c5b606f3f41803e) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
5e090d4b9b
commit
3b1951cd1b
@ -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()) {
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user