Add createMenu() method to QPlatformMenuBar

The D-Bus platform menus are only useful inside menu bars and system
tray icons, and should not be created for other cases (like the context
menus).

This adds a new virtual createMenu() method to QPlatformMenuBar class,
analogous to the already existing QPlatformSystemTrayIcon::createMenu()
method, and adds support for it to QMenuBar.

The D-Bus platform menus are now created from QDBusMenuBar class. As an
additional benefit, we no longer have to check whether the AppMenu
Registrar service is present for every created menu, and check it only
once (this should speed things a bit up).

Change-Id: Ic7d94e58a501ab9d2954aeb342ebd46ef8e62d49
Reviewed-by: J-P Nurmi <jpnurmi@theqtcompany.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
This commit is contained in:
Dmitry Shachnev 2016-02-27 20:55:41 +03:00
parent d804ea01f0
commit e4d79e1fde
7 changed files with 22 additions and 31 deletions

View File

@ -148,6 +148,7 @@ public:
virtual void handleReparent(QWindow *newParentWindow) = 0;
virtual QPlatformMenu *menuForTag(quintptr tag) const = 0;
virtual QPlatformMenu *createMenu() const { return nullptr; }
};
QT_END_NAMESPACE

View File

@ -133,6 +133,11 @@ QPlatformMenu *QDBusMenuBar::menuForTag(quintptr tag) const
return nullptr;
}
QPlatformMenu *QDBusMenuBar::createMenu() const
{
return new QDBusPlatformMenu;
}
void QDBusMenuBar::registerMenuBar()
{
static uint menuBarId = 0;

View File

@ -72,6 +72,7 @@ public:
void syncMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE;
void handleReparent(QWindow *newParentWindow) Q_DECL_OVERRIDE;
QPlatformMenu *menuForTag(quintptr tag) const Q_DECL_OVERRIDE;
QPlatformMenu *createMenu() const Q_DECL_OVERRIDE;
private:
QDBusPlatformMenu *m_menu;

View File

@ -191,13 +191,6 @@ QStringList QGenericUnixTheme::xdgIconThemePaths()
}
#ifndef QT_NO_DBUS
QPlatformMenu *QGenericUnixTheme::createPlatformMenu() const
{
if (isDBusGlobalMenuAvailable())
return new QDBusPlatformMenu();
return nullptr;
}
QPlatformMenuBar *QGenericUnixTheme::createPlatformMenuBar() const
{
if (isDBusGlobalMenuAvailable())
@ -594,13 +587,6 @@ QPlatformTheme *QKdeTheme::createKdeTheme()
}
#ifndef QT_NO_DBUS
QPlatformMenu *QKdeTheme::createPlatformMenu() const
{
if (isDBusGlobalMenuAvailable())
return new QDBusPlatformMenu();
return nullptr;
}
QPlatformMenuBar *QKdeTheme::createPlatformMenuBar() const
{
if (isDBusGlobalMenuAvailable())
@ -706,13 +692,6 @@ QString QGnomeTheme::gtkFontName() const
}
#ifndef QT_NO_DBUS
QPlatformMenu *QGnomeTheme::createPlatformMenu() const
{
if (isDBusGlobalMenuAvailable())
return new QDBusPlatformMenu();
return nullptr;
}
QPlatformMenuBar *QGnomeTheme::createPlatformMenuBar() const
{
if (isDBusGlobalMenuAvailable())

View File

@ -86,7 +86,6 @@ public:
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)
@ -112,7 +111,6 @@ public:
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)
@ -136,7 +134,6 @@ public:
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)

View File

@ -1210,12 +1210,19 @@ void QMenuBar::leaveEvent(QEvent *)
d->setCurrentAction(0);
}
QPlatformMenu *getPlatformMenu(QAction *action)
QPlatformMenu *QMenuBarPrivate::getPlatformMenu(QAction *action)
{
if (!action || !action->menu())
return 0;
return action->menu()->platformMenu();
QPlatformMenu *platformMenu = action->menu()->platformMenu();
if (!platformMenu && platformMenuBar) {
platformMenu = platformMenuBar->createMenu();
if (platformMenu)
action->menu()->setPlatformMenu(platformMenu);
}
return platformMenu;
}
/*!
@ -1236,14 +1243,14 @@ void QMenuBar::actionEvent(QActionEvent *e)
return;
if (e->type() == QEvent::ActionAdded) {
QPlatformMenu *menu = getPlatformMenu(e->action());
QPlatformMenu *menu = d->getPlatformMenu(e->action());
if (menu) {
QPlatformMenu* beforeMenu = NULL;
for (int beforeIndex = d->indexOf(e->action()) + 1;
!beforeMenu && (beforeIndex < actions().size());
++beforeIndex)
{
beforeMenu = getPlatformMenu(actions().at(beforeIndex));
beforeMenu = d->getPlatformMenu(actions().at(beforeIndex));
}
menu->setTag(reinterpret_cast<quintptr>(e->action()));
@ -1251,12 +1258,12 @@ void QMenuBar::actionEvent(QActionEvent *e)
d->platformMenuBar->insertMenu(menu, beforeMenu);
}
} else if (e->type() == QEvent::ActionRemoved) {
QPlatformMenu *menu = getPlatformMenu(e->action());
QPlatformMenu *menu = d->getPlatformMenu(e->action());
if (menu)
d->platformMenuBar->removeMenu(menu);
} else if (e->type() == QEvent::ActionChanged) {
QPlatformMenu* cur = d->platformMenuBar->menuForTag(reinterpret_cast<quintptr>(e->action()));
QPlatformMenu *menu = getPlatformMenu(e->action());
QPlatformMenu *menu = d->getPlatformMenu(e->action());
// the menu associated with the action can change, need to
// remove and/or insert the new platform menu
@ -1271,7 +1278,7 @@ void QMenuBar::actionEvent(QActionEvent *e)
!beforeMenu && (beforeIndex < actions().size());
++beforeIndex)
{
beforeMenu = getPlatformMenu(actions().at(beforeIndex));
beforeMenu = d->getPlatformMenu(actions().at(beforeIndex));
}
d->platformMenuBar->insertMenu(menu, beforeMenu);
}

View File

@ -143,6 +143,7 @@ public:
QBasicTimer autoReleaseTimer;
QPlatformMenuBar *platformMenuBar;
QPlatformMenu *getPlatformMenu(QAction *action);
inline int indexOf(QAction *act) const { return q_func()->actions().indexOf(act); }