diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 7ad3d0f..664048e 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -846,83 +846,20 @@ int switch_keyboard_layout(const Arg *arg) { 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; + const char *current_layout = xkb_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); + struct xkb_keymap *new_keymap = xkb_keymap_new_from_names( + context, &xkb_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; + xkb_rules.layout); + goto cleanup_context; } // 6. 应用新 keymap @@ -931,22 +868,34 @@ int switch_keyboard_layout(const Arg *arg) { unsigned int locked = keyboard->modifiers.locked; wlr_keyboard_set_keymap(keyboard, new_keymap); - wlr_keyboard_notify_modifiers(keyboard, depressed, latched, locked, 0); + wlr_keyboard_notify_modifiers(keyboard, depressed, latched, locked, next); keyboard->modifiers.group = 0; // 7. 更新 seat wlr_seat_set_keyboard(seat, keyboard); wlr_seat_keyboard_notify_modifiers(seat, &keyboard->modifiers); + InputDevice *id; + wl_list_for_each(id, &inputdevices, link) { + if (id->wlr_device->type != WLR_INPUT_DEVICE_KEYBOARD) { + continue; + } + + keyboard = (struct wlr_keyboard *)id->device_data; + + wlr_keyboard_set_keymap(keyboard, new_keymap); + wlr_keyboard_notify_modifiers(keyboard, depressed, latched, locked, + next); + 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); diff --git a/src/mango.c b/src/mango.c index 26e3167..3d0ef1a 100644 --- a/src/mango.c +++ b/src/mango.c @@ -697,7 +697,6 @@ static void resize_tile_client(Client *grabc, bool isdrag, int offsetx, int offsety, unsigned int time); static void refresh_monitors_workspaces_status(Monitor *m); static void init_client_properties(Client *c); -static bool check_keyboard_rules_validate(struct xkb_rule_names *rules); #include "data/static_keymap.h" #include "dispatch/bind_declare.h" @@ -2323,18 +2322,9 @@ KeyboardGroup *createkeyboardgroup(void) { group->wlr_group = wlr_keyboard_group_create(); 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. */ 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))) die("failed to compile keymap"); @@ -4477,49 +4467,6 @@ void setgaps(int oh, int ov, int ih, int iv) { 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) { if (!kb_group || !kb_group->wlr_group || !seat) { wlr_log(WLR_ERROR, "Invalid keyboard group or seat"); @@ -4541,16 +4488,6 @@ void reset_keyboard_layout(void) { 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 struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (!context) { @@ -4559,8 +4496,8 @@ void reset_keyboard_layout(void) { } // 现在安全地创建真正的keymap - struct xkb_keymap *new_keymap = - xkb_keymap_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); + struct xkb_keymap *new_keymap = xkb_keymap_new_from_names( + context, &xkb_rules, XKB_KEYMAP_COMPILE_NO_FLAGS); if (!new_keymap) { // 理论上这里不应该失败,因为前面已经验证过了 wlr_log(WLR_ERROR,