3

I'm writing a minimalistic library for window creation in xcb. I want to be able to create a non-resizeable window. I found out, that it is possible to give hints to the window manager with:

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 */

I tried to change the WM_NORMAL_HINTS and WM_SIZE_HINTS with this function, but how do I know what data I have to put in the *data parameter? Is the type XCB_ATOM_INTEGER or something else?

bakkaa
  • 673
  • 6
  • 25
  • Have you looked for documentation about what the `WM_SIZE_HINTS` are/contain? – Etan Reisner Jan 04 '15 at 20:03
  • I don't find anything helpful. I tried for hours. – bakkaa Jan 04 '15 at 20:23
  • 1
    http://cgit.freedesktop.org/xcb/util-wm/tree/icccm/icccm.c#n725 and http://cgit.freedesktop.org/xcb/util-wm/tree/icccm/xcb_icccm.h#n763 etc. Also the *very* first link in a search for `WM_SIZE_HINTS` http://tronche.com/gui/x/xlib/ICC/client-to-window-manager/wm-normal-hints.html – Etan Reisner Jan 04 '15 at 21:34
  • It works now. Thank you very much. How did you find this? – bakkaa Jan 04 '15 at 22:05
  • 1
    The tronche.com link I've used in the past and I almost stopped there but figured there had to be xcb specific docs on this too. So I searched for `WM_SIZE_HINTS` and xcb. When that didn't turn up anything overly helpful I went looking for the xcb docs (which are a broken link) and then just said "screw it" and went to the source directly. – Etan Reisner Jan 05 '15 at 01:07

2 Answers2

10

Here is the solution:

#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;
}
bakkaa
  • 673
  • 6
  • 25
9

If you want to do this without depending on xcb_icccm you can directly change the property.

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);
Geoffrey
  • 10,843
  • 3
  • 33
  • 46