From 81f7436fda781ceb386309400f76754b97b3990d Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Mon, 14 Jun 2021 17:48:00 +0200 Subject: [PATCH] xdgactivation: Let activation requests through when they come from a window manager If a client already has powers to move clients around, let them also activate using the right protocols as well. This is useful to be able to implement SNI or Notifications where the shell doesn't get full surface activation when interacting with it. --- src/xdgactivationv1.cpp | 20 +++++++++++++------- src/xdgactivationv1.h | 1 + 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/xdgactivationv1.cpp b/src/xdgactivationv1.cpp index 94f586d5cb..74ef4ae173 100644 --- a/src/xdgactivationv1.cpp +++ b/src/xdgactivationv1.cpp @@ -21,6 +21,13 @@ using namespace KWaylandServer; namespace KWin { + +static bool isPrivilegedInWindowManagement(const ClientConnection *client) +{ + auto requestedInterfaces = client->property("requestedInterfaces").toStringList(); + return requestedInterfaces.contains(QLatin1String("org_kde_plasma_window_management")); +} + XdgActivationV1Integration::XdgActivationV1Integration(XdgActivationV1Interface *activation, QObject *parent) : QObject(parent) { @@ -31,11 +38,11 @@ XdgActivationV1Integration::XdgActivationV1Integration(XdgActivationV1Interface } clear(); }); - activation->setActivationTokenCreator([this](SurfaceInterface *surface, uint serial, SeatInterface *seat, const QString &appId) -> QString { + activation->setActivationTokenCreator([this](ClientConnection *client, SurfaceInterface *surface, uint serial, SeatInterface *seat, const QString &appId) -> QString { Workspace *ws = Workspace::self(); - if (ws->activeClient()->surface() != surface) { - qCWarning(KWIN_CORE) << "Inactive surfaces cannot be granted a token"; - return {}; + if (ws->activeClient() && ws->activeClient()->surface() != surface && !isPrivilegedInWindowManagement(client)) { + qCWarning(KWIN_CORE) << "Cannot grant a token to" << client; + return QStringLiteral("not-granted-666"); } static int i = 0; @@ -44,7 +51,7 @@ XdgActivationV1Integration::XdgActivationV1Integration(XdgActivationV1Interface if (m_currentActivationToken) { clear(); } - m_currentActivationToken.reset(new ActivationToken{newToken, surface, serial, seat, appId}); + m_currentActivationToken.reset(new ActivationToken{newToken, client, surface, serial, seat, appId}); const auto icon = QIcon::fromTheme(AbstractClient::iconFromDesktopFile(appId), QIcon::fromTheme(QStringLiteral("system-run"))); Q_EMIT effects->startupAdded(m_currentActivationToken->token, icon); @@ -69,9 +76,8 @@ void XdgActivationV1Integration::activateSurface(SurfaceInterface *surface, cons } auto ownerSurfaceClient = waylandServer()->findClient(m_currentActivationToken->surface); - qCDebug(KWIN_CORE) << "activating" << client << surface << "on behalf of" << m_currentActivationToken->surface << "into" << ownerSurfaceClient; - if (ws->activeClient() == ownerSurfaceClient || m_currentActivationToken->applicationId.isEmpty() || ownerSurfaceClient->desktopFileName().isEmpty()) { + if (ws->activeClient() == ownerSurfaceClient || isPrivilegedInWindowManagement(m_currentActivationToken->client)) { ws->activateClient(client); } else { qCWarning(KWIN_CORE) << "Activation requested while owner isn't active" << ownerSurfaceClient->desktopFileName() diff --git a/src/xdgactivationv1.h b/src/xdgactivationv1.h index 9951d9c68c..01ac3e5162 100644 --- a/src/xdgactivationv1.h +++ b/src/xdgactivationv1.h @@ -30,6 +30,7 @@ public: struct ActivationToken { const QString token; + const KWaylandServer::ClientConnection *client; const KWaylandServer::SurfaceInterface *surface; const uint serial; const KWaylandServer::SeatInterface *seat;