Вы правы - вы видите дочернее окно. В частности, GTK-приложения создают дочернее окно под «реальным» окном, которое всегда имеет размер 1x1, и оно всегда получает фокус, когда приложение имеет фокус. Если вы просто запускаете свою программу с помощью терминала GNOME, вы всегда будете видеть приложение GTK с фокусом (терминал).
Если вы запустите свою программу таким образом, что у программы, не являющейся GTK, есть фокус, то этого не произойдет, но вы все равно можете найти дочернее окно с фокусом вместо верхнего уровня окно. (Один из способов сделать это - запустить sleep
перед вашей программой следующим образом: sleep 4; ./my_program
- это дает вам возможность изменить фокус.)
Чтобы найти окно верхнего уровня, я думаю, XQueryTree
поможет - оно возвращает родительское окно.
Это сработало для меня:
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
/*
Returns the parent window of "window" (i.e. the ancestor of window
that is a direct child of the root, or window itself if it is a direct child).
If window is the root window, returns window.
*/
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;
}
}
}
int main(int argc, char *argv[])
{
Display *display;
Window focus, toplevel_parent_of_focus;
XWindowAttributes attr;
int revert;
display = XOpenDisplay(NULL);
XGetInputFocus(display, &focus, &revert);
toplevel_parent_of_focus = get_toplevel_parent(display, focus);
XGetWindowAttributes(display, toplevel_parent_of_focus, &attr);
printf("[0x%x] %d x %d\n", (unsigned)toplevel_parent_of_focus,
attr.width, attr.height);
return 0;
}