XCB - 如何设置WM_SIZE_HINTS?

XCB - How to set WM_SIZE_HINTS?

我正在为 xcb 中的 window 创建编写一个简约库。 我希望能够创建一个不可调整大小的 window。我发现,可以通过以下方式向 window 经理提供提示:

xcb_void_cookie_t xcb_change_property (xcb_connection_t *c,       /* Connection to the X server */
                                       uint8_t          mode,     /* Property mode */
                                       xcb_window_t     window,   /* Window */
                                       xcb_atom_t       property, /* Property to change */
                                       xcb_atom_t       type,     /* Type of the property */
                                       uint8_t          format,   /* Format of the property (8, 16, 32) */
                                       uint32_t         data_len, /* Length of the data parameter */
                                       const void      *data);    /* Data */

我尝试使用此函数更改 WM_NORMAL_HINTS 和 WM_SIZE_HINTS,但我如何知道我必须将哪些数据放入 *data 参数中?类型是 XCB_ATOM_INTEGER 还是其他?

解决方法如下:

#include <xcb/xcb.h>
#include <xcb/xcb_icccm.h>

#define WIDTH  900
#define HEIGHT 600

int main(){
    //...
    //Connect to X Server and
    //Create a window
    //...

    xcb_size_hints_t hints;

    xcb_icccm_size_hints_set_min_size(&hints, WIDTH, HEIGHT);
    xcb_icccm_size_hints_set_max_size(&hints, WIDTH, HEIGHT);

    xcb_icccm_set_wm_size_hints(connection, window, XCB_ATOM_WM_NORMAL_HINTS, &hints);
    return 0;
}

如果你想这样做而不依赖于 xcb_icccm 你可以直接改变 属性.

struct WMSizeHints
{
  uint32_t flags;
  int32_t  x, y;
  int32_t  width, height;
  int32_t  min_width, min_height;
  int32_t  max_width, max_height;
  int32_t  width_inc, height_inc;
  int32_t  min_aspect_num, min_aspect_den;
  int32_t  max_aspect_num, max_aspect_den;
  int32_t  base_width, base_height;
  uint32_t win_gravity;
};

enum WMSizeHintsFlag
{
  WM_SIZE_HINT_US_POSITION   = 1U << 0,
  WM_SIZE_HINT_US_SIZE       = 1U << 1,
  WM_SIZE_HINT_P_POSITION    = 1U << 2,
  WM_SIZE_HINT_P_SIZE        = 1U << 3,
  WM_SIZE_HINT_P_MIN_SIZE    = 1U << 4,
  WM_SIZE_HINT_P_MAX_SIZE    = 1U << 5,
  WM_SIZE_HINT_P_RESIZE_INC  = 1U << 6,
  WM_SIZE_HINT_P_ASPECT      = 1U << 7,
  WM_SIZE_HINT_BASE_SIZE     = 1U << 8,
  WM_SIZE_HINT_P_WIN_GRAVITY = 1U << 9
};

struct WMSizeHints hints =
{
  .flags       = WM_SIZE_HINT_P_WIN_GRAVITY,
  .win_gravity = XCB_GRAVITY_STATIC
};

if (centerWindow)
  hints.win_gravity = XCB_GRAVITY_CENTER;
else
{
  hints.flags |= WM_SIZE_HINT_P_SIZE;
  hints.x = x;
  hints.y = y;
}

xcb_change_property(xcb, XCB_PROP_MODE_REPLACE, window,
  XCB_ATOM_WM_NORMAL_HINTS, XCB_ATOM_WM_SIZE_HINTS,
    32, sizeof(struct WMSizeHints) >> 2, &hints);