So for grins, I found the list of windows to the root:
/* find frame window */
cw = win->xwhan; /* index current window */
do {
/* find tree parameters */
XQueryTree(padisplay, cw, &rw, &pw, &cwl, &ncw);
cw = pw;
XGetWindowAttributes(padisplay, cw, &xwa);
dbg_printf(dlinfo, "Window: %d,%d\n", xwa.width, xwa.height);
} while (cw != rw);
/* get actual size of onscreen window, and set that as client space */
XWLOCK();
XGetWindowAttributes(padisplay, win->xwhan, &xwa);
XWUNLOCK();
*x = xwa.width;
*y = xwa.height;
dbg_printf(dlinfo, "Current window: %d,%d\n", xwa.width, xwa.height);
Resulting in:
samiam@samiam-h-pc-2:~/projects/petit_ami$ ./testg
linux/graphics.c:pa_getsizg():8612: Window: 1480,1010
linux/graphics.c:pa_getsizg():8612: Window: 5120,5760
linux/graphics.c:pa_getsizg():8622: Current window: 1440,900
So basically the frame is one window up, and then the root window is the whole screen. This was done on a single (not nested) window.
Note that the windows are nested (contain each other) by definition, so there is nothing that particularly marks the frame except perhaps that it is the closest order frame to the current window.
Lets see if I can spin the logic of this:
Older windows managers don't have the _NET_FRAME_EXTENTS property.
The "walk the frame" algorithm also works on newer windows managers.
Thus looking at the parent will yield the right answer in the majority of cases, but there is no way to be sure.
I am trying this on Ubuntu 20.04, so I presume this qualifies as a "modern window manager".
Why do I use the window size including the frame vs. the client area? Because that is the most universal size. I don't just handle the program window, but also any child windows (widgets, subwindows, etc) and so the parent dimensions are a good way to track child windows as components. I determine the client areas via a function given the parent window parameters and characteristics of the child window (frame enabled, etc).
Scott Franco
San Jose, CA