i wrote a simple window manager using Xlib. the window manager runs, and launching a terminal with the Super+t shortcut works correctly. however, when i attempted to close the focused window by sending a window close event to the X server, it didn’t work. as an alternative, i used the XDestroyWindow function, but this approach unexpectedly caused the entire window manager to close. What's the problem?
code:
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
Display *display;
Window root;
int running = 1;
/* just for debugging */
void wmlog(unsigned long a)
{
FILE *file;
file = fopen("/home/reza/.wmlog", "a");
if (file == NULL)
{
printf("error opening file.\n");
}
fprintf(file, "%lu \n", a);
fclose(file);
}
void open_xterm(Display *display, Window root) {
system("xterm &");
}
void close_focused_window(Display *display) {
Window focused;
int revert_to;
XGetInputFocus(display, &focused, &revert_to);
wmlog(focused);
XDestroyWindow(display, focused);
/*
XEvent ev;
ev.xclient.type = ClientMessage;
ev.xclient.window = focused;
ev.xclient.message_type = XInternAtom(display, "WM_PROTOCOLS", True);
ev.xclient.format = 32;
ev.xclient.data.l[0] = XInternAtom(display, "WM_DELETE_WINDOW", True);
ev.xclient.data.l[1] = CurrentTime;
XSendEvent(display, focused, False, NoEventMask, &ev);
*/
XFlush(display);
}
int main() {
Display *display = XOpenDisplay(NULL);
if (!display) {
fprintf(stderr, "Error: Unable to open display.\n");
return 1;
}
Window root = DefaultRootWindow(display);
wmlog(root);
XGrabKey(display, XKeysymToKeycode(display, XK_t), Mod4Mask, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(display, XKeysymToKeycode(display, XK_w), Mod4Mask, root, True, GrabModeAsync, GrabModeAsync);
XGrabKey(display, XKeysymToKeycode(display, XK_q), Mod4Mask, root, True, GrabModeAsync, GrabModeAsync);
XEvent event;
while (running) {
XNextEvent(display, &event);
if (event.type == KeyPress) {
if (event.xkey.keycode == XKeysymToKeycode(display, XK_t) && event.xkey.state & Mod4Mask)
open_xterm(display, root);
else if (event.xkey.keycode == XKeysymToKeycode(display, XK_w) && event.xkey.state & Mod4Mask)
close_focused_window(display);
else if (event.xkey.keycode == XKeysymToKeycode(display, XK_q) && event.xkey.state & Mod4Mask)
running = 0;
}
}
XCloseDisplay(display);
return 0;
}
upon examining the XID of both the root window and the focused window, i noticed that they share the same XID(while the focus was on the terminal window and it was receiving inputs correctly), no new MapNotify events occur while opening xterm.