The initial Slint problem was larger than thought. Hopefully a more universal fix.
This commit is contained in:
1 parent
d0fdce7285
commit
1c12bc6636
10 files changed
+294
-6
No files matched your search
@@ -175,6 +175,57 @@ PointerPosition cthulhu_read_pointer(Display *display) {
|
||||
if (cthulhu_x11_end_read(display)) result = (PointerPosition){0};
|
||||
return result;
|
||||
}
|
||||
// Resolve only the client's immediate enclosing frame. Some WMs omit or leave
|
||||
// stale _NET_FRAME_EXTENTS, while GTK reports the real reparenting frame.
|
||||
// A container with another managed client is not this client's decoration.
|
||||
// The caller holds the Xlib error guard throughout these read-only queries.
|
||||
static void cthulhu_read_frame_bounds(Display *display, Window window, Foreground *result) {
|
||||
Window root, parent, *children = NULL;
|
||||
unsigned int count = 0;
|
||||
if (!XQueryTree(display, window, &root, &parent, &children, &count)) return;
|
||||
if (children) XFree(children);
|
||||
if (parent == None || parent == root) return;
|
||||
|
||||
XWindowAttributes attributes;
|
||||
if (!XGetWindowAttributes(display, parent, &attributes) ||
|
||||
attributes.class != InputOutput || attributes.override_redirect ||
|
||||
attributes.map_state != IsViewable) return;
|
||||
Atom stateAtom = XInternAtom(display, "WM_STATE", False);
|
||||
Atom type = None; int format = 0; unsigned long items = 0;
|
||||
unsigned char *data = cthulhu_window_property(display, parent, stateAtom, &type, &format, &items);
|
||||
if (data) XFree(data);
|
||||
if (type != None) return;
|
||||
|
||||
Window treeRoot, frameParent;
|
||||
children = NULL;
|
||||
if (!XQueryTree(display, parent, &treeRoot, &frameParent, &children, &count)) return;
|
||||
int unambiguous = count <= 64, foundClient = 0;
|
||||
for (unsigned int index = 0; unambiguous && index < count; index++) {
|
||||
if (children[index] == window) { foundClient = 1; continue; }
|
||||
data = cthulhu_window_property(display, children[index], stateAtom, &type, &format, &items);
|
||||
if (data) XFree(data);
|
||||
if (type != None) unambiguous = 0;
|
||||
}
|
||||
if (children) XFree(children);
|
||||
if (!unambiguous || !foundClient) return;
|
||||
|
||||
int x, y;
|
||||
Window child;
|
||||
if (!XTranslateCoordinates(display, parent, root, 0, 0, &x, &y, &child)) return;
|
||||
int border = attributes.border_width;
|
||||
x -= border; y -= border;
|
||||
int width = attributes.width + 2 * border, height = attributes.height + 2 * border;
|
||||
// Decorations must enclose the client and remain bounded like the EWMH
|
||||
// extents. Never turn an unrelated workspace into a frame match.
|
||||
int left = result->x - x, top = result->y - y;
|
||||
int right = x + width - result->x - result->width;
|
||||
int bottom = y + height - result->y - result->height;
|
||||
if (left < 0 || top < 0 || right < 0 || bottom < 0 ||
|
||||
left >= 1024 || top >= 1024 || right >= 1024 || bottom >= 1024) return;
|
||||
result->frameX = x; result->frameY = y;
|
||||
result->frameWidth = width; result->frameHeight = height;
|
||||
}
|
||||
|
||||
// Read-only metadata connection, owned by the caller's native event thread.
|
||||
// All requests which can race window destruction share the Xlib error guard.
|
||||
Foreground read_foreground(Display *display) {
|
||||
@@ -227,6 +278,7 @@ Foreground read_foreground(Display *display) {
|
||||
}
|
||||
}
|
||||
if (data) XFree(data);
|
||||
cthulhu_read_frame_bounds(display, window, &result);
|
||||
data=cthulhu_window_property(display,window,XInternAtom(display,"_NET_WM_PID",False),&type,&format,&items);
|
||||
if (data && type==XA_CARDINAL && format==32 && items==1) result.pid=(int)((unsigned long *)data)[0];
|
||||
if (data) XFree(data);
|
||||
|
||||
Reference in new issue
Block a user