File qdbusmenu-Add-native-support-for-DBus-global-menu.patch of Package libqt5-qtbase.8869
From b6a824d0a3b4fabd9c22fe4c954d50e8755fb509 Mon Sep 17 00:00:00 2001
From: Dmitry Shachnev <mitya57@gmail.com>
Date: Fri, 15 Jan 2016 17:04:01 +0300
Subject: [PATCH] Add native support for D-Bus global menu
The protocol was originally developed by Canonical, currently supported
by Unity and Plasma.
Adjust some tests to use the non-native menu bar when they require it.
[ChangeLog][XCB / X11] QMenuBar uses the unified D-Bus AppMenu menubar
when the desktop environment supports it.
Change-Id: Iea74b40522573bcc4f70168fe7fa2a49b4f3fc21
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
---
.../com.canonical.AppMenu.Registrar.xml | 56 +++++++
src/platformsupport/dbusmenu/dbusmenu.pri | 4 +
src/platformsupport/dbusmenu/qdbusmenubar.cpp | 172 +++++++++++++++++++++
src/platformsupport/dbusmenu/qdbusmenubar_p.h | 91 +++++++++++
.../dbusmenu/qdbusmenuregistrarproxy.cpp | 64 ++++++++
.../dbusmenu/qdbusmenuregistrarproxy_p.h | 127 +++++++++++++++
.../themes/genericunix/qgenericunixthemes.cpp | 68 +++++++-
.../themes/genericunix/qgenericunixthemes_p.h | 12 ++
.../other/qaccessibility/tst_qaccessibility.cpp | 1 +
.../auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp | 5 +-
.../widgets/qmdisubwindow/tst_qmdisubwindow.cpp | 5 +-
tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp | 1 +
.../auto/widgets/widgets/qmenubar/tst_qmenubar.cpp | 5 +
13 files changed, 607 insertions(+), 4 deletions(-)
create mode 100644 src/3rdparty/dbus-ifaces/com.canonical.AppMenu.Registrar.xml
create mode 100644 src/platformsupport/dbusmenu/qdbusmenubar.cpp
create mode 100644 src/platformsupport/dbusmenu/qdbusmenubar_p.h
create mode 100644 src/platformsupport/dbusmenu/qdbusmenuregistrarproxy.cpp
create mode 100644 src/platformsupport/dbusmenu/qdbusmenuregistrarproxy_p.h
--- /dev/null
+++ b/src/3rdparty/dbus-ifaces/com.canonical.AppMenu.Registrar.xml
@@ -0,0 +1,56 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
+ <dox:d><![CDATA[
+ @mainpage
+
+ An interface to register menus that are associated with a window in an application. The
+ main interface is documented here: @ref com::canonical::AppMenu::Registrar.
+
+ The actual menus are transported using the dbusmenu protocol which is available
+ here: @ref com::canonical::dbusmenu.
+ ]]></dox:d>
+ <interface name="com.canonical.AppMenu.Registrar" xmlns:dox="http://www.ayatana.org/dbus/dox.dtd">
+ <dox:d>
+ An interface to register a menu from an application's window to be displayed in another
+ window. This manages that association between XWindow Window IDs and the dbus
+ address and object that provides the menu using the dbusmenu dbus interface.
+ </dox:d>
+ <method name="RegisterWindow">
+ <dox:d><![CDATA[
+ Associates a dbusmenu with a window
+
+ /note this method assumes that the connection from the caller is the DBus connection
+ to use for the object. Applications that use multiple DBus connections will need to
+ ensure this method is called with the same connection that implmenets the object.
+ ]]></dox:d>
+ <arg name="windowId" type="u" direction="in">
+ <dox:d>The XWindow ID of the window</dox:d>
+ </arg>
+ <arg name="menuObjectPath" type="o" direction="in">
+ <dox:d>The object on the dbus interface implementing the dbusmenu interface</dox:d>
+ </arg>
+ </method>
+ <method name="UnregisterWindow">
+ <dox:d>
+ A method to allow removing a window from the database. Windows will also be removed
+ when the client drops off DBus so this is not required. It is polite though. And
+ important for testing.
+ </dox:d>
+ <arg name="windowId" type="u" direction="in">
+ <dox:d>The XWindow ID of the window</dox:d>
+ </arg>
+ </method>
+ <method name="GetMenuForWindow">
+ <dox:d>Gets the registered menu for a given window ID.</dox:d>
+ <arg name="windowId" type="u" direction="in">
+ <dox:d>The XWindow ID of the window to get</dox:d>
+ </arg>
+ <arg name="service" type="s" direction="out">
+ <dox:d>The address of the connection on DBus (e.g. :1.23 or org.example.service)</dox:d>
+ </arg>
+ <arg name="menuObjectPath" type="o" direction="out">
+ <dox:d>The path to the object which implements the com.canonical.dbusmenu interface.</dox:d>
+ </arg>
+ </method>
+ </interface>
+</node>
--- a/src/platformsupport/dbusmenu/dbusmenu.pri
+++ b/src/platformsupport/dbusmenu/dbusmenu.pri
@@ -6,10 +6,14 @@ HEADERS += \
$$PWD/qdbusmenuadaptor_p.h \
$$PWD/qdbusmenutypes_p.h \
$$PWD/qdbusmenuconnection_p.h \
+ $$PWD/qdbusmenubar_p.h \
+ $$PWD/qdbusmenuregistrarproxy_p.h \
$$PWD/qdbusplatformmenu_p.h \
SOURCES += \
$$PWD/qdbusmenuadaptor.cpp \
$$PWD/qdbusmenutypes.cpp \
$$PWD/qdbusmenuconnection.cpp \
+ $$PWD/qdbusmenubar.cpp \
+ $$PWD/qdbusmenuregistrarproxy.cpp \
$$PWD/qdbusplatformmenu.cpp \
--- /dev/null
+++ b/src/platformsupport/dbusmenu/qdbusmenubar.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Dmitry Shachnev <mitya57@gmail.com>
+** 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$
+**
+****************************************************************************/
+
+#include "qdbusmenubar_p.h"
+#include "qdbusmenuregistrarproxy_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))
+ , m_windowId(0)
+{
+ QDBusMenuItem::registerDBusTypes();
+ connect(m_menu, &QDBusPlatformMenu::propertiesUpdated,
+ m_menuAdaptor, &QDBusMenuAdaptor::ItemsPropertiesUpdated);
+ connect(m_menu, &QDBusPlatformMenu::updated,
+ m_menuAdaptor, &QDBusMenuAdaptor::LayoutUpdated);
+}
+
+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<const QDBusPlatformMenu *>(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 && newParentWindow->winId() != m_windowId) {
+ unregisterMenuBar();
+ m_windowId = newParentWindow->winId();
+ registerMenuBar();
+ }
+}
+
+QPlatformMenu *QDBusMenuBar::menuForTag(quintptr tag) const
+{
+ QDBusPlatformMenuItem *menuItem = m_menuItems.value(tag);
+ if (menuItem)
+ return const_cast<QPlatformMenu *>(menuItem->menu());
+ return nullptr;
+}
+
+void QDBusMenuBar::registerMenuBar()
+{
+ static uint menuBarId = 0;
+
+ 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(m_windowId, 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_windowId) {
+ QDBusMenuRegistrarInterface registrar(REGISTRAR_SERVICE, REGISTRAR_PATH, connection, this);
+ QDBusPendingReply<> r = registrar.UnregisterWindow(m_windowId);
+ 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
--- /dev/null
+++ b/src/platformsupport/dbusmenu/qdbusmenubar_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Dmitry Shachnev <mitya57@gmail.com>
+** 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 <private/qdbusplatformmenu_p.h>
+#include <private/qdbusmenuadaptor_p.h>
+#include <QtCore/QHash>
+#include <QtCore/QString>
+#include <QtGui/QWindow>
+
+QT_BEGIN_NAMESPACE
+
+class QDBusMenuBar : public QPlatformMenuBar
+{
+ Q_OBJECT
+
+public:
+ QDBusMenuBar();
+ virtual ~QDBusMenuBar();
+
+ void insertMenu(QPlatformMenu *menu, QPlatformMenu *before) Q_DECL_OVERRIDE;
+ void removeMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE;
+ void syncMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE;
+ void handleReparent(QWindow *newParentWindow) Q_DECL_OVERRIDE;
+ QPlatformMenu *menuForTag(quintptr tag) const Q_DECL_OVERRIDE;
+
+private:
+ QDBusPlatformMenu *m_menu;
+ QDBusMenuAdaptor *m_menuAdaptor;
+ QHash<quintptr, QDBusPlatformMenuItem *> m_menuItems;
+ uint m_windowId;
+ 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
--- /dev/null
+++ b/src/platformsupport/dbusmenu/qdbusmenuregistrarproxy.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Dmitry Shachnev <mitya57@gmail.com>
+** 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$
+**
+****************************************************************************/
+
+/*
+ * This file was originally created by qdbusxml2cpp version 0.8
+ * Command line was: qdbusxml2cpp -p qdbusmenuregistrarproxy ../../3rdparty/dbus-ifaces/com.canonical.AppMenu.Registrar.xml
+ *
+ * However it is maintained manually.
+ */
+
+#include "qdbusmenuregistrarproxy_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*
+ * Implementation of interface class QDBusMenuRegistrarInterface
+ */
+
+QDBusMenuRegistrarInterface::QDBusMenuRegistrarInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent)
+ : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent)
+{
+}
+
+QDBusMenuRegistrarInterface::~QDBusMenuRegistrarInterface()
+{
+}
+
+QT_END_NAMESPACE
--- /dev/null
+++ b/src/platformsupport/dbusmenu/qdbusmenuregistrarproxy_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Dmitry Shachnev <mitya57@gmail.com>
+** 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$
+**
+****************************************************************************/
+
+/*
+ * This file was originally created by qdbusxml2cpp version 0.8
+ * Command line was: qdbusxml2cpp -p qdbusmenuregistrarproxy ../../3rdparty/dbus-ifaces/com.canonical.AppMenu.Registrar.xml
+ *
+ * However it is maintained manually.
+ */
+
+#ifndef QDBUSMENUREGISTRARPROXY_P_H
+#define QDBUSMENUREGISTRARPROXY_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 <QtCore/QObject>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QVariant>
+#include <QtDBus/QDBusAbstractInterface>
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusReply>
+
+QT_BEGIN_NAMESPACE
+
+/*
+ * Proxy class for interface com.canonical.AppMenu.Registrar
+ */
+class QDBusMenuRegistrarInterface : public QDBusAbstractInterface
+{
+ Q_OBJECT
+public:
+ static inline const char *staticInterfaceName()
+ {
+ return "com.canonical.AppMenu.Registrar";
+ }
+
+public:
+ explicit QDBusMenuRegistrarInterface(const QString &service,
+ const QString &path,
+ const QDBusConnection &connection,
+ QObject *parent = nullptr);
+
+ ~QDBusMenuRegistrarInterface();
+
+public Q_SLOTS: // METHODS
+ QDBusPendingReply<QString, QDBusObjectPath> GetMenuForWindow(uint windowId)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(windowId);
+ return asyncCallWithArgumentList(QStringLiteral("GetMenuForWindow"), argumentList);
+ }
+ QDBusReply<QString> GetMenuForWindow(uint windowId, QDBusObjectPath &menuObjectPath)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(windowId);
+ QDBusMessage reply = callWithArgumentList(QDBus::Block, QStringLiteral("GetMenuForWindow"), argumentList);
+ QList<QVariant> arguments = reply.arguments();
+ if (reply.type() == QDBusMessage::ReplyMessage && arguments.count() == 2)
+ menuObjectPath = qdbus_cast<QDBusObjectPath>(arguments.at(1));
+ return reply;
+ }
+
+ QDBusPendingReply<> RegisterWindow(uint windowId, const QDBusObjectPath &menuObjectPath)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(windowId) << QVariant::fromValue(menuObjectPath);
+ return asyncCallWithArgumentList(QStringLiteral("RegisterWindow"), argumentList);
+ }
+
+ QDBusPendingReply<> UnregisterWindow(uint windowId)
+ {
+ QList<QVariant> argumentList;
+ argumentList << QVariant::fromValue(windowId);
+ return asyncCallWithArgumentList(QStringLiteral("UnregisterWindow"), argumentList);
+ }
+};
+
+QT_END_NAMESPACE
+
+#endif // QDBUSMENUREGISTRARPROXY_P_H
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
@@ -53,9 +53,12 @@
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformservices.h>
#include <qpa/qplatformdialoghelper.h>
+#ifndef QT_NO_DBUS
+#include "QtPlatformSupport/private/qdbusplatformmenu_p.h"
+#include "QtPlatformSupport/private/qdbusmenubar_p.h"
+#endif
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
#include "QtPlatformSupport/private/qdbustrayicon_p.h"
-#include "QtPlatformSupport/private/qdbusplatformmenu_p.h"
#endif
#include <algorithm>
@@ -108,6 +111,21 @@ static bool isDBusTrayAvailable() {
}
#endif
+#ifndef QT_NO_DBUS
+static bool checkDBusGlobalMenuAvailable()
+{
+ QDBusConnection connection = QDBusConnection::sessionBus();
+ QString registrarService = QStringLiteral("com.canonical.AppMenu.Registrar");
+ return connection.interface()->isServiceRegistered(registrarService);
+}
+
+static bool isDBusGlobalMenuAvailable()
+{
+ static bool dbusGlobalMenuAvailable = checkDBusGlobalMenuAvailable();
+ return dbusGlobalMenuAvailable;
+}
+#endif
+
class QGenericUnixThemePrivate : public QPlatformThemePrivate
{
public:
@@ -166,6 +184,22 @@ QStringList QGenericUnixTheme::xdgIconTh
return paths;
}
+#ifndef QT_NO_DBUS
+QPlatformMenu *QGenericUnixTheme::createPlatformMenu() const
+{
+ if (isDBusGlobalMenuAvailable())
+ return new QDBusPlatformMenu();
+ return nullptr;
+}
+
+QPlatformMenuBar *QGenericUnixTheme::createPlatformMenuBar() const
+{
+ if (isDBusGlobalMenuAvailable())
+ return new QDBusMenuBar();
+ return nullptr;
+}
+#endif
+
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
QPlatformSystemTrayIcon *QGenericUnixTheme::createPlatformSystemTrayIcon() const
{
@@ -553,6 +587,22 @@ QPlatformTheme *QKdeTheme::createKdeThem
return new QKdeTheme(kdeDirs, kdeVersion);
}
+#ifndef QT_NO_DBUS
+QPlatformMenu *QKdeTheme::createPlatformMenu() const
+{
+ if (isDBusGlobalMenuAvailable())
+ return new QDBusPlatformMenu();
+ return nullptr;
+}
+
+QPlatformMenuBar *QKdeTheme::createPlatformMenuBar() const
+{
+ if (isDBusGlobalMenuAvailable())
+ return new QDBusMenuBar();
+ return nullptr;
+}
+#endif
+
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
QPlatformSystemTrayIcon *QKdeTheme::createPlatformSystemTrayIcon() const
{
@@ -649,6 +699,22 @@ QString QGnomeTheme::gtkFontName() const
return QStringLiteral("%1 %2").arg(QLatin1String(defaultSystemFontNameC)).arg(defaultSystemFontSize);
}
+#ifndef QT_NO_DBUS
+QPlatformMenu *QGnomeTheme::createPlatformMenu() const
+{
+ if (isDBusGlobalMenuAvailable())
+ return new QDBusPlatformMenu();
+ return nullptr;
+}
+
+QPlatformMenuBar *QGnomeTheme::createPlatformMenuBar() const
+{
+ if (isDBusGlobalMenuAvailable())
+ return new QDBusMenuBar();
+ return nullptr;
+}
+#endif
+
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
QPlatformSystemTrayIcon *QGnomeTheme::createPlatformSystemTrayIcon() const
{
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
@@ -79,6 +79,10 @@ public:
QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE;
static QStringList xdgIconThemePaths();
+#ifndef QT_NO_DBUS
+ QPlatformMenu *createPlatformMenu() const Q_DECL_OVERRIDE;
+ QPlatformMenuBar *createPlatformMenuBar() const Q_DECL_OVERRIDE;
+#endif
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const Q_DECL_OVERRIDE;
#endif
@@ -101,6 +105,10 @@ public:
const QPalette *palette(Palette type = SystemPalette) const Q_DECL_OVERRIDE;
const QFont *font(Font type) const Q_DECL_OVERRIDE;
+#ifndef QT_NO_DBUS
+ QPlatformMenu *createPlatformMenu() const Q_DECL_OVERRIDE;
+ QPlatformMenuBar *createPlatformMenuBar() const Q_DECL_OVERRIDE;
+#endif
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const Q_DECL_OVERRIDE;
#endif
@@ -121,6 +129,10 @@ public:
QString standardButtonText(int button) const Q_DECL_OVERRIDE;
virtual QString gtkFontName() const;
+#ifndef QT_NO_DBUS
+ QPlatformMenu *createPlatformMenu() const Q_DECL_OVERRIDE;
+ QPlatformMenuBar *createPlatformMenuBar() const Q_DECL_OVERRIDE;
+#endif
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const Q_DECL_OVERRIDE;
#endif
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -1421,6 +1421,7 @@ void tst_QAccessibility::menuTest()
{
QMainWindow mw;
mw.resize(300, 200);
+ mw.menuBar()->setNativeMenuBar(false);
QMenu *file = mw.menuBar()->addMenu("&File");
QMenu *fileNew = file->addMenu("&New...");
fileNew->menuAction()->setShortcut(tr("Ctrl+N"));
--- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
+++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp
@@ -634,7 +634,7 @@ void tst_QMdiArea::changeWindowTitle()
mw->setWindowTitle( mwc );
QMdiArea *ws = new QMdiArea( mw );
mw->setCentralWidget( ws );
- mw->menuBar();
+ mw->menuBar()->setNativeMenuBar(false);
mw->show();
QVERIFY(QTest::qWaitForWindowExposed(mw));
@@ -743,7 +743,7 @@ void tst_QMdiArea::changeModified()
mw->setWindowTitle( mwc );
QMdiArea *ws = new QMdiArea( mw );
mw->setCentralWidget( ws );
- mw->menuBar();
+ mw->menuBar()->setNativeMenuBar(false);
mw->show();
QWidget *widget = new QWidget( ws );
@@ -2008,6 +2008,7 @@ void tst_QMdiArea::iconGeometryInMenuBar
#if !defined (Q_OS_MAC) && !defined(Q_OS_WINCE)
QMainWindow mainWindow;
QMenuBar *menuBar = mainWindow.menuBar();
+ menuBar->setNativeMenuBar(false);
QMdiArea *mdiArea = new QMdiArea;
QMdiSubWindow *subWindow = mdiArea->addSubWindow(new QWidget);
mainWindow.setCentralWidget(mdiArea);
--- a/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
+++ b/tests/auto/widgets/widgets/qmdisubwindow/tst_qmdisubwindow.cpp
@@ -970,7 +970,7 @@ void tst_QMdiSubWindow::setSystemMenu()
QMdiArea *mdiArea = new QMdiArea;
mdiArea->addSubWindow(subWindow);
mainWindow.setCentralWidget(mdiArea);
- mainWindow.menuBar();
+ mainWindow.menuBar()->setNativeMenuBar(false);
mainWindow.show();
QVERIFY(QTest::qWaitForWindowExposed(&mainWindow));
QTest::qWait(60);
@@ -1470,6 +1470,7 @@ void tst_QMdiSubWindow::hideAndShow()
QMainWindow mainWindow;
mainWindow.setGeometry(0, 0, 640, 480);
QMenuBar *menuBar = mainWindow.menuBar();
+ menuBar->setNativeMenuBar(false);
mainWindow.setCentralWidget(tabWidget);
mainWindow.show();
QVERIFY(QTest::qWaitForWindowExposed(&mainWindow));
@@ -1738,6 +1739,7 @@ void tst_QMdiSubWindow::replaceMenuBarWh
mainWindow.setCentralWidget(mdiArea);
QMenuBar *menuBar = mainWindow.menuBar();
+ menuBar->setNativeMenuBar(false);
mainWindow.show();
QVERIFY(QTest::qWaitForWindowExposed(&mainWindow));
@@ -1754,6 +1756,7 @@ void tst_QMdiSubWindow::replaceMenuBarWh
// Replace.
mainWindow.setMenuBar(new QMenuBar);
menuBar = mainWindow.menuBar();
+ menuBar->setNativeMenuBar(false);
qApp->processEvents();
QVERIFY(subWindow->maximizedButtonsWidget());
--- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
+++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
@@ -455,6 +455,7 @@ void tst_QMenu::overrideMenuAction()
//test the override menu action by first creating an action to which we set its menu
QMainWindow w;
w.resize(300, 200);
+ w.menuBar()->setNativeMenuBar(false);
centerOnScreen(&w);
QAction *aFileMenu = new QAction("&File", &w);
--- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
+++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp
@@ -211,6 +211,7 @@ void tst_QMenuBar::cleanup()
TestMenu tst_QMenuBar::initSimpleMenuBar(QMenuBar *mb)
{
TestMenu result;
+ mb->setNativeMenuBar(false);
connect(mb, SIGNAL(triggered(QAction*)), this, SLOT(onSimpleActivated(QAction*)));
QMenu *menu = mb->addMenu(QStringLiteral("&accel"));
QAction *action = menu->addAction(QStringLiteral("menu1") );
@@ -278,6 +279,7 @@ void tst_QMenuBar::onComplexActionTrigge
TestMenu tst_QMenuBar::initComplexMenuBar(QMenuBar *mb)
{
TestMenu result;
+ mb->setNativeMenuBar(false);
QMenu *menu = addNumberedMenu(mb, 1);
result.menus << menu;
for (char c = 'a'; c < 'c'; ++c)
@@ -991,6 +993,7 @@ void tst_QMenuBar::check_altClosePress()
QMainWindow w;
w.setWindowTitle(QTest::currentTestFunction());
+ w.menuBar()->setNativeMenuBar(false);
QMenu *menuFile = w.menuBar()->addMenu(tr("&File"));
menuFile->addAction("Quit");
QMenu *menuEdit = w.menuBar()->addMenu(tr("&Edit"));
@@ -1066,6 +1069,7 @@ void tst_QMenuBar::check_menuPosition()
menu.addAction("item");
}
+ w.menuBar()->setNativeMenuBar(false);
QAction *menu_action = w.menuBar()->addMenu(&menu);
centerOnScreen(&w);
w.show();
@@ -1399,6 +1403,7 @@ void tst_QMenuBar::cornerWidgets()
widget.setWindowTitle(QLatin1String(QTest::currentTestFunction()) + dataTag);
QVBoxLayout *layout = new QVBoxLayout(&widget);
QMenuBar *menuBar = new QMenuBar(&widget);
+ menuBar->setNativeMenuBar(false);
layout->addWidget(menuBar);
QMenu *fileMenu = menuBar->addMenu("File");
fileMenu->addAction("Quit");