diff options
author | Josh Rahm <rahm@google.com> | 2024-03-05 10:24:45 -0700 |
---|---|---|
committer | Josh Rahm <rahm@google.com> | 2024-03-05 10:24:45 -0700 |
commit | dc83dc6725c7af7dc7345b6085ac8f281602946a (patch) | |
tree | 480e644bc144fbab444dd46c1fff4dcd4be74455 | |
parent | ba40cdae500f153633dc306c03b0709c2c6f0276 (diff) | |
download | wetterhorn-dc83dc6725c7af7dc7345b6085ac8f281602946a.tar.gz wetterhorn-dc83dc6725c7af7dc7345b6085ac8f281602946a.tar.bz2 wetterhorn-dc83dc6725c7af7dc7345b6085ac8f281602946a.zip |
Added some escape-hatch keybindings for Wetterhorn.
Specifically a way to reload the plugin and switch vterms. This is
important in case the plugin is borked and stops accepting keyboard, the
user can switch to a vterm, fix the plugin and reload it to get things
working again without running into data loss.
-rw-r--r-- | Setup.hs | 2 | ||||
-rw-r--r-- | harness/include/wl.h | 4 | ||||
-rw-r--r-- | harness/src/wl.c | 48 | ||||
-rw-r--r-- | src/Wetterhorn/Core/W.hs | 1 |
4 files changed, 43 insertions, 12 deletions
@@ -19,7 +19,7 @@ main = do let buildPath = fromJust (flagToMaybe $ configDistPref conf) callCommand $ - printf "cd wlroots && meson setup %s -Dexamples=false --reconfigure" (wlrootsDir buildPath) + printf "cd wlroots && meson setup %s -Dexamples=false -Dbackends=x11,drm,libinput --reconfigure" (wlrootsDir buildPath) callCommand $ printf "cmake -B %s -S harness" (harnessDir buildPath) diff --git a/harness/include/wl.h b/harness/include/wl.h index b8d4e14..903ba10 100644 --- a/harness/include/wl.h +++ b/harness/include/wl.h @@ -6,10 +6,11 @@ #include <unistd.h> #include <wayland-server-core.h> #include <wlr/backend.h> +#include <wlr/backend/session.h> #include <wlr/render/allocator.h> #include <wlr/render/wlr_renderer.h> -#include <wlr/types/wlr_cursor.h> #include <wlr/types/wlr_compositor.h> +#include <wlr/types/wlr_cursor.h> #include <wlr/types/wlr_data_device.h> #include <wlr/types/wlr_input_device.h> #include <wlr/types/wlr_keyboard.h> @@ -68,6 +69,7 @@ struct tinywl_server { struct wl_list outputs; struct wl_listener new_output; + struct wlr_session *session; plugin_t plugin; }; diff --git a/harness/src/wl.c b/harness/src/wl.c index 0bd0410..f083a5e 100644 --- a/harness/src/wl.c +++ b/harness/src/wl.c @@ -105,15 +105,43 @@ static void keyboard_handle_key(struct wl_listener *listener, void *data) int handled = false; uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->wlr_keyboard); uint32_t codepoint; - /* Pass the information along to the plugin for the plugin to handle. The - * plugin will return via 'handled' whether or not the key event was handled - * or not. */ - if (nsyms > 0) { - codepoint = - xkb_state_key_get_utf32(keyboard->wlr_keyboard->xkb_state, keycode); - plugin_call_update_state(server->plugin, plugin_handle_keybinding, - keyboard->wlr_keyboard, event, modifiers, syms[0], - codepoint, &handled); + int ec; + + if (nsyms > 0 && syms[0] >= XKB_KEY_XF86Switch_VT_1 && + syms[0] <= XKB_KEY_XF86Switch_VT_12) { + /* Escape-hatch to change sessions. These should always be available key + * bindings regardless of what the plugin dictates. This allows an escape + * hatch to edit the plugin in a different vterm and then use the escape + * hatch below to hot-restart the plugin if things get borked. */ + if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + wlr_session_change_vt(server->session, + syms[0] - XKB_KEY_XF86Switch_VT_1 + 1); + } + } + else if (modifiers == + (WLR_MODIFIER_SHIFT | WLR_MODIFIER_CTRL | WLR_MODIFIER_ALT) && + nsyms > 0 && syms[0] == XKB_KEY_Escape) { + /* Escape-hatch to hot-reload the plugin in case the plugin got borked and + * stops accepting keybindings. Ctrl+Shift+Alt+Escape will always reload the + * plugin.*/ + if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + if ((ec = plugin_hot_reload_same_state(&server->plugin)) != 0) { + fprintf(stderr, "Failed to hot reload plugin"); + exit(1); + } + } + } + else { + /* Pass the information along to the plugin for the plugin to handle. The + * plugin will return via 'handled' whether or not the key event was handled + * or not. */ + if (nsyms > 0) { + codepoint = + xkb_state_key_get_utf32(keyboard->wlr_keyboard->xkb_state, keycode); + plugin_call_update_state(server->plugin, plugin_handle_keybinding, + keyboard->wlr_keyboard, event, modifiers, + syms[0], codepoint, &handled); + } } } @@ -806,7 +834,7 @@ int main(int argc, char *argv[]) * output hardware. The autocreate option will choose the most suitable * backend based on the current environment, such as opening an X11 window * if an X11 server is running. */ - server.backend = wlr_backend_autocreate(server.wl_display, NULL); + server.backend = wlr_backend_autocreate(server.wl_display, &server.session); if (server.backend == NULL) { wlr_log(WLR_ERROR, "failed to create wlr_backend"); return 1; diff --git a/src/Wetterhorn/Core/W.hs b/src/Wetterhorn/Core/W.hs index b809545..b2c6b51 100644 --- a/src/Wetterhorn/Core/W.hs +++ b/src/Wetterhorn/Core/W.hs @@ -224,6 +224,7 @@ shellExec = wio . ForeignInterface.doShellExec wio :: IO a -> W a wio = liftIO +-- | Type class to lift an arbitrary 'W' computation into another monad. class Wlike m where liftW :: W a -> m a |