【问题标题】:Xlib XGetWindowProperty Zero items returnedXlib XGetWindowProperty 返回零项
【发布时间】:2015-07-02 14:48:28
【问题描述】:

我在阅读某些 XWindow ICCCM 属性时遇到问题。

问题实际上是当我尝试读取 _NET_WM_STATUS 属性时。 我正在使用的功能是:

int get_property_value(Display* display, Window window,char *propname, long max_length,
           unsigned long *nitems_return, unsigned char **prop_return){
    int result;
    Atom property;
    Atom actual_type_return;
    int actual_format_return;
    unsigned long bytes_after_return;
    unsigned char* prop_to_return;
    unsigned long n_items;
    printf("-----GET_PROPERTY_VALUE-------\n");
    printf("\tPropname: %s\n", propname);
    property = XInternAtom(display, propname, True);
    if(property==None){
      printf("\tWrong Atom\n");
      return;
    }

    result = XGetWindowProperty(display, window, property, 0,   /* long_offset */
            (~0L),  /* long_length */
            False,  /* delete */
            AnyPropertyType,    /* req_type */
            &actual_type_return,
            &actual_format_return,
            &n_items, &bytes_after_return, &prop_to_return);
    if (result != Success){
        printf("\tXGetWindowProperty failed\n");
        return (-1);
    }   else {
        printf("\tActual Type: %s\n", XGetAtomName(display,property));
        printf("\tProperty format: %d\n", actual_format_return);
        //printf("Actual property return: %s\n", XGetAtomName(display,actual_type_return));
        printf("\tByte after return: %ld\n", bytes_after_return);
        printf("\tnitems return: %d\n", n_items);
        printf("\tprop return: %s\n", prop_to_return);
    }
    printf("-----END OF GET_PROPERTY_VALUE-------\n");

    return (0);
}

get_property_value 函数在收到 ClientMessage 后调用,这是处理事件的一段代码:

    case ClientMessage:
        printf("ClientMessage\n");
        printf("Message: %s\n", XGetAtomName(display,local_event.xclient.message_type));
        unsigned long nitems_return;
        unsigned char *prop_return;
        get_property_value(display, local_event.xclient.window, XGetAtomName(display,local_event.xclient.message_type), 256, &nitems_return, (unsigned char **)&prop_return);
    break;

但是当我读取属性时,有时我会得到一个没有值的属性,这可能吗? 问题主要是当我尝试在 ClientMessage 事件中读取从 firefox 发送的 AtomProperties(我正在尝试读取 _NET_WM_STATE 值)时。

从输出中可以看出,属性名称已正确读取,但似乎它不包含任何项目。

ClientMessage
Message: _NET_WM_STATE
-----GET_PROPERTY_VALUE-------
    Propname: _NET_WM_STATE
    Actual Type: _NET_WM_STATE
    Property format: 0
    Byte after return: 0
    nitems return: 0
    prop return: (null)
-----END OF GET_PROPERTY_VALUE-------

【问题讨论】:

  • 有什么想法吗?我真的被这个问题困住了,我找不到任何有用的文档,这似乎只发生在 firefox 上。
  • 我认为你不会轻易克服这一点。 Firefox 不像普通应用程序那样使用窗口系统。您可能应该拆分问题,因为“取消隐藏 firefox 菜单”是与原始问题不同的问题(通过 IMO 方式,您将获得更多可见性)。
  • 谢谢丹尼尔!我会听从您的建议,并为 firefox 相关问题创建一个单独的问题。

标签: c x11 xlib


【解决方案1】:

我还没有足够的代表发表评论(我对此有点陌生),但我自己花了一些时间与 Xlib 搏斗,我会尝试看看我是否能提供帮助。我写了一个包含你的代码的小程序:

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

int get_property_value(Display* display, Window window,char *propname, long max_length,
           unsigned long *nitems_return, unsigned char **prop_return){
    int result;
    Atom property;
    Atom actual_type_return;
    int actual_format_return;
    unsigned long bytes_after_return;
    unsigned char* prop_to_return;
    unsigned long n_items;
    printf("-----GET_PROPERTY_VALUE-------\n");
    printf("\tPropname: %s\n", propname);
    property = XInternAtom(display, propname, True);
    if(property==None){
      printf("\tWrong Atom\n");
      return;
    }

    result = XGetWindowProperty(display, window, property, 0,   /* long_offset */
            (~0L),  /* long_length */
            False,  /* delete */
            AnyPropertyType,    /* req_type */
            &actual_type_return,
            &actual_format_return,
            &n_items, &bytes_after_return, &prop_to_return);
    if (result != Success){
        printf("\tXGetWindowProperty failed\n");
        return (-1);
    }   else {
        printf("\tActual Type: %s\n", XGetAtomName(display,actual_type_return));
        printf("\tProperty format: %d\n", actual_format_return);
        //printf("Actual property return: %s\n", XGetAtomName(display,actual_type_return));
        printf("\tByte after return: %ld\n", bytes_after_return);
        printf("\tnitems return: %d\n", n_items);
        printf("\tprop return: %s %s\n", XGetAtomName(display,*(Atom*)prop_to_return), XGetAtomName(display,((Atom*)prop_to_return)[1]));
    }
    printf("-----END OF GET_PROPERTY_VALUE-------\n");

    return (0);
}

int main(int argc, char** argv) {
    Display* dsp = XOpenDisplay(NULL);
    unsigned long nitems_return;
    unsigned char* prop_return;
    get_property_value(dsp, (Window)atoi(argv[1]), "_NET_WM_STATE", 100000, &nitems_return, &prop_return);
    return 0;
}

我确实更改了一些输出内容:我更改了“实际类型”输出以打印 actual_type_return 而不是 property 的名称(因为这看起来像是一个错字)并且我更改了“prop return”输出打印原子名称而不是二进制数据。无论如何,我将这个版本的代码指向我计算机上运行的 Firefox 实例,这就是我得到的:

$ ./xproptest 60817587
-----GET_PROPERTY_VALUE-------
    Propname: _NET_WM_STATE
    Actual Type: ATOM
    Property format: 32
    Byte after return: 0
    nitems return: 2
    prop return: _NET_WM_STATE_MAXIMIZED_VERT _NET_WM_STATE_MAXIMIZED_HORZ
-----END OF GET_PROPERTY_VALUE-------

所以,好消息是您的代码实际上可以在我的机器上完美运行。不过,我不确定为什么它对你的不起作用。当然,上面的输出是 Firefox 最大化时的输出;如果不是,则输出是这样的:

$ ./xproptest 60817587
-----GET_PROPERTY_VALUE-------
    Propname: _NET_WM_STATE
    Actual Type: ATOM
    Property format: 32
    Byte after return: 0
    nitems return: 0
    prop return:

...然后是关于我如何读取无效原子的几个错误,因为上面的代码只是假设有两个。当属性为空且没有值时,这是正确的输出;但是,请注意我的属性格式是 32,而您的属性格式是 0。通过阅读手册,似乎从成功调用 XGetWindowProperty 中获得 0 属性格式的唯一方法是在不具有的属性上调用它不存在。不过,我不确定为什么您的 Firefox 没有设置 _NET_WM_STATE

总之,我的猜测是您的代码实际上运行良好(除了其中一个输出的错字),但由于某种原因,您尝试读取的属性在您所在的窗口上不存在试图从中读取它。如果我是对的,如果您在阅读该属性后检查actual_type_return 的值,您应该会发现它是None。此外,您应该能够(如果您还没有)在代码(window)中打印您尝试读取的窗口 ID,并使用 xwininfoxprop-id 标志为了检查您正在读取的窗口是否是您认为的窗口,以及它是否实际上具有您要读取的属性。希望这将帮助您弄清楚实际问题是什么。

【讨论】:

  • 我非常感谢您的帮助,即使它不能回答我所有的问题,至少是起点。我会给你一个+1的答案。无论如何,我还不清楚为什么菜单没有出现。当我点击它时。但我可以检查的是我是否从错误的窗口读取属性。我会检查并通知您。
  • Hdast 无论如何我不明白的是,我在 ClientMessage 事件之后尝试读取此属性,以及为什么我正在读取空属性,我更新了问题中的代码,指出 get_property_value 的位置被调用。
  • 既然我把这个问题的第二部分移到了另一个,我会接受你的回答!感谢你的付出!如果您有任何想法,关于如何帮助我,这是新问题:stackoverflow.com/questions/31535560/xlib-and-firefox-behavior
猜你喜欢
  • 2014-10-10
  • 2021-09-23
  • 2016-11-24
  • 2021-10-24
  • 2017-11-19
  • 2015-01-23
  • 2016-11-24
  • 2013-12-04
  • 2010-12-31
相关资源
最近更新 更多