mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2025-11-02 09:01:43 -05:00
opt: keybaord layout config support hotreload to apply
This commit is contained in:
parent
5560623f40
commit
297356a1ef
3 changed files with 119 additions and 14 deletions
|
|
@ -880,18 +880,26 @@ void parse_config_line(Config *config, const char *line) {
|
||||||
config->drag_tile_to_tile = atoi(value);
|
config->drag_tile_to_tile = atoi(value);
|
||||||
} else if (strcmp(key, "swipe_min_threshold") == 0) {
|
} else if (strcmp(key, "swipe_min_threshold") == 0) {
|
||||||
config->swipe_min_threshold = atoi(value);
|
config->swipe_min_threshold = atoi(value);
|
||||||
} else if (!xkb_rules.rules && strcmp(key, "xkb_rules_rules") == 0) {
|
} else if (strcmp(key, "xkb_rules_rules") == 0) {
|
||||||
xkb_rules.rules = strdup(value);
|
strncpy(xkb_rules_rules, value, sizeof(xkb_rules_rules) - 1);
|
||||||
} else if (!xkb_rules.model && strcmp(key, "xkb_rules_model") == 0) {
|
xkb_rules_rules[sizeof(xkb_rules_rules) - 1] =
|
||||||
xkb_rules.model = strdup(value);
|
'\0'; // 确保字符串以 null 结尾
|
||||||
} else if (!xkb_rules.layout && strcmp(key, "xkb_rules_layout") == 0) {
|
} else if (strcmp(key, "xkb_rules_model") == 0) {
|
||||||
char *new_layouts_str = malloc(256); // 不要释放,只赋值一次
|
strncpy(xkb_rules_model, value, sizeof(xkb_rules_model) - 1);
|
||||||
strcpy(new_layouts_str, value);
|
xkb_rules_model[sizeof(xkb_rules_model) - 1] =
|
||||||
xkb_rules.layout = new_layouts_str;
|
'\0'; // 确保字符串以 null 结尾
|
||||||
} else if (!xkb_rules.variant && strcmp(key, "xkb_rules_variant") == 0) {
|
} else if (strcmp(key, "xkb_rules_layout") == 0) {
|
||||||
xkb_rules.variant = strdup(value);
|
strncpy(xkb_rules_layout, value, sizeof(xkb_rules_layout) - 1);
|
||||||
} else if (!xkb_rules.options && strcmp(key, "xkb_rules_options") == 0) {
|
xkb_rules_layout[sizeof(xkb_rules_layout) - 1] =
|
||||||
xkb_rules.options = strdup(value);
|
'\0'; // 确保字符串以 null 结尾
|
||||||
|
} else if (strcmp(key, "xkb_rules_variant") == 0) {
|
||||||
|
strncpy(xkb_rules_variant, value, sizeof(xkb_rules_variant) - 1);
|
||||||
|
xkb_rules_variant[sizeof(xkb_rules_variant) - 1] =
|
||||||
|
'\0'; // 确保字符串以 null 结尾
|
||||||
|
} else if (strcmp(key, "xkb_rules_options") == 0) {
|
||||||
|
strncpy(xkb_rules_options, value, sizeof(xkb_rules_options) - 1);
|
||||||
|
xkb_rules_options[sizeof(xkb_rules_options) - 1] =
|
||||||
|
'\0'; // 确保字符串以 null 结尾
|
||||||
} else if (strcmp(key, "scroller_proportion_preset") == 0) {
|
} else if (strcmp(key, "scroller_proportion_preset") == 0) {
|
||||||
// 1. 统计 value 中有多少个逗号,确定需要解析的浮点数个数
|
// 1. 统计 value 中有多少个逗号,确定需要解析的浮点数个数
|
||||||
int count = 0; // 初始化为 0
|
int count = 0; // 初始化为 0
|
||||||
|
|
@ -2230,6 +2238,7 @@ void reload_config(const Arg *arg) {
|
||||||
parse_config();
|
parse_config();
|
||||||
init_baked_points();
|
init_baked_points();
|
||||||
handlecursoractivity();
|
handlecursoractivity();
|
||||||
|
reset_keyboard_layout();
|
||||||
run_exec();
|
run_exec();
|
||||||
|
|
||||||
// reset border width when config change
|
// reset border width when config change
|
||||||
|
|
|
||||||
|
|
@ -102,13 +102,25 @@ Layout layouts[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* keyboard */
|
/* keyboard */
|
||||||
|
|
||||||
|
/*
|
||||||
|
only layout can modify after fisrt init
|
||||||
|
other fields change will be ignored.
|
||||||
|
*/
|
||||||
|
char xkb_rules_rules[256];
|
||||||
|
char xkb_rules_model[256];
|
||||||
|
char xkb_rules_layout[256];
|
||||||
|
char xkb_rules_variant[256];
|
||||||
|
char xkb_rules_options[256];
|
||||||
|
|
||||||
struct xkb_rule_names xkb_rules = {
|
struct xkb_rule_names xkb_rules = {
|
||||||
/* can specify fields: rules, model, layout, variant, options */
|
/* can specify fields: rules, model, layout, variant, options */
|
||||||
/* example:
|
/* example:
|
||||||
.options = "ctrl:nocaps",
|
.options = "ctrl:nocaps",
|
||||||
*/
|
*/
|
||||||
.rules = NULL, .model = NULL, .layout = NULL,
|
.rules = xkb_rules_rules, .model = xkb_rules_model,
|
||||||
.variant = NULL, .options = NULL,
|
.layout = xkb_rules_layout, .variant = xkb_rules_variant,
|
||||||
|
.options = xkb_rules_options,
|
||||||
};
|
};
|
||||||
|
|
||||||
int repeat_rate = 25;
|
int repeat_rate = 25;
|
||||||
|
|
|
||||||
84
src/maomao.c
84
src/maomao.c
|
|
@ -650,6 +650,7 @@ static Client *center_select(Monitor *m);
|
||||||
static void handlecursoractivity(void);
|
static void handlecursoractivity(void);
|
||||||
static int hidecursor(void *data);
|
static int hidecursor(void *data);
|
||||||
static bool check_hit_no_border(Client *c);
|
static bool check_hit_no_border(Client *c);
|
||||||
|
static void reset_keyboard_layout(void);
|
||||||
|
|
||||||
#include "data/static_keymap.h"
|
#include "data/static_keymap.h"
|
||||||
#include "dispatch/dispatch.h"
|
#include "dispatch/dispatch.h"
|
||||||
|
|
@ -5797,6 +5798,89 @@ char *get_layout_abbr(const char *full_name) {
|
||||||
return strdup("xx");
|
return strdup("xx");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset_keyboard_layout(void) {
|
||||||
|
if (!kb_group || !kb_group->wlr_group || !seat) {
|
||||||
|
wlr_log(WLR_ERROR, "Invalid keyboard group or seat");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_keyboard *keyboard = &kb_group->wlr_group->keyboard;
|
||||||
|
if (!keyboard || !keyboard->keymap) {
|
||||||
|
wlr_log(WLR_ERROR, "Invalid keyboard or keymap");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current layout
|
||||||
|
xkb_layout_index_t current = xkb_state_serialize_layout(
|
||||||
|
keyboard->xkb_state, XKB_STATE_LAYOUT_EFFECTIVE);
|
||||||
|
const int num_layouts = xkb_keymap_num_layouts(keyboard->keymap);
|
||||||
|
if (num_layouts < 1) {
|
||||||
|
wlr_log(WLR_INFO, "No layouts available");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create context
|
||||||
|
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
|
if (!context) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to create XKB context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get layout abbreviations
|
||||||
|
char **layout_ids = calloc(num_layouts, sizeof(char *));
|
||||||
|
if (!layout_ids) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to allocate layout IDs");
|
||||||
|
goto cleanup_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < num_layouts; i++) {
|
||||||
|
layout_ids[i] =
|
||||||
|
get_layout_abbr(xkb_keymap_layout_get_name(keyboard->keymap, i));
|
||||||
|
if (!layout_ids[i]) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to get layout abbreviation");
|
||||||
|
goto cleanup_layouts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep the same rules but just reapply them
|
||||||
|
struct xkb_rule_names rules = xkb_rules;
|
||||||
|
|
||||||
|
// Create new keymap with current rules
|
||||||
|
struct xkb_keymap *new_keymap =
|
||||||
|
xkb_keymap_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
if (!new_keymap) {
|
||||||
|
wlr_log(WLR_ERROR, "Failed to create keymap for layouts: %s",
|
||||||
|
rules.layout);
|
||||||
|
goto cleanup_layouts;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the same keymap (this will reset the layout state)
|
||||||
|
uint32_t depressed = keyboard->modifiers.depressed;
|
||||||
|
uint32_t latched = keyboard->modifiers.latched;
|
||||||
|
uint32_t locked = keyboard->modifiers.locked;
|
||||||
|
|
||||||
|
wlr_keyboard_set_keymap(keyboard, new_keymap);
|
||||||
|
|
||||||
|
wlr_keyboard_notify_modifiers(keyboard, depressed, latched, locked, 0);
|
||||||
|
keyboard->modifiers.group = current; // Keep the same layout index
|
||||||
|
|
||||||
|
// Update seat
|
||||||
|
wlr_seat_set_keyboard(seat, keyboard);
|
||||||
|
wlr_seat_keyboard_notify_modifiers(seat, &keyboard->modifiers);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
xkb_keymap_unref(new_keymap);
|
||||||
|
|
||||||
|
cleanup_layouts:
|
||||||
|
for (int i = 0; i < num_layouts; i++) {
|
||||||
|
free(layout_ids[i]);
|
||||||
|
}
|
||||||
|
free(layout_ids);
|
||||||
|
|
||||||
|
cleanup_context:
|
||||||
|
xkb_context_unref(context);
|
||||||
|
}
|
||||||
|
|
||||||
void switch_keyboard_layout(const Arg *arg) {
|
void switch_keyboard_layout(const Arg *arg) {
|
||||||
if (!kb_group || !kb_group->wlr_group || !seat) {
|
if (!kb_group || !kb_group->wlr_group || !seat) {
|
||||||
wlr_log(WLR_ERROR, "Invalid keyboard group or seat");
|
wlr_log(WLR_ERROR, "Invalid keyboard group or seat");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue