Support stopping subscription and don't cleanup when the window goes away

When the window goes away there's no x window to remove properties from and also the
DBus interface for the menu seems to go away before we could unsubscribe
wilder-5.14
Kai Uwe Broulik 8 years ago
parent 98603c5f08
commit 1d49715fd4
  1. 54
      gmenu-dbusmenu-proxy/menu.cpp
  2. 4
      gmenu-dbusmenu-proxy/menu.h
  3. 3
      gmenu-dbusmenu-proxy/menuproxy.cpp

@ -30,6 +30,8 @@
#include <QVariantList> #include <QVariantList>
#include <QWindow> #include <QWindow>
#include <algorithm>
#include "dbusmenuadaptor.h" #include "dbusmenuadaptor.h"
#include "../libdbusmenuqt/dbusmenushortcut_p.h" #include "../libdbusmenuqt/dbusmenushortcut_p.h"
@ -87,7 +89,7 @@ Menu::Menu(WId winId,
if (ok) { if (ok) {
m_applicationActions = actions; m_applicationActions = actions;
m_queriedApplicationActions = true; m_queriedApplicationActions = true;
start(); init();
} }
}); });
@ -95,12 +97,14 @@ Menu::Menu(WId winId,
if (ok) { if (ok) {
m_windowActions = actions; m_windowActions = actions;
m_queriedWindowActions = true; m_queriedWindowActions = true;
start(); init();
} }
}); });
} }
Menu::~Menu() Menu::~Menu() = default;
void Menu::cleanup()
{ {
stop(m_subscriptions); stop(m_subscriptions);
@ -137,16 +141,18 @@ QString Menu::proxyObjectPath() const
return m_proxyObjectPath; return m_proxyObjectPath;
} }
void Menu::start() void Menu::init()
{ {
if (!m_queriedApplicationActions || m_queriedWindowActions) { if (!m_queriedApplicationActions || m_queriedWindowActions) {
return; return;
} }
qDebug() << "START!"; if (!registerDBusObject()) {
start(0); return;
} }
emit requestWriteWindowProperties();
}
void Menu::start(uint id) void Menu::start(uint id)
{ {
@ -235,14 +241,6 @@ void Menu::start(uint id)
} }
} }
} }
// first time we successfully requested a menu, announce that this window supports DBusMenu
if (!m_subscriptions.isEmpty() && !wasSubscribed) {
if (registerDBusObject()) {
emit requestWriteWindowProperties();
}
}
} }
// When it was a delayed GetLayout request, send the reply now // When it was a delayed GetLayout request, send the reply now
@ -266,8 +264,30 @@ void Menu::start(uint id)
void Menu::stop(const QList<uint> &ids) void Menu::stop(const QList<uint> &ids)
{ {
// TODO qDebug() << "STOP" << ids;
Q_UNUSED(ids);
QDBusMessage msg = QDBusMessage::createMethodCall(m_serviceName,
m_menuObjectPath,
s_orgGtkMenus,
QStringLiteral("End"));
msg.setArguments({
QVariant::fromValue(ids) // don't let it unwrap it, hence in a variant
});
QDBusPendingReply<void> reply = QDBusConnection::sessionBus().asyncCall(msg);
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, ids](QDBusPendingCallWatcher *watcher) {
QDBusPendingReply<void> reply = *watcher;
if (reply.isError()) {
qWarning() << "Failed to stop subscription to" << ids << "from" << m_serviceName << "at" << m_menuObjectPath << reply.error();
} else {
// remove all subscriptions that we unsubscribed from
// TODO is there a nicer algorithm for that?
m_subscriptions.erase(std::remove_if(m_subscriptions.begin(), m_subscriptions.end(),
std::bind(&QList<uint>::contains, m_subscriptions, std::placeholders::_1)),
m_subscriptions.end());
}
});
} }
void Menu::onMenuChanged(const GMenuChangeList &changes) void Menu::onMenuChanged(const GMenuChangeList &changes)

@ -48,6 +48,8 @@ public:
const QString &menuObjectPath); const QString &menuObjectPath);
~Menu(); ~Menu();
void cleanup();
WId winId() const; WId winId() const;
QString serviceName() const; QString serviceName() const;
@ -83,7 +85,7 @@ private slots:
void onWindowActionsChanged(const GMenuActionsChange &changes); void onWindowActionsChanged(const GMenuActionsChange &changes);
private: private:
void start(); void init();
void start(uint id); void start(uint id);
void stop(const QList<uint> &id); void stop(const QList<uint> &id);

@ -164,7 +164,8 @@ void MenuProxy::onWindowAdded(WId id)
void MenuProxy::onWindowRemoved(WId id) void MenuProxy::onWindowRemoved(WId id)
{ {
delete m_menus.take(id); // destructor of Menu cleans up everything // no need to cleanup() (which removes window properties) when the window is gone, delete right away
delete m_menus.take(id);
} }
QByteArray MenuProxy::getWindowPropertyString(WId id, const QByteArray &name) QByteArray MenuProxy::getWindowPropertyString(WId id, const QByteArray &name)

Loading…
Cancel
Save