Interacting with the window manager
After we have seen how to create windows and draw on them, we take one step back, and look at how our windows are interacting with their environment (the full screen and the other windows). First of all, our application needs to interact with the window manager. The window manager is responsible to decorating drawn windows (i.e. adding a frame, an iconify button, a system menu, a title bar, etc), as well as handling icons shown when windows are being iconified. It also handles ordering of windows on the screen, and other administrative tasks. We need to give it various hints as to how we want it to treat our application's windows.
Window properties
Many of the parameters communicated to the window manager are passed using data called "properties". These properties are attached by the X server to different windows, and are stored in a format that makes it possible to read them from different machines that may use different architectures (remember that an X client program may run on a remote machine).
The property and its type (a string, an integer, etc) are Id. Their type are
xcb_atom_t
:typedef uint32_t xcb_atom_t;
typedef uint32_t xcb_atom_t;
To change the property of a window, we use the following function:
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 */
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 */
The
mode
parameter coud be one of the following values (defined in enumeration xcb_prop_mode_t in the xproto.h header file):- XCB_PROP_MODE_REPLACE
- XCB_PROP_MODE_PREPEND
- XCB_PROP_MODE_APPEND
Setting the window name and icon name
The first thing we want to do would be to set the name for our window. This is done using the
xcb_change_property()
function. This name may be used by the window manager as the title of the window (in the title bar), in a task list, etc. The property atom to use to set the name of a window isWM_NAME
(andWM_ICON_NAME
for the iconified window) and its type isSTRING
. Here is an example of utilization:#include <string.h> #include <xcb/xcb.h> #include <xcb/xcb_atom.h> int main () { xcb_connection_t *c; xcb_screen_t *screen; xcb_window_t win; char *title = "Hello World !"; char *title_icon = "Hello World ! (iconified)"; /* Open the connection to the X server */ c = xcb_connect (NULL, NULL); /* Get the first screen */ screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data; /* Ask for our window's Id */ win = xcb_generate_id (c); /* Create the window */ xcb_create_window (c, /* Connection */ 0, /* depth */ win, /* window Id */ screen->root, /* parent window */ 0, 0, /* x, y */ 250, 150, /* width, height */ 10, /* border_width */ XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */ screen->root_visual, /* visual */ 0, NULL); /* masks, not used */ /* Set the title of the window */ xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, WM_NAME, STRING, 8, strlen (title), title); /* Set the title of the window icon */ xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, WM_ICON_NAME, STRING, 8, strlen(title_icon), title_icon); /* Map the window on the screen */ xcb_map_window (c, win); xcb_flush (c); while (1) {} return 0; }
#include <string.h> #include <xcb/xcb.h> #include <xcb/xcb_atom.h> int main () { xcb_connection_t *c; xcb_screen_t *screen; xcb_window_t win; char *title = "Hello World !"; char *title_icon = "Hello World ! (iconified)"; /* Open the connection to the X server */ c = xcb_connect (NULL, NULL); /* Get the first screen */ screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data; /* Ask for our window's Id */ win = xcb_generate_id (c); /* Create the window */ xcb_create_window (c, /* Connection */ 0, /* depth */ win, /* window Id */ screen->root, /* parent window */ 0, 0, /* x, y */ 250, 150, /* width, height */ 10, /* border_width */ XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */ screen->root_visual, /* visual */ 0, NULL); /* masks, not used */ /* Set the title of the window */ xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, WM_NAME, STRING, 8, strlen (title), title); /* Set the title of the window icon */ xcb_change_property (c, XCB_PROP_MODE_REPLACE, win, WM_ICON_NAME, STRING, 8, strlen(title_icon), title_icon); /* Map the window on the screen */ xcb_map_window (c, win); xcb_flush (c); while (1) {} return 0; }
Note: the use of the atoms needs our program to be compiled and linked against xcb_atom, so that we have to use
gcc prog.c -o prog `pkg-config --cflags --libs xcb_atom`
for the program to compile fine.