Add better icccm support
This commit is contained in:
111
X-kutu.c
111
X-kutu.c
@@ -1,3 +1,4 @@
|
||||
#include <xcb/xproto.h>
|
||||
#define CLEANMASK(m) ((m & ~0x80))
|
||||
|
||||
// Definitions for modifier keys
|
||||
@@ -12,10 +13,12 @@
|
||||
// Standard headers
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// XCB header
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_icccm.h>
|
||||
|
||||
// Global variables
|
||||
// Connection to X server
|
||||
@@ -72,7 +75,6 @@ void add_mousebind(int button) {
|
||||
// Deploy function to initialize the X connection, set up event masks, and
|
||||
// prepare the window manager
|
||||
int deploy(void) {
|
||||
uint32_t values[2];
|
||||
int mask;
|
||||
|
||||
// Start X connection and return -1 if it fails
|
||||
@@ -85,7 +87,12 @@ int deploy(void) {
|
||||
|
||||
// Setuup event masks
|
||||
mask = XCB_CW_EVENT_MASK;
|
||||
values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY;
|
||||
|
||||
uint32_t values[] = {XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
|
||||
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
|
||||
XCB_EVENT_MASK_STRUCTURE_NOTIFY |
|
||||
XCB_EVENT_MASK_PROPERTY_CHANGE};
|
||||
|
||||
xcb_change_window_attributes_checked(conn, scr->root, mask, values);
|
||||
|
||||
xcb_flush(conn);
|
||||
@@ -186,6 +193,52 @@ void resize_window(xcb_window_t win, int width, int height) {
|
||||
xcb_flush(conn);
|
||||
}
|
||||
|
||||
xcb_size_hints_t get_wm_n_hints(xcb_window_t win) {
|
||||
xcb_size_hints_t hints;
|
||||
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_normal_hints(conn, win);
|
||||
xcb_icccm_get_wm_normal_hints_reply(conn, cookie, &hints, NULL);
|
||||
return hints;
|
||||
}
|
||||
|
||||
xcb_icccm_wm_hints_t get_wm_hints(xcb_window_t win) {
|
||||
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_hints(conn, win);
|
||||
xcb_icccm_wm_hints_t hints;
|
||||
xcb_icccm_get_wm_hints_reply(conn, cookie, &hints, NULL);
|
||||
return hints;
|
||||
}
|
||||
|
||||
char *get_wm_name(xcb_window_t win) {
|
||||
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_name(conn, win);
|
||||
xcb_icccm_get_text_property_reply_t reply;
|
||||
xcb_icccm_get_wm_name_reply(conn, cookie, &reply, NULL);
|
||||
return reply.name;
|
||||
}
|
||||
|
||||
uint8_t get_wm_transient_for(xcb_window_t win) {
|
||||
xcb_get_property_cookie_t cookie = xcb_icccm_get_wm_transient_for(conn, win);
|
||||
return xcb_icccm_get_wm_transient_for_reply(conn, cookie, &win, NULL);
|
||||
}
|
||||
|
||||
void set_wm_state(xcb_window_t win, int state) {
|
||||
xcb_intern_atom_cookie_t cookie =
|
||||
xcb_intern_atom(conn, 0, strlen("WM_STATE"), "WM_STATE");
|
||||
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, cookie, NULL);
|
||||
if (!reply)
|
||||
return;
|
||||
|
||||
xcb_atom_t WM_STATE = reply->atom;
|
||||
free(reply);
|
||||
|
||||
uint32_t data[2];
|
||||
data[0] = state;
|
||||
data[1] = XCB_WINDOW_NONE;
|
||||
|
||||
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win, WM_STATE, WM_STATE, 32,
|
||||
2, data);
|
||||
|
||||
xcb_flush(conn);
|
||||
}
|
||||
|
||||
// Wait for an event and return it as an Event structure
|
||||
// This function is blocking
|
||||
// The event is sent by value, so no need to free anything
|
||||
@@ -225,7 +278,7 @@ Event wait_for_event(void) {
|
||||
case XCB_MAP_NOTIFY: {
|
||||
xcb_map_notify_event_t *e;
|
||||
e = (xcb_map_notify_event_t *)ev;
|
||||
ret.type = -1;
|
||||
ret.type = 4;
|
||||
ret.window = e->window;
|
||||
ret.override_redirect = e->override_redirect;
|
||||
} break;
|
||||
@@ -233,9 +286,8 @@ Event wait_for_event(void) {
|
||||
case XCB_MAP_REQUEST: {
|
||||
xcb_map_request_event_t *e;
|
||||
e = (xcb_map_request_event_t *)ev;
|
||||
ret.type = 4;
|
||||
ret.type = 5;
|
||||
ret.window = e->window;
|
||||
ret.override_redirect = 1;
|
||||
} break;
|
||||
|
||||
case XCB_BUTTON_PRESS: {
|
||||
@@ -249,7 +301,7 @@ Event wait_for_event(void) {
|
||||
XCB_EVENT_MASK_POINTER_MOTION_HINT,
|
||||
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, e->child,
|
||||
XCB_NONE, XCB_CURRENT_TIME);
|
||||
ret.type = 5;
|
||||
ret.type = 6;
|
||||
ret.window = e->child;
|
||||
ret.is_root = e->child == scr->root;
|
||||
ret.x = e->event_x;
|
||||
@@ -259,7 +311,7 @@ Event wait_for_event(void) {
|
||||
|
||||
case XCB_MOTION_NOTIFY: {
|
||||
xcb_motion_notify_event_t *e = (xcb_motion_notify_event_t *)ev;
|
||||
ret.type = 6;
|
||||
ret.type = 7;
|
||||
ret.window = e->child;
|
||||
ret.x = e->event_x;
|
||||
ret.y = e->event_y;
|
||||
@@ -270,7 +322,7 @@ Event wait_for_event(void) {
|
||||
xcb_button_release_event_t *e = (xcb_button_release_event_t *)ev;
|
||||
// Ungrab pointer after dragging
|
||||
xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
|
||||
ret.type = 7;
|
||||
ret.type = 8;
|
||||
ret.x = e->event_x;
|
||||
ret.y = e->event_y;
|
||||
ret.btn = e->detail;
|
||||
@@ -279,7 +331,7 @@ Event wait_for_event(void) {
|
||||
case XCB_KEY_PRESS: {
|
||||
xcb_key_press_event_t *e;
|
||||
e = (xcb_key_press_event_t *)ev;
|
||||
ret.type = 8;
|
||||
ret.type = 9;
|
||||
ret.window = e->child;
|
||||
ret.btn = e->detail;
|
||||
ret.state = e->state;
|
||||
@@ -288,22 +340,49 @@ Event wait_for_event(void) {
|
||||
case XCB_KEY_RELEASE: {
|
||||
xcb_key_release_event_t *e;
|
||||
e = (xcb_key_release_event_t *)ev;
|
||||
ret.type = 9;
|
||||
ret.type = 10;
|
||||
ret.window = e->child;
|
||||
ret.btn = e->detail;
|
||||
ret.state = e->state;
|
||||
} break;
|
||||
|
||||
case XCB_CONFIGURE_NOTIFY: {
|
||||
xcb_configure_notify_event_t *e;
|
||||
e = (xcb_configure_notify_event_t *)ev;
|
||||
ret.type = 10;
|
||||
case XCB_UNMAP_NOTIFY: {
|
||||
xcb_unmap_notify_event_t *e;
|
||||
e = (xcb_unmap_notify_event_t *)ev;
|
||||
ret.type = 11;
|
||||
ret.window = e->window;
|
||||
} break;
|
||||
|
||||
case XCB_CONFIGURE_REQUEST: {
|
||||
xcb_configure_request_event_t *e = (xcb_configure_request_event_t *)ev;
|
||||
ret.type = 12;
|
||||
ret.window = e->window;
|
||||
ret.x = e->x;
|
||||
ret.y = e->y;
|
||||
ret.width = e->width;
|
||||
ret.height = e->height;
|
||||
// ret.stack_mode =
|
||||
// e->value_mask & XCB_CONFIG_WINDOW_STACK_MODE ? e->stack_mode : 0;
|
||||
} break;
|
||||
|
||||
case XCB_RESIZE_REQUEST: {
|
||||
xcb_resize_request_event_t *e = (xcb_resize_request_event_t *)ev;
|
||||
ret.type = 13;
|
||||
ret.window = e->window;
|
||||
ret.width = e->width;
|
||||
ret.height = e->height;
|
||||
ret.x = e->x;
|
||||
ret.y = e->y;
|
||||
} break;
|
||||
|
||||
// case XCB_CONFIGURE_NOTIFY: {
|
||||
// xcb_configure_notify_event_t *e;
|
||||
// e = (xcb_configure_notify_event_t *)ev;
|
||||
// ret.type = 12;
|
||||
// ret.window = e->window;
|
||||
// ret.width = e->width;
|
||||
// ret.height = e->height;
|
||||
// ret.x = e->x;
|
||||
// ret.y = e->y;
|
||||
// } break;
|
||||
}
|
||||
|
||||
xcb_flush(conn);
|
||||
|
||||
Reference in New Issue
Block a user