I'm trying to create a simple application that interacts with the xcb library functions. My objective is to emulate the behavior of a simple window manager. From what I understood, I need to setup Substructure Redirection on the root window, then listen to specific events on that window in order to organize its top level windows the way I want. The problem is, I just cannot figure out how to test the solution I came up with.
This is the code responsible for doing what I explained:
#include <stdlib.h>
#include <stdio.h>
#include <xcb/xcb.h>
#include <xcb/xproto.h>
int main() {
xcb_connection_t *connection = xcb_connect(NULL, NULL);
xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;
/* Subscribing to the desired events */
uint32_t mask = XCB_CW_EVENT_MASK |
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
uint32_t values[3] = { XCB_KEY_PRESS, 1, 1 };
/* This applies the values and mask to the root window I think */
xcb_change_window_attributes(connection, screen->root, mask, values);
xcb_flush(connection);
xcb_generic_event_t *ev;
while( (ev = xcb_wait_for_event(connection)) ) {
switch(ev->response_type & ~0x80) {
case XCB_KEY_PRESS: {
xcb_key_press_event_t *ev = (xcb_key_press_event_t *)ev;
if(ev->state & XCB_MOD_MASK_1) {
printf("Pressed the Alt key modifier\n");
}
printf("Key pressed: Keycode %d\n", ev->detail);
break;
}
case XCB_CREATE_NOTIFY: {
printf("CREATE NOTIFY\n");
break;
}
case XCB_MAP_NOTIFY: {
printf("MAP NOTIFY\n");
break;
}
}
free(ev);
}
xcb_disconnect(connection);
}
As you can see, the code is pretty simple, and I plan to expand it if I can find a solution to the problem at hand.
I'm using Xephyr to run the program. I just ran Xephyr -br -ac -noreset -screen 500x500 :1 to create a new window, and then DISPLAY=:1 ./myprogram to test it. Obviously nothing happens in the screen, but I wonder how can I get the outputs of the printf calls.
EDIT:
The XCB_CREATE_NOTIFY and XCB_MAP_NOTIFY events are there because I'm expecting that when I init a new application inside this window, the X server would send that request to the window manager, which has the substructure redirection toggled. That way I could correctly alter the desired properties of the window. Please correct me if I'm wrong.
Call
xcb_flush()before youwhile-loop.By default, sent requests end up in the output buffer. You need to explicitly call
xcb_flush()to have the requests actually sent.There is no output since no
printfcalls run yet, because yourChangeWindowAttributesrequest was not yet actually sent.Actually, when doing that and running your program under x11trace shows:
Your request fails. And does not send what you expect it to send.
You want:
This still produces no output. I see events of type
ConfigureRequestandMapRequestbeing generated, but none of these events are being printed.I added the following to the
switchto actually get some output:(Also, your
printfcalls are missing a trailing\n.)