mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-07-06 00:06:43 -04:00
Merge 7b36f7990d into ce32e929b9
This commit is contained in:
commit
3734d5f54b
5 changed files with 142 additions and 2 deletions
|
|
@ -83,6 +83,10 @@ repeat_delay=600
|
|||
numlockon=0
|
||||
xkb_rules_layout=us
|
||||
|
||||
# per-device keyboard rules: override xkb layout for specific keyboards
|
||||
# keyboardrule=name:ErgoDox EZ,xkb_layout:us,xkb_variant:colemak
|
||||
# keyboardrule=name:Keychron,xkb_rules:evdev,xkb_layout:us,xkb_variant:dvorak
|
||||
|
||||
# Trackpad
|
||||
# need relogin to make it apply
|
||||
disable_trackpad=0
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ c_args = [
|
|||
'-g',
|
||||
'-Wno-unused-function',
|
||||
'-DWLR_USE_UNSTABLE',
|
||||
'-D_GNU_SOURCE',
|
||||
'-D_POSIX_C_SOURCE=200809L',
|
||||
'-DVERSION="@0@"'.format(version_with_hash),
|
||||
'-DSYSCONFDIR="@0@"'.format('/etc'),
|
||||
|
|
|
|||
|
|
@ -180,6 +180,15 @@ typedef struct {
|
|||
int32_t noanim;
|
||||
} ConfigLayerRule;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *xkb_rules;
|
||||
char *xkb_model;
|
||||
char *xkb_layout;
|
||||
char *xkb_variant;
|
||||
char *xkb_options;
|
||||
} ConfigKeyboardRule;
|
||||
|
||||
typedef struct {
|
||||
int32_t animations;
|
||||
int32_t layer_animations;
|
||||
|
|
@ -334,6 +343,9 @@ typedef struct {
|
|||
ConfigLayerRule *layer_rules; // 动态数组
|
||||
int32_t layer_rules_count; // 数量
|
||||
|
||||
ConfigKeyboardRule *keyboard_rules;
|
||||
int32_t keyboard_rules_count;
|
||||
|
||||
ConfigWinRule *window_rules;
|
||||
int32_t window_rules_count;
|
||||
|
||||
|
|
@ -400,6 +412,18 @@ bool apply_rule_to_state(Monitor *m, const ConfigMonitorRule *rule,
|
|||
struct wlr_output_state *state, int vrr, int custom);
|
||||
bool monitor_matches_rule(Monitor *m, const ConfigMonitorRule *rule);
|
||||
|
||||
// Find matching keyboard rule by device name (substring match, case-insensitive)
|
||||
static inline ConfigKeyboardRule *find_keyboard_rule(Config *cfg, const char *device_name) {
|
||||
if (!device_name || !cfg->keyboard_rules)
|
||||
return NULL;
|
||||
for (int32_t i = 0; i < cfg->keyboard_rules_count; i++) {
|
||||
if (cfg->keyboard_rules[i].name &&
|
||||
strcasestr(device_name, cfg->keyboard_rules[i].name))
|
||||
return &cfg->keyboard_rules[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Helper function to trim whitespace from start and end of a string
|
||||
void trim_whitespace(char *str) {
|
||||
if (str == NULL || *str == '\0')
|
||||
|
|
@ -2240,6 +2264,67 @@ bool parse_option(Config *config, char *key, char *value) {
|
|||
|
||||
config->layer_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));
|
||||
|
||||
char *saveptr;
|
||||
char *param = strtok_r(value, ",", &saveptr);
|
||||
bool parse_error = false;
|
||||
while (param != NULL) {
|
||||
trim_whitespace(param);
|
||||
char *eq = strchr(param, ':');
|
||||
if (eq != NULL) {
|
||||
*eq = '\0';
|
||||
char *sub_key = param;
|
||||
char *sub_value = eq + 1;
|
||||
trim_whitespace(sub_key);
|
||||
trim_whitespace(sub_value);
|
||||
if (strcmp(sub_key, "name") == 0) {
|
||||
rule->name = strdup(sub_value);
|
||||
} else if (strcmp(sub_key, "xkb_rules") == 0) {
|
||||
rule->xkb_rules = strdup(sub_value);
|
||||
} else if (strcmp(sub_key, "xkb_model") == 0) {
|
||||
rule->xkb_model = strdup(sub_value);
|
||||
} else if (strcmp(sub_key, "xkb_layout") == 0) {
|
||||
rule->xkb_layout = strdup(sub_value);
|
||||
} else if (strcmp(sub_key, "xkb_variant") == 0) {
|
||||
rule->xkb_variant = strdup(sub_value);
|
||||
} else if (strcmp(sub_key, "xkb_options") == 0) {
|
||||
rule->xkb_options = strdup(sub_value);
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Unknown keyboardrule "
|
||||
"parameter: %s\n", sub_key);
|
||||
}
|
||||
*eq = ':';
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m Malformed keyboardrule "
|
||||
"parameter: %s\n", param);
|
||||
parse_error = true;
|
||||
}
|
||||
param = strtok_r(NULL, ",", &saveptr);
|
||||
}
|
||||
|
||||
if (rule->name == NULL) {
|
||||
fprintf(stderr,
|
||||
"\033[1m\033[31m[ERROR]:\033[33m keyboardrule requires name\n");
|
||||
parse_error = true;
|
||||
}
|
||||
|
||||
config->keyboard_rules_count++;
|
||||
return !parse_error;
|
||||
} else if (strcmp(key, "windowrule") == 0) {
|
||||
config->window_rules =
|
||||
realloc(config->window_rules,
|
||||
|
|
@ -3261,6 +3346,27 @@ void free_config(void) {
|
|||
config.layer_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].xkb_rules)
|
||||
free((void *)config.keyboard_rules[i].xkb_rules);
|
||||
if (config.keyboard_rules[i].xkb_model)
|
||||
free((void *)config.keyboard_rules[i].xkb_model);
|
||||
if (config.keyboard_rules[i].xkb_layout)
|
||||
free((void *)config.keyboard_rules[i].xkb_layout);
|
||||
if (config.keyboard_rules[i].xkb_variant)
|
||||
free((void *)config.keyboard_rules[i].xkb_variant);
|
||||
if (config.keyboard_rules[i].xkb_options)
|
||||
free((void *)config.keyboard_rules[i].xkb_options);
|
||||
}
|
||||
free(config.keyboard_rules);
|
||||
config.keyboard_rules = NULL;
|
||||
config.keyboard_rules_count = 0;
|
||||
}
|
||||
|
||||
// 释放 env
|
||||
if (config.env) {
|
||||
for (int32_t i = 0; i < config.env_count; i++) {
|
||||
|
|
|
|||
|
|
@ -1041,6 +1041,8 @@ int32_t switch_keyboard_layout(const Arg *arg) {
|
|||
if (id->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) {
|
||||
continue;
|
||||
}
|
||||
if (id->has_custom_keymap)
|
||||
continue;
|
||||
|
||||
struct wlr_keyboard *tkb = (struct wlr_keyboard *)id->device_data;
|
||||
|
||||
|
|
|
|||
27
src/mango.c
27
src/mango.c
|
|
@ -274,6 +274,7 @@ typedef struct {
|
|||
struct libinput_device *libinput_device;
|
||||
struct wl_listener destroy_listener;
|
||||
void *device_data;
|
||||
bool has_custom_keymap;
|
||||
} InputDevice;
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -3043,6 +3044,7 @@ void createidleinhibitor(struct wl_listener *listener, void *data) {
|
|||
void createkeyboard(struct wlr_keyboard *keyboard) {
|
||||
|
||||
struct libinput_device *device = NULL;
|
||||
bool has_custom = false;
|
||||
|
||||
if (wlr_input_device_is_libinput(&keyboard->base) &&
|
||||
(device = wlr_libinput_get_device_handle(&keyboard->base))) {
|
||||
|
|
@ -3057,8 +3059,31 @@ void createkeyboard(struct wlr_keyboard *keyboard) {
|
|||
&input_dev->destroy_listener);
|
||||
|
||||
wl_list_insert(&inputdevices, &input_dev->link);
|
||||
|
||||
ConfigKeyboardRule *rule =
|
||||
find_keyboard_rule(&config, libinput_device_get_name(device));
|
||||
if (rule && (rule->xkb_layout || rule->xkb_variant || rule->xkb_options)) {
|
||||
struct xkb_rule_names rules = {
|
||||
.rules = rule->xkb_rules ? rule->xkb_rules : config.xkb_rules.rules,
|
||||
.model = rule->xkb_model ? rule->xkb_model : config.xkb_rules.model,
|
||||
.layout = rule->xkb_layout,
|
||||
.variant = rule->xkb_variant,
|
||||
.options = rule->xkb_options ? rule->xkb_options : config.xkb_rules.options,
|
||||
};
|
||||
struct xkb_context *ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
struct xkb_keymap *custom_keymap =
|
||||
xkb_keymap_new_from_names(ctx, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
if (custom_keymap) {
|
||||
wlr_keyboard_set_keymap(keyboard, custom_keymap);
|
||||
xkb_keymap_unref(custom_keymap);
|
||||
has_custom = true;
|
||||
input_dev->has_custom_keymap = true;
|
||||
}
|
||||
xkb_context_unref(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_custom)
|
||||
/* Set the keymap to match the group keymap */
|
||||
wlr_keyboard_set_keymap(keyboard, kb_group->wlr_group->keyboard.keymap);
|
||||
|
||||
|
|
@ -5724,6 +5749,8 @@ void reset_keyboard_layout(void) {
|
|||
if (id->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) {
|
||||
continue;
|
||||
}
|
||||
if (id->has_custom_keymap)
|
||||
continue;
|
||||
|
||||
struct wlr_keyboard *tkb = (struct wlr_keyboard *)id->device_data;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue