aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Rahm <rahm@google.com>2024-03-05 10:24:45 -0700
committerJosh Rahm <rahm@google.com>2024-03-05 10:24:45 -0700
commitdc83dc6725c7af7dc7345b6085ac8f281602946a (patch)
tree480e644bc144fbab444dd46c1fff4dcd4be74455
parentba40cdae500f153633dc306c03b0709c2c6f0276 (diff)
downloadwetterhorn-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.hs2
-rw-r--r--harness/include/wl.h4
-rw-r--r--harness/src/wl.c48
-rw-r--r--src/Wetterhorn/Core/W.hs1
4 files changed, 43 insertions, 12 deletions
diff --git a/Setup.hs b/Setup.hs
index 50385ed..f3a2180 100644
--- a/Setup.hs
+++ b/Setup.hs
@@ -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