【问题标题】:Idiomatic way to get the length of a window property in X11?在 X11 中获取窗口属性长度的惯用方法?
【发布时间】:2020-04-21 22:11:53
【问题描述】:

我昨天刚开始学习 X11,我很难找到有关它的信息。

我希望能够检索 X11 窗口的 UTF-8 标题 _NET_WM_NAME。问题是您应该使用长度参数调用它。我目前的解决方案包括首先使用带有 0 长度参数的 XGetWindowProperty 检索字符串的长度,然后使用 bytes_after_return 信息再次调用 XGetWindowProperty length

问题在于这涉及到两次分配和释放。我不是一个超级高级的程序员,但这可能不太好,对吧?虽然在实践中,为获取窗口标题之类的小而罕见的事情进行两次分配可能不会产生太大影响,但我到处听到仍然应该避免不必要的分配和释放。

这是我的代码:

Atom actualType;
int actualFormat;
unsigned long nItems;
unsigned long bytesAfter;
unsigned char* prop;

XGetWindowProperty(
    display, 
    window,
    _NET_WM_NAME,
    0UL,
    0UL,
    False,
    UTF8_STRING,
    &actualType,
    &actualFormat,
    &nItems,
    &bytesAfter,
    &prop
);

XFree(prop);

XGetWindowProperty(
    display, 
    window,
    _NET_WM_NAME,
    0UL,
    (bytesAfter + 3UL) / 4UL, // Divide by four and round up
    False,
    UTF8_STRING,
    &actualType,
    &actualFormat,
    &nItems,
    &bytesAfter,
    &prop
);

printf("title: %s", prop);

XFree(prop);

有没有更好的方法来做到这一点?

另一种解决方案是在每次设置标题时存储标题,但我不确定保存的标题和实际标题是否可能去同步。

谢谢大家

【问题讨论】:

    标签: c utf-8 x11


    【解决方案1】:

    如果无法避免,多次分配并没有什么问题,而且您可能无论如何都需要为大量数据这样做。请求合理数量的字节并根据需要使用循环处理传入数据,利用偏移参数指定继续读取的位置。如果4*length大于要返回的数据量,那么它只会返回必要的数据量,所以你不用担心使用bytesAfter参数计算正确的长度:

    Atom actualType;
    int actualFormat;
    unsigned long nItems;
    unsigned long bytesAfter;
    unsigned char* prop;
    
    // specify length as number of bytes divided by 4
    #define MB (1048576)
    long length = (64 * MB) / 4;
    
    printf("title: ");
    for (long offset = 0;; offset += length) {
    
        XGetWindowProperty(
            display,
            window,
            _NET_WM_NAME,
            offset,
            length,
            False,
            UTF8_STRING,
            &actualType,
            &actualFormat,
            &nItems,
            &bytesAfter,
            &prop
        );
    
        printf("%s", prop);
        XFree(prop);
        if (bytesAfter == 0)
            break;
    }
    

    当然,如果您愿意,您可以请求更多数据,根据需要根据bytesAfter 调整length,这样做确实更有效,因为需要更少的请求/响应周期,更不用说分配了。但是,有时要处理的数据太多,这就是为什么您可能仍需要循环。如果您使用 XConvertSelection 并需要处理 INCR 属性,则尤其如此,因为这意味着显示服务器要发送大量数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-30
      • 1970-01-01
      • 2012-04-06
      • 2013-01-25
      • 2019-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多