feat(backend/X11): 实现按键抓取功能
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
#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>
|
||||||
@@ -160,6 +161,8 @@ backend_t *backend_create(const char *display_name) {
|
|||||||
backend->have_xfixes = false;
|
backend->have_xfixes = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
backend->key_symbols = xcb_key_symbols_alloc(conn);
|
||||||
|
|
||||||
atoms_init(backend);
|
atoms_init(backend);
|
||||||
create_wm_check_window(backend);
|
create_wm_check_window(backend);
|
||||||
create_no_focus_window(backend);
|
create_no_focus_window(backend);
|
||||||
@@ -456,6 +459,12 @@ find_or_push_configure(window_configure_list_t *configs, xcb_window_t window) {
|
|||||||
return cfg;
|
return cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
backend_bind_key(backend_t *backend, const effect_bind_key_t *bind_key) {
|
||||||
|
auto root = backend->screen->root;
|
||||||
|
window_grab_keys(backend, root, bind_key->keys, bind_key->count);
|
||||||
|
}
|
||||||
|
|
||||||
static void backend_merge_effects(
|
static void backend_merge_effects(
|
||||||
backend_t *backend,
|
backend_t *backend,
|
||||||
const effect_t *effects,
|
const effect_t *effects,
|
||||||
@@ -517,6 +526,9 @@ static void backend_merge_effects(
|
|||||||
backend_restack_windows(backend, &e->as.restack_windows);
|
backend_restack_windows(backend, &e->as.restack_windows);
|
||||||
backend_change_window_list(backend, true, &e->as.restack_windows);
|
backend_change_window_list(backend, true, &e->as.restack_windows);
|
||||||
break;
|
break;
|
||||||
|
case ZDWM_EFFECT_BIND_KEY:
|
||||||
|
backend_bind_key(backend, &e->as.bind_key);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
|
#include <xcb/xcb_keysyms.h>
|
||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
#define ATOM_LIST(X) \
|
#define ATOM_LIST(X) \
|
||||||
@@ -76,6 +77,7 @@ typedef struct window_list_t {
|
|||||||
} window_list_t;
|
} window_list_t;
|
||||||
|
|
||||||
struct backend_t {
|
struct backend_t {
|
||||||
|
xcb_key_symbols_t *key_symbols;
|
||||||
xcb_connection_t *conn;
|
xcb_connection_t *conn;
|
||||||
xcb_screen_t *screen;
|
xcb_screen_t *screen;
|
||||||
int screenp;
|
int screenp;
|
||||||
|
|||||||
@@ -4,11 +4,14 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#include <xcb/xcb_icccm.h>
|
#include <xcb/xcb_icccm.h>
|
||||||
|
#include <xcb/xcb_keysyms.h>
|
||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
#include "base/array.h"
|
#include "base/array.h"
|
||||||
|
#include "base/macros.h"
|
||||||
#include "base/memory.h"
|
#include "base/memory.h"
|
||||||
#include "core/backend.h"
|
#include "core/backend.h"
|
||||||
|
#include "core/types.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
static char *window_get_text_property(
|
static char *window_get_text_property(
|
||||||
@@ -326,3 +329,52 @@ void window_list_reset(window_list_t *window_list) {
|
|||||||
p_clear(window_list->windows, window_list->count);
|
p_clear(window_list->windows, window_list->count);
|
||||||
window_list->count = 0;
|
window_list->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint16_t get_xcb_modifier(modifier_mask_t modifiers) {
|
||||||
|
typedef struct modifier_map_t {
|
||||||
|
modifier_bit_t modifier;
|
||||||
|
xcb_mod_mask_t mask;
|
||||||
|
} modifier_map_t;
|
||||||
|
static constexpr modifier_map_t modifier_map[] = {
|
||||||
|
{ZDWM_MOD_SHIFT, XCB_MOD_MASK_SHIFT},
|
||||||
|
{ZDWM_MOD_CONTROL, XCB_MOD_MASK_CONTROL},
|
||||||
|
{ZDWM_MOD_1, XCB_MOD_MASK_1},
|
||||||
|
{ZDWM_MOD_2, XCB_MOD_MASK_2},
|
||||||
|
{ZDWM_MOD_3, XCB_MOD_MASK_3},
|
||||||
|
{ZDWM_MOD_4, XCB_MOD_MASK_4},
|
||||||
|
{ZDWM_MOD_5, XCB_MOD_MASK_5},
|
||||||
|
};
|
||||||
|
|
||||||
|
uint16_t mods = ZDWM_MOD_NONE;
|
||||||
|
for (size_t i = 0; i < countof(modifier_map); ++i) {
|
||||||
|
auto item = &modifier_map[i];
|
||||||
|
if (modifiers & item->modifier) mods |= item->mask;
|
||||||
|
}
|
||||||
|
return mods;
|
||||||
|
}
|
||||||
|
|
||||||
|
void window_grab_keys(
|
||||||
|
backend_t *backend,
|
||||||
|
xcb_window_t window,
|
||||||
|
const key_bind_t *keys,
|
||||||
|
size_t count
|
||||||
|
) {
|
||||||
|
auto conn = backend->conn;
|
||||||
|
auto key_symbols = backend->key_symbols;
|
||||||
|
|
||||||
|
xcb_ungrab_key(conn, XCB_GRAB_ANY, window, XCB_MOD_MASK_ANY);
|
||||||
|
|
||||||
|
xcb_grab_mode_t mode = XCB_GRAB_MODE_ASYNC;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; ++i) {
|
||||||
|
auto key = &keys[i];
|
||||||
|
auto keycodes = xcb_key_symbols_get_keycode(key_symbols, keys->keysym);
|
||||||
|
if (!keycodes) continue;
|
||||||
|
|
||||||
|
auto modifiers = get_xcb_modifier(key->modifiers);
|
||||||
|
for (auto keycode = keycodes; *keycode != XCB_NO_SYMBOL; ++keycode) {
|
||||||
|
xcb_grab_key(conn, true, window, modifiers, *keycode, mode, mode);
|
||||||
|
}
|
||||||
|
p_delete(&keycodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <xcb/xproto.h>
|
#include <xcb/xproto.h>
|
||||||
|
|
||||||
#include "core/backend.h"
|
#include "core/backend.h"
|
||||||
|
#include "core/plan.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
typedef struct atoms_t atoms_t;
|
typedef struct atoms_t atoms_t;
|
||||||
@@ -87,3 +88,10 @@ void window_clean_event_mask(xcb_connection_t *conn, xcb_window_t window);
|
|||||||
|
|
||||||
void window_list_push(window_list_t *window_list, xcb_window_t window);
|
void window_list_push(window_list_t *window_list, xcb_window_t window);
|
||||||
void window_list_reset(window_list_t *window_list);
|
void window_list_reset(window_list_t *window_list);
|
||||||
|
|
||||||
|
void window_grab_keys(
|
||||||
|
backend_t *backend,
|
||||||
|
xcb_window_t window,
|
||||||
|
const key_bind_t *keys,
|
||||||
|
size_t count
|
||||||
|
);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include "base/array.h"
|
#include "base/array.h"
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "base/memory.h"
|
#include "base/memory.h"
|
||||||
#include "core/event.h"
|
#include "core/types.h"
|
||||||
|
|
||||||
typedef struct key_binding_t {
|
typedef struct key_binding_t {
|
||||||
const char *key_str;
|
const char *key_str;
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ typedef enum event_type_t {
|
|||||||
ZDWM_EVENT_CONFIGURE_REQUEST,
|
ZDWM_EVENT_CONFIGURE_REQUEST,
|
||||||
} event_type_t;
|
} event_type_t;
|
||||||
|
|
||||||
typedef uint32_t modifier_mask_t;
|
|
||||||
typedef uint32_t keysym_t;
|
|
||||||
|
|
||||||
typedef struct key_press_event_t {
|
typedef struct key_press_event_t {
|
||||||
modifier_mask_t modifiers;
|
modifier_mask_t modifiers;
|
||||||
keysym_t keysym;
|
keysym_t keysym;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ typedef enum effect_type_t {
|
|||||||
ZDWM_EFFECT_CHANGE_BORDER_WIDTH,
|
ZDWM_EFFECT_CHANGE_BORDER_WIDTH,
|
||||||
ZDWM_EFFECT_CHANGE_WINDOW_LIST,
|
ZDWM_EFFECT_CHANGE_WINDOW_LIST,
|
||||||
ZDWM_EFFECT_RESTACK_WINDOWS,
|
ZDWM_EFFECT_RESTACK_WINDOWS,
|
||||||
|
ZDWM_EFFECT_BIND_KEY,
|
||||||
} effect_type_t;
|
} effect_type_t;
|
||||||
|
|
||||||
typedef struct effect_only_window_id_t {
|
typedef struct effect_only_window_id_t {
|
||||||
@@ -48,6 +49,16 @@ typedef struct effect_window_list_t {
|
|||||||
size_t count;
|
size_t count;
|
||||||
} effect_window_list_t;
|
} effect_window_list_t;
|
||||||
|
|
||||||
|
typedef struct key_bind_t {
|
||||||
|
modifier_mask_t modifiers;
|
||||||
|
keysym_t keysym;
|
||||||
|
} key_bind_t;
|
||||||
|
|
||||||
|
typedef struct effect_bind_key_t {
|
||||||
|
const key_bind_t *keys;
|
||||||
|
size_t count;
|
||||||
|
} effect_bind_key_t;
|
||||||
|
|
||||||
typedef struct effect_t {
|
typedef struct effect_t {
|
||||||
effect_type_t type;
|
effect_type_t type;
|
||||||
union {
|
union {
|
||||||
@@ -61,6 +72,7 @@ typedef struct effect_t {
|
|||||||
effect_change_border_width_t change_border_width;
|
effect_change_border_width_t change_border_width;
|
||||||
effect_window_list_t change_window_list;
|
effect_window_list_t change_window_list;
|
||||||
effect_window_list_t restack_windows;
|
effect_window_list_t restack_windows;
|
||||||
|
effect_bind_key_t bind_key;
|
||||||
} as;
|
} as;
|
||||||
} effect_t;
|
} effect_t;
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ typedef zdwm_rule_match_t rule_match_t;
|
|||||||
typedef zdwm_rule_action_t rule_action_t;
|
typedef zdwm_rule_action_t rule_action_t;
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
|
typedef uint32_t modifier_mask_t;
|
||||||
|
typedef uint32_t keysym_t;
|
||||||
|
|
||||||
#define ZDWM_OUTPUT_ID_INVALID ((output_id_t)UINT32_MAX)
|
#define ZDWM_OUTPUT_ID_INVALID ((output_id_t)UINT32_MAX)
|
||||||
|
|
||||||
typedef struct point_t {
|
typedef struct point_t {
|
||||||
|
|||||||
Reference in New Issue
Block a user