commit: f630001c12464c6e87b88a17dfe22f0720472e87
parent: 873201bd3820be6fa456c74c97a42d902055718c
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Mon, 8 Jul 2019 11:42:25 +0200
Make bindings configuration similar to dwm
Diffstat:
M | config.h | 27 | ++++++++++++++++++++------- |
M | inaban.c | 89 | ++++++++++++++++++++++++++++++++++++------------------------------------------- |
M | inaban.h | 21 | +++++++++++++++++++++ |
3 files changed, 82 insertions(+), 55 deletions(-)
diff --git a/config.h b/config.h
@@ -1,7 +1,20 @@
-#define INABAN_BINDING_MOD WLR_MODIFIER_ALT
-#define INABAN_CMD_LAUNCHER "bemenu-run"
-#define INABAN_CMD_TERMINAL "wlterm"
-#define INABAN_MODBIND_LAUNCHER XKB_KEY_p
-#define INABAN_MODBIND_NEXT_VIEW XKB_KEY_j
-#define INABAN_MODBIND_TERMINAL XKB_KEY_Return
-#define INABAN_MODBIND_TERMINATE XKB_KEY_Escape
+#ifndef CONFIG_H
+#define CONFIG_H
+
+static const char *menucmd[] = {"bemenu-run", NULL};
+static const char *termcmd[] = {"cage", "-d", "st", NULL};
+
+// See `enum wlr_keyboard_modifier` in `<wlr/types/wlr_keyboard.h>`
+#define MODKEY WLR_MODIFIER_ALT
+// clang-format off
+static Shortcut shortcuts[] = {
+ /* modifier, keysym, function, argument */
+ {MODKEY, XKB_KEY_p, spawn, {.v = menucmd}},
+ {MODKEY | ShiftMask, XKB_KEY_Return, spawn, {.v = termcmd}},
+ {MODKEY | ShiftMask, XKB_KEY_q, quit, {0}},
+// {MODKEY | ShiftMask, XKB_KEY_c, killclient, {0}},
+// {MODKEY, XKB_KEY_j, focusstack, {.i = +1}},
+// {MODKEY, XKB_KEY_k, focusstack, {.i = -1}},
+};
+// clang-format on
+#endif /* CONFIG_H */
diff --git a/inaban.c b/inaban.c
@@ -11,10 +11,26 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
+#include <unistd.h> /* execvp() */
#include <unistd.h>
+#define LENGTH(X) (sizeof X / sizeof X[0])
+
struct inaban_server server = {0};
+void
+spawn(const Arg *arg)
+{
+ if(fork() == 0)
+ {
+ setsid();
+ execvp(((char **)arg->v)[0], (char **)arg->v);
+ fprintf(stderr, "execvp %s", ((char **)arg->v)[0]);
+ perror(" failed");
+ exit(EXIT_SUCCESS);
+ }
+}
+
static void
focus_view(struct inaban_view *view, struct wlr_surface *surface)
{
@@ -53,12 +69,12 @@ focus_view(struct inaban_view *view, struct wlr_surface *surface)
&keyboard->modifiers);
}
+/* This event is raised when a modifier key, such as shift or alt, is pressed.
+ * We simply communicate this to the client. */
static void
keyboard_handle_modifiers(struct wl_listener *listener, void *data)
{
(void)data;
- /* This event is raised when a modifier key, such as shift or alt, is
- * pressed. We simply communicate this to the client. */
struct inaban_keyboard *keyboard = wl_container_of(listener, keyboard, modifiers);
/*
* A seat can only have one keyboard, but this is a limitation of the
@@ -72,68 +88,37 @@ keyboard_handle_modifiers(struct wl_listener *listener, void *data)
&keyboard->device->keyboard->modifiers);
}
-static bool
-handle_keybinding(struct inaban_server *server, xkb_keysym_t sym)
-{
- /*
- * Here we handle compositor keybindings. This is when the compositor is
- * processing keys, rather than passing them on to the client for its own
- * processing.
- *
- * This function assumes Mod (such as Alt or Logo) is held down.
- */
- switch(sym)
- {
- case INABAN_MODBIND_TERMINATE: wl_display_terminate(server->wl_display); break;
- case INABAN_MODBIND_NEXT_VIEW:
- /* Cycle to the next view */
- if(wl_list_length(&server->views) < 2) break;
- struct inaban_view *current_view = wl_container_of(server->views.next, current_view, link);
- struct inaban_view *next_view = wl_container_of(current_view->link.next, next_view, link);
- focus_view(next_view, next_view->xdg_surface->surface);
- /* Move the previous view to the end of the list */
- wl_list_remove(¤t_view->link);
- wl_list_insert(server->views.prev, ¤t_view->link);
- break;
- case INABAN_MODBIND_LAUNCHER:
- if(fork() == 0) execl("/bin/sh", "/bin/sh", "-c", INABAN_CMD_LAUNCHER, (void *)NULL);
- break;
- case INABAN_MODBIND_TERMINAL:
- if(fork() == 0) execl("/bin/sh", "/bin/sh", "-c", INABAN_CMD_TERMINAL, (void *)NULL);
- break;
- default: return false;
- }
- return true;
-}
-
+/* This event is raised when a key is pressed or released. */
static void
keyboard_handle_key(struct wl_listener *listener, void *data)
{
- /* This event is raised when a key is pressed or released. */
struct inaban_keyboard *keyboard = wl_container_of(listener, keyboard, key);
struct inaban_server *server = keyboard->server;
struct wlr_event_keyboard_key *event = data;
struct wlr_seat *seat = server->seat;
/* Translate libinput keycode -> xkbcommon */
- uint32_t keycode = event->keycode + 8;
- /* Get a list of keysyms based on the keymap for this keyboard */
- const xkb_keysym_t *syms;
- int nsyms = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, keycode, &syms);
+ uint32_t keycode = event->keycode + 8;
+ xkb_keysym_t keysym = xkb_state_key_get_one_sym(keyboard->device->keyboard->xkb_state, keycode);
bool handled = false;
uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard);
- if((modifiers & INABAN_BINDING_MOD) && event->state == WLR_KEY_PRESSED)
+
+ if(event->state == WLR_KEY_PRESSED)
{
- /* If alt is held down and this button was _pressed_, we attempt to
- * process it as a compositor keybinding. */
- for(int i = 0; i < nsyms; i++)
- handled = handle_keybinding(server, syms[i]);
+ wlr_log(WLR_DEBUG, "key_pressed: {modifiers: %x, keycode: %x, keysym: %x}", modifiers, keycode, keysym);
+
+ for(size_t i = 0; i < LENGTH(shortcuts); i++)
+ if((keysym == shortcuts[i].keysym) && (modifiers == shortcuts[i].mod) && shortcuts[i].func)
+ {
+ shortcuts[i].func(&(shortcuts[i].arg));
+ handled = true;
+ }
}
+ /* Otherwise, we pass it along to the client. */
if(!handled)
{
- /* Otherwise, we pass it along to the client. */
wlr_seat_set_keyboard(seat, keyboard->device);
wlr_seat_keyboard_notify_key(seat, event->time_msec, event->keycode, event->state);
}
@@ -625,6 +610,13 @@ drop_permissions(void)
}
void
+quit(const Arg *arg)
+{
+ (void)arg;
+ wl_display_terminate(server.wl_display);
+}
+
+void
sigterm_handler(int signal)
{
(void)signal;
@@ -632,7 +624,8 @@ sigterm_handler(int signal)
}
void
-usage(char *argv0) {
+usage(char *argv0)
+{
printf("Usage: %s [-s startup command]\n", argv0);
}
diff --git a/inaban.h b/inaban.h
@@ -1,6 +1,8 @@
// Copyright 2019 Haelwenn (lanodan) Monnier
// Distributed under the terms of the BSD License
// Based on wlroots's TinyWL which is distributed under CC0
+#ifndef INABAN_H
+#define INABAN_H
#include <stdbool.h>
#include <wayland-server.h>
#include <wlr/backend.h>
@@ -89,3 +91,22 @@ struct render_data
struct inaban_view *view;
struct timespec *when;
};
+
+typedef union {
+ int i;
+ unsigned int ui;
+ float f;
+ const void *v;
+} Arg;
+
+typedef struct
+{
+ uint32_t mod;
+ xkb_keysym_t keysym;
+ void (*func)(const Arg *);
+ const Arg arg;
+} Shortcut;
+
+void spawn(const Arg *arg);
+void quit(const Arg *arg);
+#endif /* INABAN_H */