From 8447f5f006287887ee2910d9710d7bd867aca6e8 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 26 Apr 2018 19:09:32 -0700 Subject: [PATCH] QShortcut: Try harder to find a widget for parentless menubars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add QPlatformMenuBar::parentWindow(). Since we call handleReparent() every so often, it's reasonable to be able to get its value back. While this parent window won't give us much information from the point of view of the actual QWidget parent for the menubar, the main reason we will need this is to check for modality blockage. Indeed, QApplicationPrivate::tryModalHelper() only cares about the widget's window since modality blockage is decided at the window level. Change-Id: Ie79f483424b01e430bc9168ba82489e30d15aec6 Task-number: QTBUG-67938 Reviewed-by: Eike Ziller Reviewed-by: Richard Moe Gustavsen Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qplatformmenu.h | 1 + src/plugins/platforms/cocoa/qcocoamenubar.h | 1 + src/plugins/platforms/cocoa/qcocoamenubar.mm | 6 ++++++ src/widgets/kernel/qshortcut.cpp | 12 ++++++++++-- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h index e3fa5c71b1f..28c29a704c8 100644 --- a/src/gui/kernel/qplatformmenu.h +++ b/src/gui/kernel/qplatformmenu.h @@ -158,6 +158,7 @@ public: virtual void removeMenu(QPlatformMenu *menu) = 0; virtual void syncMenu(QPlatformMenu *menuItem) = 0; virtual void handleReparent(QWindow *newParentWindow) = 0; + virtual QWindow *parentWindow() const { return nullptr; } virtual QPlatformMenu *menuForTag(quintptr tag) const = 0; virtual QPlatformMenu *createMenu() const; diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h index 0ed653911a8..50b6e69720e 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.h +++ b/src/plugins/platforms/cocoa/qcocoamenubar.h @@ -60,6 +60,7 @@ public: void removeMenu(QPlatformMenu *menu) override; void syncMenu(QPlatformMenu *menuItem) override; void handleReparent(QWindow *newParentWindow) override; + QWindow *parentWindow() const override; QPlatformMenu *menuForTag(quintptr tag) const override; inline NSMenu *nsMenu() const diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm index 3564f0176e7..30bff78a364 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.mm +++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm @@ -241,6 +241,12 @@ void QCocoaMenuBar::handleReparent(QWindow *newParentWindow) updateMenuBarImmediately(); } +QWindow *QCocoaMenuBar::parentWindow() const +{ + return m_window ? m_window->window() : nullptr; +} + + QCocoaWindow *QCocoaMenuBar::findWindowForMenubar() { if (qApp->focusWindow()) diff --git a/src/widgets/kernel/qshortcut.cpp b/src/widgets/kernel/qshortcut.cpp index fde039c75e4..a680ff79130 100644 --- a/src/widgets/kernel/qshortcut.cpp +++ b/src/widgets/kernel/qshortcut.cpp @@ -149,8 +149,16 @@ static bool correctWidgetContext(Qt::ShortcutContext context, QWidget *w, QWidge bool visible = w->isVisible(); #if QT_CONFIG(menubar) if (QMenuBar *menuBar = qobject_cast(w)) { - if (menuBar->isNativeMenuBar()) - visible = true; + if (auto *pmb = menuBar->platformMenuBar()) { + if (menuBar->parentWidget()) { + visible = true; + } else { + if (auto *ww = qobject_cast(pmb->parentWindow())) + w = ww->widget(); // Good enough since we only care about the window + else + return false; // This is not a QWidget window. We won't deliver + } + } } #endif