Skip to content

Instantly share code, notes, and snippets.

@mochaaP
Created September 14, 2022 07:13
Show Gist options
  • Save mochaaP/c96481ef25d56da1d1d51a62f93ef049 to your computer and use it in GitHub Desktop.
Save mochaaP/c96481ef25d56da1d1d51a62f93ef049 to your computer and use it in GitHub Desktop.
x11 invisible window (for my i3 persistent workspace dirty workaround)
#include <xcb/xcb.h>
#include <xcb/xcb_ewmh.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <cstdlib>
#define PROGRAM "xcb-invis"
int main(int argc, char *argv[]) {
if (argv[1] == nullptr) {
fprintf(stderr, "usage: %s <WM_NAME>", PROGRAM);
return 2;
}
xcb_connection_t *connection = xcb_connect(NULL, NULL);
const xcb_setup_t *setup = xcb_get_setup(connection);
xcb_screen_t *screen = xcb_setup_roots_iterator(setup).data;
xcb_ewmh_connection_t ewmh;
xcb_intern_atom_cookie_t *ewmh_cookie = xcb_ewmh_init_atoms(connection, &ewmh);
xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(screen);
xcb_depth_t *depth = NULL;
for (; depth_iter.rem; xcb_depth_next(&depth_iter)) {
/* printf("%i\n", depth_iter.data->depth); */
if (depth_iter.data->depth == 32 && depth_iter.data->visuals_len) {
depth = depth_iter.data;
break;
}
}
xcb_visualtype_iterator_t visual_iter = xcb_depth_visuals_iterator(depth);
xcb_visualtype_t *visual = NULL;
for (; visual_iter.rem; xcb_visualtype_next(&visual_iter)) {
if (visual_iter.data->_class == XCB_VISUAL_CLASS_TRUE_COLOR) {
visual = visual_iter.data;
break;
}
}
xcb_colormap_t colormapId = xcb_generate_id (connection);
xcb_create_colormap (connection,
XCB_COLORMAP_ALLOC_NONE,
colormapId,
screen->root,
visual->visual_id );
unsigned int cw_mask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP;
unsigned int cw_values[] = { 0x00000000, 0, colormapId };
xcb_window_t window = xcb_generate_id(connection);
auto cookie = xcb_create_window_checked(
connection,
depth->depth,
window,
screen->root,
screen->width_in_pixels - 1, screen->height_in_pixels - 1,
1, 1,
0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
visual->visual_id,
cw_mask,
cw_values);
auto error = xcb_request_check(connection, cookie);
if (error) {
fprintf(stderr, "ERROR: failed to create window: %i\n", error->error_code);
xcb_disconnect(connection);
return -1;
}
if (xcb_ewmh_init_atoms_replies(&ewmh, ewmh_cookie, NULL)) {
xcb_change_property(connection, XCB_PROP_MODE_REPLACE, window, ewmh._NET_WM_STATE, XCB_ATOM_ATOM, 32, 1, &(ewmh._NET_WM_STATE_SKIP_TASKBAR));
}
size_t len = strlen(PROGRAM) + strlen(argv[1]) + 2;
char* window_class = static_cast<char*>(malloc(len));
if (window_class == NULL) {
abort();
}
memcpy(window_class, argv[1], strlen(argv[1]) + 1);
memcpy(window_class + strlen(argv[1]) + 1, PROGRAM, strlen(PROGRAM) + 1);
xcb_change_property (connection, XCB_PROP_MODE_REPLACE, window,
XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8,
len, window_class);
xcb_change_property (connection, XCB_PROP_MODE_REPLACE, window,
XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8,
strlen(PROGRAM), PROGRAM);
xcb_map_window(connection, window);
xcb_flush(connection);
pause();
xcb_disconnect(connection);
return 0;
}
@mochaaP
Copy link
Author

mochaaP commented Oct 15, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment