Commit 1a33a294 authored by Kai Uwe Broulik's avatar Kai Uwe Broulik 🍇
Browse files

Monitor DBus menu service

Only track menus if it is available and cleanup when it goes away
parent 21eb03b4
......@@ -25,6 +25,8 @@
#include <QByteArray>
#include <QDBusConnection>
#include <QDBusConnectionInterface>
#include <QDBusServiceWatcher>
#include <QCoreApplication>
#include <QHash>
#include <QTimer>
......@@ -39,6 +41,8 @@
static const QString s_ourServiceName = QStringLiteral("org.kde.plasma.gmenu_dbusmenu_proxy");
static const QString s_dbusMenuRegistrar = QStringLiteral("com.canonical.AppMenu.Registrar");
static const QByteArray s_gtkUniqueBusName = QByteArrayLiteral("_GTK_UNIQUE_BUS_NAME");
static const QByteArray s_gtkApplicationObjectPath = QByteArrayLiteral("_GTK_APPLICATION_OBJECT_PATH");
......@@ -50,27 +54,66 @@ static const QByteArray s_gtkAppMenuObjectPath = QByteArrayLiteral("_GTK_APP_MEN
static const QByteArray s_kdeNetWmAppMenuServiceName = QByteArrayLiteral("_KDE_NET_WM_APPMENU_SERVICE_NAME");
static const QByteArray s_kdeNetWmAppMenuObjectPath = QByteArrayLiteral("_KDE_NET_WM_APPMENU_OBJECT_PATH");
MenuProxy::MenuProxy() : QObject()
MenuProxy::MenuProxy()
: QObject()
, m_serviceWatcher(new QDBusServiceWatcher(this))
{
// TODO do nothing if no dbusmenu service is unavailable and wait for it to come
m_serviceWatcher->setConnection(QDBusConnection::sessionBus());
m_serviceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration |
QDBusServiceWatcher::WatchForRegistration);
m_serviceWatcher->addWatchedService(s_dbusMenuRegistrar);
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceRegistered, this, [this](const QString &service) {
Q_UNUSED(service);
qDebug() << "Global menu service became available, starting";
init();
});
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, [this](const QString &service) {
Q_UNUSED(service);
qDebug() << "Global menu service disappeared, cleaning up";
teardown();
});
// It's fine to do a blocking call here as we're a separate binary with no UI
if (QDBusConnection::sessionBus().interface()->isServiceRegistered(s_dbusMenuRegistrar)) {
qDebug() << "Global menu service is there, starting up right away";
init();
} else {
qDebug() << "No global menu service available, waiting for it before we do anything";
}
}
bool MenuProxy::init()
{
if (!QDBusConnection::sessionBus().registerService(s_ourServiceName)) {
qWarning() << "Failed to register DBus service" << s_ourServiceName;
//qApp->exit(1); // doensn't work?
::exit(1);
return;
return false;
}
connect(KWindowSystem::self(), &KWindowSystem::windowAdded, this, &MenuProxy::onWindowAdded);
connect(KWindowSystem::self(), &KWindowSystem::windowRemoved, this, &MenuProxy::onWindowRemoved);
for (WId id : KWindowSystem::windows()) { // detaches?
const auto windows = KWindowSystem::windows();
for (WId id : windows) {
onWindowAdded(id);
}
if (m_menus.isEmpty()) {
qDebug() << "Up and running but no menus in sight";
}
return true;
}
void MenuProxy::teardown()
{
QDBusConnection::sessionBus().unregisterService(s_ourServiceName);
disconnect(KWindowSystem::self(), &KWindowSystem::windowAdded, this, &MenuProxy::onWindowAdded);
disconnect(KWindowSystem::self(), &KWindowSystem::windowRemoved, this, &MenuProxy::onWindowRemoved);
qDeleteAll(m_menus);
m_menus.clear();
}
void MenuProxy::onWindowAdded(WId id)
......
......@@ -26,6 +26,8 @@
#include <xcb/xcb_atom.h>
class QDBusServiceWatcher;
class Menu;
class MenuProxy : public QObject//, public QAbstractNativeEventFilter
......@@ -44,6 +46,9 @@ private Q_SLOTS:
void onWindowRemoved(WId id);
private:
bool init();
void teardown();
// FIXME the get one reads "UTF8String" (reads gnome) the write thing writes "String" (writes kde)
QByteArray getWindowPropertyString(WId id, const QByteArray &name);
void writeWindowProperty(WId id, const QByteArray &name, const QByteArray &value);
......@@ -51,4 +56,6 @@ private:
QHash<WId, Menu *> m_menus;
QDBusServiceWatcher *m_serviceWatcher;
};
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment