mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-03-31 07:11:28 -04:00
kbl
This commit is contained in:
parent
8a1f3597e1
commit
a2b6ab3e54
4 changed files with 196 additions and 10 deletions
|
|
@ -111,6 +111,13 @@ typedef struct {
|
||||||
int32_t vrr; // variable refresh rate
|
int32_t vrr; // variable refresh rate
|
||||||
} ConfigMonitorRule;
|
} ConfigMonitorRule;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *name;
|
||||||
|
int32_t vendor, product;
|
||||||
|
struct xkb_keymap *keymap;
|
||||||
|
struct xkb_context *ctx;
|
||||||
|
} ConfigKeyboardRule;
|
||||||
|
|
||||||
// 修改后的宏定义
|
// 修改后的宏定义
|
||||||
#define CHVT(n) \
|
#define CHVT(n) \
|
||||||
{ \
|
{ \
|
||||||
|
|
@ -321,6 +328,9 @@ typedef struct {
|
||||||
ConfigMonitorRule *monitor_rules; // 动态数组
|
ConfigMonitorRule *monitor_rules; // 动态数组
|
||||||
int32_t monitor_rules_count; // 条数
|
int32_t monitor_rules_count; // 条数
|
||||||
|
|
||||||
|
ConfigKeyboardRule *keyboard_rules; // 动态数组
|
||||||
|
int32_t keyboard_rules_count; // 条数
|
||||||
|
|
||||||
KeyBinding *key_bindings;
|
KeyBinding *key_bindings;
|
||||||
int32_t key_bindings_count;
|
int32_t key_bindings_count;
|
||||||
|
|
||||||
|
|
@ -1840,6 +1850,113 @@ bool parse_option(Config *config, char *key, char *value) {
|
||||||
|
|
||||||
config->monitor_rules_count++;
|
config->monitor_rules_count++;
|
||||||
return !parse_error;
|
return !parse_error;
|
||||||
|
} else if (strcmp(key, "keyboardrule") == 0) {
|
||||||
|
config->keyboard_rules =
|
||||||
|
realloc(config->keyboard_rules, (config->keyboard_rules_count + 1) *
|
||||||
|
sizeof(ConfigKeyboardRule));
|
||||||
|
if (!config->keyboard_rules) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\033[1m\033[31m[ERROR]:\033[33m Failed to allocate "
|
||||||
|
"memory for keyboard rules\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigKeyboardRule *rule =
|
||||||
|
&config->keyboard_rules[config->keyboard_rules_count];
|
||||||
|
memset(rule, 0, sizeof(ConfigKeyboardRule));
|
||||||
|
|
||||||
|
// 设置默认值
|
||||||
|
rule->vendor = -1;
|
||||||
|
rule->product = -1;
|
||||||
|
rule->keymap = NULL;
|
||||||
|
|
||||||
|
char rule_xkb_rules_rules[256];
|
||||||
|
char rule_xkb_rules_model[256];
|
||||||
|
char rule_xkb_rules_layout[256];
|
||||||
|
char rule_xkb_rules_variant[256];
|
||||||
|
char rule_xkb_rules_options[256];
|
||||||
|
|
||||||
|
strcpy(rule_xkb_rules_rules, xkb_rules_rules);
|
||||||
|
strcpy(rule_xkb_rules_model, xkb_rules_model);
|
||||||
|
strcpy(rule_xkb_rules_layout, xkb_rules_layout);
|
||||||
|
strcpy(rule_xkb_rules_variant, xkb_rules_variant);
|
||||||
|
strcpy(rule_xkb_rules_options, xkb_rules_options);
|
||||||
|
|
||||||
|
bool parse_error = false;
|
||||||
|
char *token = strtok(value, ",");
|
||||||
|
while (token != NULL) {
|
||||||
|
char *colon = strchr(token, ':');
|
||||||
|
if (colon != NULL) {
|
||||||
|
*colon = '\0';
|
||||||
|
char *key = token;
|
||||||
|
char *val = colon + 1;
|
||||||
|
|
||||||
|
trim_whitespace(key);
|
||||||
|
trim_whitespace(val);
|
||||||
|
|
||||||
|
if (strcmp(key, "vendor") == 0) {
|
||||||
|
rule->vendor = atoi(val);
|
||||||
|
} else if (strcmp(key, "product") == 0) {
|
||||||
|
rule->product = atoi(val);
|
||||||
|
} else if (strcmp(key, "name") == 0) {
|
||||||
|
rule->name = strdup(val);
|
||||||
|
} else if (strcmp(key, "xkb_rules_rules") == 0) {
|
||||||
|
strcpy(rule_xkb_rules_rules, val);
|
||||||
|
rule_xkb_rules_rules[sizeof(rule_xkb_rules_rules) - 1] =
|
||||||
|
'\0'; // 确保字符串以 null 结尾
|
||||||
|
} else if (strcmp(key, "xkb_rules_model") == 0) {
|
||||||
|
strcpy(rule_xkb_rules_model, val);
|
||||||
|
rule_xkb_rules_model[sizeof(rule_xkb_rules_model) - 1] =
|
||||||
|
'\0'; // 确保字符串以 null 结尾
|
||||||
|
} else if (strcmp(key, "xkb_rules_layout") == 0) {
|
||||||
|
strcpy(rule_xkb_rules_layout, val);
|
||||||
|
rule_xkb_rules_layout[sizeof(rule_xkb_rules_layout) - 1] =
|
||||||
|
'\0'; // 确保字符串以 null 结尾
|
||||||
|
} else if (strcmp(key, "xkb_rules_variant") == 0) {
|
||||||
|
strcpy(rule_xkb_rules_variant, val);
|
||||||
|
rule_xkb_rules_variant[sizeof(rule_xkb_rules_variant) - 1] =
|
||||||
|
'\0'; // 确保字符串以 null 结尾
|
||||||
|
} else if (strcmp(key, "xkb_rules_options") == 0) {
|
||||||
|
strcpy(rule_xkb_rules_options, val);
|
||||||
|
rule_xkb_rules_options[sizeof(rule_xkb_rules_options) - 1] =
|
||||||
|
'\0'; // 确保字符串以 null 结尾
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\033[1m\033[31m[ERROR]:\033[33m Unknown "
|
||||||
|
"keyboard rule "
|
||||||
|
"option:\033[1m\033[31m %s\n",
|
||||||
|
key);
|
||||||
|
parse_error = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
token = strtok(NULL, ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct xkb_rule_names rule_xkb_rules = {
|
||||||
|
.rules = (rule_xkb_rules_rules[0] == '\0') ? NULL : rule_xkb_rules_rules,
|
||||||
|
.model = (rule_xkb_rules_model[0] == '\0') ? NULL : rule_xkb_rules_model,
|
||||||
|
.layout = (rule_xkb_rules_layout[0] == '\0') ? NULL : rule_xkb_rules_layout,
|
||||||
|
.variant = (rule_xkb_rules_variant[0] == '\0') ? NULL : rule_xkb_rules_variant,
|
||||||
|
.options = (rule_xkb_rules_options[0] == '\0') ? NULL : rule_xkb_rules_options,
|
||||||
|
};
|
||||||
|
|
||||||
|
rule->ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
|
rule->keymap = xkb_keymap_new_from_names(rule->ctx, &rule_xkb_rules,
|
||||||
|
XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
|
||||||
|
// 添加调试信息
|
||||||
|
fprintf(stderr, "\033[1m\033[32m[DEBUG]:\033[0m Created keymap: %p\n", (void*)rule->keymap);
|
||||||
|
if (rule->keymap) {
|
||||||
|
fprintf(stderr, " Keymap created successfully.\n");
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, " Failed to create keymap.\n");
|
||||||
|
// 可以尝试获取更多错误信息
|
||||||
|
// xkb_context_get_log_string(rule->ctx) 可能会提供错误信息
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
config->keyboard_rules_count++;
|
||||||
|
return !parse_error;
|
||||||
} else if (strcmp(key, "tagrule") == 0) {
|
} else if (strcmp(key, "tagrule") == 0) {
|
||||||
config->tag_rules =
|
config->tag_rules =
|
||||||
realloc(config->tag_rules,
|
realloc(config->tag_rules,
|
||||||
|
|
@ -2976,6 +3093,21 @@ void free_config(void) {
|
||||||
config.monitor_rules_count = 0;
|
config.monitor_rules_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 释放 keyboard_rules
|
||||||
|
if (config.keyboard_rules) {
|
||||||
|
for (int32_t i = 0; i < config.keyboard_rules_count; i++) {
|
||||||
|
if (config.keyboard_rules[i].name)
|
||||||
|
free((void *)config.keyboard_rules[i].name);
|
||||||
|
if (config.keyboard_rules[i].ctx)
|
||||||
|
xkb_context_unref(config.keyboard_rules[i].ctx);
|
||||||
|
if (config.keyboard_rules[i].keymap)
|
||||||
|
xkb_keymap_unref(config.keyboard_rules[i].keymap);
|
||||||
|
}
|
||||||
|
free(config.keyboard_rules);
|
||||||
|
config.keyboard_rules = NULL;
|
||||||
|
config.keyboard_rules_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// 释放 layer_rules
|
// 释放 layer_rules
|
||||||
if (config.layer_rules) {
|
if (config.layer_rules) {
|
||||||
for (int32_t i = 0; i < config.layer_rules_count; i++) {
|
for (int32_t i = 0; i < config.layer_rules_count; i++) {
|
||||||
|
|
@ -3443,6 +3575,8 @@ bool parse_config(void) {
|
||||||
config.window_rules_count = 0;
|
config.window_rules_count = 0;
|
||||||
config.monitor_rules = NULL;
|
config.monitor_rules = NULL;
|
||||||
config.monitor_rules_count = 0;
|
config.monitor_rules_count = 0;
|
||||||
|
config.keyboard_rules = NULL;
|
||||||
|
config.keyboard_rules_count = 0;
|
||||||
config.key_bindings = NULL;
|
config.key_bindings = NULL;
|
||||||
config.key_bindings_count = 0;
|
config.key_bindings_count = 0;
|
||||||
config.mouse_bindings = NULL;
|
config.mouse_bindings = NULL;
|
||||||
|
|
|
||||||
|
|
@ -150,20 +150,20 @@ void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
active_kb = get_active_keyboard_device();
|
active_kb = get_active_keyboard_device();
|
||||||
if(active_kb) {
|
if (active_kb) {
|
||||||
sprintf(active_kb_name, "vendor:%d,product:%d,name:%s", active_kb->vendor, active_kb->product, active_kb->name);
|
sprintf(active_kb_name, "vendor:%d,product:%d,name:%s",
|
||||||
|
active_kb->vendor, active_kb->product, active_kb->name);
|
||||||
} else {
|
} else {
|
||||||
sprintf(active_kb_name, "-1 -1 unknown");
|
sprintf(active_kb_name, "-1 -1 unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keyboard = active_kb ? (struct wlr_keyboard *)active_kb->device_data
|
||||||
keyboard = active_kb ? (struct wlr_keyboard*)active_kb->device_data: &kb_group->wlr_group->keyboard;
|
: &kb_group->wlr_group->keyboard;
|
||||||
current = xkb_state_serialize_layout(keyboard->xkb_state,
|
current = xkb_state_serialize_layout(keyboard->xkb_state,
|
||||||
XKB_STATE_LAYOUT_EFFECTIVE);
|
XKB_STATE_LAYOUT_EFFECTIVE);
|
||||||
get_layout_abbr(kb_layout,
|
get_layout_abbr(kb_layout,
|
||||||
xkb_keymap_layout_get_name(keyboard->keymap, current));
|
xkb_keymap_layout_get_name(keyboard->keymap, current));
|
||||||
|
|
||||||
|
|
||||||
zdwl_ipc_output_v2_send_layout(
|
zdwl_ipc_output_v2_send_layout(
|
||||||
ipc_output->resource,
|
ipc_output->resource,
|
||||||
monitor->pertag->ltidxs[monitor->pertag->curtag] - layouts);
|
monitor->pertag->ltidxs[monitor->pertag->curtag] - layouts);
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc,
|
||||||
*pl = l;
|
*pl = l;
|
||||||
}
|
}
|
||||||
|
|
||||||
InputDevice * get_active_keyboard_device(void) {
|
InputDevice *get_active_keyboard_device(void) {
|
||||||
InputDevice *id;
|
InputDevice *id;
|
||||||
wl_list_for_each(id, &inputdevices, link) {
|
wl_list_for_each(id, &inputdevices, link) {
|
||||||
if (id->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) {
|
if (id->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) {
|
||||||
|
|
|
||||||
54
src/mango.c
54
src/mango.c
|
|
@ -786,7 +786,9 @@ static Client *get_scroll_stack_head(Client *c);
|
||||||
static bool client_only_in_one_tag(Client *c);
|
static bool client_only_in_one_tag(Client *c);
|
||||||
static Client *get_focused_stack_client(Client *sc);
|
static Client *get_focused_stack_client(Client *sc);
|
||||||
static bool client_is_in_same_stack(Client *sc, Client *tc, Client *fc);
|
static bool client_is_in_same_stack(Client *sc, Client *tc, Client *fc);
|
||||||
static InputDevice * get_active_keyboard_device(void);
|
static InputDevice *get_active_keyboard_device(void);
|
||||||
|
static bool apply_keyboard_rules(InputDevice *id,
|
||||||
|
struct wlr_keyboard *keyboard);
|
||||||
|
|
||||||
#include "data/static_keymap.h"
|
#include "data/static_keymap.h"
|
||||||
#include "dispatch/bind_declare.h"
|
#include "dispatch/bind_declare.h"
|
||||||
|
|
@ -2560,9 +2562,52 @@ void createidleinhibitor(struct wl_listener *listener, void *data) {
|
||||||
checkidleinhibitor(NULL);
|
checkidleinhibitor(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool apply_keyboard_rules(InputDevice *id, struct wlr_keyboard *keyboard) {
|
||||||
|
int ji = 0;
|
||||||
|
ConfigKeyboardRule *r;
|
||||||
|
bool match_rule = true;
|
||||||
|
|
||||||
|
if (id->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ji = 0; ji < config.keyboard_rules_count; ji++) {
|
||||||
|
if (config.keyboard_rules_count < 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
r = &config.keyboard_rules[ji];
|
||||||
|
|
||||||
|
if (r->vendor != -1) {
|
||||||
|
if (r->vendor != id->vendor) {
|
||||||
|
match_rule = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->product != -1) {
|
||||||
|
if (r->product != id->product) {
|
||||||
|
match_rule = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r->name != NULL) {
|
||||||
|
if (strcmp(r->name, id->name) != 0) {
|
||||||
|
match_rule = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_rule) {
|
||||||
|
wlr_keyboard_set_keymap(keyboard, r->keymap);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void createkeyboard(struct wlr_keyboard *keyboard) {
|
void createkeyboard(struct wlr_keyboard *keyboard) {
|
||||||
|
|
||||||
struct libinput_device *device = NULL;
|
struct libinput_device *device = NULL;
|
||||||
|
bool hit_rule = false;
|
||||||
|
|
||||||
if (wlr_input_device_is_libinput(&keyboard->base) &&
|
if (wlr_input_device_is_libinput(&keyboard->base) &&
|
||||||
(device = wlr_libinput_get_device_handle(&keyboard->base))) {
|
(device = wlr_libinput_get_device_handle(&keyboard->base))) {
|
||||||
|
|
@ -2592,9 +2637,12 @@ void createkeyboard(struct wlr_keyboard *keyboard) {
|
||||||
wl_signal_add(&keyboard->events.key, &input_dev->source_keyboard_key);
|
wl_signal_add(&keyboard->events.key, &input_dev->source_keyboard_key);
|
||||||
|
|
||||||
wl_list_insert(&inputdevices, &input_dev->link);
|
wl_list_insert(&inputdevices, &input_dev->link);
|
||||||
|
|
||||||
|
hit_rule = apply_keyboard_rules(input_dev, keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the keymap to match the group keymap */
|
/* Set the keymap to match the group keymap */
|
||||||
|
if (!hit_rule)
|
||||||
wlr_keyboard_set_keymap(keyboard, kb_group->wlr_group->keyboard.keymap);
|
wlr_keyboard_set_keymap(keyboard, kb_group->wlr_group->keyboard.keymap);
|
||||||
|
|
||||||
wlr_keyboard_notify_modifiers(keyboard, 0, 0, locked_mods, 0);
|
wlr_keyboard_notify_modifiers(keyboard, 0, 0, locked_mods, 0);
|
||||||
|
|
@ -5084,7 +5132,11 @@ void reset_keyboard_layout(void) {
|
||||||
|
|
||||||
struct wlr_keyboard *tkb = (struct wlr_keyboard *)id->device_data;
|
struct wlr_keyboard *tkb = (struct wlr_keyboard *)id->device_data;
|
||||||
|
|
||||||
|
bool hit_rules = apply_keyboard_rules(id, tkb);
|
||||||
|
|
||||||
|
if (!hit_rules)
|
||||||
wlr_keyboard_set_keymap(tkb, keyboard->keymap);
|
wlr_keyboard_set_keymap(tkb, keyboard->keymap);
|
||||||
|
|
||||||
wlr_keyboard_notify_modifiers(tkb, depressed, latched, locked, 0);
|
wlr_keyboard_notify_modifiers(tkb, depressed, latched, locked, 0);
|
||||||
tkb->modifiers.group = 0;
|
tkb->modifiers.group = 0;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue