Compare commits
2 Commits
76f9e15130
...
88bf451cd4
| Author | SHA1 | Date | |
|---|---|---|---|
|
88bf451cd4
|
|||
|
edda316709
|
@@ -32,6 +32,7 @@ add_executable(${APP_NAME}
|
|||||||
xwindow.c
|
xwindow.c
|
||||||
event.c
|
event.c
|
||||||
action.c
|
action.c
|
||||||
|
xkb.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# use C23
|
# use C23
|
||||||
@@ -46,9 +47,12 @@ pkg_check_modules(deps REQUIRED
|
|||||||
xcb
|
xcb
|
||||||
xcb-aux
|
xcb-aux
|
||||||
xcb-cursor
|
xcb-cursor
|
||||||
|
xcb-keysyms
|
||||||
xcb-randr
|
xcb-randr
|
||||||
xcb-xfixes
|
xcb-xfixes
|
||||||
xcb-xinerama
|
xcb-xinerama
|
||||||
|
xcb-xkb
|
||||||
|
xkbcommon-x11
|
||||||
|
|
||||||
cairo
|
cairo
|
||||||
cairo-xcb
|
cairo-xcb
|
||||||
|
|||||||
10
src/action.c
10
src/action.c
@@ -1,8 +1,18 @@
|
|||||||
#include "action.h"
|
#include "action.h"
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "monitor.h"
|
#include "monitor.h"
|
||||||
#include "wm.h"
|
#include "wm.h"
|
||||||
|
|
||||||
void select_tag_of_current_monitor(const user_action_arg_t *arg) {
|
void select_tag_of_current_monitor(const user_action_arg_t *arg) {
|
||||||
monitor_select_tag(wm.current_monitor, arg->ui);
|
monitor_select_tag(wm.current_monitor, arg->ui);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void spawn(const user_action_arg_t *arg) {
|
||||||
|
const char *cmd = (const char *)arg->ptr;
|
||||||
|
if (cmd == nullptr || strlen(cmd) == 0) return;
|
||||||
|
|
||||||
|
g_spawn_command_line_async((const char *)arg->ptr, nullptr);
|
||||||
|
}
|
||||||
|
|||||||
16
src/action.h
16
src/action.h
@@ -7,7 +7,7 @@ typedef union user_action_arg_t {
|
|||||||
bool b;
|
bool b;
|
||||||
int32_t i;
|
int32_t i;
|
||||||
uint32_t ui;
|
uint32_t ui;
|
||||||
void *ptr;
|
const void *ptr;
|
||||||
} user_action_arg_t;
|
} user_action_arg_t;
|
||||||
|
|
||||||
typedef enum click_area_t {
|
typedef enum click_area_t {
|
||||||
@@ -24,6 +24,8 @@ typedef enum modifier_t {
|
|||||||
modifier_any = XCB_MOD_MASK_ANY,
|
modifier_any = XCB_MOD_MASK_ANY,
|
||||||
} modifier_t;
|
} modifier_t;
|
||||||
|
|
||||||
|
typedef uint16_t modifier_value_t;
|
||||||
|
|
||||||
typedef enum button_index_t {
|
typedef enum button_index_t {
|
||||||
button_any = XCB_BUTTON_INDEX_ANY,
|
button_any = XCB_BUTTON_INDEX_ANY,
|
||||||
button_left = XCB_BUTTON_INDEX_1,
|
button_left = XCB_BUTTON_INDEX_1,
|
||||||
@@ -32,11 +34,19 @@ typedef enum button_index_t {
|
|||||||
} button_index_t;
|
} button_index_t;
|
||||||
|
|
||||||
typedef struct button_t {
|
typedef struct button_t {
|
||||||
click_area_t click_area;
|
click_area_t click_area : 16;
|
||||||
modifier_t modifiers;
|
modifier_value_t modifiers;
|
||||||
button_index_t button;
|
button_index_t button;
|
||||||
void (*func)(const user_action_arg_t *arg);
|
void (*func)(const user_action_arg_t *arg);
|
||||||
const user_action_arg_t arg;
|
const user_action_arg_t arg;
|
||||||
} button_t;
|
} button_t;
|
||||||
|
|
||||||
|
typedef struct keyboard_t {
|
||||||
|
modifier_value_t modifiers;
|
||||||
|
xcb_keysym_t keysym;
|
||||||
|
void (*func)(const user_action_arg_t *arg);
|
||||||
|
const user_action_arg_t arg;
|
||||||
|
} keyboard_t;
|
||||||
|
|
||||||
void select_tag_of_current_monitor(const user_action_arg_t *arg);
|
void select_tag_of_current_monitor(const user_action_arg_t *arg);
|
||||||
|
void spawn(const user_action_arg_t *arg);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <X11/keysym.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "action.h"
|
#include "action.h"
|
||||||
@@ -23,3 +24,9 @@ static const char *const active_tag_color = "#eeeeee";
|
|||||||
static const button_t button_list[] = {
|
static const button_t button_list[] = {
|
||||||
{click_tag, modifier_none, button_left, select_tag_of_current_monitor, {0}},
|
{click_tag, modifier_none, button_left, select_tag_of_current_monitor, {0}},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char launcher[] =
|
||||||
|
"rofi -show combi -modes window,drun,run,ssh,combi,windowcd";
|
||||||
|
static const keyboard_t key_list[] = {
|
||||||
|
{modifier_super, XK_p, spawn, {.ptr = launcher}},
|
||||||
|
};
|
||||||
|
|||||||
13
src/event.c
13
src/event.c
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xcb_event.h>
|
#include <xcb/xcb_event.h>
|
||||||
|
#include <xcb/xcb_keysyms.h>
|
||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
#include "action.h"
|
#include "action.h"
|
||||||
@@ -46,7 +46,16 @@ static void button_press(xcb_button_press_event_t *ev) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void key_press(xcb_key_press_event_t *ev) { printf("key press\n"); }
|
static void key_press(xcb_key_press_event_t *ev) {
|
||||||
|
xcb_keysym_t keysym = xcb_key_press_lookup_keysym(wm.key_symbols, ev, 0);
|
||||||
|
for (int i = 0; i < countof(key_list); i++) {
|
||||||
|
keyboard_t key = key_list[i];
|
||||||
|
if (keysym == key.keysym && ev->state == key.modifiers && key.func) {
|
||||||
|
key.func(&key.arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_xcb_event(xcb_generic_event_t *event) {
|
static void handle_xcb_event(xcb_generic_event_t *event) {
|
||||||
uint8_t event_type = XCB_EVENT_RESPONSE_TYPE(event);
|
uint8_t event_type = XCB_EVENT_RESPONSE_TYPE(event);
|
||||||
|
|||||||
25
src/wm.c
25
src/wm.c
@@ -12,10 +12,12 @@
|
|||||||
#include <xcb/randr.h>
|
#include <xcb/randr.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xcb_aux.h>
|
#include <xcb/xcb_aux.h>
|
||||||
|
#include <xcb/xcb_keysyms.h>
|
||||||
#include <xcb/xfixes.h>
|
#include <xcb/xfixes.h>
|
||||||
#include <xcb/xinerama.h>
|
#include <xcb/xinerama.h>
|
||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
|
#include "action.h"
|
||||||
#include "backtrace.h"
|
#include "backtrace.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
@@ -36,6 +38,7 @@ static void wm_scan_clients(void);
|
|||||||
static void wm_clean(void);
|
static void wm_clean(void);
|
||||||
static void wm_setup(void);
|
static void wm_setup(void);
|
||||||
static void wm_init_color_set(void);
|
static void wm_init_color_set(void);
|
||||||
|
static void wm_setup_keybindings(void);
|
||||||
|
|
||||||
wm_t wm;
|
wm_t wm;
|
||||||
|
|
||||||
@@ -265,6 +268,8 @@ void wm_clean(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
xcursor_clean();
|
xcursor_clean();
|
||||||
|
xcb_ungrab_key(wm.xcb_conn, XCB_GRAB_ANY, wm.screen->root, modifier_any);
|
||||||
|
xcb_key_symbols_free(wm.key_symbols);
|
||||||
xcb_disconnect(wm.xcb_conn);
|
xcb_disconnect(wm.xcb_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,7 +290,15 @@ static void wm_setup(void) {
|
|||||||
monitor_draw_bar(m);
|
monitor_draw_bar(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
xwindow_change_cursor(wm.screen->root, cursor_normal);
|
xcb_params_cw_t params = {
|
||||||
|
.cursor = xcursor_get_xcb_cursor(cursor_normal),
|
||||||
|
.event_mask =
|
||||||
|
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_KEY_PRESS,
|
||||||
|
};
|
||||||
|
xcb_aux_change_window_attributes(wm.xcb_conn, wm.screen->root, XCB_CW_CURSOR,
|
||||||
|
¶ms);
|
||||||
|
|
||||||
|
wm_setup_keybindings();
|
||||||
xcb_flush(wm.xcb_conn);
|
xcb_flush(wm.xcb_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,6 +310,16 @@ void wm_init_color_set(void) {
|
|||||||
color_parse(active_tag_color, &wm.color_set.active_tag_color);
|
color_parse(active_tag_color, &wm.color_set.active_tag_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wm_setup_keybindings(void) {
|
||||||
|
if (wm.key_symbols) {
|
||||||
|
xcb_key_symbols_free(wm.key_symbols);
|
||||||
|
p_delete(&wm.key_symbols);
|
||||||
|
}
|
||||||
|
|
||||||
|
wm.key_symbols = xcb_key_symbols_alloc(wm.xcb_conn);
|
||||||
|
xwindow_grab_keys(wm.screen->root, key_list, countof(key_list));
|
||||||
|
}
|
||||||
|
|
||||||
void wm_restart(void) {
|
void wm_restart(void) {
|
||||||
wm_atexit(true);
|
wm_atexit(true);
|
||||||
execvp(cmd_argv[0], cmd_argv);
|
execvp(cmd_argv[0], cmd_argv);
|
||||||
|
|||||||
7
src/wm.h
7
src/wm.h
@@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <xcb/xcb_keysyms.h>
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
@@ -19,10 +21,15 @@ typedef struct wm_t {
|
|||||||
|
|
||||||
xcb_connection_t *xcb_conn;
|
xcb_connection_t *xcb_conn;
|
||||||
xcb_screen_t *screen;
|
xcb_screen_t *screen;
|
||||||
|
xcb_key_symbols_t *key_symbols;
|
||||||
int default_screen;
|
int default_screen;
|
||||||
bool have_xfixes;
|
bool have_xfixes;
|
||||||
bool have_xinerama;
|
bool have_xinerama;
|
||||||
bool have_randr;
|
bool have_randr;
|
||||||
|
bool have_xkb;
|
||||||
|
|
||||||
|
struct xkb_context *xkb_ctx;
|
||||||
|
struct xkb_state *xkb_state;
|
||||||
|
|
||||||
color_set_t color_set;
|
color_set_t color_set;
|
||||||
} wm_t;
|
} wm_t;
|
||||||
|
|||||||
45
src/xkb.c
Normal file
45
src/xkb.c
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
#include "xkb.h"
|
||||||
|
|
||||||
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/xkb.h>
|
||||||
|
#include <xkbcommon/xkbcommon-x11.h>
|
||||||
|
#include <xkbcommon/xkbcommon.h>
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
#include "wm.h"
|
||||||
|
|
||||||
|
static void xkb_fill_state(void) {}
|
||||||
|
|
||||||
|
static void xkb_init_keymap(void) {
|
||||||
|
wm.xkb_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
|
if (!wm.xkb_ctx) fatal("Cannot get XKB context");
|
||||||
|
|
||||||
|
xkb_fill_state();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xkb_free_keymap(void) {
|
||||||
|
xkb_state_unref(wm.xkb_state);
|
||||||
|
xkb_context_unref(wm.xkb_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xkb_init(void) {
|
||||||
|
wm.have_xkb = xkb_x11_setup_xkb_extension(
|
||||||
|
wm.xcb_conn, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION,
|
||||||
|
XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS, nullptr, nullptr, nullptr, nullptr);
|
||||||
|
if (!wm.have_xkb) {
|
||||||
|
warn("XKB not found or not supported");
|
||||||
|
xkb_init_keymap();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_discard_reply(wm.xcb_conn,
|
||||||
|
xcb_xkb_per_client_flags(
|
||||||
|
wm.xcb_conn, XCB_XKB_ID_USE_CORE_KBD,
|
||||||
|
XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT,
|
||||||
|
XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT, 0, 0, 0)
|
||||||
|
.sequence);
|
||||||
|
|
||||||
|
xkb_init_keymap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void xkb_free(void) { xkb_free_keymap(); }
|
||||||
4
src/xkb.h
Normal file
4
src/xkb.h
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void xkb_init(void);
|
||||||
|
void xkb_free(void);
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
#include "xwindow.h"
|
#include "xwindow.h"
|
||||||
|
|
||||||
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xcb_aux.h>
|
#include <xcb/xcb_aux.h>
|
||||||
|
#include <xcb/xcb_keysyms.h>
|
||||||
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
|
#include "action.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "wm.h"
|
#include "wm.h"
|
||||||
#include "xcursor.h"
|
#include "xcursor.h"
|
||||||
@@ -105,3 +109,20 @@ void xwindow_change_cursor(xcb_window_t window, cursor_t cursor) {
|
|||||||
xcb_params_cw_t params = {.cursor = xcursor_get_xcb_cursor(cursor)};
|
xcb_params_cw_t params = {.cursor = xcursor_get_xcb_cursor(cursor)};
|
||||||
xcb_aux_change_window_attributes(wm.xcb_conn, window, XCB_CW_CURSOR, ¶ms);
|
xcb_aux_change_window_attributes(wm.xcb_conn, window, XCB_CW_CURSOR, ¶ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void xwindow_grab_keys(xcb_window_t window, const keyboard_t *keys,
|
||||||
|
int keys_length) {
|
||||||
|
xcb_connection_t *conn = wm.xcb_conn;
|
||||||
|
xcb_ungrab_key(conn, XCB_GRAB_ANY, window, modifier_any);
|
||||||
|
|
||||||
|
xcb_grab_mode_t mode = XCB_GRAB_MODE_ASYNC;
|
||||||
|
xcb_keycode_t *keycode = nullptr;
|
||||||
|
|
||||||
|
for (int i = 0; i < keys_length; i++) {
|
||||||
|
keycode = xcb_key_symbols_get_keycode(wm.key_symbols, keys[i].keysym);
|
||||||
|
if (keycode) {
|
||||||
|
xcb_grab_key(conn, true, window, keys[i].modifiers, *keycode, mode, mode);
|
||||||
|
p_delete(&keycode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
|
#include "action.h"
|
||||||
#include "xcursor.h"
|
#include "xcursor.h"
|
||||||
|
|
||||||
typedef struct visual_t {
|
typedef struct visual_t {
|
||||||
@@ -12,3 +13,5 @@ typedef struct visual_t {
|
|||||||
|
|
||||||
visual_t *xwindow_get_xcb_visual(bool prefer_alpha);
|
visual_t *xwindow_get_xcb_visual(bool prefer_alpha);
|
||||||
void xwindow_change_cursor(xcb_window_t window, cursor_t cursor);
|
void xwindow_change_cursor(xcb_window_t window, cursor_t cursor);
|
||||||
|
void xwindow_grab_keys(xcb_window_t window, const keyboard_t *keys,
|
||||||
|
int keys_length);
|
||||||
|
|||||||
Reference in New Issue
Block a user