Close popups on windowWillMiniaturize notification

We do this on windowDidMove/windowWillClose, but we don't on a 'will
miniaturize' notification. This can leave an application with an
orphan popup window, such as context menu which looks really weird.
I err on a safe side though - I don't close all popups - the application's
logic can be such that it has several windows and one of them gets
minimized (we can do this via QWidget's interface, for example) - would
be strange if all popups close. So I only close popups that have
the miniaturized window as a transient parent.

Task-number: QTBUG-77833
Change-Id: Ib655a27c0ce8661f9e7156e6035f7fffaff901b1
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
bb10
Timur Pocheptsov 2019-08-28 14:37:25 +02:00
parent ea1c8d4e65
commit 048e66a11d
4 changed files with 23 additions and 10 deletions

View File

@ -124,6 +124,8 @@ public:
void beep() const override;
void closePopups(QWindow *forWindow = nullptr);
private Q_SLOTS:
void focusWindowChanged(QWindow *);

View File

@ -487,6 +487,19 @@ void QCocoaIntegration::beep() const
NSBeep();
}
void QCocoaIntegration::closePopups(QWindow *forWindow)
{
for (auto it = m_popupWindowStack.begin(); it != m_popupWindowStack.end();) {
auto *popup = *it;
if (!forWindow || popup->window()->transientParent() == forWindow) {
it = m_popupWindowStack.erase(it);
QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(popup->window());
} else {
++it;
}
}
}
void QCocoaIntegration::focusWindowChanged(QWindow *focusWindow)
{
// Don't revert icon just because we lost focus

View File

@ -151,6 +151,7 @@ public:
Q_NOTIFICATION_HANDLER(NSWindowDidEndLiveResizeNotification) void windowDidEndLiveResize();
Q_NOTIFICATION_HANDLER(NSWindowDidBecomeKeyNotification) void windowDidBecomeKey();
Q_NOTIFICATION_HANDLER(NSWindowDidResignKeyNotification) void windowDidResignKey();
Q_NOTIFICATION_HANDLER(NSWindowWillMiniaturizeNotification) void windowWillMiniaturize();
Q_NOTIFICATION_HANDLER(NSWindowDidMiniaturizeNotification) void windowDidMiniaturize();
Q_NOTIFICATION_HANDLER(NSWindowDidDeminiaturizeNotification) void windowDidDeminiaturize();
Q_NOTIFICATION_HANDLER(NSWindowWillEnterFullScreenNotification) void windowWillEnterFullScreen();

View File

@ -71,14 +71,6 @@ enum {
defaultWindowHeight = 160
};
static void qt_closePopups()
{
while (QCocoaWindow *popup = QCocoaIntegration::instance()->popPopupWindow()) {
QWindowSystemInterface::handleCloseEvent(popup->window());
QWindowSystemInterface::flushWindowSystemEvents();
}
}
Q_LOGGING_CATEGORY(lcCocoaNotifications, "qt.qpa.cocoa.notifications");
static void qRegisterNotificationCallbacks()
@ -800,6 +792,11 @@ void QCocoaWindow::windowDidExitFullScreen()
}
}
void QCocoaWindow::windowWillMiniaturize()
{
QCocoaIntegration::instance()->closePopups(window());
}
void QCocoaWindow::windowDidMiniaturize()
{
if (!isContentView())
@ -1138,7 +1135,7 @@ void QCocoaWindow::viewDidChangeGlobalFrame()
void QCocoaWindow::windowWillMove()
{
// Close any open popups on window move
qt_closePopups();
QCocoaIntegration::instance()->closePopups();
}
void QCocoaWindow::windowDidMove()
@ -1267,7 +1264,7 @@ void QCocoaWindow::windowWillClose()
{
// Close any open popups on window closing.
if (window() && !windowIsPopupType(window()->type()))
qt_closePopups();
QCocoaIntegration::instance()->closePopups();
}
// ----------------------- NSWindowDelegate callbacks -----------------------