mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-03-30 11:11:14 -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
|
||||
} ConfigMonitorRule;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int32_t vendor, product;
|
||||
struct xkb_keymap *keymap;
|
||||
struct xkb_context *ctx;
|
||||
} ConfigKeyboardRule;
|
||||
|
||||
// 修改后的宏定义
|
||||
#define CHVT(n) \
|
||||
{ \
|
||||
|
|
@ -321,6 +328,9 @@ typedef struct {
|
|||
ConfigMonitorRule *monitor_rules; // 动态数组
|
||||
int32_t monitor_rules_count; // 条数
|
||||
|
||||
ConfigKeyboardRule *keyboard_rules; // 动态数组
|
||||
int32_t keyboard_rules_count; // 条数
|
||||
|
||||
KeyBinding *key_bindings;
|
||||
int32_t key_bindings_count;
|
||||
|
||||
|
|
@ -1840,6 +1850,113 @@ bool parse_option(Config *config, char *key, char *value) {
|
|||
|
||||
config->monitor_rules_count++;
|
||||
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) {
|
||||
config->tag_rules =
|
||||
realloc(config->tag_rules,
|
||||
|
|
@ -2976,6 +3093,21 @@ void free_config(void) {
|
|||
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
|
||||
if (config.layer_rules) {
|
||||
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.monitor_rules = NULL;
|
||||
config.monitor_rules_count = 0;
|
||||
config.keyboard_rules = NULL;
|
||||
config.keyboard_rules_count = 0;
|
||||
config.key_bindings = NULL;
|
||||
config.key_bindings_count = 0;
|
||||
config.mouse_bindings = NULL;
|
||||
|
|
|
|||
|
|
@ -150,20 +150,20 @@ void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output) {
|
|||
}
|
||||
|
||||
active_kb = get_active_keyboard_device();
|
||||
if(active_kb) {
|
||||
sprintf(active_kb_name, "vendor:%d,product:%d,name:%s", active_kb->vendor, active_kb->product, active_kb->name);
|
||||
if (active_kb) {
|
||||
sprintf(active_kb_name, "vendor:%d,product:%d,name:%s",
|
||||
active_kb->vendor, active_kb->product, active_kb->name);
|
||||
} else {
|
||||
sprintf(active_kb_name, "-1 -1 unknown");
|
||||
}
|
||||
|
||||
|
||||
keyboard = active_kb ? (struct wlr_keyboard*)active_kb->device_data: &kb_group->wlr_group->keyboard;
|
||||
keyboard = active_kb ? (struct wlr_keyboard *)active_kb->device_data
|
||||
: &kb_group->wlr_group->keyboard;
|
||||
current = xkb_state_serialize_layout(keyboard->xkb_state,
|
||||
XKB_STATE_LAYOUT_EFFECTIVE);
|
||||
get_layout_abbr(kb_layout,
|
||||
xkb_keymap_layout_get_name(keyboard->keymap, current));
|
||||
|
||||
|
||||
zdwl_ipc_output_v2_send_layout(
|
||||
ipc_output->resource,
|
||||
monitor->pertag->ltidxs[monitor->pertag->curtag] - layouts);
|
||||
|
|
|
|||
|
|
@ -129,13 +129,13 @@ void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc,
|
|||
*pl = l;
|
||||
}
|
||||
|
||||
InputDevice * get_active_keyboard_device(void) {
|
||||
InputDevice *get_active_keyboard_device(void) {
|
||||
InputDevice *id;
|
||||
wl_list_for_each(id, &inputdevices, link) {
|
||||
if (id->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (id->isactivate) {
|
||||
return id;
|
||||
}
|
||||
|
|
|
|||
58
src/mango.c
58
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 Client *get_focused_stack_client(Client *sc);
|
||||
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 "dispatch/bind_declare.h"
|
||||
|
|
@ -2560,9 +2562,52 @@ void createidleinhibitor(struct wl_listener *listener, void *data) {
|
|||
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) {
|
||||
|
||||
struct libinput_device *device = NULL;
|
||||
bool hit_rule = false;
|
||||
|
||||
if (wlr_input_device_is_libinput(&keyboard->base) &&
|
||||
(device = wlr_libinput_get_device_handle(&keyboard->base))) {
|
||||
|
|
@ -2592,10 +2637,13 @@ void createkeyboard(struct wlr_keyboard *keyboard) {
|
|||
wl_signal_add(&keyboard->events.key, &input_dev->source_keyboard_key);
|
||||
|
||||
wl_list_insert(&inputdevices, &input_dev->link);
|
||||
|
||||
hit_rule = apply_keyboard_rules(input_dev, keyboard);
|
||||
}
|
||||
|
||||
/* Set the keymap to match the group keymap */
|
||||
wlr_keyboard_set_keymap(keyboard, kb_group->wlr_group->keyboard.keymap);
|
||||
if (!hit_rule)
|
||||
wlr_keyboard_set_keymap(keyboard, kb_group->wlr_group->keyboard.keymap);
|
||||
|
||||
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;
|
||||
|
||||
wlr_keyboard_set_keymap(tkb, keyboard->keymap);
|
||||
bool hit_rules = apply_keyboard_rules(id, tkb);
|
||||
|
||||
if (!hit_rules)
|
||||
wlr_keyboard_set_keymap(tkb, keyboard->keymap);
|
||||
|
||||
wlr_keyboard_notify_modifiers(tkb, depressed, latched, locked, 0);
|
||||
tkb->modifiers.group = 0;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue