diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-09-28 17:07:05 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-10-12 14:08:08 +0200 |
commit | 3b6a02788523c88b0ceb2bc80364a4088dae1e47 (patch) | |
tree | 49c1793eb94669b475de663579a8e2d03cdf2bd8 /src/widgets/kernel/qapplication.cpp | |
parent | 971bf3a9bbbc4daa10ff1f6fd24b911faf2c8c7f (diff) |
macOS: fix window activation when popup is open
On macOS, it is possible to right-click-open a context menu for a window
that is not active. This does not activate the window.
When then clicking into the window to activate it, the popup is closed,
but only after the WindowActivate events has been sent. This blocks the
event delivery, as QApplication (since commit 78264f333eb7c2623807)
interpreted activation changes while popups are open to be just delayed
focus events. The UI ends up in a broken state where focus cannot be set
on the widgets in the window.
To fix this, don't ignore such activation events on macOS. As a drive-by,
give the variables more meaningful names.
Note: We cannot call closeAllPopups before delivering WindowActivate,
as that would close the popup before the mouse event is delivered, making
it impossible to select any of the actions from the menu.
Ideally, clicking into a popup of an otherwise inactive application would
not activate that application (that is the default behavior for native
macOS applications), but that's out of scope for this patch.
Fixes: QTBUG-78750
Task-number: QTBUG-69710
Task-number: QTBUG-66513
Pick-to: 6.2
Change-Id: I6344370ae7be31630e37514e04918b2d6cb8b69a
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Diffstat (limited to 'src/widgets/kernel/qapplication.cpp')
-rw-r--r-- | src/widgets/kernel/qapplication.cpp | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index c1915755c5..456544609e 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1909,14 +1909,18 @@ QWidget *qt_tlw_for_window(QWindow *wnd) void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) { Q_UNUSED(previous); - QWindow *wnd = QGuiApplicationPrivate::focus_window; - if (inPopupMode()) // some delayed focus event to ignore +#ifndef Q_OS_MACOS + // Some delayed focus event to ignore, unless we are on cocoa where + // popups can be opened via right-click on inactive applications + if (inPopupMode()) return; - QWidget *tlw = qt_tlw_for_window(wnd); - QApplication::setActiveWindow(tlw); +#endif + QWindow *focusWindow = QGuiApplicationPrivate::focus_window; + QWidget *focusWidget = qt_tlw_for_window(focusWindow); + QApplication::setActiveWindow(focusWidget); // QTBUG-37126, Active X controls may set the focus on native child widgets. - if (wnd && tlw && wnd != tlw->windowHandle()) { - if (QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(wnd)) + if (focusWindow && focusWidget && focusWindow != focusWidget->windowHandle()) { + if (QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(focusWindow)) if (QWidget *widget = widgetWindow->widget()) if (widget->inherits("QAxHostWidget")) widget->setFocus(Qt::ActiveWindowFocusReason); |