这是一个简约的Linux应用程序,用于使用X11启动和关闭窗口。当用户在终端上按ctrl-c或点击Windows管理器上的“关闭”按钮时,我想要一个干净的出口(按valgrind)。我花了一段时间才找到这些信息,所以我想我会发布工作代码以及提出几个问题。我使用信号捕捉“ctrl-c”,Atom用于捕捉关闭按钮单击。从X11应用程序中清除退出?
问题:
1)这是完成从X11应用程序干净退出的正确/最佳方式?
2)我可以在信号处理程序代码中发送一个事件吗?有些人说不......
3)除Atom之外,还有其他方法可用于捕获Windows管理器事件吗?
// use "gcc main.c -lX11" to compile
#include <string.h>
#include <signal.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
// global data
struct {
Display* display;
Window* window;
char done;
} global;
void SignalHandler(int n) {
switch(n) {
case SIGINT: // user pressed ctrl-c from terminal
global.done = 1; // tell event loop to exit
XClientMessageEvent event; // dummy event to wake up XNextEvent
memset(&event, 0, sizeof(XClientMessageEvent));
event.type = ClientMessage;
event.format = 32; // not used but cannot be zero
XSendEvent(global.display, *global.window, 0, 0, (XEvent*)&event);
XFlush(global.display); // make event happen immediately
}
}
void RegisterSignals() { signal(SIGINT, SignalHandler); }
int main() {
memset(&global, 0, sizeof(global));
RegisterSignals();
Display* display = XOpenDisplay(NULL);
global.display = display;
Visual* visual = DefaultVisual(display, 0);
int depth = DefaultDepth(display, 0);
XSetWindowAttributes frame_attr;
frame_attr.background_pixel = XWhitePixel(display, 0);
Window window = XCreateWindow(display, XRootWindow(display, 0),
0, 0, 400, 300, 5, depth, InputOutput, visual, CWBackPixel, &frame_attr);
global.window = &window;
XStoreName(display, window, "Title");
XSelectInput(display, window, 0xFFFF);
XFontStruct* font = XLoadQueryFont(display, "10x20");
XGCValues gc_values;
gc_values.font = font->fid;
gc_values.foreground = XBlackPixel(display, 0);
GC gc = XCreateGC(display, window, GCFont + GCForeground, &gc_values);
// Windows Manager Stuff (like clicking close button)
Atom wmDeleteWindow = XInternAtom(display, "WM_DELETE_WINDOW", True);
XSetWMProtocols(display, window, &wmDeleteWindow, 1);
XMapWindow(display, window);
XEvent event;
while (!global.done) {
XNextEvent(display, (XEvent *)&event); // blocks until event
switch (event.type) {
// other events go here...
case ClientMessage:
// user clicked close button on window
if (event.xclient.data.l[0] == wmDeleteWindow) { global.done = 1; }
}
}
// Cleanup
XFreeGC(display, gc);
XFreeFont(display, font);
XCloseDisplay(display);
return 0;
}
为什么你的代码只需使用Xlib的应用程序? –
@BasileStarynkevitch:因为OP想要? (学习的目的,也许这是一个简单的,定制的框架的启动等) – datenwolf
的确,为什么不......但是,这是一个非常漫长的旅程...... –