Reputation: 1049
I ma currently looking retrieve the window present at a certain position. I've already retrieved the list of windows but I'm not sure how to proceed to retrieve the topmost one.
Here is what I have accomplished so far (contains a testing main):
#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
typedef struct
{
int x;
int y;
int w;
int h;
} area_coords_t;
static inline Window get_toplevel_parent(Display * display, Window window)
{
Window parent;
Window root;
Window * children;
unsigned int num_children;
while (1) {
if (0 == XQueryTree(display, window, &root, &parent, &children, &num_children)) {
fprintf(stderr, "XQueryTree error\n");
abort(); //change to whatever error handling you prefer
}
if (children) { //must test for null
XFree(children);
}
if (window == root || parent == root) {
return window;
}
else {
window = parent;
}
}
}
static inline void print_windows(Display *display, area_coords_t *area)
{
Window *list;
Window toplevel;
Atom prop = XInternAtom(display, "_NET_CLIENT_LIST",False);
Atom type;
unsigned long len;
XWindowAttributes attr;
if (XGetWindowProperty(display, XDefaultRootWindow(display), prop,
0, 1024, False, XA_WINDOW, &type, &(int) { 0 }, &len, &(unsigned long) { 0 }, (unsigned char **) &list) != Success)
return;
for (unsigned long it = 0; it < len; ++it)
{
toplevel = get_toplevel_parent(display, list[it]);
XGetWindowAttributes(display, toplevel, &attr);
/* Retrieve only windows in the given area */
//if (area->x >= attr.x && area->x <= attr.x + attr.width && area->y >= attr.y && area->y <= attr.y + attr.height)
printf("%dx%dx%dx%d\n", attr.x, attr.y, attr.width, attr.height);
}
}
int main(void)
{
Display *display = XOpenDisplay(NULL);
/* Should retrieve a window occupying at least a pixel at of the bottom right part of the screen of a 1920x1080 screen */
area_coords_t coords = { 1920 / 2, 1080 / 2, 1920 / 2, 1080 / 2 };
print_windows(display, &coords);
return 0;
}
The problem with that is the windows do not seem to be ordered.
How can I retrieve the topmost window to ensure I get the appropriate window for a given position ?
Upvotes: 2
Views: 703
Reputation: 1
XQueryTree()
returns the windows in stacking order, topmost last.
Description
The
XQueryTree()
function returns the root ID, the parent window ID, a pointer to the list of children windows (NULL
when there are no children), and the number of children in the list for the specified window. The children are listed in current stacking order, from bottommost (first) to topmost (last).XQueryTree()
returns zero if it fails and nonzero if it succeeds. To free a non-NULL
children list when it is no longer needed, useXFree()
.
I've never used the call for this purpose, and haven't done direct X11 programming in years, but from that I'd imagine you could just loop through the returned list from querying the root window and save the window ID of any window covering your desired location to the same variable every time. Since the last one found covering that location is the topmost (at least it was when you made the call...), that would be the window ID of the visible window at that location.
Upvotes: 2