22
src/Config.c
22
src/Config.c
@@ -263,33 +263,19 @@ void config_unref(lua_State *L, Config *cfg)
|
|||||||
cfg->input.keyboard.xkb_options = NULL;
|
cfg->input.keyboard.xkb_options = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int trigger_ref_modsym(
|
void config_trigger_ref(lua_State *L, Config *cfg, int ref)
|
||||||
lua_State *L, Config const *cfg, uint32_t mods, xkb_keysym_t sym)
|
|
||||||
{
|
{
|
||||||
if (!L || !cfg)
|
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
|
||||||
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)) {
|
if (!lua_isfunction(L, -1)) {
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
return -2;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lua_pcall(L, 0, 0, 0) != LUA_OK) {
|
if (lua_pcall(L, 0, 0, 0) != LUA_OK) {
|
||||||
fprintf(stderr, "config: action error: %s\n", lua_tostring(L, -1));
|
fprintf(stderr, "config: action error: %s\n", lua_tostring(L, -1));
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
return -3;
|
return;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_config_file(lua_State *L, char const *path)
|
static int load_config_file(lua_State *L, char const *path)
|
||||||
|
|||||||
@@ -29,8 +29,7 @@ char const *get_config_path(void);
|
|||||||
|
|
||||||
int config_load_ref(lua_State *L, int idx, Config *out);
|
int config_load_ref(lua_State *L, int idx, Config *out);
|
||||||
void config_unref(lua_State *L, Config *cfg);
|
void config_unref(lua_State *L, Config *cfg);
|
||||||
int trigger_ref_modsym(
|
void config_trigger_ref(lua_State *L, Config *cfg, int ref);
|
||||||
lua_State *L, Config const *cfg, uint32_t mods, xkb_keysym_t sym);
|
|
||||||
|
|
||||||
struct ConfigManager {
|
struct ConfigManager {
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
|
|||||||
120
src/LunarWM.c
120
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 *)
|
static void Keyboard_modifiers_notify(struct wl_listener *listener, void *)
|
||||||
{
|
{
|
||||||
auto *kbd
|
auto *kbd
|
||||||
= wl_container_of(listener, (LunarWM_Keyboard *)(NULL), modifiers);
|
= 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_set_keyboard(kbd->server->wayland.seat, kbd->wlr_keyboard);
|
||||||
wlr_seat_keyboard_notify_modifiers(
|
wlr_seat_keyboard_notify_modifiers(
|
||||||
kbd->server->wayland.seat, &kbd->wlr_keyboard->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)
|
static void Keyboard_key_notify(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
auto *kbd = wl_container_of(listener, (LunarWM_Keyboard *)(NULL), key);
|
auto *kbd = wl_container_of(listener, (LunarWM_Keyboard *)(NULL), key);
|
||||||
|
if (!kbd->server || !kbd->server->wayland.seat) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
auto *server = kbd->server;
|
auto *server = kbd->server;
|
||||||
auto *event = (struct wlr_keyboard_key_event *)data;
|
auto *event = (struct wlr_keyboard_key_event *)data;
|
||||||
struct wlr_seat *seat = server->wayland.seat;
|
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;
|
bool handled = false;
|
||||||
uint32_t const modifiers = wlr_keyboard_get_modifiers(kbd->wlr_keyboard);
|
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
|
if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
||||||
|
if (server->wayland.session && keysym >= XKB_KEY_XF86Switch_VT_1
|
||||||
&& keysym <= XKB_KEY_XF86Switch_VT_12) {
|
&& keysym <= XKB_KEY_XF86Switch_VT_12) {
|
||||||
unsigned const vt = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
|
unsigned const vt = keysym - XKB_KEY_XF86Switch_VT_1 + 1;
|
||||||
wlr_session_change_vt(server->wayland.session, vt);
|
wlr_session_change_vt(server->wayland.session, vt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) {
|
|
||||||
for (int i = 0; i < nsyms; i++) {
|
for (int i = 0; i < server->cman->cfg.keybindings.count; i++) {
|
||||||
if (trigger_ref_modsym(
|
BindingRef ref = server->cman->cfg.keybindings.items[i];
|
||||||
server->cman->L, &server->cman->cfg, modifiers, syms[i])
|
if (ref.mods_mask == 0 || ref.sym == XKB_KEY_NoSymbol)
|
||||||
== 0)
|
continue;
|
||||||
return; // handled
|
|
||||||
|
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 (!handled) {
|
||||||
|
if (!seat)
|
||||||
|
return;
|
||||||
|
if (!kbd->wlr_keyboard)
|
||||||
|
return;
|
||||||
wlr_seat_set_keyboard(seat, kbd->wlr_keyboard);
|
wlr_seat_set_keyboard(seat, kbd->wlr_keyboard);
|
||||||
wlr_seat_keyboard_notify_key(
|
wlr_seat_keyboard_notify_key(
|
||||||
seat, event->time_msec, event->keycode, event->state);
|
seat, event->time_msec, event->keycode, event->state);
|
||||||
@@ -1232,6 +1225,24 @@ static void cleanup_xr(LunarWM *this)
|
|||||||
|
|
||||||
static void cleanup_wayland(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) {
|
if (this->wayland.v_toplevels) {
|
||||||
for (size_t i = 0; i < vector_size(this->wayland.v_toplevels); ++i) {
|
for (size_t i = 0; i < vector_size(this->wayland.v_toplevels); ++i) {
|
||||||
if (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;
|
this->wayland.cursor = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->wayland.backend) {
|
||||||
|
wlr_backend_destroy(this->wayland.backend);
|
||||||
|
this->wayland.backend = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->wayland.seat) {
|
if (this->wayland.seat) {
|
||||||
wlr_seat_destroy(this->wayland.seat);
|
wlr_seat_destroy(this->wayland.seat);
|
||||||
this->wayland.seat = NULL;
|
this->wayland.seat = NULL;
|
||||||
@@ -1261,16 +1277,6 @@ static void cleanup_wayland(LunarWM *this)
|
|||||||
wlr_renderer_destroy(this->wayland.renderer);
|
wlr_renderer_destroy(this->wayland.renderer);
|
||||||
this->wayland.renderer = NULL;
|
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) {
|
if (this->wayland.display) {
|
||||||
wl_display_destroy(this->wayland.display);
|
wl_display_destroy(this->wayland.display);
|
||||||
this->wayland.display = NULL;
|
this->wayland.display = NULL;
|
||||||
|
|||||||
Reference in New Issue
Block a user