Fix global menu for Xwayland windows

In a Plasma Wayland session, kded does not use the XCB QPA and so Qt doesn't
have an X11 connection. For X11 windows, it has to set some properties on
registration to make them known, so just make an X11 connection in that case.
wilder-5.22
Fabian Vogt 5 years ago
parent d5440ef980
commit e4af18d67d
  1. 31
      appmenu/appmenu.cpp
  2. 9
      appmenu/appmenu.h
  3. 3
      appmenu/menuimporter.cpp

@ -42,7 +42,6 @@
#include <kpluginfactory.h>
#include <kpluginloader.h>
#include <KSharedConfig>
#include <KWindowSystem>
#if HAVE_X11
#include <QX11Info>
@ -100,16 +99,32 @@ AppMenuModule::AppMenuModule(QObject* parent, const QList<QVariant>&)
if (QDBusConnection::sessionBus().interface()->isServiceRegistered(QStringLiteral("org.kde.kappmenuview"))) {
setupMenuImporter();
}
#if HAVE_X11
if (!QX11Info::connection()) {
m_xcbConn = xcb_connect(nullptr, nullptr);
}
#endif
}
AppMenuModule::~AppMenuModule() = default;
AppMenuModule::~AppMenuModule()
{
#if HAVE_X11
if (m_xcbConn) {
xcb_disconnect(m_xcbConn);
}
#endif
}
void AppMenuModule::slotWindowRegistered(WId id, const QString &serviceName, const QDBusObjectPath &menuObjectPath)
{
#if HAVE_X11
if (KWindowSystem::isPlatformX11()) {
auto *c = QX11Info::connection();
auto *c = QX11Info::connection();
if (!c) {
c = m_xcbConn;
}
if(c) {
static xcb_atom_t s_serviceNameAtom = XCB_ATOM_NONE;
static xcb_atom_t s_objectPathAtom = XCB_ATOM_NONE;
@ -126,8 +141,14 @@ void AppMenuModule::slotWindowRegistered(WId id, const QString &serviceName, con
}
}
xcb_change_property(c, XCB_PROP_MODE_REPLACE, id, atom, XCB_ATOM_STRING,
auto cookie = xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, id, atom, XCB_ATOM_STRING,
8, value.length(), value.constData());
xcb_generic_error_t *error;
if ((error = xcb_request_check(c, cookie))) {
qWarning() << "Got an error";
free(error);
return;
}
};
// TODO only set the property if it doesn't already exist

@ -27,6 +27,11 @@
#ifndef APPMENUMODULE_H
#define APPMENUMODULE_H
#include <config-X11.h>
#ifdef HAVE_X11
#include <xcb/xcb.h>
#endif
#include <kdedmodule.h>
#include <QPointer>
@ -92,6 +97,10 @@ private:
AppmenuDBus *m_appmenuDBus;
QDBusServiceWatcher *m_menuViewWatcher;
QPointer<VerticalMenu> m_menu;
#ifdef HAVE_X11
xcb_connection_t *m_xcbConn = nullptr;
#endif
};
#endif

@ -67,9 +67,10 @@ void MenuImporter::RegisterWindow(WId id, const QDBusObjectPath& path)
{
KWindowInfo info(id, NET::WMWindowType, NET::WM2WindowClass);
NET::WindowTypes mask = NET::AllTypesMask;
auto type = info.windowType(mask);
// Menu can try to register, right click in gimp for example
if (info.windowType(mask) & (NET::Menu|NET::DropdownMenu|NET::PopupMenu)) {
if (type != NET::Unknown && (type & (NET::Menu|NET::DropdownMenu|NET::PopupMenu))) {
return;
}

Loading…
Cancel
Save