aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2025-02-10 19:38:20 +0100
committerdec05eba <dec05eba@protonmail.com>2025-02-10 19:38:20 +0100
commitd0aee0cb0f8e471aedc40554ccd92ba60cf8aab6 (patch)
treeaddad76fd0b0e1328916ec782d513319f14b9a76
parent238492aecf7f6fa31ff3d9fee528b50a7ab3e946 (diff)
Better x11 window detection on wayland
-rw-r--r--src/main.cpp52
1 files changed, 50 insertions, 2 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 6f7e6f1..7c62591 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -226,6 +226,45 @@ static Window window_get_target_window_child(Display *display, Window window) {
return found_window;
}
+static bool window_has_title(Display *dpy, Window window) {
+ bool result = false;
+ const Atom net_wm_name_atom = XInternAtom(dpy, "_NET_WM_NAME", False);
+ const Atom wm_name_atom = XInternAtom(dpy, "WM_NAME", False);
+ const Atom utf8_string_atom = XInternAtom(dpy, "UTF8_STRING", False);
+
+ Atom type = None;
+ int format = 0;
+ unsigned long num_items = 0;
+ unsigned long bytes_left = 0;
+ unsigned char *data = NULL;
+ XGetWindowProperty(dpy, window, net_wm_name_atom, 0, 1024, False, utf8_string_atom, &type, &format, &num_items, &bytes_left, &data);
+
+ if(type == utf8_string_atom && format == 8 && data) {
+ result = true;
+ goto done;
+ }
+
+ if(data)
+ XFree(data);
+
+ type = None;
+ format = 0;
+ num_items = 0;
+ bytes_left = 0;
+ data = NULL;
+ XGetWindowProperty(dpy, window, wm_name_atom, 0, 1024, False, 0, &type, &format, &num_items, &bytes_left, &data);
+
+ if((type == XA_STRING || type == utf8_string_atom) && data) {
+ result = true;
+ goto done;
+ }
+
+ done:
+ if(data)
+ XFree(data);
+ return result;
+}
+
static mgl::vec2i get_cursor_position(Display *dpy, Window *window) {
Window root_window = None;
*window = None;
@@ -233,8 +272,17 @@ static mgl::vec2i get_cursor_position(Display *dpy, Window *window) {
unsigned int dummy_u;
mgl::vec2i root_pos;
XQueryPointer(dpy, DefaultRootWindow(dpy), &root_window, window, &root_pos.x, &root_pos.y, &dummy_i, &dummy_i, &dummy_u);
- if(window)
- *window = window_get_target_window_child(dpy, *window);
+
+ const Window direct_window = *window;
+ *window = window_get_target_window_child(dpy, *window);
+ // HACK: Count some other x11 windows as having an x11 window focused. Some games seem to create an Input window and that gets focused.
+ if(!*window) {
+ XWindowAttributes attr;
+ memset(&attr, 0, sizeof(attr));
+ XGetWindowAttributes(dpy, direct_window, &attr);
+ if(attr.c_class == InputOnly && !window_has_title(dpy, direct_window))
+ *window = direct_window;
+ }
return root_pos;
}