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
Dmitry Shachnev 2016-01-15 17:04:01 +03:00 committed by Shawn Rutledge
parent 950bb7185c
commit b6a824d0a3
13 changed files with 607 additions and 4 deletions

View File

@ -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>

View File

@ -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 \

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
{

View File

@ -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

View File

@ -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"));

View File

@ -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);

View File

@ -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());

View File

@ -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);

View File

@ -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");