【问题标题】:Xlib How Does This (Removing Window Decoration) Work?Xlib 这个(移除窗口装饰)是如何工作的?
【发布时间】:2011-07-05 07:02:03
【问题描述】:

以下代码如何去除窗口边框?

//note the struct is declared elsewhere, is here just for clarity.
//code is from [http://tonyobryan.com/index.php?article=9][1]
typedef struct Hints
{
    unsigned long   flags;
    unsigned long   functions;
    unsigned long   decorations;
    long            inputMode;
    unsigned long   status;
} Hints;

//code to remove decoration
Hints hints;
Atom property;
hints.flags = 2;
hints.decorations = 0;
property = XInternAtom(display, "_MOTIF_WM_HINTS", true);
XChangeProperty(display,window,property,property,32,PropModeReplace,(unsigned char *)&hints,5);
XMapWindow(display, window);

到目前为止,我已经收集到 Atom 是一种类似于 Window 和 Display 的标识符,但我无法弄清楚 Hints 结构或“_MOTIF_WM_HINTS”的来源。谁能为我解释所有这些代码?在此先感谢,呃。

【问题讨论】:

  • 这是您的来源,还是您的目的地? tonyobryan.com/index.php?article=9
  • 这是我的源代码的一个小sn-p。 Hint 结构在别处声明,但为了清楚起见在此显示。而且我读过那篇文章,它没有解释提示结构(“我认为这个结构来自 Motif,但我不确定”......)
  • 是的,它实际上不是我的来源,好点。
  • 您正在运行的窗口管理器负责是否遵守此提示。如果它尊重它,那么如果窗口设置了这个提示,窗口管理器将从窗口中删除窗口装饰。

标签: c++ linux xlib window-managers


【解决方案1】:

很难找到任何“官方”的标准或类似的标准,但是 _MOTIF_WM_HINTS 属性似乎确实来自... Motif 工具包(好吧,你 猜到了:-))。 见the MotifZone site

警告:以下内容不完整,但我希望能有所启发。

XmNmwmDecorations、XmNmwmFunctions 和 XmNmwmInputMode 的文档 工具包的功能表明该属性是各种位掩码 用于控制外观、功能(调整大小、移动...)和输入的值 窗口管理器应该提供/给予窗口的模式。 请参阅man vendorshellOreilly Motif reference books, Vol6a chapter 16

属性是整个 X11 事物的一部分。一个窗口可以有任意数量的 在其上定义的属性。属性有名称,但设置/获取 属性是通过“原子”(各种标识符)完成的,以避免发送 每个 get/set 调用的整个字符串。 见Properties and Atoms

当前窗口管理器(如果有)可以对窗口属性做出反应 通过设置适当的事件过滤器并作用于 PropertyNotify 进行更改 事件,或者只是检查窗口在映射(或移动,或其他)时具有的属性。如果窗口管理器知道 _MOTIF_WM_HINT 属性,它将 解释这些并(希望)做你想做的事。 (注意:我不确定该特权是否已移交给窗口 管理器,或者其他窗口是否可以监听那些“PropertyNotify”事件。不是 确保这实际上与您的问题有关。)

因此,只要您的窗口管理器知道,您的代码就可以正常工作 关于 _MOTIF_WM_HINTS 属性。

你从获取原子开始 (标识符/快捷方式)为它使用 XInternAtom,并通过 XChangeProperty() 设置它的值 在通过 MapWindow() 实际绘制窗口之前(不确定是否会 如果您在 MapWindow() 之后执行此操作,则可以工作,这可能取决于您的窗口 经理)。

[编辑:将 .decorations 部分设置为零会清除所有装饰位,因此这要求窗口管理器基本上不要管你的边界。]

我无法在某个“官方”的地方找到该结构的定义。它在 openmotif-2.3.3 发行版的 lib/X11/MwmUtils.h 中定义。不确定如何使用 .flags 条目(找不到我一生的代码:-/),但我怀疑它用于指示 {decoration, function, inputMode} “子属性”中的哪一个你是作用于。 (不要相信我的话。)

附带说明,使用 _MOTIF_WM_HINTS 可能不是您的最佳选择。 现在。您是否查看过 freedesktop 上的Extended Window Manager hints specification 和其他信息/标准/草案?我敢打赌,大多数“现代”窗口管理器/桌面环境/厨房水槽都会倾向于坚持这一点,而不是保持与 Motif 的向后兼容性。我猜这一切都取决于您要编码的内容。

感谢阅读:-)

【讨论】:

  • 感谢所有这些提示,我会查看您提供给我的所有链接!
  • 我尝试使用提到的 _NET_WM_WINDOW_TYPE 属性。至少在 GNOME/GDM3 上,这些不仅没有提供与 Motif 提示相同的功能,而且实际上还有不好的副作用,比如需要在工作之前取消映射和重新映射窗口。
【解决方案2】:

查看_MOTIF_WM_HINTS 属性。我将您的代码更改为工作状态:

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define MAPIT
#undef REPEAT

void waitxevt(Display* d, int type)

{

    XEvent e; /* XEvent holder */

    do { XNextEvent(d, &e); } while (e.type != type);

}

void frame(Display* d, Window w, int e)

{

    Atom window_type;
    Atom motif_hints;
    long value;

#ifdef MAPIT
    XUnmapWindow(d, w);
    waitxevt(d, UnmapNotify);
#endif
    window_type = XInternAtom(d, "_NET_WM_WINDOW_TYPE", False);
    if (e) value = XInternAtom(d, "_NET_WM_WINDOW_TYPE_NORMAL", False);
    else value = XInternAtom(d, "_NET_WM_WINDOW_TYPE_DOCK", False);
    XChangeProperty(d, w, window_type, XA_ATOM, 32, PropModeReplace, (unsigned char *) &value, 1);
    
    long hints[5] = {e ? 0 : 2, 0, 0, 0, 0};
    motif_hints = XInternAtom(d, "_MOTIF_WM_HINTS", False);

    XChangeProperty(d, w, motif_hints, motif_hints, 32, PropModeReplace, (unsigned char *)&hints, 5);
    
#ifdef MAPIT
    XMapWindow(d, w);
    waitxevt(d, MapNotify);
#endif

}

int main(void) {

    Display*     d;
    Window       w;
    XEvent       e;
    const char*  msg = "Hello, World!";
    int          s;
    GC           gracxt;
    int          frmenb = 0;
 
    d = XOpenDisplay(NULL);
    if (d == NULL) {

        fprintf(stderr, "Cannot open display\n");
        exit(1);

    }
 
    s = DefaultScreen(d);
    gracxt = XDefaultGC(d, s);

    w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 640, 480, 5,
                            BlackPixel(d, s), WhitePixel(d, s));
    XSelectInput(d, w, ExposureMask|KeyPressMask|StructureNotifyMask);
    XMapWindow(d, w);
    waitxevt(d, MapNotify);

    while (1) {

        XNextEvent(d, &e);
        if (e.type == Expose) XDrawString(d, w, gracxt, 10, 50, msg, strlen(msg));
        if (e.type == KeyPress) {

            frame(d, w, frmenb);
            frmenb = frmenb == 0 ? 1 : 0;
#ifdef REPEAT
            frame(d, w, frmenb);
            frmenb = !frmenb;
#endif

        }

    }

    XCloseDisplay(d);

    return 0;

}

唯一改变的是包含提示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-25
    • 2020-09-22
    • 1970-01-01
    • 2020-10-15
    • 2016-01-06
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    相关资源
    最近更新 更多