kwin/src/killprompt.cpp
Aleix Pol Gonzalez bf1ce85474 Make it possible to build KWin without libxcb
Now that we have Wayland around, there's a whole branch of dependencies
that shouldn't be necessary anymore.
This allows to build KWin without all of it, allowing us to have a much
more compact alignment for cases where all the legacy software isn't
necessary anymore.

Bundle KWindowSystem X11-specific headers into it too, since it's part
of the same process.

Signed-off-by: Victoria Fischer <victoria.fischer@mbition.io>
2024-02-28 16:03:50 +00:00

116 lines
3.1 KiB
C++

/*
* SPDX-FileCopyrightText: 2023 Kai Uwe Broulik <kde@broulik.de>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "killprompt.h"
#include "client_machine.h"
#include "wayland/display.h"
#include "wayland/seat.h"
#include "wayland/xdgforeign_v2.h"
#include "wayland_server.h"
#include "xdgactivationv1.h"
#include "xdgshellwindow.h"
#if KWIN_BUILD_X11
#include "x11window.h"
#endif
#include <QDir>
#include <QFileInfo>
#include <QString>
namespace KWin
{
KillPrompt::KillPrompt(Window *window)
: m_window(window)
{
#if KWIN_BUILD_X11
Q_ASSERT(qobject_cast<X11Window *>(window) || qobject_cast<XdgToplevelWindow *>(window));
#else
Q_ASSERT(qobject_cast<XdgToplevelWindow *>(window));
#endif
m_process.setProcessChannelMode(QProcess::ForwardedChannels);
const QFileInfo binaryInfo(KWIN_KILLER_BIN);
const QFileInfo buildDirBinary{QDir{QCoreApplication::applicationDirPath()}, binaryInfo.fileName()};
if (buildDirBinary.exists()) {
m_process.setProgram(buildDirBinary.absoluteFilePath());
} else {
m_process.setProgram(KWIN_KILLER_BIN);
}
}
bool KillPrompt::isRunning() const
{
return m_process.state() == QProcess::Running;
}
void KillPrompt::start(quint32 timestamp)
{
if (isRunning()) {
return;
}
QProcessEnvironment env = kwinApp()->processStartupEnvironment();
QString wid;
QString timestampString;
QString hostname = QStringLiteral("localhost");
QString appId = !m_window->desktopFileName().isEmpty() ? m_window->desktopFileName() : m_window->resourceClass();
QString platform;
#if KWIN_BUILD_X11
if (auto *x11Window = qobject_cast<X11Window *>(m_window)) {
platform = QStringLiteral("xcb");
wid = QString::number(x11Window->window());
timestampString = QString::number(timestamp);
if (!x11Window->clientMachine()->isLocal()) {
hostname = x11Window->clientMachine()->hostName();
}
} else
#endif
if (auto *xdgToplevel = qobject_cast<XdgToplevelWindow *>(m_window)) {
platform = QStringLiteral("wayland");
auto *exported = waylandServer()->exportAsForeign(xdgToplevel->surface());
wid = exported->handle();
auto *seat = waylandServer()->seat();
const QString token = waylandServer()->xdgActivationIntegration()->requestPrivilegedToken(nullptr, seat->display()->serial(), seat, QStringLiteral("org.kde.kwin.killer"));
env.insert(QStringLiteral("XDG_ACTIVATION_TOKEN"), token);
env.remove(QStringLiteral("QT_WAYLAND_RECONNECT"));
}
QStringList args{
QStringLiteral("-platform"),
platform,
QStringLiteral("--pid"),
QString::number(m_window->pid()),
QStringLiteral("--windowname"),
m_window->captionNormal(),
QStringLiteral("--applicationname"),
appId,
QStringLiteral("--wid"),
wid,
QStringLiteral("--hostname"),
hostname,
QStringLiteral("--timestamp"),
timestampString,
};
m_process.setArguments(args);
m_process.setProcessEnvironment(env);
m_process.start();
}
void KillPrompt::quit()
{
m_process.terminate();
}
} // namespace KWin