From ad0d09ebd22dac6a1f1bae2382e0a660850538a4 Mon Sep 17 00:00:00 2001 From: Slendi Date: Sun, 10 Aug 2025 08:45:45 +0300 Subject: [PATCH] Fix crashing Signed-off-by: Slendi --- src/Config.c | 36 +++++--------- src/Config.h | 3 +- src/LunarWM.c | 128 ++++++++++++++++++++++++++------------------------ 3 files changed, 79 insertions(+), 88 deletions(-) diff --git a/src/Config.c b/src/Config.c index 9fd6e4c..a01fcae 100644 --- a/src/Config.c +++ b/src/Config.c @@ -263,33 +263,19 @@ void config_unref(lua_State *L, Config *cfg) cfg->input.keyboard.xkb_options = NULL; } -int trigger_ref_modsym( - lua_State *L, Config const *cfg, uint32_t mods, xkb_keysym_t sym) +void config_trigger_ref(lua_State *L, Config *cfg, int ref) { - if (!L || !cfg) - return -1; - - for (size_t i = 0; i < cfg->keybindings.count; ++i) { - BindingRef const *br = &cfg->keybindings.items[i]; - if (br->sym != sym) - continue; - if ((mods & br->mods_mask) != br->mods_mask) - continue; - - lua_rawgeti(L, LUA_REGISTRYINDEX, br->action_ref); - if (!lua_isfunction(L, -1)) { - lua_pop(L, 1); - return -2; - } - - if (lua_pcall(L, 0, 0, 0) != LUA_OK) { - fprintf(stderr, "config: action error: %s\n", lua_tostring(L, -1)); - lua_pop(L, 1); - return -3; - } - return 0; + lua_rawgeti(L, LUA_REGISTRYINDEX, ref); + if (!lua_isfunction(L, -1)) { + lua_pop(L, 1); + return; + } + + if (lua_pcall(L, 0, 0, 0) != LUA_OK) { + fprintf(stderr, "config: action error: %s\n", lua_tostring(L, -1)); + lua_pop(L, 1); + return; } - return 1; } static int load_config_file(lua_State *L, char const *path) diff --git a/src/Config.h b/src/Config.h index 93f9b2e..46e8a50 100644 --- a/src/Config.h +++ b/src/Config.h @@ -29,8 +29,7 @@ char const *get_config_path(void); int config_load_ref(lua_State *L, int idx, Config *out); void config_unref(lua_State *L, Config *cfg); -int trigger_ref_modsym( - lua_State *L, Config const *cfg, uint32_t mods, xkb_keysym_t sym); +void config_trigger_ref(lua_State *L, Config *cfg, int ref); struct ConfigManager { lua_State *L; diff --git a/src/LunarWM.c b/src/LunarWM.c index 6f21954..0c0e7b2 100644 --- a/src/LunarWM.c +++ b/src/LunarWM.c @@ -149,49 +149,13 @@ static void keysym_name(xkb_keysym_t sym, char *buf, size_t bufsz) } } -static size_t fill_mod_list(uint32_t mods, char const *outv[4]) -{ - size_t k = 0; - if (mods & WLR_MODIFIER_LOGO) - outv[k++] = "Super"; - if (mods & WLR_MODIFIER_SHIFT) - outv[k++] = "Shift"; - if (mods & WLR_MODIFIER_CTRL) - outv[k++] = "Ctrl"; - if (mods & WLR_MODIFIER_ALT) - outv[k++] = "Alt"; - return k; -} - -static char *make_hotkey_string(uint32_t mods, xkb_keysym_t sym) -{ - char keyname[128]; - keysym_name(sym, keyname, sizeof keyname); - - char const *mods_list[4] = { 0 }; - size_t mcount = fill_mod_list(mods, mods_list); - - size_t need = strlen(keyname) + 1; - for (size_t i = 0; i < mcount; ++i) - need += strlen(mods_list[i]) + 1; - - char *s = (char *)malloc(need); - if (!s) - return NULL; - - s[0] = 0; - for (size_t i = 0; i < mcount; ++i) { - strcat(s, mods_list[i]); - strcat(s, "-"); - } - strcat(s, keyname); - return s; -} - static void Keyboard_modifiers_notify(struct wl_listener *listener, void *) { auto *kbd = wl_container_of(listener, (LunarWM_Keyboard *)(NULL), modifiers); + if (!kbd->server || !kbd->server->wayland.seat) { + return; + } wlr_seat_set_keyboard(kbd->server->wayland.seat, kbd->wlr_keyboard); wlr_seat_keyboard_notify_modifiers( kbd->server->wayland.seat, &kbd->wlr_keyboard->modifiers); @@ -200,6 +164,9 @@ static void Keyboard_modifiers_notify(struct wl_listener *listener, void *) static void Keyboard_key_notify(struct wl_listener *listener, void *data) { auto *kbd = wl_container_of(listener, (LunarWM_Keyboard *)(NULL), key); + if (!kbd->server || !kbd->server->wayland.seat) { + return; + } auto *server = kbd->server; auto *event = (struct wlr_keyboard_key_event *)data; struct wlr_seat *seat = server->wayland.seat; @@ -213,23 +180,49 @@ static void Keyboard_key_notify(struct wl_listener *listener, void *data) bool handled = false; uint32_t const modifiers = wlr_keyboard_get_modifiers(kbd->wlr_keyboard); - if (server->wayland.session && event->state == WL_KEYBOARD_KEY_STATE_PRESSED - && keysym >= XKB_KEY_XF86Switch_VT_1 - && keysym <= XKB_KEY_XF86Switch_VT_12) { - unsigned const vt = keysym - XKB_KEY_XF86Switch_VT_1 + 1; - wlr_session_change_vt(server->wayland.session, vt); - return; - } + if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { - for (int i = 0; i < nsyms; i++) { - if (trigger_ref_modsym( - server->cman->L, &server->cman->cfg, modifiers, syms[i]) - == 0) - return; // handled + if (server->wayland.session && keysym >= XKB_KEY_XF86Switch_VT_1 + && keysym <= XKB_KEY_XF86Switch_VT_12) { + unsigned const vt = keysym - XKB_KEY_XF86Switch_VT_1 + 1; + wlr_session_change_vt(server->wayland.session, vt); + return; + } + + for (int i = 0; i < server->cman->cfg.keybindings.count; i++) { + BindingRef ref = server->cman->cfg.keybindings.items[i]; + if (ref.mods_mask == 0 || ref.sym == XKB_KEY_NoSymbol) + continue; + + bool sym_match = false; + if (syms && nsyms > 0) { + xkb_keysym_t want = xkb_keysym_to_lower(ref.sym); + for (int s = 0; s < nsyms; ++s) { + if (syms[s] == want) { + sym_match = true; + break; + } + if (xkb_keysym_to_lower(syms[s]) == want) { + sym_match = true; + break; + } + } + } + + if (((modifiers & ref.mods_mask) == ref.mods_mask) && sym_match) { + config_trigger_ref( + server->cman->L, &server->cman->cfg, ref.action_ref); + handled = true; + break; + } } } if (!handled) { + if (!seat) + return; + if (!kbd->wlr_keyboard) + return; wlr_seat_set_keyboard(seat, kbd->wlr_keyboard); wlr_seat_keyboard_notify_key( seat, event->time_msec, event->keycode, event->state); @@ -1232,6 +1225,24 @@ static void cleanup_xr(LunarWM *this) static void cleanup_wayland(LunarWM *this) { + assert(this); + + if (this->wayland.new_xdg_toplevel_listener.link.prev + || this->wayland.new_xdg_toplevel_listener.link.next) { + wl_list_remove(&this->wayland.new_xdg_toplevel_listener.link); + this->wayland.new_xdg_toplevel_listener.notify = NULL; + } + if (this->wayland.new_xdg_popup_listener.link.prev + || this->wayland.new_xdg_popup_listener.link.next) { + wl_list_remove(&this->wayland.new_xdg_popup_listener.link); + this->wayland.new_xdg_popup_listener.notify = NULL; + } + if (this->wayland.new_input_listener.link.prev + || this->wayland.new_input_listener.link.next) { + wl_list_remove(&this->wayland.new_input_listener.link); + this->wayland.new_input_listener.notify = NULL; + } + if (this->wayland.v_toplevels) { for (size_t i = 0; i < vector_size(this->wayland.v_toplevels); ++i) { if (this->wayland.v_toplevels[i]) { @@ -1248,6 +1259,11 @@ static void cleanup_wayland(LunarWM *this) this->wayland.cursor = NULL; } + if (this->wayland.backend) { + wlr_backend_destroy(this->wayland.backend); + this->wayland.backend = NULL; + } + if (this->wayland.seat) { wlr_seat_destroy(this->wayland.seat); this->wayland.seat = NULL; @@ -1261,16 +1277,6 @@ static void cleanup_wayland(LunarWM *this) wlr_renderer_destroy(this->wayland.renderer); this->wayland.renderer = NULL; } - if (this->wayland.session) { - wlr_session_destroy(this->wayland.session); - this->wayland.session = NULL; - } - - if (this->wayland.backend) { - wlr_backend_destroy(this->wayland.backend); - this->wayland.backend = NULL; - } - if (this->wayland.display) { wl_display_destroy(this->wayland.display); this->wayland.display = NULL;