macOS: fix window deactivation when a popup is open

On macOS, we get explicit notifications when a window becomes or resigns
the key, before we have had a chance to close open popups. The popup is
then closed later, but the delivery of the WindowDeactivate event has
already been aborted as QApplication interprets such notifications while
in popup mode as delayed focus events.

This leaves the focus widget still displaying focus even though its
window is no longer active. Trying to activate the window again then
does not correctly transfer focus.

To fix this, close all popup explicitly when a window resigns key.

Task-number: QTBUG-78750
Fixes: QTBUG-66513
Fixes: QTBUG-69710
Pick-to: 6.2
Change-Id: I590757c7d3532dbe4b5358a8e121ce8aa871a699
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Volker Hilsheimer 2021-09-28 17:06:44 +02:00
parent 07cfab07a2
commit b1b75326f4

View File

@ -1208,13 +1208,18 @@ void QCocoaWindow::windowDidResignKey()
if (isForeignWindow())
return;
// Make sure popups are closed before we deliver activation changes, which are
// otherwise ignored by QApplication.
QGuiApplicationPrivate::instance()->closeAllPopups();
// The current key window will be non-nil if another window became key. If that
// window is a Qt window, we delay the window activation event until the didBecomeKey
// notification is delivered to the active window, to ensure an atomic update.
NSWindow *newKeyWindow = [NSApp keyWindow];
if (newKeyWindow && newKeyWindow != m_view.window
&& [newKeyWindow conformsToProtocol:@protocol(QNSWindowProtocol)])
&& [newKeyWindow conformsToProtocol:@protocol(QNSWindowProtocol)]) {
return;
}
// Lost key window, go ahead and set the active window to zero
if (!windowIsPopupType()) {