Xlib:XGetWindowAttributes 始终返回 1x1?

发布于 2024-09-27 00:12:18 字数 664 浏览 10 评论 0原文

我想要当前聚焦窗口的宽度和高度。窗口的选择就像一个魅力,而高度和宽度总是返回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;
}

这不是“真正的”窗口,而是当前活动的组件(如文本框或按钮?)以及为什么那么它的大小是否仍然是 1x1 呢?如果是这种情况,我如何获得包含此控件的应用程序的主窗口?意思是...有点顶级窗口,除了根窗口之外的最顶层窗口。

PS:不知道是否真的重要;我使用 Ubuntu 10.04 32 位和 64 位。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

戏蝶舞 2024-10-04 00:12:18

你是对的 - 你看到的是一个子窗口。特别是 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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文