Introduce KillPrompt class
This encapsulates running and querying for the killer helper and allows to more easily re-use it for Wayland windows.
This commit is contained in:
parent
1237b80920
commit
214e471a50
5 changed files with 145 additions and 19 deletions
|
@ -114,6 +114,7 @@ target_sources(kwin PRIVATE
|
||||||
keyboard_layout.cpp
|
keyboard_layout.cpp
|
||||||
keyboard_layout_switching.cpp
|
keyboard_layout_switching.cpp
|
||||||
keyboard_repeat.cpp
|
keyboard_repeat.cpp
|
||||||
|
killprompt.cpp
|
||||||
killwindow.cpp
|
killwindow.cpp
|
||||||
kscreenintegration.cpp
|
kscreenintegration.cpp
|
||||||
layers.cpp
|
layers.cpp
|
||||||
|
|
86
src/killprompt.cpp
Normal file
86
src/killprompt.cpp
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* 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 "x11window.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace KWin
|
||||||
|
{
|
||||||
|
|
||||||
|
KillPrompt::KillPrompt(Window *window)
|
||||||
|
: m_window(window)
|
||||||
|
{
|
||||||
|
Q_ASSERT(qobject_cast<X11Window *>(window));
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
if (auto *x11Window = qobject_cast<X11Window *>(m_window)) {
|
||||||
|
wid = QString::number(x11Window->window());
|
||||||
|
timestampString = QString::number(timestamp);
|
||||||
|
if (!x11Window->clientMachine()->isLocal()) {
|
||||||
|
hostname = x11Window->clientMachine()->hostName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList args{
|
||||||
|
QStringLiteral("--pid"),
|
||||||
|
QString::number(m_window->pid()),
|
||||||
|
QStringLiteral("--windowname"),
|
||||||
|
m_window->captionNormal(),
|
||||||
|
QStringLiteral("--applicationname"),
|
||||||
|
m_window->resourceClass(),
|
||||||
|
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
|
45
src/killprompt.h
Normal file
45
src/killprompt.h
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 Kai Uwe Broulik <kde@broulik.de>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
namespace KWin
|
||||||
|
{
|
||||||
|
|
||||||
|
class Window;
|
||||||
|
|
||||||
|
class KillPrompt
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Creates a kill helper process.
|
||||||
|
* @param window The window to kill, must be an X11Window
|
||||||
|
*/
|
||||||
|
explicit KillPrompt(Window *window);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Whether the kill helper process is currently running.
|
||||||
|
*/
|
||||||
|
bool isRunning() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts the kill helper process.
|
||||||
|
* @param timestamp The X activation timestamp.
|
||||||
|
*/
|
||||||
|
void start(quint32 timestamp = 0);
|
||||||
|
/**
|
||||||
|
* @brief Terminate the kill helper process.
|
||||||
|
*/
|
||||||
|
void quit();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Window *m_window = nullptr;
|
||||||
|
QProcess m_process;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace KWin
|
|
@ -23,6 +23,7 @@
|
||||||
#include "effect/effecthandler.h"
|
#include "effect/effecthandler.h"
|
||||||
#include "focuschain.h"
|
#include "focuschain.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
|
#include "killprompt.h"
|
||||||
#include "netinfo.h"
|
#include "netinfo.h"
|
||||||
#include "placement.h"
|
#include "placement.h"
|
||||||
#include "scene/surfaceitem_x11.h"
|
#include "scene/surfaceitem_x11.h"
|
||||||
|
@ -290,7 +291,6 @@ X11Window::X11Window()
|
||||||
, blocks_compositing(false)
|
, blocks_compositing(false)
|
||||||
, in_group(nullptr)
|
, in_group(nullptr)
|
||||||
, ping_timer(nullptr)
|
, ping_timer(nullptr)
|
||||||
, m_killHelperPID(0)
|
|
||||||
, m_pingTimestamp(XCB_TIME_CURRENT_TIME)
|
, m_pingTimestamp(XCB_TIME_CURRENT_TIME)
|
||||||
, m_userTime(XCB_TIME_CURRENT_TIME) // Not known yet
|
, m_userTime(XCB_TIME_CURRENT_TIME) // Not known yet
|
||||||
, allowed_actions()
|
, allowed_actions()
|
||||||
|
@ -356,9 +356,8 @@ X11Window::~X11Window()
|
||||||
{
|
{
|
||||||
delete info;
|
delete info;
|
||||||
|
|
||||||
if (m_killHelperPID && !::kill(m_killHelperPID, 0)) { // means the process is alive
|
if (m_killPrompt) {
|
||||||
::kill(m_killHelperPID, SIGTERM);
|
m_killPrompt->quit();
|
||||||
m_killHelperPID = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_ASSERT(!isInteractiveMoveResize());
|
Q_ASSERT(!isInteractiveMoveResize());
|
||||||
|
@ -2106,15 +2105,14 @@ void X11Window::gotPing(xcb_timestamp_t timestamp)
|
||||||
|
|
||||||
setUnresponsive(false);
|
setUnresponsive(false);
|
||||||
|
|
||||||
if (m_killHelperPID && !::kill(m_killHelperPID, 0)) { // means the process is alive
|
if (m_killPrompt) {
|
||||||
::kill(m_killHelperPID, SIGTERM);
|
m_killPrompt->quit();
|
||||||
m_killHelperPID = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Window::killProcess(bool ask, xcb_timestamp_t timestamp)
|
void X11Window::killProcess(bool ask, xcb_timestamp_t timestamp)
|
||||||
{
|
{
|
||||||
if (m_killHelperPID && !::kill(m_killHelperPID, 0)) { // means the process is alive
|
if (m_killPrompt && m_killPrompt->isRunning()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Q_ASSERT(!ask || timestamp != XCB_TIME_CURRENT_TIME);
|
Q_ASSERT(!ask || timestamp != XCB_TIME_CURRENT_TIME);
|
||||||
|
@ -2132,16 +2130,10 @@ void X11Window::killProcess(bool ask, xcb_timestamp_t timestamp)
|
||||||
::kill(pid, SIGTERM);
|
::kill(pid, SIGTERM);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QString hostname = clientMachine()->isLocal() ? QStringLiteral("localhost") : clientMachine()->hostName();
|
if (!m_killPrompt) {
|
||||||
// execute helper from build dir or the system installed one
|
m_killPrompt = std::make_unique<KillPrompt>(this);
|
||||||
const QFileInfo buildDirBinary{QDir{QCoreApplication::applicationDirPath()}, QStringLiteral("kwin_killer_helper")};
|
}
|
||||||
QProcess::startDetached(buildDirBinary.exists() ? buildDirBinary.absoluteFilePath() : KWIN_KILLER_BIN,
|
m_killPrompt->start(timestamp);
|
||||||
QStringList() << QStringLiteral("--pid") << QString::number(unsigned(pid)) << QStringLiteral("--hostname") << hostname
|
|
||||||
<< QStringLiteral("--windowname") << captionNormal()
|
|
||||||
<< QStringLiteral("--applicationname") << resourceClass()
|
|
||||||
<< QStringLiteral("--wid") << QString::number(window())
|
|
||||||
<< QStringLiteral("--timestamp") << QString::number(timestamp),
|
|
||||||
QString(), &m_killHelperPID);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@ class KStartupInfoId;
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class KillPrompt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Defines Predicates on how to search for a Client.
|
* @brief Defines Predicates on how to search for a Client.
|
||||||
*
|
*
|
||||||
|
@ -479,7 +481,7 @@ private:
|
||||||
QString cap_normal, cap_iconic, cap_suffix;
|
QString cap_normal, cap_iconic, cap_suffix;
|
||||||
Group *in_group;
|
Group *in_group;
|
||||||
QTimer *ping_timer;
|
QTimer *ping_timer;
|
||||||
qint64 m_killHelperPID;
|
std::unique_ptr<KillPrompt> m_killPrompt;
|
||||||
xcb_timestamp_t m_pingTimestamp;
|
xcb_timestamp_t m_pingTimestamp;
|
||||||
xcb_timestamp_t m_userTime;
|
xcb_timestamp_t m_userTime;
|
||||||
NET::Actions allowed_actions;
|
NET::Actions allowed_actions;
|
||||||
|
|
Loading…
Reference in a new issue