diff --git a/include/callbacks.h b/include/callbacks.h new file mode 100644 index 0000000..56bfeb0 --- /dev/null +++ b/include/callbacks.h @@ -0,0 +1,17 @@ +#ifndef __KEYBINDS_CALLBACKS_H +#define __KEYBINDS_CALLBACKS_H + +#include "types.h" + +void run(absn_server *server, const absn_arg *arg); + +void kill_focus(absn_server *server, const absn_arg *arg); +void cycle_focus(absn_server *server, const absn_arg *arg); +void toggle_fullscreen(absn_server *server, const absn_arg *arg); + +void increase_master_width(absn_server *server, const absn_arg *arg); +void increase_master_count(absn_server *server, const absn_arg *arg); + +void quit(absn_server *server, const absn_arg *arg); + +#endif diff --git a/include/config.h b/include/config.h index 2b5944d..db663dc 100644 --- a/include/config.h +++ b/include/config.h @@ -1,6 +1,9 @@ #ifndef __CONFIG_H_ #define __CONFIG_H_ +#include "callbacks.h" +#include "types.h" + #define CURSOR_MOD WLR_MODIFIER_ALT #define CURSOR_MOVE_BUTTON BTN_LEFT #define CURSOR_RESIZE_BUTTON BTN_RIGHT @@ -17,4 +20,22 @@ static const float unfocused_bc[4] = { 0.28, 0.28, 0.28, 1.0 }; #define OUTPUT_GAP 0 #define LAYOUT_GAP 0 +#define ALT WLR_MODIFIER_ALT +#define CTRL WLR_MODIFIER_CTRL +#define SHIFT WLR_MODIFIER_SHIFT +#define LOGO WLR_MODIFIER_LOGO + +static const absn_keybind keybinds[] = { + { ALT, XKB_KEY_Return, &run, { .v = "alacritty" } }, + { ALT, XKB_KEY_q, kill_focus, { 0 } }, + { ALT, XKB_KEY_j, cycle_focus, { .i = +1 } }, + { ALT, XKB_KEY_k, cycle_focus, { .i = -1 } }, + { ALT, XKB_KEY_f, toggle_fullscreen, { 0 } }, + { ALT, XKB_KEY_h, increase_master_count, { .i = +1 } }, + { ALT, XKB_KEY_l, increase_master_count, { .i = -1 } }, + { ALT | SHIFT, XKB_KEY_h, increase_master_width, { .f = -0.05 } }, + { ALT | SHIFT, XKB_KEY_l, increase_master_width, { .f = +0.05 } }, + { ALT, XKB_KEY_E, quit, { 0 } }, +}; + #endif diff --git a/include/focus.h b/include/focus.h index 477ac04..1abf77a 100644 --- a/include/focus.h +++ b/include/focus.h @@ -4,10 +4,6 @@ #include "types.h" void focus_toplevel(absn_toplevel *toplevel); - absn_toplevel *focus_get_topmost(absn_server *server); -void focus_next(absn_server *server); -void focus_prev(absn_server *server); - #endif diff --git a/include/keybinds-callbacks.h b/include/keybinds-callbacks.h deleted file mode 100644 index f16d0bf..0000000 --- a/include/keybinds-callbacks.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef __KEYBINDS_CALLBACKS_H -#define __KEYBINDS_CALLBACKS_H - -#endif diff --git a/include/types.h b/include/types.h index 11c1133..d126440 100644 --- a/include/types.h +++ b/include/types.h @@ -33,7 +33,8 @@ (L).notify = (C); \ wl_signal_add(&(E), &(L)); \ } while (0); -#define UNUSED(X) (void)(X) +#define UNUSED(X) (void)(X) +#define CLEANMASK(M) (M & ~WLR_MODIFIER_CAPS) /* cursor mode */ enum { @@ -224,4 +225,17 @@ typedef struct { struct wl_listener destroy; } absn_keyboard; +typedef struct { + int i; + float f; + const void *v; +} absn_arg; + +typedef struct { + uint32_t mods; + xkb_keysym_t keysym; + void (*cb)(absn_server *, const absn_arg *); + const absn_arg arg; +} absn_keybind; + #endif /* __TYPES_H_ */ diff --git a/src/callbacks.c b/src/callbacks.c new file mode 100644 index 0000000..e9e5091 --- /dev/null +++ b/src/callbacks.c @@ -0,0 +1,107 @@ +#include +#include +#include +#include + +#include "focus.h" +#include "layout.h" +#include "toplevel.h" +#include "types.h" + +void +run(absn_server *server, const absn_arg *arg) +{ + UNUSED(server); + if (fork() == 0) { + setsid(); + execl("/bin/sh", "sh", "-c", arg->v, NULL); + } +} + +void +kill_focus(absn_server *server, const absn_arg *arg) +{ + UNUSED(arg); + if (!server->focused_output) + return; + +#ifdef XWAYLAND + if (server->focused_toplevel->type == TOPLEVEL_X11) { + wlr_xwayland_surface_close(server->focused_toplevel->xw); + } else +#endif + { + wlr_xdg_toplevel_send_close(server->focused_toplevel->xdg); + } +} + +void +cycle_focus(absn_server *server, const absn_arg *arg) +{ + absn_toplevel *toplevel = focus_get_topmost(server); + if (!toplevel) + return; + + absn_toplevel *new_focus; + if (arg->i > 0) { + wl_list_for_each(new_focus, &toplevel->link, link) + { + if (&new_focus->link == &toplevel->server->toplevels) + continue; + break; + } + } else { + wl_list_for_each_reverse(new_focus, &toplevel->link, link) + { + if (&new_focus->link == &toplevel->server->toplevels) + continue; + break; + } + } + focus_toplevel(new_focus); +} + +void +toggle_fullscreen(absn_server *server, const absn_arg *arg) +{ + UNUSED(arg); + if (!server->focused_toplevel) + return; + toplevel_set_fullscreen(server->focused_toplevel, + !server->focused_toplevel->fullscreen); +} + +void +increase_master_width(absn_server *server, const absn_arg *arg) +{ + if (!server->focused_output) + return; + + if (server->focused_output->mstack_width + arg->f >= 1.0 || + server->focused_output->mstack_width + arg->f <= 0.0) + return; + + server->focused_output->mstack_width += arg->f; + layout_arrange(server->focused_output); +} + +void +increase_master_count(absn_server *server, const absn_arg *arg) +{ + if (!server->focused_output) + return; + + if (server->focused_output->mstack_count + arg->i <= 0) + return; + + server->focused_output->mstack_count += arg->i; + layout_arrange(server->focused_output); +} + +noreturn void +quit(absn_server *server, const absn_arg *arg) +{ + UNUSED(arg); + wl_display_terminate(server->display); + exit(EXIT_SUCCESS); +} diff --git a/src/keybinds-callbacks.c b/src/keybinds-callbacks.c deleted file mode 100644 index e69de29..0000000 diff --git a/src/keyboard.c b/src/keyboard.c index e438f61..bcdcbc4 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -5,9 +5,7 @@ #include #include -#include "focus.h" -#include "layout.h" -#include "toplevel.h" +#include "config.h" #include "types.h" void @@ -23,62 +21,18 @@ handle_modifiers(struct wl_listener *listener, void *data) } static bool -handle_keybind(absn_server *server, xkb_keysym_t keysym) +handle_keybind(absn_server *server, uint32_t mods, xkb_keysym_t keysym) { - switch (keysym) { - case XKB_KEY_Escape: - wl_display_terminate(server->display); - break; - case XKB_KEY_Return: - if (fork() == 0) - execl("/bin/sh", "sh", "-c", "alacritty", NULL); - break; - case XKB_KEY_r: - if (fork() == 0) - execl("/bin/sh", "sh", "-c", "wofi --show drun", NULL); - break; - case XKB_KEY_f: - if (server->focused_toplevel) - toplevel_set_fullscreen(server->focused_toplevel, - !server->focused_toplevel->fullscreen); - break; - case XKB_KEY_j: - focus_next(server); - break; - case XKB_KEY_k: - focus_prev(server); - break; - case XKB_KEY_h: - if (server->focused_output && - server->focused_output->mstack_width > 0.15) { - server->focused_output->mstack_width -= 0.1; - layout_arrange(server->focused_output); + int nkeyb = sizeof(keybinds) / sizeof(keybinds[0]); + for (int i = 0; i < nkeyb; ++i) { + if (CLEANMASK(keybinds[i].mods) == CLEANMASK(mods) && + xkb_keysym_to_lower(keybinds[i].keysym) == + xkb_keysym_to_lower(keysym)) { + keybinds[i].cb(server, &keybinds[i].arg); + return true; } - break; - case XKB_KEY_l: - if (server->focused_output && - server->focused_output->mstack_width < 0.9) { - server->focused_output->mstack_width += 0.1; - layout_arrange(server->focused_output); - } - break; - case XKB_KEY_H: - if (server->focused_output) { - server->focused_output->mstack_count += 1; - layout_arrange(server->focused_output); - } - break; - case XKB_KEY_L: - if (server->focused_output && - server->focused_output->mstack_count > 1) { - server->focused_output->mstack_count -= 1; - layout_arrange(server->focused_output); - } - break; - default: - return false; } - return true; + return false; } void @@ -87,17 +41,19 @@ handle_key(struct wl_listener *listener, void *data) absn_keyboard *keyboard = wl_container_of(listener, keyboard, key); struct wlr_keyboard_key_event *event = data; - uint32_t keycode = event->keycode + 8; - uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->wlr); + /* translate keycode to xkbcommon */ + uint32_t code = event->keycode + 8; + uint32_t mods = wlr_keyboard_get_modifiers(keyboard->wlr); const xkb_keysym_t *syms; - int nsyms = xkb_state_key_get_syms(keyboard->wlr->xkb_state, keycode, + int nsyms = xkb_state_key_get_syms(keyboard->wlr->xkb_state, code, &syms); bool handled = false; - if ((modifiers & WLR_MODIFIER_ALT) && - (event->state == WL_KEYBOARD_KEY_STATE_PRESSED)) { + if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { for (int i = 0; i < nsyms; ++i) { - handled = handle_keybind(keyboard->server, syms[i]); + handled = handle_keybind(keyboard->server, mods, + syms[i]) || + handled; } }