有时我很好奇窗口管理器如何处理不响应的应用程序_NET_WM_PING
,例如,弹出窗口显示“您想终止此应用程序吗?“这对于调试 图形应用程序并了解如何不同的应用程序处理不同的信号和不同的窗口管理器 与应用程序交互。
例如:
kwin
有Client::pingWindow()
功能,并显示“您想终止此应用程序吗?“ 信息。mutter
有meta_display_ping_window
功能,并显示“应用程序没有响应“ 信息。xfwm4
有一个clientSendNetWMPing
功能,并显示一个“此窗口可能正忙并且没有响应”信息。
我想有意触发这些行为,能够运行无响应的程序,例如strace
查看它收到的信号。我正在沿着 Python/Tkinter 或 bash/zenity 脚本的思路思考,但我对其他可能性持开放态度。理想情况下,该程序不会使 CPU 饱和,但这也不是问题。 (请注意,这SIGSTOP
不会触发窗口管理器所需的行为。)
有什么简单而可靠的方法可以有意创建一个不响应的图形进程_NET_WM_PING
,从而引起窗口管理器的注意?
答案1
确切的答案将取决于框架等。
所有 GUI 框架上的通用“线程”是一个中央/主事件处理程序,用于接收重绘、键盘和鼠标输入等事件/请求。
这就是处理程序,您可以在其中处理一个不会响应但处于紧密while true; do nothing; done
循环中的事件。
答案2
您可以用几行代码敲出一个 GUI 应用程序,并将其包装在捕获您信号的东西中。 Tkinter 与 python 的说法非常简单。看这里
答案3
这是一段快速而肮脏的 C++ 代码,它创建一个窗口并冻结。
// freeze.cpp
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtCore/QMutex>
int main (int argc, char** argv) {
QApplication a (argc, argv);
QMainWindow w;
QMutex m;
w.show ();
m.lock ();
m.lock ();
return (a.exec ());
}
这取决于Qt5框架。安装Qt5开发包后,可以使用以下命令行编译代码(实际上,这不是构建Qt应用程序的正确方法):
$ g++ freeze.cpp -fPIC -std=c++11 -I/usr/include/qt5 -I/usr/include/qt -lQt5Core -lQt5Gui -lQt5Widgets
答案4
替换zenity
为您选择的任何具有该_NET_WM_PING
属性的 X 应用程序。
#!/bin/bash
zenity --question &
sleep 5
kill -STOP $!
您需要使用kill -CONT xxxx
,替换xxxx
为 X 应用程序的 PID,以允许它消失。
xprop | grep _NET_WM_PING # Click on the zenity GTK dialog
WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST