Xlib: XGetWindowAttributes always returns 1x1?

随声附和 提交于 2019-12-10 17:11:39

问题


I'd like to have width and height of the currently focussed window. The selection of the window works like a charm whereas the height and width are always returning 1.

#include <X11/Xlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    Display *display;
    Window focus;
    XWindowAttributes attr;
    int revert;

    display = XOpenDisplay(NULL);
    XGetInputFocus(display, &focus, &revert);
    XGetWindowAttributes(display, focus, &attr);
    printf("[0x%x] %d x %d\n", (unsigned)focus, attr.width, attr.height);

    return 0;
}

Is this not the "real" window but the currently active component (like a textbox or a button?) And why would it have the size of 1x1 anyways then? If this is the case, how do i get the main window of the application containig this control? Means... kinda the top-level window, the top-most window except the root window.

PS: Don't know whether it's really important; I use Ubuntu 10.04 32 and 64 bit.


回答1:


You're right - you're seeing a child window. GTK applications, in particular, create a child window under the "real" window, which is always 1x1, and that always gets the focus when the application has the focus. If you're just running your program using the GNOME terminal, you'll always be seeing a GTK application with the focus (the terminal).

If you run your program in such a way that a non-GTK program happens to have the focus, then this doesn't happen, but you could still end up finding a child window with the focus instead of the top-level window. (One way of doing this is to run sleep before your program like this: sleep 4; ./my_program - this gives you a chance to change the focus.)

To find the top-level window, I think XQueryTree will help - it returns the parent window.

This worked for me:

#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;
}


来源:https://stackoverflow.com/questions/3909713/xlib-xgetwindowattributes-always-returns-1x1

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!