D-Bus tray icon menus: support submenus

In this case GetLayout will be called with the D-Bus menu ID of the
menu item which contains the submenu.

Task-number: QTBUG-45191
Change-Id: Ia8108272910eac10f040db5865ec4e070da80edb
Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>
bb10
Shawn Rutledge 2015-03-25 13:33:39 +01:00 committed by Frederik Gladhorn
parent ffc74e6d70
commit 509f77cca2
5 changed files with 36 additions and 26 deletions

View File

@ -87,26 +87,32 @@ uint QDBusMenuLayoutItem::populate(int id, int depth, const QStringList &propert
m_properties.insert(QLatin1String("children-display"), QLatin1String("submenu"));
Q_FOREACH (const QDBusPlatformMenu *menu, QDBusPlatformMenu::topLevelMenus()) {
if (menu)
Q_FOREACH (const QDBusPlatformMenuItem *item, menu->items()) {
QDBusMenuLayoutItem child;
child.populate(item, depth - 1, propertyNames);
m_children << child;
}
populate(menu, depth, propertyNames);
}
} else {
// TODO insert menu properties (name-value pairs)
return 1; // revision
}
QDBusPlatformMenu *menu = QDBusPlatformMenu::byId(id);
if (depth != 0 && menu) {
Q_FOREACH (QDBusPlatformMenuItem *item, menu->items()) {
QDBusMenuLayoutItem child;
child.populate(item, depth - 1, propertyNames);
m_children << child;
}
const QDBusPlatformMenu *menu = QDBusPlatformMenu::byId(id);
if (!menu) {
QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id);
if (item)
menu = static_cast<const QDBusPlatformMenu *>(item->menu());
}
if (depth != 0 && menu)
populate(menu, depth, propertyNames);
if (menu)
return menu->revision();
return 1;
return 1; // revision
}
void QDBusMenuLayoutItem::populate(const QDBusPlatformMenu *menu, int depth, const QStringList &propertyNames)
{
Q_FOREACH (QDBusPlatformMenuItem *item, menu->items()) {
QDBusMenuLayoutItem child;
child.populate(item, depth - 1, propertyNames);
m_children << child;
}
}
void QDBusMenuLayoutItem::populate(const QDBusPlatformMenuItem *item, int depth, const QStringList &propertyNames)
@ -116,7 +122,6 @@ void QDBusMenuLayoutItem::populate(const QDBusPlatformMenuItem *item, int depth,
m_id = item->dbusID();
QDBusMenuItem proxy(item);
m_properties = proxy.m_properties;
// TODO populate m_children
}
const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuLayoutItem &item)

View File

@ -82,6 +82,7 @@ class QDBusMenuLayoutItem
{
public:
uint populate(int id, int depth, const QStringList &propertyNames);
void populate(const QDBusPlatformMenu *menu, int depth, const QStringList &propertyNames);
void populate(const QDBusPlatformMenuItem *item, int depth, const QStringList &propertyNames);
int m_id;

View File

@ -43,6 +43,7 @@ Q_LOGGING_CATEGORY(qLcMenu, "qt.qpa.menu")
static int nextDBusID = 1;
QHash<int, QDBusPlatformMenu *> menusByID;
QHash<int, QDBusPlatformMenuItem *> menuItemsByID;
QList<QDBusPlatformMenu *> QDBusPlatformMenu::m_topLevelMenus;
QDBusPlatformMenuItem::QDBusPlatformMenuItem(quintptr tag)
: m_tag(tag ? tag : reinterpret_cast<quintptr>(this)) // QMenu will overwrite this later
@ -144,6 +145,8 @@ QDBusPlatformMenu::QDBusPlatformMenu(quintptr tag)
, m_revision(0)
{
menusByID.insert(m_dbusID, this);
// Assume it's top-level until we find out otherwise
m_topLevelMenus << this;
}
QDBusPlatformMenu::~QDBusPlatformMenu()
@ -162,6 +165,9 @@ void QDBusPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMen
else
m_items.insert(idx, item);
m_itemsByTag.insert(item->tag(), item);
// If a menu is found as a submenu under an item, we know that it's not a top-level menu.
if (item->menu())
m_topLevelMenus.removeOne(const_cast<QDBusPlatformMenu *>(static_cast<const QDBusPlatformMenu *>(item->menu())));
}
void QDBusPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem)
@ -188,12 +194,6 @@ QDBusPlatformMenu *QDBusPlatformMenu::byId(int id)
return menusByID[id];
}
QList<QDBusPlatformMenu *> QDBusPlatformMenu::topLevelMenus()
{
// TODO just the top-level menus, not all menus
return menusByID.values();
}
void QDBusPlatformMenu::emitUpdated()
{
emit updated(++m_revision, m_dbusID);

View File

@ -133,6 +133,8 @@ public:
void setFont(const QFont &font) Q_DECL_OVERRIDE { Q_UNUSED(font); }
void setMenuType(MenuType type) Q_DECL_OVERRIDE { Q_UNUSED(type); }
int dbusID() const { return m_dbusID; }
void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) Q_DECL_OVERRIDE
{
Q_UNUSED(parentWindow);
@ -152,9 +154,9 @@ public:
bool operator==(const QDBusPlatformMenu& other) { return m_tag == other.m_tag; }
static QDBusPlatformMenu* byId(int id);
static QList<QDBusPlatformMenu *> topLevelMenus();
static QList<QDBusPlatformMenu *> topLevelMenus() { return m_topLevelMenus; }
uint revision() { return m_revision; }
uint revision() const { return m_revision; }
void emitUpdated();
@ -173,6 +175,7 @@ private:
uint m_revision;
QHash<quintptr, QDBusPlatformMenuItem *> m_itemsByTag;
QList<QDBusPlatformMenuItem *> m_items;
static QList<QDBusPlatformMenu *> m_topLevelMenus;
};
QT_END_NAMESPACE

View File

@ -191,9 +191,10 @@ void QDBusTrayIcon::updateToolTip(const QString &tooltip)
QPlatformMenu *QDBusTrayIcon::createMenu() const
{
qCDebug(qLcTray);
QDBusPlatformMenu *ret = new QDBusPlatformMenu();
if (!m_menu)
const_cast<QDBusTrayIcon *>(this)->m_menu = new QDBusPlatformMenu();
return m_menu;
const_cast<QDBusTrayIcon *>(this)->m_menu = ret;
return ret;
}
void QDBusTrayIcon::updateMenu(QPlatformMenu * menu)