From f5ea4baa0dc81907f4375fe9620dc9c73c26d94c Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Thu, 21 Jan 2016 20:15:02 +0300 Subject: dbusmenu: Add support for shortcuts To do that, split out and export a QKeySequencePrivate::keyName() function that returns the key text representation without the modifiers. The implementation is compatible with libdbusmenu-qt. Change-Id: Ibc3190a3949813a1610728cf89574027e5d2778d Reviewed-by: Shawn Rutledge --- src/platformsupport/dbusmenu/qdbusmenutypes.cpp | 37 ++++++++++++++++++++++--- src/platformsupport/dbusmenu/qdbusmenutypes_p.h | 3 ++ 2 files changed, 36 insertions(+), 4 deletions(-) (limited to 'src/platformsupport/dbusmenu') diff --git a/src/platformsupport/dbusmenu/qdbusmenutypes.cpp b/src/platformsupport/dbusmenu/qdbusmenutypes.cpp index 8d5d96353c..9f356bf281 100644 --- a/src/platformsupport/dbusmenu/qdbusmenutypes.cpp +++ b/src/platformsupport/dbusmenu/qdbusmenutypes.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "qdbusplatformmenu_p.h" @@ -165,6 +166,7 @@ void QDBusMenuItem::registerDBusTypes() qDBusRegisterMetaType(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); + qDBusRegisterMetaType(); } QDBusMenuItem::QDBusMenuItem(const QDBusPlatformMenuItem *item) @@ -183,13 +185,11 @@ QDBusMenuItem::QDBusMenuItem(const QDBusPlatformMenuItem *item) m_properties.insert(QLatin1String("toggle-type"), QLatin1String("checkmark")); m_properties.insert(QLatin1String("toggle-state"), item->isChecked() ? 1 : 0); } - /* TODO support shortcuts const QKeySequence &scut = item->shortcut(); if (!scut.isEmpty()) { - QDBusMenuShortcut shortcut(scut); - properties.insert(QLatin1String("shortcut"), QVariant::fromValue(shortcut)); + QDBusMenuShortcut shortcut = convertKeySequence(scut); + m_properties.insert(QLatin1String("shortcut"), QVariant::fromValue(shortcut)); } - */ const QIcon &icon = item->icon(); if (!icon.name().isEmpty()) { m_properties.insert(QLatin1String("icon-name"), icon.name()); @@ -226,6 +226,35 @@ QString QDBusMenuItem::convertMnemonic(const QString &label) return ret; } +QDBusMenuShortcut QDBusMenuItem::convertKeySequence(const QKeySequence &sequence) +{ + QDBusMenuShortcut shortcut; + for (int i = 0; i < sequence.count(); ++i) { + QStringList tokens; + int key = sequence[i]; + if (key & Qt::MetaModifier) + tokens << QStringLiteral("Super"); + if (key & Qt::ControlModifier) + tokens << QStringLiteral("Control"); + if (key & Qt::AltModifier) + tokens << QStringLiteral("Alt"); + if (key & Qt::ShiftModifier) + tokens << QStringLiteral("Shift"); + if (key & Qt::KeypadModifier) + tokens << QStringLiteral("Num"); + + QString keyName = QKeySequencePrivate::keyName(key, QKeySequence::PortableText); + if (keyName == QLatin1String("+")) + tokens << QStringLiteral("plus"); + else if (keyName == QLatin1String("-")) + tokens << QStringLiteral("minus"); + else + tokens << keyName; + shortcut << tokens; + } + return shortcut; +} + const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuEvent &ev) { arg.beginStructure(); diff --git a/src/platformsupport/dbusmenu/qdbusmenutypes_p.h b/src/platformsupport/dbusmenu/qdbusmenutypes_p.h index bc9f064f88..047e3c597e 100644 --- a/src/platformsupport/dbusmenu/qdbusmenutypes_p.h +++ b/src/platformsupport/dbusmenu/qdbusmenutypes_p.h @@ -58,6 +58,7 @@ class QDBusPlatformMenu; class QDBusPlatformMenuItem; class QDBusMenuItem; typedef QVector QDBusMenuItemList; +typedef QVector QDBusMenuShortcut; class QDBusMenuItem { @@ -67,6 +68,7 @@ public: static QDBusMenuItemList items(const QList &ids, const QStringList &propertyNames); static QString convertMnemonic(const QString &label); + static QDBusMenuShortcut convertKeySequence(const QKeySequence &sequence); static void registerDBusTypes(); int m_id; @@ -140,5 +142,6 @@ Q_DECLARE_METATYPE(QDBusMenuLayoutItem) Q_DECLARE_METATYPE(QDBusMenuLayoutItemList) Q_DECLARE_METATYPE(QDBusMenuEvent) Q_DECLARE_METATYPE(QDBusMenuEventList) +Q_DECLARE_METATYPE(QDBusMenuShortcut) #endif -- cgit v1.2.3 From 68f97cdf5f088f98ee6598b83da99f5201367c6a Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Thu, 21 Jan 2016 20:27:43 +0300 Subject: dbusmenu: Add missing methods for getting QDBusPlatformMenu properties Similar to the existing methods for QDBusPlatformMenuItem. These methods will be needed for implementing the D-Bus platform menu bar. Change-Id: Iae3a5892b71fa9a7c72c323ee4b3ab2afd7d4d76 Reviewed-by: Shawn Rutledge --- src/platformsupport/dbusmenu/qdbusplatformmenu_p.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/platformsupport/dbusmenu') diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h index 6d2d27463f..5892391299 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h @@ -138,8 +138,11 @@ public: const QString text() const { return m_text; } void setText(const QString &text) Q_DECL_OVERRIDE; + QIcon icon() const { return m_icon; } void setIcon(const QIcon &icon) Q_DECL_OVERRIDE; + bool isEnabled() const { return m_isEnabled; } void setEnabled(bool enabled) Q_DECL_OVERRIDE; + bool isVisible() const { return m_isVisible; } void setVisible(bool visible) Q_DECL_OVERRIDE; void setMinimumWidth(int width) Q_DECL_OVERRIDE { Q_UNUSED(width); } void setFont(const QFont &font) Q_DECL_OVERRIDE { Q_UNUSED(font); } -- cgit v1.2.3 From f83816ec4fe3907e8545e8de2d4ff3c54c864c10 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Thu, 21 Jan 2016 20:19:49 +0300 Subject: dbusmenu: Fix return type for QDBusMenuAdaptor::EventGroup method Change-Id: If7454eeaafb31737f023e7359b2a1c513dd5772f Reviewed-by: Shawn Rutledge --- src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp | 3 ++- src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/platformsupport/dbusmenu') diff --git a/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp b/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp index 381caf77b3..ef5f30470a 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp +++ b/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp @@ -102,10 +102,11 @@ void QDBusMenuAdaptor::Event(int id, const QString &eventId, const QDBusVariant item->trigger(); } -void QDBusMenuAdaptor::EventGroup(const QDBusMenuEventList &events) +QList QDBusMenuAdaptor::EventGroup(const QDBusMenuEventList &events) { Q_FOREACH (const QDBusMenuEvent &ev, events) Event(ev.m_id, ev.m_eventId, ev.m_data, ev.m_timestamp); + return QList(); // idErrors } QDBusMenuItemList QDBusMenuAdaptor::GetGroupProperties(const QList &ids, const QStringList &propertyNames) diff --git a/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h b/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h index 41ab761f12..98eae53f0b 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h +++ b/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h @@ -157,7 +157,7 @@ public Q_SLOTS: // METHODS bool AboutToShow(int id); QList AboutToShowGroup(const QList &ids, QList &idErrors); void Event(int id, const QString &eventId, const QDBusVariant &data, uint timestamp); - void EventGroup(const QDBusMenuEventList &events); + QList EventGroup(const QDBusMenuEventList &events); QDBusMenuItemList GetGroupProperties(const QList &ids, const QStringList &propertyNames); uint GetLayout(int parentId, int recursionDepth, const QStringList &propertyNames, QDBusMenuLayoutItem &layout); QDBusVariant GetProperty(int id, const QString &name); -- cgit v1.2.3 From 9c7f37e648024a8c7129e332dfb12b3ebd1ebf25 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Thu, 21 Jan 2016 20:43:50 +0300 Subject: dbusmenu: Refactor the code to allow dynamic updating of menus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Transfer propertiesUpdated and updated signals from submenus to parent menus. Without this, the adaptor only receives this signal from top-level menu items, and doesn't receive it from items of submenus. Connect to these signals when a menu item is added or synced, and disconnect when it is removed. * Make QDBusPlatformMenus use IDs of items containing them, not their own IDs (own IDs do not make any sense since they are not exported over D-Bus). * Store toplevel menus per-adaptor, to make it possible to export multiple menus (for example a menubar and a tray icon menu). * Adjust the QDBusMenuLayoutItem::populate methods to always get the menu via its containing item and to populate the menus recursively. * Map D-Bus menu AboutToShow method to platform menu aboutToShow method, and map hovered and closed events to hovered and aboutToHide signals. (QTBUG-46293) * Always set the visible property on item. Otherwise, when an item becomes visible, the D-Bus menu still thinks it's invisible because that property was not changed back to true. (QTBUG-48647) * Call emitUpdated from insertMenuItem and removeMenuItem methods, as they really update layout. Do not call it from syncMenuItem, it changes only properties but not the layout. * Start revision numbering with 1, because libdbusmenu-based hosts ignore updated signal with revision=1. Task-number: QTBUG-46293 Task-number: QTBUG-48647 Change-Id: Icf713405db0443e25462c1a19046df7689fe5e78 Reviewed-by: Shawn Rutledge Reviewed-by: Błażej Szczygieł --- src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp | 34 +++++++++-- src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h | 5 +- src/platformsupport/dbusmenu/qdbusmenutypes.cpp | 35 ++++++----- src/platformsupport/dbusmenu/qdbusmenutypes_p.h | 2 +- src/platformsupport/dbusmenu/qdbusplatformmenu.cpp | 71 +++++++++++++++------- src/platformsupport/dbusmenu/qdbusplatformmenu_p.h | 9 +-- 6 files changed, 102 insertions(+), 54 deletions(-) (limited to 'src/platformsupport/dbusmenu') diff --git a/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp b/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp index ef5f30470a..0e9ea57406 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp +++ b/src/platformsupport/dbusmenu/qdbusmenuadaptor.cpp @@ -51,8 +51,9 @@ QT_BEGIN_NAMESPACE -QDBusMenuAdaptor::QDBusMenuAdaptor(QObject *parent) - : QDBusAbstractAdaptor(parent) +QDBusMenuAdaptor::QDBusMenuAdaptor(QDBusPlatformMenu *topLevelMenu) + : QDBusAbstractAdaptor(topLevelMenu) + , m_topLevelMenu(topLevelMenu) { setAutoRelaySignals(true); } @@ -80,7 +81,17 @@ uint QDBusMenuAdaptor::version() const bool QDBusMenuAdaptor::AboutToShow(int id) { qCDebug(qLcMenu) << id; - return false; + if (id == 0) { + emit m_topLevelMenu->aboutToShow(); + } else { + QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id); + if (item) { + const QDBusPlatformMenu *menu = static_cast(item->menu()); + if (menu) + emit const_cast(menu)->aboutToShow(); + } + } + return false; // updateNeeded (we don't know that, so false) } QList QDBusMenuAdaptor::AboutToShowGroup(const QList &ids, QList &idErrors) @@ -88,6 +99,8 @@ QList QDBusMenuAdaptor::AboutToShowGroup(const QList &ids, QList qCDebug(qLcMenu) << ids; Q_UNUSED(idErrors) idErrors.clear(); + Q_FOREACH (int id, ids) + AboutToShow(id); return QList(); // updatesNeeded } @@ -97,9 +110,20 @@ void QDBusMenuAdaptor::Event(int id, const QString &eventId, const QDBusVariant Q_UNUSED(timestamp) QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id); qCDebug(qLcMenu) << id << (item ? item->text() : QLatin1String("")) << eventId; - // Events occur on both menus and menuitems, but we only care if it's an item being clicked. if (item && eventId == QLatin1String("clicked")) item->trigger(); + if (item && eventId == QLatin1String("hovered")) + emit item->hovered(); + if (eventId == QLatin1String("closed")) { + // There is no explicit AboutToHide method, so map closed event to aboutToHide method + const QDBusPlatformMenu *menu = Q_NULLPTR; + if (item) + menu = static_cast(item->menu()); + else if (id == 0) + menu = m_topLevelMenu; + if (menu) + emit const_cast(menu)->aboutToHide(); + } } QList QDBusMenuAdaptor::EventGroup(const QDBusMenuEventList &events) @@ -117,7 +141,7 @@ QDBusMenuItemList QDBusMenuAdaptor::GetGroupProperties(const QList &ids, co uint QDBusMenuAdaptor::GetLayout(int parentId, int recursionDepth, const QStringList &propertyNames, QDBusMenuLayoutItem &layout) { - uint ret = layout.populate(parentId, recursionDepth, propertyNames); + uint ret = layout.populate(parentId, recursionDepth, propertyNames, m_topLevelMenu); qCDebug(qLcMenu) << parentId << "depth" << recursionDepth << propertyNames << layout.m_id << layout.m_properties << "revision" << ret << layout; return ret; } diff --git a/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h b/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h index 98eae53f0b..7bec4ad8f3 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h +++ b/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h @@ -140,7 +140,7 @@ class QDBusMenuAdaptor: public QDBusAbstractAdaptor " \n" "") public: - QDBusMenuAdaptor(QObject *parent); + QDBusMenuAdaptor(QDBusPlatformMenu *topLevelMenu); virtual ~QDBusMenuAdaptor(); public: // PROPERTIES @@ -166,6 +166,9 @@ Q_SIGNALS: // SIGNALS void ItemActivationRequested(int id, uint timestamp); void ItemsPropertiesUpdated(const QDBusMenuItemList &updatedProps, const QDBusMenuItemKeysList &removedProps); void LayoutUpdated(uint revision, int parent); + +private: + QDBusPlatformMenu *m_topLevelMenu; }; QT_END_NAMESPACE diff --git a/src/platformsupport/dbusmenu/qdbusmenutypes.cpp b/src/platformsupport/dbusmenu/qdbusmenutypes.cpp index 9f356bf281..b642038e7f 100644 --- a/src/platformsupport/dbusmenu/qdbusmenutypes.cpp +++ b/src/platformsupport/dbusmenu/qdbusmenutypes.cpp @@ -80,29 +80,27 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuItemKeys &key return arg; } -uint QDBusMenuLayoutItem::populate(int id, int depth, const QStringList &propertyNames) +uint QDBusMenuLayoutItem::populate(int id, int depth, const QStringList &propertyNames, const QDBusPlatformMenu *topLevelMenu) { qCDebug(qLcMenu) << id << "depth" << depth << propertyNames; m_id = id; if (id == 0) { m_properties.insert(QLatin1String("children-display"), QLatin1String("submenu")); - Q_FOREACH (const QDBusPlatformMenu *menu, QDBusPlatformMenu::topLevelMenus()) { - if (menu) - populate(menu, depth, propertyNames); - } + if (topLevelMenu) + populate(topLevelMenu, depth, propertyNames); return 1; // revision } - const QDBusPlatformMenu *menu = QDBusPlatformMenu::byId(id); - if (!menu) { - QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id); - if (item) - menu = static_cast(item->menu()); + QDBusPlatformMenuItem *item = QDBusPlatformMenuItem::byId(id); + if (item) { + const QDBusPlatformMenu *menu = static_cast(item->menu()); + + if (menu) { + if (depth != 0) + populate(menu, depth, propertyNames); + return menu->revision(); + } } - if (depth != 0 && menu) - populate(menu, depth, propertyNames); - if (menu) - return menu->revision(); return 1; // revision } @@ -118,11 +116,13 @@ void QDBusMenuLayoutItem::populate(const QDBusPlatformMenu *menu, int depth, con void QDBusMenuLayoutItem::populate(const QDBusPlatformMenuItem *item, int depth, const QStringList &propertyNames) { - Q_UNUSED(depth) - Q_UNUSED(propertyNames) m_id = item->dbusID(); QDBusMenuItem proxy(item); m_properties = proxy.m_properties; + + const QDBusPlatformMenu *menu = static_cast(item->menu()); + if (depth != 0 && menu) + populate(menu, depth, propertyNames); } const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuLayoutItem &item) @@ -199,8 +199,7 @@ QDBusMenuItem::QDBusMenuItem(const QDBusPlatformMenuItem *item) m_properties.insert(QLatin1String("icon-data"), buf.data()); } } - if (!item->isVisible()) - m_properties.insert(QLatin1String("visible"), false); + m_properties.insert(QLatin1String("visible"), item->isVisible()); } QDBusMenuItemList QDBusMenuItem::items(const QList &ids, const QStringList &propertyNames) diff --git a/src/platformsupport/dbusmenu/qdbusmenutypes_p.h b/src/platformsupport/dbusmenu/qdbusmenutypes_p.h index 047e3c597e..7ff44bbeff 100644 --- a/src/platformsupport/dbusmenu/qdbusmenutypes_p.h +++ b/src/platformsupport/dbusmenu/qdbusmenutypes_p.h @@ -96,7 +96,7 @@ typedef QVector QDBusMenuItemKeysList; class QDBusMenuLayoutItem { public: - uint populate(int id, int depth, const QStringList &propertyNames); + uint populate(int id, int depth, const QStringList &propertyNames, const QDBusPlatformMenu *topLevelMenu); void populate(const QDBusPlatformMenu *menu, int depth, const QStringList &propertyNames); void populate(const QDBusPlatformMenuItem *item, int depth, const QStringList &propertyNames); diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp index 62f041bc86..9f99ef97e5 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp @@ -41,9 +41,7 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(qLcMenu, "qt.qpa.menu") static int nextDBusID = 1; -QHash menusByID; QHash menuItemsByID; -QList QDBusPlatformMenu::m_topLevelMenus; QDBusPlatformMenuItem::QDBusPlatformMenuItem(quintptr tag) : m_tag(tag ? tag : reinterpret_cast(this)) // QMenu will overwrite this later @@ -85,7 +83,11 @@ void QDBusPlatformMenuItem::setIcon(const QIcon &icon) */ void QDBusPlatformMenuItem::setMenu(QPlatformMenu *menu) { - m_subMenu = static_cast(menu); + if (m_subMenu) + static_cast(m_subMenu)->setContainingMenuItem(Q_NULLPTR); + m_subMenu = menu; + if (menu) + static_cast(menu)->setContainingMenuItem(this); } void QDBusPlatformMenuItem::setEnabled(bool enabled) @@ -130,7 +132,11 @@ void QDBusPlatformMenuItem::trigger() QDBusPlatformMenuItem *QDBusPlatformMenuItem::byId(int id) { - return menuItemsByID[id]; + // We need to check contains because otherwise QHash would insert + // a default-constructed nullptr value into menuItemsByID + if (menuItemsByID.contains(id)) + return menuItemsByID[id]; + return Q_NULLPTR; } QList QDBusPlatformMenuItem::byIds(const QList &ids) @@ -149,18 +155,13 @@ QDBusPlatformMenu::QDBusPlatformMenu(quintptr tag) , m_isEnabled(true) , m_isVisible(true) , m_isSeparator(false) - , m_dbusID(nextDBusID++) - , m_revision(0) + , m_revision(1) + , m_containingMenuItem(Q_NULLPTR) { - menusByID.insert(m_dbusID, this); - // Assume it's top-level until we find out otherwise - m_topLevelMenus << this; } QDBusPlatformMenu::~QDBusPlatformMenu() { - menusByID.remove(m_dbusID); - m_topLevelMenus.removeOne(this); } void QDBusPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) @@ -174,38 +175,59 @@ 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(static_cast(item->menu()))); + syncSubMenu(static_cast(item->menu())); + emitUpdated(); } void QDBusPlatformMenu::removeMenuItem(QPlatformMenuItem *menuItem) { - m_items.removeAll(static_cast(menuItem)); + QDBusPlatformMenuItem *item = static_cast(menuItem); + m_items.removeAll(item); m_itemsByTag.remove(menuItem->tag()); + if (item->menu()) { + // disconnect from the signals we connected to in syncSubMenu() + const QDBusPlatformMenu *menu = static_cast(item->menu()); + disconnect(menu, &QDBusPlatformMenu::propertiesUpdated, + this, &QDBusPlatformMenu::propertiesUpdated); + disconnect(menu, &QDBusPlatformMenu::updated, + this, &QDBusPlatformMenu::updated); + } + emitUpdated(); +} + +void QDBusPlatformMenu::syncSubMenu(const QDBusPlatformMenu *menu) +{ + // The adaptor is only connected to the propertiesUpdated signal of the top-level + // menu, so the submenus should transfer their signals to their parents. + connect(menu, &QDBusPlatformMenu::propertiesUpdated, + this, &QDBusPlatformMenu::propertiesUpdated, Qt::UniqueConnection); + connect(menu, &QDBusPlatformMenu::updated, + this, &QDBusPlatformMenu::updated, Qt::UniqueConnection); } void QDBusPlatformMenu::syncMenuItem(QPlatformMenuItem *menuItem) { + QDBusPlatformMenuItem *item = static_cast(menuItem); + // if a submenu was added to this item, we need to connect to its signals + if (item->menu()) + syncSubMenu(static_cast(item->menu())); // TODO keep around copies of the QDBusMenuLayoutItems so they can be updated? // or eliminate them by putting dbus streaming operators in this class instead? // or somehow tell the dbusmenu client that something has changed, so it will ask for properties again - emitUpdated(); QDBusMenuItemList updated; QDBusMenuItemKeysList removed; - updated << QDBusMenuItem(static_cast(menuItem)); + updated << QDBusMenuItem(item); qCDebug(qLcMenu) << updated; emit propertiesUpdated(updated, removed); } -QDBusPlatformMenu *QDBusPlatformMenu::byId(int id) -{ - return menusByID[id]; -} - void QDBusPlatformMenu::emitUpdated() { - emit updated(++m_revision, m_dbusID); + if (m_containingMenuItem) + emit updated(++m_revision, m_containingMenuItem->dbusID()); + else + emit updated(++m_revision, 0); } void QDBusPlatformMenu::setTag(quintptr tag) @@ -233,6 +255,11 @@ void QDBusPlatformMenu::setVisible(bool isVisible) m_isVisible = isVisible; } +void QDBusPlatformMenu::setContainingMenuItem(QDBusPlatformMenuItem *item) +{ + m_containingMenuItem = item; +} + QPlatformMenuItem *QDBusPlatformMenu::menuItemAt(int position) const { return m_items.at(position); diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h index 5892391299..f2419b5378 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h @@ -130,6 +130,7 @@ public: ~QDBusPlatformMenu(); void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) Q_DECL_OVERRIDE; void removeMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; + void syncSubMenu(const QDBusPlatformMenu *menu); void syncMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; void syncSeparatorsCollapsible(bool enable) Q_DECL_OVERRIDE { Q_UNUSED(enable); } @@ -147,8 +148,7 @@ public: void setMinimumWidth(int width) Q_DECL_OVERRIDE { Q_UNUSED(width); } 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 setContainingMenuItem(QDBusPlatformMenuItem *item); void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) Q_DECL_OVERRIDE { @@ -169,9 +169,6 @@ public: bool operator==(const QDBusPlatformMenu& other) { return m_tag == other.m_tag; } - static QDBusPlatformMenu* byId(int id); - static QList topLevelMenus() { return m_topLevelMenus; } - uint revision() const { return m_revision; } void emitUpdated(); @@ -187,12 +184,10 @@ private: bool m_isEnabled; bool m_isVisible; bool m_isSeparator; - int m_dbusID; uint m_revision; QHash m_itemsByTag; QList m_items; QDBusPlatformMenuItem *m_containingMenuItem; - static QList m_topLevelMenus; }; QT_END_NAMESPACE -- cgit v1.2.3 From 12b19ca56c274565803d00bf551c32fc0f4a39b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Mon, 8 Feb 2016 10:24:59 +0000 Subject: Fix clang 3.7 developer build [Werror, Winconsistent-missing-override] Change-Id: Ia5c149c6e6886c38bb9a83cd8b36737a57876b41 Reviewed-by: Friedemann Kleint Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/platformsupport/dbusmenu/qdbusplatformmenu_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/platformsupport/dbusmenu') diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h index f2419b5378..58cac11af4 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h @@ -141,7 +141,7 @@ public: void setText(const QString &text) Q_DECL_OVERRIDE; QIcon icon() const { return m_icon; } void setIcon(const QIcon &icon) Q_DECL_OVERRIDE; - bool isEnabled() const { return m_isEnabled; } + bool isEnabled() const Q_DECL_OVERRIDE { return m_isEnabled; } void setEnabled(bool enabled) Q_DECL_OVERRIDE; bool isVisible() const { return m_isVisible; } void setVisible(bool visible) Q_DECL_OVERRIDE; -- cgit v1.2.3 From a4fac65938fdee74c07d34727920fb74087f82c6 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Sat, 6 Feb 2016 14:42:39 +0300 Subject: dbustray: Support late registering of tray icon menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a menu is added to the tray icon after the icon itself has been registered, we need to register the menu properly. Change-Id: I19a6d78848142d66c2cd882746d8d55c0b9a2818 Reviewed-by: Błażej Szczygieł Reviewed-by: Shawn Rutledge --- src/platformsupport/dbusmenu/qdbusmenuconnection.cpp | 18 ++++++++++-------- src/platformsupport/dbusmenu/qdbusmenuconnection_p.h | 1 + 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'src/platformsupport/dbusmenu') diff --git a/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp b/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp index 73793d7497..66a74e7a9a 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp +++ b/src/platformsupport/dbusmenu/qdbusmenuconnection.cpp @@ -80,6 +80,14 @@ void QDBusMenuConnection::dbusError(const QDBusError &error) } #ifndef QT_NO_SYSTEMTRAYICON +bool QDBusMenuConnection::registerTrayIconMenu(QDBusTrayIcon *item) +{ + bool success = connection().registerObject(MenuBarPath, item->menu()); + if (!success) // success == false is normal, because the object may be already registered + qCDebug(qLcMenu) << "failed to register" << item->instanceId() << MenuBarPath; + return success; +} + bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item) { bool success = connection().registerService(item->instanceId()); @@ -95,14 +103,8 @@ bool QDBusMenuConnection::registerTrayIcon(QDBusTrayIcon *item) return false; } - if (item->menu()) { - success = connection().registerObject(MenuBarPath, item->menu()); - if (!success) { - unregisterTrayIcon(item); - qWarning() << "failed to register" << item->instanceId() << MenuBarPath; - return false; - } - } + if (item->menu()) + registerTrayIconMenu(item); QDBusMessage registerMethod = QDBusMessage::createMethodCall( StatusNotifierWatcherService, StatusNotifierWatcherPath, StatusNotifierWatcherService, diff --git a/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h b/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h index 8d230bd3bf..9208d38c9b 100644 --- a/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h +++ b/src/platformsupport/dbusmenu/qdbusmenuconnection_p.h @@ -65,6 +65,7 @@ public: QDBusConnection connection() const { return m_connection; } bool isStatusNotifierHostRegistered() const { return m_statusNotifierHostRegistered; } #ifndef QT_NO_SYSTEMTRAYICON + bool registerTrayIconMenu(QDBusTrayIcon *item); bool registerTrayIcon(QDBusTrayIcon *item); bool unregisterTrayIcon(QDBusTrayIcon *item); #endif // QT_NO_SYSTEMTRAYICON -- cgit v1.2.3