From 3e7463411e549100eee7abe2a8fae16fd965f8f6 Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 29 Jul 2019 14:27:16 +0200 Subject: Fix crash when the focus widget gets a focus proxy after the fact QApplicationPrivate::focus_widget became a dangling pointer in the following scenario: A widget first gets focus and later on gets a focus proxy. QApplicationPrivate::focus_widget was still pointing to the initial widget. Upon destruction, QWidget::hasFocus() [which follows to the focus proxy and then compares with focus_widget] was therefore false for both widgets. So QWidget::clearFocus() didn't call QApplicationPrivate::setFocusWidget(0) for either of them. As a result, focus_widget remained set, and became dangling. In real life, this happened with a QWebEngineView, which the application gave focus to upon creation. At that time it doesn't have a focus proxy yet. That happens later, in QWebEngineViewPrivate::widgetChanged. https://bugs.kde.org/show_bug.cgi?id=381793 Change-Id: Ifee610bb76a2d4d2797b98ece9bffe5fffe3c6a6 Reviewed-by: Volker Hilsheimer --- src/widgets/kernel/qwidget.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/widgets/kernel') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 353a80d1c5..04290a4ce1 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6436,8 +6436,18 @@ void QWidget::setFocusProxy(QWidget * w) } } + QWidget *oldDeepestFocusProxy = d_func()->deepestFocusProxy(); + if (!oldDeepestFocusProxy) + oldDeepestFocusProxy = this; + const bool changingAppFocusWidget = (QApplicationPrivate::focus_widget == oldDeepestFocusProxy); + d->createExtra(); d->extra->focus_proxy = w; + + if (changingAppFocusWidget) { + QWidget *newDeepestFocusProxy = d_func()->deepestFocusProxy(); + QApplicationPrivate::focus_widget = newDeepestFocusProxy ? newDeepestFocusProxy : this; + } } -- cgit v1.2.3