wm

My window manager
git clone git://pcardenasb.com/wm
Log | Files | Refs

commit 23e6353cbaf1098914016eb4f0770a07e498ebe4
parent 54d6a6bb00d5f176e6d0a7ab5d00da52b40fa74b
Author: Pablo Cárdenas <pablo.cardenas@imca.edu.pe>
Date:   Tue,  7 Jan 2025 21:15:13 -0500

Support for WM_TAKE_FOCUS

Diffstat:
Mpwm.c | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 68 insertions(+), 19 deletions(-)

diff --git a/pwm.c b/pwm.c @@ -53,7 +53,7 @@ int main(void) } Window root = DefaultRootWindow(dpy); - printf("root = %lx\n", root); + printf("root = 0x%lx\n", root); XSelectInput(dpy, root, SubstructureRedirectMask | SubstructureNotifyMask | ButtonPressMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | StructureNotifyMask | PropertyChangeMask); XGrabKey(dpy, XKeysymToKeycode(dpy, XStringToKeysym("j")), Mod4Mask, root, True, GrabModeAsync, GrabModeAsync); @@ -191,12 +191,59 @@ int main(void) XSetInputFocus(dpy, windows[current_index], RevertToParent, CurrentTime); XRaiseWindow(dpy, windows[current_index]); XSetWindowBorder(dpy, windows[current_index], 0xAAAAAA); + + // Send WM_TAKE_FOCUS if supported + Atom *protocols; + int n; + int supported = 0; + if (XGetWMProtocols(dpy, windows[current_index], &protocols, &n)) { + while (!supported && n--) { + supported = XInternAtom(dpy, "WM_TAKE_FOCUS", False) == protocols[n]; + } + XFree(protocols); + } + printf("supported WM_TAKE_FOCUS = %d\n", exists); + if (supported) { + XClientMessageEvent send_ev = { + .type = ClientMessage, + .window = windows[current_index], + .message_type = XInternAtom(dpy, "WM_PROTOCOLS", False), + .format = 32, + .data.l[0] = XInternAtom(dpy, "WM_TAKE_FOCUS", False), + .data.l[1] = CurrentTime, + }; + XSendEvent(dpy, windows[current_index], False, NoEventMask, (XEvent *)&send_ev); + } + } else if (ev.xkey.keycode == XKeysymToKeycode(dpy, XStringToKeysym("k"))) { XSetWindowBorder(dpy, windows[current_index], BORDER_COLOR); current_index = (current_index + 1) % num_windows; XSetInputFocus(dpy, windows[current_index], RevertToParent, CurrentTime); XRaiseWindow(dpy, windows[current_index]); XSetWindowBorder(dpy, windows[current_index], 0xAAAAAA); + + // Send WM_TAKE_FOCUS if supported + Atom *protocols; + int n; + int supported = 0; + if (XGetWMProtocols(dpy, windows[current_index], &protocols, &n)) { + while (!supported && n--) { + supported = XInternAtom(dpy, "WM_TAKE_FOCUS", False) == protocols[n]; + } + XFree(protocols); + } + printf("supported WM_TAKE_FOCUS = %d\n", exists); + if (supported) { + XClientMessageEvent send_ev = { + .type = ClientMessage, + .window = windows[current_index], + .message_type = XInternAtom(dpy, "WM_PROTOCOLS", False), + .format = 32, + .data.l[0] = XInternAtom(dpy, "WM_TAKE_FOCUS", False), + .data.l[1] = CurrentTime, + }; + XSendEvent(dpy, windows[current_index], False, NoEventMask, (XEvent *)&send_ev); + } } else if (ev.xkey.keycode == XKeysymToKeycode(dpy, XStringToKeysym("c"))) { if (wmcheckwin) { XDestroyWindow(dpy, wmcheckwin); @@ -251,28 +298,29 @@ int main(void) } } else if (ev.xkey.keycode == XKeysymToKeycode(dpy, XStringToKeysym("q"))) { - // TODO: Only send event If the window supports (XGetWMProtocols) + // Send WM_TAKE_DELETE if supported Atom *protocols; int n; - int exists = 0; + int supported = 0; if (XGetWMProtocols(dpy, windows[current_index], &protocols, &n)) { - while (!exists && n--) { - printf("protocols[%d] = %s\n", n, XGetAtomName(dpy, protocols[n])); - exists = XInternAtom(dpy, "WM_DELETE_WINDOW", False) == protocols[n]; + while (!supported && n--) { + supported = XInternAtom(dpy, "WM_DELETE_WINDOW", False) == protocols[n]; } XFree(protocols); } - printf("exists = %d\n", exists); + printf("supported WM_DELETE_WINDOW = %d\n", exists); - XClientMessageEvent send_ev = { - .type = ClientMessage, - .window = windows[current_index], - .message_type = XInternAtom(dpy, "WM_PROTOCOLS", False), - .format = 32, - .data.l[0] = XInternAtom(dpy, "WM_DELETE_WINDOW", False), - .data.l[1] = CurrentTime, - }; - XSendEvent(dpy, windows[current_index], False, NoEventMask, (XEvent *)&send_ev); + if (supported) { + XClientMessageEvent send_ev = { + .type = ClientMessage, + .window = windows[current_index], + .message_type = XInternAtom(dpy, "WM_PROTOCOLS", False), + .format = 32, + .data.l[0] = XInternAtom(dpy, "WM_DELETE_WINDOW", False), + .data.l[1] = CurrentTime, + }; + XSendEvent(dpy, windows[current_index], False, NoEventMask, (XEvent *)&send_ev); + } } else if (ev.xkey.keycode == XKeysymToKeycode(dpy, XStringToKeysym("Return"))) { char *const cmd_argv[] = {"st", NULL}; spawn(cmd_argv, dpy); @@ -305,8 +353,9 @@ int main(void) break; case PropertyNotify: fprintf(stderr, - "%d: PropertyNotify : ev.xproperty.atom = %ld: %s : ev.xproperty.state = %d\n", + "%d: PropertyNotify : window = 0x%lx, ev.xproperty.atom = %ld: %s : ev.xproperty.state = %d\n", ev.type, + ev.xproperty.window, ev.xproperty.atom, XGetAtomName(dpy, ev.xproperty.atom), ev.xproperty.state); @@ -324,10 +373,10 @@ int main(void) XConfigureWindow(dpy, ev.xconfigurerequest.window, ev.xconfigurerequest.value_mask, &wc); break; case CreateNotify: - fprintf(stderr, "ev.type = %2d = CreateNotify, window = %lx\n", ev.type, ev.xcreatewindow.window); + fprintf(stderr, "ev.type = %2d = CreateNotify, window = 0x%lx\n", ev.type, ev.xcreatewindow.window); break; case DestroyNotify: - fprintf(stderr, "ev.type = %2d = DestroyNotify, window = %lx\n", ev.type, ev.xdestroywindow.window); + fprintf(stderr, "ev.type = %2d = DestroyNotify, window = 0x%lx\n", ev.type, ev.xdestroywindow.window); break; default: fprintf(stderr, "ev.type = %2d ", ev.type);