QQuickMenu: respect Qt::AA_DontUseNativeMenuWindows
Now that we enable native menus by default for the macOS style, we also need to make sure that we actually respect the Qt::AA_DontUseNativeMenuWindows. Pick-to: 6.8 Change-Id: I2a02b5528110a4e0514fb53c0673653f0086dfe8 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
This commit is contained in:
parent
744fda3674
commit
399c3c4216
|
@ -214,6 +214,9 @@ static const int SUBMENU_DELAY = 225;
|
||||||
is the default when the style doesn't set a popup type).
|
is the default when the style doesn't set a popup type).
|
||||||
If you add customizations to a menu, and want those to be used regardless of the
|
If you add customizations to a menu, and want those to be used regardless of the
|
||||||
style, you should set the popup type to be \c Popup.Window (or \c Popup.Item) explicitly.
|
style, you should set the popup type to be \c Popup.Window (or \c Popup.Item) explicitly.
|
||||||
|
Another alternative is to set the \c Qt::AA_DontUseNativeMenuWindows
|
||||||
|
\l {Qt::ApplicationAttribute}{application attribute}. This will disable native context
|
||||||
|
menus for the whole application, irrespective of the style.
|
||||||
|
|
||||||
Whether a menu will be able to use the preferred type depends on the platform.
|
Whether a menu will be able to use the preferred type depends on the platform.
|
||||||
\c Popup.Item is supported on all platforms, but \c Popup.Window is
|
\c Popup.Item is supported on all platforms, but \c Popup.Window is
|
||||||
|
@ -364,9 +367,14 @@ QQuickMenu *QQuickMenuPrivate::rootMenu() const
|
||||||
|
|
||||||
bool QQuickMenuPrivate::useNativeMenu() const
|
bool QQuickMenuPrivate::useNativeMenu() const
|
||||||
{
|
{
|
||||||
// If we're inside a MenuBar, it'll decide whether or not we
|
if (QGuiApplication::testAttribute(Qt::AA_DontUseNativeMenuWindows))
|
||||||
// should be native or not. Otherwise, the root menu (which
|
return false;
|
||||||
// might be this menu) will decide.
|
|
||||||
|
// If we're inside a MenuBar, it'll decide whether or not we should be
|
||||||
|
// native. Otherwise, the root menu (which might be this menu) will decide.
|
||||||
|
// Note that this is just a preference, QPA can still fail to create a native
|
||||||
|
// menu. In that case we'll fall back to let QQuickPopup create the menu/popup
|
||||||
|
// instead, and end up with Window or Item as resolved popup type.
|
||||||
QQuickMenu *root = rootMenu();
|
QQuickMenu *root = rootMenu();
|
||||||
if (auto menuBar = QQuickMenuPrivate::get(root)->menuBar.get())
|
if (auto menuBar = QQuickMenuPrivate::get(root)->menuBar.get())
|
||||||
return QQuickMenuBarPrivate::get(menuBar)->useNativeMenu(q_func());
|
return QQuickMenuBarPrivate::get(menuBar)->useNativeMenu(q_func());
|
||||||
|
|
|
@ -101,6 +101,7 @@ private slots:
|
||||||
void nativeDynamicActions();
|
void nativeDynamicActions();
|
||||||
void nativeDynamicSubmenus();
|
void nativeDynamicSubmenus();
|
||||||
void nativeMenuSeparator();
|
void nativeMenuSeparator();
|
||||||
|
void AA_DontUseNativeMenuWindows();
|
||||||
void dontUseNativeMenuWindowsChanges();
|
void dontUseNativeMenuWindowsChanges();
|
||||||
void nativeMixedItems();
|
void nativeMixedItems();
|
||||||
void effectivePosition_data();
|
void effectivePosition_data();
|
||||||
|
@ -1841,6 +1842,9 @@ void tst_QQuickMenu::addRemoveSubMenus()
|
||||||
|
|
||||||
void tst_QQuickMenu::subMenuPopupType()
|
void tst_QQuickMenu::subMenuPopupType()
|
||||||
{
|
{
|
||||||
|
// Undo the setting of AA_DontUseNativeMenuWindows to true from init()
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows, false);
|
||||||
|
|
||||||
// Check that all sub-menus will end up with an effective popup
|
// Check that all sub-menus will end up with an effective popup
|
||||||
// type equal to the root menu.
|
// type equal to the root menu.
|
||||||
QQuickControlsApplicationHelper helper(this, QLatin1String("subMenus.qml"));
|
QQuickControlsApplicationHelper helper(this, QLatin1String("subMenus.qml"));
|
||||||
|
@ -2284,6 +2288,9 @@ void tst_QQuickMenu::invalidUrlInImgTag()
|
||||||
|
|
||||||
void tst_QQuickMenu::nativeStatic()
|
void tst_QQuickMenu::nativeStatic()
|
||||||
{
|
{
|
||||||
|
// Undo the setting of AA_DontUseNativeMenuWindows to true from init()
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows, false);
|
||||||
|
|
||||||
QQuickControlsApplicationHelper helper(this, QLatin1String("nativeStatic.qml"));
|
QQuickControlsApplicationHelper helper(this, QLatin1String("nativeStatic.qml"));
|
||||||
QVERIFY2(helper.ready, helper.failureMessage());
|
QVERIFY2(helper.ready, helper.failureMessage());
|
||||||
QQuickApplicationWindow *window = helper.appWindow;
|
QQuickApplicationWindow *window = helper.appWindow;
|
||||||
|
@ -2386,6 +2393,9 @@ void tst_QQuickMenu::nativeDynamicActions()
|
||||||
|
|
||||||
void tst_QQuickMenu::nativeDynamicSubmenus()
|
void tst_QQuickMenu::nativeDynamicSubmenus()
|
||||||
{
|
{
|
||||||
|
// Undo the setting of AA_DontUseNativeMenuWindows to true from init()
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows, false);
|
||||||
|
|
||||||
QQuickControlsApplicationHelper helper(this, QLatin1String("nativeDynamicSubmenus.qml"));
|
QQuickControlsApplicationHelper helper(this, QLatin1String("nativeDynamicSubmenus.qml"));
|
||||||
QVERIFY2(helper.ready, helper.failureMessage());
|
QVERIFY2(helper.ready, helper.failureMessage());
|
||||||
QQuickApplicationWindow *window = helper.appWindow;
|
QQuickApplicationWindow *window = helper.appWindow;
|
||||||
|
@ -2493,6 +2503,9 @@ void tst_QQuickMenu::nativeDynamicSubmenus()
|
||||||
|
|
||||||
void tst_QQuickMenu::nativeMenuSeparator()
|
void tst_QQuickMenu::nativeMenuSeparator()
|
||||||
{
|
{
|
||||||
|
// Undo the setting of AA_DontUseNativeMenuWindows to true from init()
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows, false);
|
||||||
|
|
||||||
QQuickControlsApplicationHelper helper(this, QLatin1String("nativeMenuSeparator.qml"));
|
QQuickControlsApplicationHelper helper(this, QLatin1String("nativeMenuSeparator.qml"));
|
||||||
QVERIFY2(helper.ready, helper.failureMessage());
|
QVERIFY2(helper.ready, helper.failureMessage());
|
||||||
QQuickApplicationWindow *window = helper.appWindow;
|
QQuickApplicationWindow *window = helper.appWindow;
|
||||||
|
@ -2530,6 +2543,30 @@ void tst_QQuickMenu::nativeMenuSeparator()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QQuickMenu::AA_DontUseNativeMenuWindows()
|
||||||
|
{
|
||||||
|
// Check that we end up with a non-native menu when AA_DontUseNativeMenuWindows
|
||||||
|
// is set, even if popupType is Native.
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows);
|
||||||
|
|
||||||
|
QQuickControlsApplicationHelper helper(this, QLatin1String("applicationwindow.qml"));
|
||||||
|
QVERIFY2(helper.ready, helper.failureMessage());
|
||||||
|
QQuickApplicationWindow *window = helper.appWindow;
|
||||||
|
window->show();
|
||||||
|
QVERIFY(QTest::qWaitForWindowExposed(window));
|
||||||
|
|
||||||
|
QQuickMenu *menu = window->property("menu").value<QQuickMenu*>();
|
||||||
|
QVERIFY(menu);
|
||||||
|
QQuickMenuPrivate *menu_d = QQuickMenuPrivate::get(menu);
|
||||||
|
|
||||||
|
menu->setPopupType(QQuickPopup::Native);
|
||||||
|
// Note: since a native menu is blocking, we cannot open it, in case
|
||||||
|
// the test fails and it actually opens. That would block the test as
|
||||||
|
// well. So we just check that useNativeMenu returns false for now.
|
||||||
|
QVERIFY(!menu_d->useNativeMenu());
|
||||||
|
QVERIFY(!menu_d->maybeNativeHandle());
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QQuickMenu::dontUseNativeMenuWindowsChanges()
|
void tst_QQuickMenu::dontUseNativeMenuWindowsChanges()
|
||||||
{
|
{
|
||||||
QSKIP("QTBUG-125967 This test will need to be fixed, by using popupType: Popup.Native instead of AA_DontUseNativeMenuWindows.");
|
QSKIP("QTBUG-125967 This test will need to be fixed, by using popupType: Popup.Native instead of AA_DontUseNativeMenuWindows.");
|
||||||
|
|
|
@ -209,6 +209,13 @@ ApplicationWindow {
|
||||||
onClicked: subMenu.removeLastAction()
|
onClicked: subMenu.removeLastAction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Row {
|
||||||
|
Switch {
|
||||||
|
text: qsTr("Don't use native menu windows")
|
||||||
|
checked: CppSettings.dontUseNativeMenuWindows
|
||||||
|
onClicked: CppSettings.dontUseNativeMenuWindows = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,3 +41,19 @@ void CppSettings::setPopupType(int newPopupType)
|
||||||
mSettings.setValue("popupType", newPopupType);
|
mSettings.setValue("popupType", newPopupType);
|
||||||
emit popupTypeChanged();
|
emit popupTypeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CppSettings::dontUseNativeMenuWindows() const
|
||||||
|
{
|
||||||
|
return mSettings.value("dontUseNativeMenuWindows").toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppSettings::setDontUseNativeMenuWindows(bool dontUseNativeMenuWindows)
|
||||||
|
{
|
||||||
|
const bool oldValue = this->dontUseNativeMenuWindows();
|
||||||
|
if (dontUseNativeMenuWindows == oldValue)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuWindows, dontUseNativeMenuWindows);
|
||||||
|
mSettings.setValue("dontUseNativeMenuWindows", dontUseNativeMenuWindows);
|
||||||
|
emit dontUseNativeMenuWindowsChanged();
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ class CppSettings : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(bool dontUseNativeMenuBar READ dontUseNativeMenuBar WRITE setDontUseNativeMenuBar
|
Q_PROPERTY(bool dontUseNativeMenuBar READ dontUseNativeMenuBar WRITE setDontUseNativeMenuBar
|
||||||
NOTIFY dontUseNativeMenuBarChanged FINAL)
|
NOTIFY dontUseNativeMenuBarChanged FINAL)
|
||||||
|
Q_PROPERTY(bool dontUseNativeMenuWindows READ dontUseNativeMenuWindows WRITE setDontUseNativeMenuWindows
|
||||||
|
NOTIFY dontUseNativeMenuBarChanged FINAL)
|
||||||
Q_PROPERTY(int popupType READ popupType WRITE setPopupType
|
Q_PROPERTY(int popupType READ popupType WRITE setPopupType
|
||||||
NOTIFY popupTypeChanged FINAL)
|
NOTIFY popupTypeChanged FINAL)
|
||||||
QML_ELEMENT
|
QML_ELEMENT
|
||||||
|
@ -27,8 +29,12 @@ public:
|
||||||
int popupType() const;
|
int popupType() const;
|
||||||
void setPopupType(int newPopupType);
|
void setPopupType(int newPopupType);
|
||||||
|
|
||||||
|
bool dontUseNativeMenuWindows() const;
|
||||||
|
void setDontUseNativeMenuWindows(bool newDontUseNativeMenuWindows);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void dontUseNativeMenuBarChanged();
|
void dontUseNativeMenuBarChanged();
|
||||||
|
void dontUseNativeMenuWindowsChanged();
|
||||||
void popupTypeChanged();
|
void popupTypeChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue