XLib - 当我在main函数中构造XWindowAttributes时,窗口提示的行为有所不同?

时间:2014-10-27 03:07:43

标签: c++ x11 xlib

我正在尝试一些基本的Xlib内容。我正在创建一个基本窗口并为它创建一个OpenGL上下文。

我试图阻止用户调整大小或手动全屏显示窗口。我添加了代码:

XSizeHints hints;
hints.min_width = hints.max_width = setup.w;
hints.min_height = hints.max_height = setup.h;
XSetWMNormalHints(dpy, win, &hints);

这首先起作用。然而,经过实验,我发现它有时神秘地停止工作。这不是一个不常见的窗口管理器或类似的事情,我使用安装Ubuntu的默认Windows管理器。导致它变化的原因是,我是否在main中包含这一行:

XWindowAttributes atts;

我把它放在哪里都没关系。在开始时,或在循环内,甚至在返回之后。只要我把它放在main的某个地方,提示就会阻止调整大小(只是要清楚,变量的任何名称都可以工作)。如果我完全使用它并不重要,它最初是为了调用XGetWindowAttributes。当我尝试将其移动到单独的函数调用中时,我发现了这个问题。如果我拿出来,窗口将有一个全屏按钮,我将能够缩小它。我已尝试声明变量其他位置,例如在包含Window和GLXContext的结构中。

这里发生了什么?我看到它的方式,我要么有一个非常微妙和不寻常的错误来自我的虚拟机或类似的奇怪的东西,或者我错过了一些明显的信息。任何人都可以对此有所了解吗?

2 个答案:

答案 0 :(得分:1)

好吧,我没有解释为什么在main中声明一个XWindowAttributes实例使其工作,但我确实弄清楚我的代码有什么问题,并且当我做出以下更改时我能够按预期运行:

  1. 不要直接创建XSizeHints,如上所示。按如下方式创建:

    XSizeHints *hints = XAllocSizeHints();
    
  2. 在对象中设置标志,指​​定使用哪些变量:

    hints->flags = PMinSize|PMaxSize;
    
  3. 使用XSetWMNormalHints和XSetWMSizeHints:

    XSetWMNormalHints(dpy, win, hints);
    XSetWMSizeHints(dpy, win, hints, PMinSize|PMaxSize);
    
  4. 我还在我的struct中添加了一个指针,其中包含有关窗口的数据。上面的代码一起变成了:

    XSizeHints *hints = wind->hints = XAllocSizeHints();
    hints->flags = PMinSize|PMaxSize;
    hints->min_width = hints->max_width = setup.w;
    hints->min_height = hints->max_height = setup.h;
    XSetWMNormalHints(dpy, win, hints);
    XSetWMSizeHints(dpy, win, hints, PMinSize|PMaxSize);
    

答案 1 :(得分:0)

对于那些来这里的人:

1。与Windows管理器通信

所有关于约定的内容,如《 Xlib编程手册VOL1》中12.3所述。一些WM会完全忽略诸如最大和最小大小之类的提示,因为例如它们将Windows作为平铺Windows管理。因此,您的Window Manager如何获得选择是一个问题。

2。按正确的顺序进行操作。

这也许会回答您的问题: “这是怎么回事?”

X的大多数困难都来自于您的制造顺序。我遇到了和您一样的麻烦,并解决了这个问题,因为我发现自己没有遵循正确的流程。 《 Xlib Prog手册》的第12.3.1章说: “一旦客户创建了窗口,但未将其制成地图,它必须放置属性以帮助WM有效地对其进行管理”

对于您而言,这意味着在映射窗口之后,您将无法使用XSetWM *功能。一些属性会产生影响,而其他一些则不会,有时某些属性会被错误的值覆盖。

3。正确的顺序。 (AFAIK)

a。设置错误处理程序

b。取得展示

c。初始化您的上下文(此处为GLX)并从中获取视觉效果。

d。设置窗口属性(事件蒙版,...)

e。创建您的窗口

e。设置WM属性(例如,您的sizehints,最小/最大大小,类,标题等)

在可能的情况下,e.1始终使用XAlloc *初始化指针

e.2使用X11r4 XSetWMProperties ,可以将它们全部一次放置,避免使用不推荐使用的功能。

e.3 X释放您的“指针”

f。设置您感兴趣的Wm协议(WM_DELETE_WINDOW,...)

g根据您的需要设置其他一些属性(例如_NET_WM_PID等)

h。最后,映射您的窗口

4。看看会发生什么:使用xprop

xprop将报告Windows管理器如何识别您的窗口。 如果正确设置了尺寸提示,您将看到一些像这样的行:

WM_NORMAL_HINTS(WM_SIZE_HINTS):
                user specified location: 550, 200
                user specified size: 500 by 500
                program specified minimum size: 500 by 500
                program specified maximum size: 65535 by 65535

希望它对未来的用户有帮助,

(PS:TS @ Oct 27 '14在15:26的先前答案有一个错误:XSetWMSizeHints期望Atom为第三个参数。)