mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2025-10-29 05:40:21 -04:00
Compare commits
8 commits
5429b723f6
...
3fa306fc19
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3fa306fc19 | ||
|
|
bf6644c9f5 | ||
|
|
25067738ed | ||
|
|
a31b95b349 | ||
|
|
e9565f88f6 | ||
|
|
776738cc28 | ||
|
|
5e8c5c8732 | ||
|
|
f7379f625d |
6 changed files with 271 additions and 45 deletions
|
|
@ -86,7 +86,7 @@ drag_tile_to_tile=1
|
|||
# keyboard
|
||||
repeat_rate=25
|
||||
repeat_delay=600
|
||||
numlockon=1
|
||||
numlockon=0
|
||||
xkb_rules_layout=us
|
||||
|
||||
# Trackpad
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
project('mango', ['c', 'cpp'],
|
||||
version : '0.10.2',
|
||||
version : '0.10.3',
|
||||
)
|
||||
|
||||
subdir('protocols')
|
||||
|
|
|
|||
|
|
@ -20,9 +20,15 @@ enum { NUM_TYPE_MINUS, NUM_TYPE_PLUS, NUM_TYPE_DEFAULT };
|
|||
|
||||
enum { KEY_TYPE_SYM, KEY_TYPE_CODE };
|
||||
|
||||
typedef struct {
|
||||
uint32_t keycode1;
|
||||
uint32_t keycode2;
|
||||
uint32_t keycode3;
|
||||
} MultiKeycode;
|
||||
|
||||
typedef struct {
|
||||
xkb_keysym_t keysym;
|
||||
uint32_t keycode;
|
||||
MultiKeycode keycode;
|
||||
int type;
|
||||
} KeySymCode;
|
||||
|
||||
|
|
@ -325,6 +331,8 @@ typedef struct {
|
|||
|
||||
char keymode[28];
|
||||
|
||||
struct xkb_context *ctx;
|
||||
struct xkb_keymap *keymap;
|
||||
} Config;
|
||||
|
||||
typedef int (*FuncType)(const Arg *);
|
||||
|
|
@ -613,23 +621,120 @@ uint32_t parse_mod(const char *mod_str) {
|
|||
return mod;
|
||||
}
|
||||
|
||||
KeySymCode parse_key(const char *key_str) {
|
||||
KeySymCode kc;
|
||||
// 定义辅助函数:在 keymap 中查找 keysym 对应的多个 keycode
|
||||
static int find_keycodes_for_keysym(struct xkb_keymap *keymap, xkb_keysym_t sym,
|
||||
MultiKeycode *multi_kc) {
|
||||
xkb_keycode_t min_keycode = xkb_keymap_min_keycode(keymap);
|
||||
xkb_keycode_t max_keycode = xkb_keymap_max_keycode(keymap);
|
||||
|
||||
multi_kc->keycode1 = 0;
|
||||
multi_kc->keycode2 = 0;
|
||||
multi_kc->keycode3 = 0;
|
||||
|
||||
int found_count = 0;
|
||||
|
||||
for (xkb_keycode_t keycode = min_keycode;
|
||||
keycode <= max_keycode && found_count < 3; keycode++) {
|
||||
// 使用布局0和层级0
|
||||
const xkb_keysym_t *syms;
|
||||
int num_syms =
|
||||
xkb_keymap_key_get_syms_by_level(keymap, keycode, 0, 0, &syms);
|
||||
|
||||
for (int i = 0; i < num_syms; i++) {
|
||||
if (syms[i] == sym) {
|
||||
switch (found_count) {
|
||||
case 0:
|
||||
multi_kc->keycode1 = keycode;
|
||||
break;
|
||||
case 1:
|
||||
multi_kc->keycode2 = keycode;
|
||||
break;
|
||||
case 2:
|
||||
multi_kc->keycode3 = keycode;
|
||||
break;
|
||||
}
|
||||
found_count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found_count;
|
||||
}
|
||||
|
||||
void cleanup_config_keymap(void) {
|
||||
if (config.keymap != NULL) {
|
||||
xkb_keymap_unref(config.keymap);
|
||||
config.keymap = NULL;
|
||||
}
|
||||
if (config.ctx != NULL) {
|
||||
xkb_context_unref(config.ctx);
|
||||
config.ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void create_config_keymap(void) {
|
||||
// 初始化 xkb 上下文和 keymap
|
||||
|
||||
if (config.ctx == NULL) {
|
||||
config.ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
}
|
||||
|
||||
if (config.keymap == NULL) {
|
||||
config.keymap = xkb_keymap_new_from_names(
|
||||
config.ctx, &xkb_fallback_rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
}
|
||||
}
|
||||
|
||||
KeySymCode parse_key(const char *key_str, bool isbindsym) {
|
||||
KeySymCode kc = {0}; // 初始化为0
|
||||
|
||||
if (config.keymap == NULL || config.ctx == NULL) {
|
||||
// 处理错误
|
||||
kc.type = KEY_TYPE_SYM;
|
||||
kc.keysym = XKB_KEY_NoSymbol;
|
||||
return kc;
|
||||
}
|
||||
|
||||
// 处理 code: 前缀的情况
|
||||
if (strncmp(key_str, "code:", 5) == 0) {
|
||||
char *endptr;
|
||||
xkb_keycode_t keycode = (xkb_keycode_t)strtol(key_str + 5, &endptr, 10);
|
||||
kc.type = KEY_TYPE_CODE;
|
||||
kc.keycode = keycode;
|
||||
kc.keycode.keycode1 = keycode; // 只设置第一个
|
||||
kc.keycode.keycode2 = 0;
|
||||
kc.keycode.keycode3 = 0;
|
||||
return kc;
|
||||
}
|
||||
|
||||
// 普通键名直接转换
|
||||
xkb_keysym_t sym = xkb_keysym_from_name(key_str, XKB_KEYSYM_NO_FLAGS);
|
||||
kc.type = KEY_TYPE_SYM;
|
||||
kc.keycode = 0;
|
||||
kc.keysym = sym;
|
||||
|
||||
if (isbindsym) {
|
||||
kc.type = KEY_TYPE_SYM;
|
||||
kc.keysym = sym;
|
||||
return kc;
|
||||
}
|
||||
|
||||
if (sym != XKB_KEY_NoSymbol) {
|
||||
// 尝试找到对应的多个 keycode
|
||||
int found_count =
|
||||
find_keycodes_for_keysym(config.keymap, sym, &kc.keycode);
|
||||
if (found_count > 0) {
|
||||
kc.type = KEY_TYPE_CODE;
|
||||
kc.keysym = sym; // 仍然保存 keysym 供参考
|
||||
} else {
|
||||
kc.type = KEY_TYPE_SYM;
|
||||
kc.keysym = sym;
|
||||
// keycode 字段保持为0
|
||||
}
|
||||
} else {
|
||||
// 无法解析的键名
|
||||
kc.type = KEY_TYPE_SYM;
|
||||
kc.keysym = XKB_KEY_NoSymbol;
|
||||
// keycode 字段保持为0
|
||||
}
|
||||
|
||||
return kc;
|
||||
}
|
||||
|
||||
|
|
@ -1650,7 +1755,8 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
trim_whitespace(mod_str);
|
||||
trim_whitespace(keysym_str);
|
||||
rule->globalkeybinding.mod = parse_mod(mod_str);
|
||||
rule->globalkeybinding.keysymcode = parse_key(keysym_str);
|
||||
rule->globalkeybinding.keysymcode =
|
||||
parse_key(keysym_str, false);
|
||||
}
|
||||
}
|
||||
token = strtok(NULL, ",");
|
||||
|
|
@ -1787,7 +1893,8 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
|
||||
config->exec_once_count++;
|
||||
|
||||
} else if (strncmp(key, "bind", 4) == 0) {
|
||||
} else if (strncmp(key, "bind", 4) == 0 ||
|
||||
strncmp(key, "bindsym", 7) == 0) {
|
||||
config->key_bindings =
|
||||
realloc(config->key_bindings,
|
||||
(config->key_bindings_count + 1) * sizeof(KeyBinding));
|
||||
|
|
@ -1834,7 +1941,8 @@ void parse_option(Config *config, char *key, char *value) {
|
|||
}
|
||||
|
||||
binding->mod = parse_mod(mod_str);
|
||||
binding->keysymcode = parse_key(keysym_str);
|
||||
binding->keysymcode =
|
||||
parse_key(keysym_str, strncmp(key, "bindsym", 7) == 0);
|
||||
binding->arg.v = NULL;
|
||||
binding->arg.v2 = NULL;
|
||||
binding->arg.v3 = NULL;
|
||||
|
|
@ -2432,6 +2540,9 @@ void free_config(void) {
|
|||
|
||||
// 释放动画资源
|
||||
free_baked_points();
|
||||
|
||||
// 清理解析按键用的keymap
|
||||
cleanup_config_keymap();
|
||||
}
|
||||
|
||||
void override_config(void) {
|
||||
|
|
@ -2815,6 +2926,8 @@ void parse_config(void) {
|
|||
config.cursor_theme = NULL;
|
||||
strcpy(config.keymode, "default");
|
||||
|
||||
create_config_keymap();
|
||||
|
||||
// 获取 MANGOCONFIG 环境变量
|
||||
const char *mangoconfig = getenv("MANGOCONFIG");
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ int center_master_overspread = 0; // 中心master时是否铺满
|
|||
int center_when_single_stack = 1; // 单个stack时是否居中
|
||||
/* logging */
|
||||
int log_level = WLR_ERROR;
|
||||
unsigned int numlockon = 1; // 是否打开右边小键盘
|
||||
unsigned int numlockon = 0; // 是否打开右边小键盘
|
||||
unsigned int capslock = 0; // 是否启用快捷键
|
||||
|
||||
unsigned int ov_tab_mode = 0; // alt tab切换模式
|
||||
|
|
@ -114,6 +114,19 @@ char xkb_rules_layout[256];
|
|||
char xkb_rules_variant[256];
|
||||
char xkb_rules_options[256];
|
||||
|
||||
/* keyboard */
|
||||
static const struct xkb_rule_names xkb_fallback_rules = {
|
||||
.layout = "us",
|
||||
.variant = NULL,
|
||||
.model = NULL,
|
||||
.rules = NULL,
|
||||
.options = NULL,
|
||||
};
|
||||
|
||||
static const struct xkb_rule_names xkb_default_rules = {
|
||||
.options = NULL,
|
||||
};
|
||||
|
||||
struct xkb_rule_names xkb_rules = {
|
||||
/* can specify fields: rules, model, layout, variant, options */
|
||||
/* example:
|
||||
|
|
|
|||
|
|
@ -861,6 +861,13 @@ int switch_keyboard_layout(const Arg *arg) {
|
|||
|
||||
// 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;
|
||||
}
|
||||
|
||||
char *layout_buf = (char *)rules.layout; // 假设这是可修改的
|
||||
|
||||
// 清空原有内容(安全方式)
|
||||
|
|
|
|||
157
src/mango.c
157
src/mango.c
|
|
@ -36,6 +36,7 @@
|
|||
#include <wlr/types/wlr_data_control_v1.h>
|
||||
#include <wlr/types/wlr_data_device.h>
|
||||
#include <wlr/types/wlr_drm.h>
|
||||
#include <wlr/types/wlr_drm_lease_v1.h>
|
||||
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
||||
#include <wlr/types/wlr_ext_data_control_v1.h>
|
||||
#include <wlr/types/wlr_ext_image_capture_source_v1.h>
|
||||
|
|
@ -571,6 +572,7 @@ static void quitsignal(int signo);
|
|||
static void powermgrsetmode(struct wl_listener *listener, void *data);
|
||||
static void rendermon(struct wl_listener *listener, void *data);
|
||||
static void requestdecorationmode(struct wl_listener *listener, void *data);
|
||||
static void requestdrmlease(struct wl_listener *listener, void *data);
|
||||
static void requeststartdrag(struct wl_listener *listener, void *data);
|
||||
static void resize(Client *c, struct wlr_box geo, int interact);
|
||||
static void run(char *startup_cmd);
|
||||
|
|
@ -690,6 +692,7 @@ 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"
|
||||
|
|
@ -727,6 +730,7 @@ static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr;
|
|||
static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr;
|
||||
static struct wlr_output_power_manager_v1 *power_mgr;
|
||||
static struct wlr_pointer_gestures_v1 *pointer_gestures;
|
||||
static struct wlr_drm_lease_v1_manager *drm_lease_manager;
|
||||
|
||||
static struct wlr_cursor *cursor;
|
||||
static struct wlr_xcursor_manager *cursor_mgr;
|
||||
|
|
@ -830,6 +834,7 @@ static struct wl_listener request_set_cursor_shape = {.notify = setcursorshape};
|
|||
static struct wl_listener request_start_drag = {.notify = requeststartdrag};
|
||||
static struct wl_listener start_drag = {.notify = startdrag};
|
||||
static struct wl_listener new_session_lock = {.notify = locksession};
|
||||
static struct wl_listener drm_lease_request = {.notify = requestdrmlease};
|
||||
|
||||
#ifdef XWAYLAND
|
||||
static void activatex11(struct wl_listener *listener, void *data);
|
||||
|
|
@ -1934,6 +1939,7 @@ void cleanuplisteners(void) {
|
|||
wl_list_remove(&request_start_drag.link);
|
||||
wl_list_remove(&start_drag.link);
|
||||
wl_list_remove(&new_session_lock.link);
|
||||
wl_list_remove(&drm_lease_request.link);
|
||||
#ifdef XWAYLAND
|
||||
wl_list_remove(&new_xwayland_surface.link);
|
||||
wl_list_remove(&xwayland_ready.link);
|
||||
|
|
@ -2365,9 +2371,18 @@ 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, &xkb_rules,
|
||||
if (!(keymap = xkb_keymap_new_from_names(context, &rules,
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS)))
|
||||
die("failed to compile keymap");
|
||||
|
||||
|
|
@ -2518,6 +2533,14 @@ void createmon(struct wl_listener *listener, void *data) {
|
|||
if (!wlr_output_init_render(wlr_output, alloc, drw))
|
||||
return;
|
||||
|
||||
if (wlr_output->non_desktop) {
|
||||
if (drm_lease_manager) {
|
||||
wlr_drm_lease_v1_manager_offer_output(drm_lease_manager,
|
||||
wlr_output);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m = wlr_output->data = ecalloc(1, sizeof(*m));
|
||||
m->wlr_output = wlr_output;
|
||||
|
||||
|
|
@ -3226,7 +3249,9 @@ keybinding(unsigned int mods, xkb_keysym_t sym, unsigned int keycode) {
|
|||
normalize_keysym(sym) ==
|
||||
normalize_keysym(k->keysymcode.keysym)) ||
|
||||
(k->keysymcode.type == KEY_TYPE_CODE &&
|
||||
keycode == k->keysymcode.keycode)) &&
|
||||
(keycode == k->keysymcode.keycode.keycode1 ||
|
||||
keycode == k->keysymcode.keycode.keycode2 ||
|
||||
keycode == k->keysymcode.keycode.keycode3))) &&
|
||||
k->func) {
|
||||
|
||||
isbreak = k->func(&k->arg);
|
||||
|
|
@ -3258,14 +3283,18 @@ bool keypressglobal(struct wlr_surface *last_surface,
|
|||
|
||||
if (!r->globalkeybinding.mod ||
|
||||
(!r->globalkeybinding.keysymcode.keysym &&
|
||||
!r->globalkeybinding.keysymcode.keycode))
|
||||
!r->globalkeybinding.keysymcode.keycode.keycode1 &&
|
||||
!r->globalkeybinding.keysymcode.keycode.keycode2 &&
|
||||
!r->globalkeybinding.keysymcode.keycode.keycode3))
|
||||
continue;
|
||||
|
||||
/* match key only (case insensitive) ignoring mods */
|
||||
if (((r->globalkeybinding.keysymcode.type == KEY_TYPE_SYM &&
|
||||
r->globalkeybinding.keysymcode.keysym == keysym) ||
|
||||
(r->globalkeybinding.keysymcode.type == KEY_TYPE_CODE &&
|
||||
r->globalkeybinding.keysymcode.keycode == keycode)) &&
|
||||
(r->globalkeybinding.keysymcode.keycode.keycode1 == keycode ||
|
||||
r->globalkeybinding.keysymcode.keycode.keycode2 == keycode ||
|
||||
r->globalkeybinding.keysymcode.keycode.keycode3 == keycode))) &&
|
||||
r->globalkeybinding.mod == mods) {
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (c && c != lastc) {
|
||||
|
|
@ -4109,6 +4138,16 @@ void requestdecorationmode(struct wl_listener *listener, void *data) {
|
|||
}
|
||||
}
|
||||
|
||||
static void requestdrmlease(struct wl_listener *listener, void *data) {
|
||||
struct wlr_drm_lease_request_v1 *req = data;
|
||||
struct wlr_drm_lease_v1 *lease = wlr_drm_lease_request_v1_grant(req);
|
||||
|
||||
if (!lease) {
|
||||
wlr_log(WLR_ERROR, "Failed to grant lease request");
|
||||
wlr_drm_lease_request_v1_reject(req);
|
||||
}
|
||||
}
|
||||
|
||||
void requeststartdrag(struct wl_listener *listener, void *data) {
|
||||
struct wlr_seat_request_start_drag_event *event = data;
|
||||
|
||||
|
|
@ -4451,7 +4490,7 @@ void setmaxmizescreen(Client *c, int maxmizescreen) {
|
|||
|
||||
if (!c->force_maximize && !c->ismaxmizescreen) {
|
||||
client_set_maximized(c, false);
|
||||
} else {
|
||||
} else if (!c->force_maximize && c->ismaxmizescreen) {
|
||||
client_set_maximized(c, true);
|
||||
}
|
||||
|
||||
|
|
@ -4526,6 +4565,46 @@ 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;
|
||||
}
|
||||
|
||||
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");
|
||||
|
|
@ -4547,6 +4626,16 @@ 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) {
|
||||
|
|
@ -4554,35 +4643,34 @@ void reset_keyboard_layout(void) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Get layout abbreviations
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Keep the same rules but just reapply them
|
||||
struct xkb_rule_names rules = xkb_rules;
|
||||
|
||||
// Create new keymap with current rules
|
||||
// 现在安全地创建真正的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_layouts;
|
||||
// 理论上这里不应该失败,因为前面已经验证过了
|
||||
wlr_log(WLR_ERROR,
|
||||
"Unexpected failure to create keymap after validation");
|
||||
goto cleanup_context;
|
||||
}
|
||||
|
||||
// Apply the same keymap (this will reset the layout state)
|
||||
// 验证新keymap是否有布局
|
||||
const int new_num_layouts = xkb_keymap_num_layouts(new_keymap);
|
||||
if (new_num_layouts < 1) {
|
||||
wlr_log(WLR_ERROR, "New keymap has no layouts");
|
||||
xkb_keymap_unref(new_keymap);
|
||||
goto cleanup_context;
|
||||
}
|
||||
|
||||
// 确保当前布局索引在新keymap中有效
|
||||
if (current >= new_num_layouts) {
|
||||
wlr_log(WLR_INFO,
|
||||
"Current layout index %u out of range for new keymap, "
|
||||
"resetting to 0",
|
||||
current);
|
||||
current = 0;
|
||||
}
|
||||
|
||||
// Apply the new keymap
|
||||
unsigned int depressed = keyboard->modifiers.depressed;
|
||||
unsigned int latched = keyboard->modifiers.latched;
|
||||
unsigned int locked = keyboard->modifiers.locked;
|
||||
|
|
@ -4599,9 +4687,6 @@ void reset_keyboard_layout(void) {
|
|||
// Cleanup
|
||||
xkb_keymap_unref(new_keymap);
|
||||
|
||||
cleanup_layouts:
|
||||
free(layout_ids);
|
||||
|
||||
cleanup_context:
|
||||
xkb_context_unref(context);
|
||||
}
|
||||
|
|
@ -4965,6 +5050,14 @@ void setup(void) {
|
|||
|
||||
dwl_input_method_relay = dwl_im_relay_create();
|
||||
|
||||
drm_lease_manager = wlr_drm_lease_v1_manager_create(dpy, backend);
|
||||
if (drm_lease_manager) {
|
||||
wl_signal_add(&drm_lease_manager->events.request, &drm_lease_request);
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Failed to create wlr_drm_lease_device_v1; VR will "
|
||||
"not be available");
|
||||
}
|
||||
|
||||
wl_global_create(dpy, &zdwl_ipc_manager_v2_interface, 2, NULL,
|
||||
dwl_ipc_manager_bind);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue