activation: Fix activation notification of Xwayland clients

Most xwayland clients don't know their desktop file name, so use the
StartupWMClass field in their desktop files as means to inferring their
desktop file name.

BUG: 455265
This commit is contained in:
Aleix Pol 2022-07-18 18:56:35 +02:00
parent b2aacba086
commit c68a0f5dc0

View file

@ -17,6 +17,7 @@
#include "wayland_server.h" #include "wayland_server.h"
#include "window.h" #include "window.h"
#include "workspace.h" #include "workspace.h"
#include <KApplicationTrader>
#include <KDesktopFile> #include <KDesktopFile>
using namespace KWaylandServer; using namespace KWaylandServer;
@ -31,6 +32,25 @@ static bool isPrivilegedInWindowManagement(const ClientConnection *client)
return requestedInterfaces.contains(QLatin1String("org_kde_plasma_window_management")); return requestedInterfaces.contains(QLatin1String("org_kde_plasma_window_management"));
} }
static const QString windowDesktopFileName(Window *window)
{
QString ret = window->desktopFileName();
if (!ret.isEmpty()) {
return ret;
}
// Fallback to StartupWMClass for legacy apps
const auto resourceName = window->resourceName();
const auto service = KApplicationTrader::query([&resourceName](const KService::Ptr &service) {
return service->property("StartupWMClass") == resourceName;
});
if (!service.isEmpty()) {
ret = service.constFirst()->desktopEntryName();
}
return ret;
}
XdgActivationV1Integration::XdgActivationV1Integration(XdgActivationV1Interface *activation, QObject *parent) XdgActivationV1Integration::XdgActivationV1Integration(XdgActivationV1Interface *activation, QObject *parent)
: QObject(parent) : QObject(parent)
{ {
@ -41,7 +61,7 @@ XdgActivationV1Integration::XdgActivationV1Integration(XdgActivationV1Interface
} }
// We check that it's not the app that we are trying to activate // We check that it's not the app that we are trying to activate
if (window->desktopFileName() != m_currentActivationToken->applicationId) { if (windowDesktopFileName(window) != m_currentActivationToken->applicationId) {
// But also that the new one has been requested after the token was requested // But also that the new one has been requested after the token was requested
if (window->lastUsageSerial() < m_currentActivationToken->serial) { if (window->lastUsageSerial() < m_currentActivationToken->serial) {
return; return;