diff --git a/src/appmenu/appmenumodel.cpp b/src/appmenu/appmenumodel.cpp index f13a904..d805160 100644 --- a/src/appmenu/appmenumodel.cpp +++ b/src/appmenu/appmenumodel.cpp @@ -31,11 +31,44 @@ #include #include +#include + #include #include "../libdbusmenuqt/dbusmenuimporter.h" #include +#include + +static QByteArray getWindowPropertyString(WId id, const QByteArray &name) +{ + xcb_connection_t *c = QX11Info::connection(); + QByteArray value; + + const xcb_intern_atom_cookie_t atomCookie = xcb_intern_atom(c, false, name.length(), name.constData()); + QScopedPointer atomReply(xcb_intern_atom_reply(c, atomCookie, Q_NULLPTR)); + if (atomReply.isNull()) { + return value; + } + + static const long MAX_PROP_SIZE = 10000; + auto propertyCookie = xcb_get_property(c, false, id, atomReply->atom, XCB_ATOM_STRING, 0, MAX_PROP_SIZE); + QScopedPointer propertyReply(xcb_get_property_reply(c, propertyCookie, NULL)); + if (propertyReply.isNull()) { + return value; + } + + if (propertyReply->type == XCB_ATOM_STRING && propertyReply->format == 8 && propertyReply->value_len > 0) { + const char *data = (const char *) xcb_get_property_value(propertyReply.data()); + int len = propertyReply->value_len; + if (data) { + value = QByteArray(data, data[len - 1] ? len : len - 1); + } + } + + return value; +} + class CDBusMenuImporter : public DBusMenuImporter { public: @@ -107,16 +140,6 @@ void AppMenuModel::setVisible(bool visible) } } -QRect AppMenuModel::screenGeometry() const -{ -// return m_tasksModel->screenGeometry(); -} - -void AppMenuModel::setScreenGeometry(QRect geometry) -{ -// m_tasksModel->setScreenGeometry(geometry); -} - int AppMenuModel::rowCount(const QModelIndex &parent) const { Q_UNUSED(parent); @@ -136,11 +159,15 @@ void AppMenuModel::update() void AppMenuModel::onActiveWindowChanged() { - KWindowInfo info(KWindowSystem::activeWindow(), - NET::WMState | NET::WMVisibleName, - NET::WM2AppMenuObjectPath | NET::WM2AppMenuServiceName); - const QString objectPath = info.applicationMenuObjectPath(); - const QString serviceName = info.applicationMenuServiceName(); + // 为了兼容旧版本,不使用新的 API +// KWindowInfo info(KWindowSystem::activeWindow(), +// NET::WMState | NET::WMVisibleName, +// NET::WM2AppMenuObjectPath | NET::WM2AppMenuServiceName); +// const QString objectPath = info.applicationMenuObjectPath(); +// const QString serviceName = info.applicationMenuServiceName(); + + const QString objectPath = QString::fromUtf8(getWindowPropertyString(KWindowSystem::activeWindow(), "_KDE_NET_WM_APPMENU_OBJECT_PATH")); + const QString serviceName = QString::fromUtf8(getWindowPropertyString(KWindowSystem::activeWindow(), "_KDE_NET_WM_APPMENU_SERVICE_NAME")); if (!objectPath.isEmpty() && !serviceName.isEmpty()) { setMenuAvailable(true); diff --git a/src/appmenu/appmenumodel.h b/src/appmenu/appmenumodel.h index 081d822..2c80b4b 100644 --- a/src/appmenu/appmenumodel.h +++ b/src/appmenu/appmenumodel.h @@ -41,8 +41,6 @@ class AppMenuModel : public QAbstractListModel Q_PROPERTY(bool menuAvailable READ menuAvailable WRITE setMenuAvailable NOTIFY menuAvailableChanged) Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged) - Q_PROPERTY(QRect screenGeometry READ screenGeometry WRITE setScreenGeometry NOTIFY screenGeometryChanged) - public: explicit AppMenuModel(QObject *parent = nullptr); ~AppMenuModel() override; @@ -63,9 +61,6 @@ public: bool visible() const; - QRect screenGeometry() const; - void setScreenGeometry(QRect geometry); - Q_SIGNALS: void requestActivateIndex(int index); @@ -77,7 +72,6 @@ private Q_SLOTS: Q_SIGNALS: void menuAvailableChanged(); void modelNeedsUpdate(); - void screenGeometryChanged(); void visibleChanged(); private: