From 0a69fecaca02ed2ee48e39a087d03190a54d9cb6 Mon Sep 17 00:00:00 2001 From: reionwong Date: Sat, 29 Aug 2026 22:57:05 -0400 Subject: [PATCH] fix(platformtheme): restore the global menu bar via QGenericUnixTheme --- platformtheme/platformtheme.cpp | 20 ++-- platformtheme/platformtheme.h | 5 +- platformtheme/qdbusmenubar.cpp | 156 -------------------------------- platformtheme/qdbusmenubar_p.h | 101 --------------------- 4 files changed, 9 insertions(+), 273 deletions(-) delete mode 100644 platformtheme/qdbusmenubar.cpp delete mode 100644 platformtheme/qdbusmenubar_p.h diff --git a/platformtheme/platformtheme.cpp b/platformtheme/platformtheme.cpp index 364e770..0e3a62e 100644 --- a/platformtheme/platformtheme.cpp +++ b/platformtheme/platformtheme.cpp @@ -64,7 +64,7 @@ QVariant PlatformTheme::themeHint(QPlatformTheme::ThemeHint hintType) const if (hint.isValid()) { return hint; } else { - return QPlatformTheme::themeHint(hintType); + return QGenericUnixTheme::themeHint(hintType); } } @@ -108,15 +108,7 @@ const QFont* PlatformTheme::font(Font type) const } } - return QPlatformTheme::font(type); -} - -QPlatformMenuBar *PlatformTheme::createPlatformMenuBar() const -{ - // Qt 6 no longer exports the private QDBusPlatformMenu implementation - // used by the old Qt 5 global-menu code. The old implementation would - // make this platform theme plugin fail to load at runtime. - return nullptr; + return QGenericUnixTheme::font(type); } void PlatformTheme::onFontChanged() @@ -148,8 +140,10 @@ void PlatformTheme::onIconThemeChanged() void PlatformTheme::setQtQuickControlsTheme() { - //if the user has explicitly set something else, don't meddle - if (!QQuickStyle::name().isEmpty()) { + // Qt 6's QQuickStyle::name() resolves to the default style instead of + // returning an empty string, so it can no longer tell us whether the user + // picked a style explicitly. Honour the environment variable instead. + if (!qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) { return; } @@ -161,5 +155,5 @@ void PlatformTheme::setQtQuickControlsTheme() return; } - QQuickStyle::setStyle(QLatin1String("fish-style")); + QQuickStyle::setStyle(QLatin1String("Fish")); } diff --git a/platformtheme/platformtheme.h b/platformtheme/platformtheme.h index dbaef46..4eabab6 100644 --- a/platformtheme/platformtheme.h +++ b/platformtheme/platformtheme.h @@ -1,7 +1,7 @@ #ifndef PLATFORMTHEME_H #define PLATFORMTHEME_H -#include +#include #include "hintsettings.h" #include "systemtrayicon.h" @@ -12,7 +12,7 @@ class QIconEngine; class QWindow; class X11Integration; -class PlatformTheme : public QObject, public QPlatformTheme +class PlatformTheme : public QObject, public QGenericUnixTheme { Q_OBJECT @@ -23,7 +23,6 @@ public: QVariant themeHint(ThemeHint hint) const override; const QFont *font(Font type) const override; - QPlatformMenuBar *createPlatformMenuBar() const override; QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const override { auto trayIcon = new SystemTrayIcon; diff --git a/platformtheme/qdbusmenubar.cpp b/platformtheme/qdbusmenubar.cpp deleted file mode 100644 index b7b5de3..0000000 --- a/platformtheme/qdbusmenubar.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include "qdbusmenubar_p.h" - - -QT_BEGIN_NAMESPACE - -/* note: do not change these to QStringLiteral; - we are unloaded before QtDBus is done using the strings. - */ -#define REGISTRAR_SERVICE QLatin1String("com.canonical.AppMenu.Registrar") -#define REGISTRAR_PATH QLatin1String("/com/canonical/AppMenu/Registrar") - -QDBusMenuBar::QDBusMenuBar() - : QPlatformMenuBar() - , m_menu(new QDBusPlatformMenu()) - , m_menuAdaptor(new QDBusMenuAdaptor(m_menu)) -{ - QDBusMenuItem::registerDBusTypes(); - connect(m_menu, &QDBusPlatformMenu::propertiesUpdated, - m_menuAdaptor, &QDBusMenuAdaptor::ItemsPropertiesUpdated); - connect(m_menu, &QDBusPlatformMenu::updated, - m_menuAdaptor, &QDBusMenuAdaptor::LayoutUpdated); - - // This signal is new in Qt 5.8 but distros might have backported it, hence a runtime look-up - if (m_menu->metaObject()->indexOfSignal("popupRequested(int,uint)") != -1) { - connect(m_menu, SIGNAL(popupRequested(int,uint)), m_menuAdaptor, SIGNAL(ItemActivationRequested(int,uint))); - } -} - -QDBusMenuBar::~QDBusMenuBar() -{ - unregisterMenuBar(); - delete m_menuAdaptor; - delete m_menu; - qDeleteAll(m_menuItems); -} - -QDBusPlatformMenuItem *QDBusMenuBar::menuItemForMenu(QPlatformMenu *menu) -{ - if (!menu) - return nullptr; - quintptr tag = menu->tag(); - const auto it = m_menuItems.constFind(tag); - if (it != m_menuItems.cend()) { - return *it; - } else { - QDBusPlatformMenuItem *item = new QDBusPlatformMenuItem; - updateMenuItem(item, menu); - m_menuItems.insert(tag, item); - return item; - } -} - -void QDBusMenuBar::updateMenuItem(QDBusPlatformMenuItem *item, QPlatformMenu *menu) -{ - const QDBusPlatformMenu *ourMenu = qobject_cast(menu); - item->setText(ourMenu->text()); - item->setIcon(ourMenu->icon()); - item->setEnabled(ourMenu->isEnabled()); - item->setVisible(ourMenu->isVisible()); - item->setMenu(menu); -} - -void QDBusMenuBar::insertMenu(QPlatformMenu *menu, QPlatformMenu *before) -{ - QDBusPlatformMenuItem *menuItem = menuItemForMenu(menu); - QDBusPlatformMenuItem *beforeItem = menuItemForMenu(before); - m_menu->insertMenuItem(menuItem, beforeItem); - m_menu->emitUpdated(); -} - -void QDBusMenuBar::removeMenu(QPlatformMenu *menu) -{ - QDBusPlatformMenuItem *menuItem = menuItemForMenu(menu); - m_menu->removeMenuItem(menuItem); - m_menu->emitUpdated(); -} - -void QDBusMenuBar::syncMenu(QPlatformMenu *menu) -{ - QDBusPlatformMenuItem *menuItem = menuItemForMenu(menu); - updateMenuItem(menuItem, menu); -} - -void QDBusMenuBar::handleReparent(QWindow *newParentWindow) -{ - if (newParentWindow == m_window) { - return; - } - - QWindow *oldWindow = m_window; - - unregisterMenuBar(); - m_window = newParentWindow; - - if (newParentWindow) { - registerMenuBar(); - } - - emit windowChanged(newParentWindow, oldWindow); -} - -QPlatformMenu *QDBusMenuBar::menuForTag(quintptr tag) const -{ - QDBusPlatformMenuItem *menuItem = m_menuItems.value(tag); - if (menuItem) - return const_cast(menuItem->menu()); - return nullptr; -} - -QPlatformMenu *QDBusMenuBar::createMenu() const -{ - return new QDBusPlatformMenu; -} - -void QDBusMenuBar::registerMenuBar() -{ - static uint menuBarId = 0; - - if (!m_window) { - qWarning("Cannot register window menu without window"); - return; - } - - QDBusConnection connection = QDBusConnection::sessionBus(); - m_objectPath = QStringLiteral("/MenuBar/%1").arg(++menuBarId); - if (!connection.registerObject(m_objectPath, m_menu)) - return; - - QDBusMenuRegistrarInterface registrar(REGISTRAR_SERVICE, REGISTRAR_PATH, connection, this); - QDBusPendingReply<> r = registrar.RegisterWindow(static_cast(window()->winId()), QDBusObjectPath(m_objectPath)); - r.waitForFinished(); - if (r.isError()) { - qWarning("Failed to register window menu, reason: %s (\"%s\")", - qUtf8Printable(r.error().name()), qUtf8Printable(r.error().message())); - connection.unregisterObject(m_objectPath); - } -} - -void QDBusMenuBar::unregisterMenuBar() -{ - QDBusConnection connection = QDBusConnection::sessionBus(); - - if (m_window) { - QDBusMenuRegistrarInterface registrar(REGISTRAR_SERVICE, REGISTRAR_PATH, connection, this); - QDBusPendingReply<> r = registrar.UnregisterWindow(static_cast(window()->winId())); - r.waitForFinished(); - if (r.isError()) - qWarning("Failed to unregister window menu, reason: %s (\"%s\")", - qUtf8Printable(r.error().name()), qUtf8Printable(r.error().message())); - } - - if (!m_objectPath.isEmpty()) - connection.unregisterObject(m_objectPath); -} - -QT_END_NAMESPACE diff --git a/platformtheme/qdbusmenubar_p.h b/platformtheme/qdbusmenubar_p.h deleted file mode 100644 index a4afdb8..0000000 --- a/platformtheme/qdbusmenubar_p.h +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Dmitry Shachnev -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDBUSMENUBAR_P_H -#define QDBUSMENUBAR_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QDBusMenuBar : public QPlatformMenuBar -{ - Q_OBJECT - -public: - QDBusMenuBar(); - ~QDBusMenuBar() override; - - void insertMenu(QPlatformMenu *menu, QPlatformMenu *before) override; - void removeMenu(QPlatformMenu *menu) override; - void syncMenu(QPlatformMenu *menu) override; - void handleReparent(QWindow *newParentWindow) override; - QPlatformMenu *menuForTag(quintptr tag) const override; - QPlatformMenu *createMenu() const override; - - QWindow *window() const { return m_window; } - QString objectPath() const { return m_objectPath; } - -Q_SIGNALS: - void windowChanged(QWindow *newWindow, QWindow *oldWindow); - -private: - QDBusPlatformMenu *m_menu; - QDBusMenuAdaptor *m_menuAdaptor; - QHash m_menuItems; - QPointer m_window; - QString m_objectPath; - - QDBusPlatformMenuItem *menuItemForMenu(QPlatformMenu *menu); - static void updateMenuItem(QDBusPlatformMenuItem *item, QPlatformMenu *menu); - void registerMenuBar(); - void unregisterMenuBar(); -}; - -QT_END_NAMESPACE - -#endif // QDBUSMENUBAR_P_H