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:
| M | pwm.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);