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_switching.cpp
|
||||
keyboard_repeat.cpp
|
||||
killprompt.cpp
|
||||
killwindow.cpp
|
||||
kscreenintegration.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 "focuschain.h"
|
||||
#include "group.h"
|
||||
#include "killprompt.h"
|
||||
#include "netinfo.h"
|
||||
#include "placement.h"
|
||||
#include "scene/surfaceitem_x11.h"
|
||||
|
@ -290,7 +291,6 @@ X11Window::X11Window()
|
|||
, blocks_compositing(false)
|
||||
, in_group(nullptr)
|
||||
, ping_timer(nullptr)
|
||||
, m_killHelperPID(0)
|
||||
, m_pingTimestamp(XCB_TIME_CURRENT_TIME)
|
||||
, m_userTime(XCB_TIME_CURRENT_TIME) // Not known yet
|
||||
, allowed_actions()
|
||||
|
@ -356,9 +356,8 @@ X11Window::~X11Window()
|
|||
{
|
||||
delete info;
|
||||
|
||||
if (m_killHelperPID && !::kill(m_killHelperPID, 0)) { // means the process is alive
|
||||
::kill(m_killHelperPID, SIGTERM);
|
||||
m_killHelperPID = 0;
|
||||
if (m_killPrompt) {
|
||||
m_killPrompt->quit();
|
||||
}
|
||||
|
||||
Q_ASSERT(!isInteractiveMoveResize());
|
||||
|
@ -2106,15 +2105,14 @@ void X11Window::gotPing(xcb_timestamp_t timestamp)
|
|||
|
||||
setUnresponsive(false);
|
||||
|
||||
if (m_killHelperPID && !::kill(m_killHelperPID, 0)) { // means the process is alive
|
||||
::kill(m_killHelperPID, SIGTERM);
|
||||
m_killHelperPID = 0;
|
||||
if (m_killPrompt) {
|
||||
m_killPrompt->quit();
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
Q_ASSERT(!ask || timestamp != XCB_TIME_CURRENT_TIME);
|
||||
|
@ -2132,16 +2130,10 @@ void X11Window::killProcess(bool ask, xcb_timestamp_t timestamp)
|
|||
::kill(pid, SIGTERM);
|
||||
}
|
||||
} else {
|
||||
QString hostname = clientMachine()->isLocal() ? QStringLiteral("localhost") : clientMachine()->hostName();
|
||||
// execute helper from build dir or the system installed one
|
||||
const QFileInfo buildDirBinary{QDir{QCoreApplication::applicationDirPath()}, QStringLiteral("kwin_killer_helper")};
|
||||
QProcess::startDetached(buildDirBinary.exists() ? buildDirBinary.absoluteFilePath() : KWIN_KILLER_BIN,
|
||||
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);
|
||||
if (!m_killPrompt) {
|
||||
m_killPrompt = std::make_unique<KillPrompt>(this);
|
||||
}
|
||||
m_killPrompt->start(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ class KStartupInfoId;
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
class KillPrompt;
|
||||
|
||||
/**
|
||||
* @brief Defines Predicates on how to search for a Client.
|
||||
*
|
||||
|
@ -479,7 +481,7 @@ private:
|
|||
QString cap_normal, cap_iconic, cap_suffix;
|
||||
Group *in_group;
|
||||
QTimer *ping_timer;
|
||||
qint64 m_killHelperPID;
|
||||
std::unique_ptr<KillPrompt> m_killPrompt;
|
||||
xcb_timestamp_t m_pingTimestamp;
|
||||
xcb_timestamp_t m_userTime;
|
||||
NET::Actions allowed_actions;
|
||||
|
|
Loading…
Reference in a new issue