21#include <KApplicationTrader>
22#include <KDesktopFile>
27static bool isPrivilegedInWindowManagement(
const ClientConnection *client)
30 auto requestedInterfaces = client->property(
"requestedInterfaces").toStringList();
31 return requestedInterfaces.contains(QLatin1String(
"org_kde_plasma_window_management")) || requestedInterfaces.contains(QLatin1String(
"kde_lockscreen_overlay_v1"));
34static const QString windowDesktopFileName(
Window *window)
36 QString ret = window->desktopFileName();
42 const auto resourceName = window->resourceName();
43 const auto service = KApplicationTrader::query([&resourceName](
const KService::Ptr &service) {
44 return service->property<QString>(
"StartupWMClass").compare(resourceName, Qt::CaseInsensitive) == 0;
47 if (!service.isEmpty()) {
48 ret = service.constFirst()->desktopEntryName();
58 if (!m_currentActivationToken || !window || window->property(
"token").toString() == m_currentActivationToken->token) {
63 if (windowDesktopFileName(window) != m_currentActivationToken->applicationId) {
65 if (window->lastUsageSerial() < m_currentActivationToken->serial) {
75 const bool isPrivileged = isPrivilegedInWindowManagement(client);
77 qCWarning(KWIN_CORE) <<
"Cannot grant a token to" << client;
78 return QStringLiteral(
"not-granted-666");
81 return requestToken(isPrivileged, surface, serial, seat, appId);
87QString XdgActivationV1Integration::requestToken(
bool isPrivileged, SurfaceInterface *surface, uint serial, SeatInterface *seat,
const QString &appId)
90 const auto newToken = QStringLiteral(
"kwin-%1").arg(++i);
92 if (m_currentActivationToken) {
95 bool showNotify =
false;
96 QIcon icon = QIcon::fromTheme(QStringLiteral(
"system-run"));
97 if (
const QString desktopFilePath = Window::findDesktopFile(appId); !desktopFilePath.isEmpty()) {
98 KDesktopFile df(desktopFilePath);
99 Window *window = Workspace::self()->activeWindow();
100 if (!window || appId != window->desktopFileName()) {
101 const auto desktop = df.desktopGroup();
102 showNotify = desktop.readEntry(
"X-KDE-StartupNotify", desktop.readEntry(
"StartupNotify",
true));
104 icon = QIcon::fromTheme(df.readIcon(), icon);
106 std::unique_ptr<PlasmaWindowActivationInterface> activation;
110 m_currentActivationToken = std::make_unique<ActivationToken>(ActivationToken{newToken, isPrivileged, surface, serial,
seat, appId, showNotify, std::move(activation)});
117void XdgActivationV1Integration::activateSurface(
SurfaceInterface *surface,
const QString &token)
122 qCWarning(KWIN_CORE) <<
"could not find the toplevel to activate" << surface;
126 if (!m_currentActivationToken || m_currentActivationToken->token != token) {
127 qCDebug(KWIN_CORE) <<
"Refusing to activate " << window <<
" (provided token: " << token <<
", current token:" << (m_currentActivationToken ? m_currentActivationToken->token : QStringLiteral(
"null")) <<
")";
128 window->demandAttention();
133 qCDebug(KWIN_CORE) <<
"activating" << window << surface <<
"on behalf of" << m_currentActivationToken->surface <<
"into" << ownerWindow;
137 qCWarning(KWIN_CORE) <<
"Activation requested while owner isn't active" << (ownerWindow ? ownerWindow->desktopFileName() :
"null")
138 << m_currentActivationToken->applicationId;
139 window->demandAttention();
144void XdgActivationV1Integration::clear()
146 Q_ASSERT(m_currentActivationToken);
147 if (m_currentActivationToken->showNotify) {
150 m_currentActivationToken.reset();
155#include "moc_xdgactivationv1.cpp"
Convenient Class which represents a wl_client.
void startupRemoved(const QString &id)
void startupAdded(const QString &id, const QIcon &icon)
std::unique_ptr< PlasmaWindowActivationInterface > createActivation(const QString &app_id)
Represents a Seat on the Wayland Display.
Resource representing a wl_surface.
Window * findWindow(const SurfaceInterface *surface) const
PlasmaWindowActivationFeedbackInterface * plasmaActivationFeedback() const
SurfaceInterface * surface() const
quint32 lastUsageSerial() const
Window * activeWindow() const
void activateWindow(Window *window, bool force=false)
void windowActivated(KWin::Window *)
static Workspace * self()
void activateSurface(SurfaceInterface *surface, const QString &token)
XdgActivationV1Integration(XdgActivationV1Interface *activation, QObject *parent)
void activateRequested(SurfaceInterface *surface, const QString &token)
Notifies about the surface being activated using token.
KWayland::Client::Seat * seat
WaylandServer * waylandServer()