break change: remove switch_keyboard_layout dispatch

This commit is contained in:
DreamMaoMao 2025-11-01 19:06:04 +08:00
parent f06dc505e3
commit e03be59c80
4 changed files with 3 additions and 206 deletions

View file

@ -911,8 +911,6 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value,
(*arg).v = strdup(arg_value); (*arg).v = strdup(arg_value);
} else if (strcmp(func_name, "switch_layout") == 0) { } else if (strcmp(func_name, "switch_layout") == 0) {
func = switch_layout; func = switch_layout;
} else if (strcmp(func_name, "switch_keyboard_layout") == 0) {
func = switch_keyboard_layout;
} else if (strcmp(func_name, "togglefloating") == 0) { } else if (strcmp(func_name, "togglefloating") == 0) {
func = togglefloating; func = togglefloating;
} else if (strcmp(func_name, "togglefullscreen") == 0) { } else if (strcmp(func_name, "togglefullscreen") == 0) {

View file

@ -27,7 +27,6 @@ int spawn_on_empty(const Arg *arg);
int setkeymode(const Arg *arg); int setkeymode(const Arg *arg);
int setlayout(const Arg *arg); int setlayout(const Arg *arg);
int switch_layout(const Arg *arg); int switch_layout(const Arg *arg);
int switch_keyboard_layout(const Arg *arg);
int setmfact(const Arg *arg); int setmfact(const Arg *arg);
int quit(const Arg *arg); int quit(const Arg *arg);
int moveresize(const Arg *arg); int moveresize(const Arg *arg);

View file

@ -817,143 +817,6 @@ int spawn_on_empty(const Arg *arg) {
return 0; return 0;
} }
int switch_keyboard_layout(const Arg *arg) {
if (!kb_group || !kb_group->wlr_group || !seat) {
wlr_log(WLR_ERROR, "Invalid keyboard group or seat");
return 0;
}
struct wlr_keyboard *keyboard = &kb_group->wlr_group->keyboard;
if (!keyboard || !keyboard->keymap) {
wlr_log(WLR_ERROR, "Invalid keyboard or keymap");
return 0;
}
// 1. 获取当前布局和计算下一个布局
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 < 2) {
wlr_log(WLR_INFO, "Only one layout available");
return 0;
}
xkb_layout_index_t next = (current + 1) % num_layouts;
// 2. 创建上下文
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (!context) {
wlr_log(WLR_ERROR, "Failed to create XKB context");
return 0;
}
// 3. 分配并获取布局缩写
const 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;
}
}
// 4. 安全地处理 rules.layout
struct xkb_rule_names rules = xkb_rules;
// 验证规则是否有效
if (!check_keyboard_rules_validate(&rules)) {
wlr_log(WLR_ERROR,
"Keyboard rules validation failed, skipping layout reset");
rules = xkb_default_rules;
}
// 安全地处理 layout 字符串
const char *current_layout = rules.layout;
if (!current_layout || strlen(current_layout) == 0) {
wlr_log(WLR_INFO, "Using default layout 'us'");
current_layout = "us";
}
// 创建足够大的缓冲区来构建新的布局字符串
unsigned int layout_buf_size =
1024; // 使用固定大小避免依赖可能为NULL的字符串
char *layout_buf = calloc(layout_buf_size, sizeof(char));
if (!layout_buf) {
wlr_log(WLR_ERROR, "Failed to allocate layout buffer");
goto cleanup_layouts;
}
// 构建新的布局字符串
for (int i = 0; i < num_layouts; i++) {
const char *layout = layout_ids[(next + i) % num_layouts];
if (!layout)
continue;
if (i > 0) {
strncat(layout_buf, ",", layout_buf_size - strlen(layout_buf) - 1);
}
if (strchr(layout, ',')) {
// 处理包含逗号的布局名
char *quoted = malloc(strlen(layout) + 3);
if (quoted) {
snprintf(quoted, strlen(layout) + 3, "\"%s\"", layout);
strncat(layout_buf, quoted,
layout_buf_size - strlen(layout_buf) - 1);
free(quoted);
}
} else {
strncat(layout_buf, layout,
layout_buf_size - strlen(layout_buf) - 1);
}
}
// 更新 rules 结构体
rules.layout = layout_buf;
// 5. 创建新 keymap
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_layout_buf;
}
// 6. 应用新 keymap
unsigned int depressed = keyboard->modifiers.depressed;
unsigned int latched = keyboard->modifiers.latched;
unsigned int locked = keyboard->modifiers.locked;
wlr_keyboard_set_keymap(keyboard, new_keymap);
wlr_keyboard_notify_modifiers(keyboard, depressed, latched, locked, 0);
keyboard->modifiers.group = 0;
// 7. 更新 seat
wlr_seat_set_keyboard(seat, keyboard);
wlr_seat_keyboard_notify_modifiers(seat, &keyboard->modifiers);
// 8. 清理资源
xkb_keymap_unref(new_keymap);
cleanup_layout_buf:
free(layout_buf);
cleanup_layouts:
free(layout_ids);
cleanup_context:
xkb_context_unref(context);
printstatus();
return 0;
}
int switch_layout(const Arg *arg) { int switch_layout(const Arg *arg) {
int jk, ji; int jk, ji;

View file

@ -697,7 +697,6 @@ static void resize_tile_client(Client *grabc, bool isdrag, int offsetx,
int offsety, unsigned int time); int offsety, unsigned int time);
static void refresh_monitors_workspaces_status(Monitor *m); static void refresh_monitors_workspaces_status(Monitor *m);
static void init_client_properties(Client *c); static void init_client_properties(Client *c);
static bool check_keyboard_rules_validate(struct xkb_rule_names *rules);
#include "data/static_keymap.h" #include "data/static_keymap.h"
#include "dispatch/bind_declare.h" #include "dispatch/bind_declare.h"
@ -2323,18 +2322,9 @@ KeyboardGroup *createkeyboardgroup(void) {
group->wlr_group = wlr_keyboard_group_create(); group->wlr_group = wlr_keyboard_group_create();
group->wlr_group->data = group; group->wlr_group->data = group;
// 4. 直接修改 rules.layout保持原有逻辑
struct xkb_rule_names rules = xkb_rules;
// 验证规则是否有效
if (!check_keyboard_rules_validate(&rules)) {
wlr_log(WLR_ERROR,
"Keyboard rules validation failed, skipping layout reset");
rules = xkb_default_rules;
}
/* Prepare an XKB keymap and assign it to the keyboard group. */ /* Prepare an XKB keymap and assign it to the keyboard group. */
context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (!(keymap = xkb_keymap_new_from_names(context, &rules, if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules,
XKB_KEYMAP_COMPILE_NO_FLAGS))) XKB_KEYMAP_COMPILE_NO_FLAGS)))
die("failed to compile keymap"); die("failed to compile keymap");
@ -4477,49 +4467,6 @@ void setgaps(int oh, int ov, int ih, int iv) {
arrange(selmon, false); arrange(selmon, false);
} }
// 验证键盘规则是否有效
bool check_keyboard_rules_validate(struct xkb_rule_names *rules) {
if (!rules) {
wlr_log(WLR_ERROR, "Keyboard rules are NULL");
return false;
}
if (!rules->layout || strlen(rules->layout) == 0)
return false;
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (!context) {
wlr_log(WLR_ERROR, "Failed to create XKB context for validation");
return false;
}
bool valid = false;
struct xkb_keymap *test_keymap =
xkb_keymap_new_from_names(context, rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
if (test_keymap) {
// 检查keymap是否至少有一个布局
if (xkb_keymap_num_layouts(test_keymap) > 0) {
valid = true;
} else {
wlr_log(WLR_ERROR, "Keymap has no layouts");
}
xkb_keymap_unref(test_keymap);
} else {
wlr_log(WLR_ERROR,
"Invalid keyboard rules: rules=%s, model=%s, layout=%s, "
"variant=%s, options=%s",
rules->rules ? rules->rules : "NULL",
rules->model ? rules->model : "NULL",
rules->layout ? rules->layout : "NULL",
rules->variant ? rules->variant : "NULL",
rules->options ? rules->options : "NULL");
}
xkb_context_unref(context);
return valid;
}
void reset_keyboard_layout(void) { void reset_keyboard_layout(void) {
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");
@ -4541,16 +4488,6 @@ void reset_keyboard_layout(void) {
return; return;
} }
// Keep the same rules but just reapply them
struct xkb_rule_names rules = xkb_rules;
// 验证规则是否有效
if (!check_keyboard_rules_validate(&rules)) {
wlr_log(WLR_ERROR,
"Keyboard rules validation failed, skipping layout reset");
rules = xkb_default_rules;
}
// Create context // Create context
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (!context) { if (!context) {
@ -4559,8 +4496,8 @@ void reset_keyboard_layout(void) {
} }
// 现在安全地创建真正的keymap // 现在安全地创建真正的keymap
struct xkb_keymap *new_keymap = struct xkb_keymap *new_keymap = xkb_keymap_new_from_names(
xkb_keymap_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); context, &xkb_rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
if (!new_keymap) { if (!new_keymap) {
// 理论上这里不应该失败,因为前面已经验证过了 // 理论上这里不应该失败,因为前面已经验证过了
wlr_log(WLR_ERROR, wlr_log(WLR_ERROR,