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>bb10
parent
950bb7185c
commit
b6a824d0a3
|
|
@ -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>
|
||||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -59,9 +59,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>
|
||||
|
|
@ -114,6 +117,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:
|
||||
|
|
@ -172,6 +190,22 @@ QStringList QGenericUnixTheme::xdgIconThemePaths()
|
|||
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
|
||||
{
|
||||
|
|
@ -559,6 +593,22 @@ QPlatformTheme *QKdeTheme::createKdeTheme()
|
|||
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
|
||||
{
|
||||
|
|
@ -655,6 +705,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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -85,6 +85,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
|
||||
|
|
@ -107,6 +111,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
|
||||
|
|
@ -127,6 +135,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
|
||||
|
|
|
|||
|
|
@ -1411,6 +1411,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"));
|
||||
|
|
|
|||
|
|
@ -632,7 +632,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));
|
||||
|
||||
|
|
@ -741,7 +741,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 );
|
||||
|
|
@ -2006,6 +2006,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);
|
||||
|
|
|
|||
|
|
@ -967,7 +967,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);
|
||||
|
|
@ -1467,6 +1467,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));
|
||||
|
|
@ -1735,6 +1736,7 @@ void tst_QMdiSubWindow::replaceMenuBarWhileMaximized()
|
|||
|
||||
mainWindow.setCentralWidget(mdiArea);
|
||||
QMenuBar *menuBar = mainWindow.menuBar();
|
||||
menuBar->setNativeMenuBar(false);
|
||||
mainWindow.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&mainWindow));
|
||||
|
||||
|
|
@ -1751,6 +1753,7 @@ void tst_QMdiSubWindow::replaceMenuBarWhileMaximized()
|
|||
// Replace.
|
||||
mainWindow.setMenuBar(new QMenuBar);
|
||||
menuBar = mainWindow.menuBar();
|
||||
menuBar->setNativeMenuBar(false);
|
||||
qApp->processEvents();
|
||||
|
||||
QVERIFY(subWindow->maximizedButtonsWidget());
|
||||
|
|
|
|||
|
|
@ -447,6 +447,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);
|
||||
|
|
|
|||
|
|
@ -206,6 +206,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") );
|
||||
|
|
@ -273,6 +274,7 @@ void tst_QMenuBar::onComplexActionTriggered()
|
|||
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)
|
||||
|
|
@ -986,6 +988,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"));
|
||||
|
|
@ -1061,6 +1064,7 @@ void tst_QMenuBar::check_menuPosition()
|
|||
menu.addAction("item");
|
||||
}
|
||||
|
||||
w.menuBar()->setNativeMenuBar(false);
|
||||
QAction *menu_action = w.menuBar()->addMenu(&menu);
|
||||
centerOnScreen(&w);
|
||||
w.show();
|
||||
|
|
@ -1394,6 +1398,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");
|
||||
|
|
|
|||
Loading…
Reference in New Issue