设置快捷键

This commit is contained in:
2025-11-22 22:22:54 +08:00
parent 76f9e15130
commit edda316709
9 changed files with 92 additions and 6 deletions

View File

@@ -46,6 +46,7 @@ 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

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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}},
};

View File

@@ -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);

View File

@@ -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,
&params);
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);

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <xcb/xcb_keysyms.h>
#include "types.h" #include "types.h"
@@ -19,6 +20,7 @@ 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;

View File

@@ -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, &params); xcb_aux_change_window_attributes(wm.xcb_conn, window, XCB_CW_CURSOR, &params);
} }
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);
}
}
}

View File

@@ -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);