Commit ade3fa2c13a0bc6f3e7fa6506bcb3680260e3ffb Parent: 4f571200cbe4afcc4967618f5c201032fdeef551 Author: mcol <mcol@posteo.net> Date: 2020-11-22 01:29:14 +0000 Committer: mcol <mcol@posteo.net> Committed: 2020-11-22 01:29:14 +0000 Implement custom keybindings for various deskwm actions
src/types.h Modified
@@ -48,6 +48,7 @@ struct wl_listener request_set_selection_listener; struct wl_list keyboards; enum wlr_keyboard_modifier mod; + struct wl_list keybindings; enum cursor_mode cursor_mode; struct view *grabbed_view; double grab_x, grab_y;
src/shell.h Modified
@@ -3,7 +3,7 @@ #include "types.h" -void close_current_window(struct server *server); +void close_current_window(struct server *server, void *data); void unmap_view(struct view *view); void map_view(struct view *view); void focus_view(struct view *view, struct wlr_surface *surface);
src/shell.c Modified
@@ -6,7 +6,7 @@ #include "types.h" -void close_current_window(struct server *server) { +void close_current_window(struct server *server, void *data) { struct wlr_surface *surface = server->seat->keyboard_state.focused_surface; if (surface) { struct wlr_xdg_surface *xdg_surface = surface->role_data;
src/input.h Modified
@@ -2,8 +2,10 @@ #define DESKWM_INPUT_H #include "types.h" +#include "shell.h" -void set_modifier(struct server *server, char *modifier); +enum wlr_keyboard_modifier modifier_by_name(char *mod); +void add_binding(struct server *server, char *data, int line); void process_cursor_move(struct server *server, uint32_t time, double zoom); void process_cursor_resize(struct server *server, uint32_t time, double zoom); bool view_at( @@ -21,7 +23,6 @@ void on_cursor_axis(struct wl_listener *listener, void *data); void on_cursor_frame(struct wl_listener *listener, void *data); void on_modifier(struct wl_listener *listener, void *data); -bool handle_keybinding(struct server *server, xkb_keysym_t sym); void on_key(struct wl_listener *listener, void *data); void on_new_keyboard(struct server *server, struct wlr_input_device *device); void on_new_input(struct wl_listener *listener, void *data); @@ -30,4 +31,14 @@ void set_up_cursor(struct server *server); void set_up_keyboard(struct server *server); +typedef void (*action)(struct server *server, void *data); + +struct keybinding { + struct wl_list link; + enum wlr_keyboard_modifier mods; + xkb_keysym_t key; + action action; + void *data; +}; + #endif
src/input.c Modified
@@ -1,3 +1,4 @@ +#include <inttypes.h> #include <unistd.h> #include <wlr/types/wlr_cursor.h> #include <wlr/types/wlr_keyboard.h> @@ -9,24 +10,114 @@ #include "shell.h" #include "types.h" +#define is_int(s) (strspn(s, "-0123456789") == strlen(s)) -void set_modifier(struct server *server, char *mod) { + +void shutdown(struct server *server, void *data) { + wl_display_terminate(server->display); +} + + +void exec_command(struct server *server, void *data) { + if (fork() == 0) { + //char *const command[] = {data}; + //execvp(command[0], command); + execl("/bin/sh", "/bin/sh", "-c", data, (void *)NULL); + } +} + + +enum wlr_keyboard_modifier modifier_by_name(char *mod) { if (strcasecmp(mod, "shift") == 0) - server->mod = WLR_MODIFIER_SHIFT; - else if (strcasecmp(mod, "caps") == 0) - server->mod = WLR_MODIFIER_CAPS; - else if (strcasecmp(mod, "ctrl") == 0) - server->mod = WLR_MODIFIER_CTRL; - else if (strcasecmp(mod, "alt") == 0) - server->mod = WLR_MODIFIER_ALT; - else if (strcasecmp(mod, "mod2") == 0) - server->mod = WLR_MODIFIER_MOD2; - else if (strcasecmp(mod, "mod3") == 0) - server->mod = WLR_MODIFIER_MOD3; - else if (strcasecmp(mod, "mod4") == 0) - server->mod = WLR_MODIFIER_LOGO; - else if (strcasecmp(mod, "mod5") == 0) - server->mod = WLR_MODIFIER_MOD5; + return WLR_MODIFIER_SHIFT; + if (strcasecmp(mod, "caps") == 0) + return WLR_MODIFIER_CAPS; + if (strcasecmp(mod, "ctrl") == 0) + return WLR_MODIFIER_CTRL; + if (strcasecmp(mod, "alt") == 0) + return WLR_MODIFIER_ALT; + if (strcasecmp(mod, "mod2") == 0) + return WLR_MODIFIER_MOD2; + if (strcasecmp(mod, "mod3") == 0) + return WLR_MODIFIER_MOD3; + if (strcasecmp(mod, "logo") == 0) + return WLR_MODIFIER_LOGO; + if (strcasecmp(mod, "mod5") == 0) + return WLR_MODIFIER_MOD5; + return 0; +} + + +void assign_action(char *name, char *data, struct keybinding *kb) { + kb->data = NULL; + kb->action = NULL; + + if (strcasecmp(name, "shutdown") == 0) + kb->action = &shutdown; + else if (strcasecmp(name, "close_current_window") == 0) + kb->action = &close_current_window; + else if (strcasecmp(name, "next_desk") == 0) + kb->action = &next_desk; + else if (strcasecmp(name, "prev_desk") == 0) + kb->action = &prev_desk; + else if (strcasecmp(name, "reset_pan") == 0) + kb->action = &reset_pan; + else if (strcasecmp(name, "save_pan") == 0) + kb->action = &save_pan; + else if (strcasecmp(name, "zoom_desk") == 0) { + kb->action = &zoom_desk; + kb->data = calloc(1, sizeof(int)); + *(int *)(kb->data) = atoi(data); + } + else if (strcasecmp(name, "exec") == 0) { + kb->action = &exec_command; + kb->data = calloc(strlen(data), sizeof(char)); + strncpy(kb->data, data, strlen(data)); + } +} + + +void add_binding(struct server *server, char *data, int line) { + struct keybinding *kb = calloc(1, sizeof(struct keybinding)); + enum wlr_keyboard_modifier mod; + char *s = strtok(data, " \t\n\r"); + + // modifiers + kb->mods = 0; + for (int i = 0; i < 8; i++) { + mod = modifier_by_name(s); + if (mod == 0) + break; + kb->mods |= mod; + s = strtok(NULL, " \t\n\r"); + } + + // key + kb->key = xkb_keysym_from_name(s, XKB_KEYSYM_CASE_INSENSITIVE); + if (kb->key == XKB_KEY_NoSymbol) { + wlr_log(WLR_ERROR, "Config line %i: No such key '%s'.", line, s); + free(kb); + return; + } + + // action + s = strtok(NULL, " \t\n\r"); + assign_action(s, strtok(NULL, ""), kb); + if (kb->action == NULL) { + wlr_log(WLR_ERROR, "Config line %i: No such action '%s'.", line, s); + free(kb); + return; + } + + struct keybinding *kb_existing; + wl_list_for_each(kb_existing, &server->keybindings, link) { + if (kb_existing->key == kb->key && kb_existing->mods == kb->mods) { + wlr_log(WLR_ERROR, "Config line %i: binding exists for key combo.", line); + free(kb); + return; + } + } + wl_list_insert(&server->keybindings, &kb->link); } @@ -193,7 +284,7 @@ struct server *server = wl_container_of(listener, server, cursor_axis_listener); struct wlr_event_pointer_axis *event = data; if (server->cursor_mode == CURSOR_PAN) { - zoom_desk(server->current_desk, event->delta); + zoom_desk(server, &event->delta); } else { wlr_seat_pointer_notify_axis( server->seat, event->time_msec, event->orientation, event->delta, @@ -223,46 +314,6 @@ } -bool handle_keybinding(struct server *server, xkb_keysym_t sym) { - switch (sym) { - - case XKB_KEY_Up: - if (fork() == 0) { - execl("/usr/bin/thunar", "/usr/bin/thunar", (void *)NULL); - } - break; - - case XKB_KEY_Escape: - wl_display_terminate(server->display); - break; - - case XKB_KEY_Left: - prev_desk(server); - break; - - case XKB_KEY_Right: - next_desk(server); - break; - - case XKB_KEY_Q: - close_current_window(server); - break; - - case XKB_KEY_r: - reset_pan(server->current_desk); - break; - - case XKB_KEY_R: - save_pan(server->current_desk); - break; - - default: - return false; - } - return true; -} - - void on_key(struct wl_listener *listener, void *data) { struct keyboard *keyboard = wl_container_of(listener, keyboard, key_listener); struct server *server = keyboard->server; @@ -278,9 +329,17 @@ bool handled = false; uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); + struct keybinding *kb; if ((modifiers & server->mod) && event->state == WLR_KEY_PRESSED) { + modifiers &= ~server->mod; for (int i = 0; i < nsyms; i++) { - handled = handle_keybinding(server, syms[i]); + wl_list_for_each(kb, &server->keybindings, link) { + if (syms[i] == kb->key && modifiers == kb->mods) { + kb->action(server, kb->data); + handled = true; + } else if (modifiers == kb->mods) { + } + } } }
src/desk.h Modified
@@ -5,11 +5,11 @@ void add_desk(struct server *server); void remove_desk(struct desk *desk); -void next_desk(struct server *server); -void prev_desk(struct server *server); -void reset_pan(struct desk *desk); -void save_pan(struct desk *desk); -void zoom_desk(struct desk *desk, int dir); +void next_desk(struct server *server, void *data); +void prev_desk(struct server *server, void *data); +void reset_pan(struct server *server, void *data); +void save_pan(struct server *server, void *data); +void zoom_desk(struct server *server, void *data); struct wallpaper { struct wlr_texture *texture;
src/desk.c Modified
@@ -38,7 +38,7 @@ } -void next_desk(struct server *server) { +void next_desk(struct server *server, void *data) { struct desk *desk; if (server->current_desk->index + 1 == num_desks) { desk = wl_container_of(server->desks.next, desk, link); @@ -49,7 +49,7 @@ } -void prev_desk(struct server *server) { +void prev_desk(struct server *server, void *data) { struct desk *desk; if (server->current_desk->index == 0) { desk = wl_container_of(server->desks.prev, desk, link); @@ -60,7 +60,8 @@ } -void reset_pan(struct desk *desk) { +void reset_pan(struct server *server, void *data) { + struct desk *desk = server->current_desk; struct view *view; wl_list_for_each(view, &desk->views, link) { view->x -= desk->panned_x; @@ -71,14 +72,15 @@ } -void save_pan(struct desk *desk) { - desk->panned_x = desk->panned_y = 0; +void save_pan(struct server *server, void *data) { + server->current_desk->panned_x = server->current_desk->panned_y = 0; } -void zoom_desk(struct desk *desk, int dir) { +void zoom_desk(struct server *server, void *data) { /* dir > 0 ? zoom in : zoom out */ - struct server *server = desk->server; + struct desk *desk = server->current_desk; + int dir = *(int*)data; double f = dir > 0 ? 1.015 : 1/1.015; if ( (f > 1 && desk->zoom >= server->zoom_max) ||
src/config.c Modified
@@ -93,6 +93,7 @@ server->zoom_max = 3; server->mod = WLR_MODIFIER_LOGO; + wl_list_init(&server->keybindings); } @@ -120,7 +121,9 @@ char *s; char linebuf[1024]; + int line = 0; while (fgets(linebuf, sizeof(linebuf), fd)) { + line++; if (!(s = strtok(linebuf, " \t\n\r")) || s[0] == '#') { continue; } @@ -132,7 +135,7 @@ } } else if (!strcasecmp(s, "set_modifier")) { if ((s = strtok(NULL, " \t\n\r"))) { - set_modifier(server, s); + server->mod = modifier_by_name(s); } } else if (!strcasecmp(s, "zoom_min")) { if ((s = strtok(NULL, " \t\n\r")) && is_decimal(s)) { @@ -142,6 +145,8 @@ if ((s = strtok(NULL, " \t\n\r")) && is_decimal(s)) { server->zoom_max = strtod(s, NULL); } + } else if (!strcasecmp(s, "bind")) { + add_binding(server, strtok(NULL, ""), line); } } fclose(fd);
deskwm.conf Modified
@@ -13,12 +13,35 @@ # ignored. Options that are commented out contain their default values. +## General settings + # These specify the min and max magnification bounds when zooming. #zoom_min 0.5 #zoom_max 3 +## Keybindings + +# Set the modifier key used for keybindings +# Can be one of: Shift, Caps, Ctrl, Alt, Mod2, Mod3, Logo, Mod5 +#set_modifier Logo + +# Define keybindings +# additional modifiers, key, action(, data) +bind Ctrl Escape shutdown +bind Ctrl q close_current_window +bind Tab next_desk +bind ISO_Left_Tab prev_desk +bind r save_pan +bind Shift r reset_pan +bind i zoom_desk 1 +bind o zoom_desk -1 +# The line after 'exec' is executed by /bin/sh +bind Return exec wterm + + ## Configure desks + # Commands until a further desk is added pertain to desk 1. # This can be a path to a png image, or a colour in the form #rrggbb.