From 6d80584299e56a937120fbf47520e62fc2b07a37 Mon Sep 17 00:00:00 2001 From: sewn Date: Thu, 27 Jun 2024 02:44:26 +0300 Subject: [PATCH] support xdg_activation_v1 and implement passing to execution flag --- Makefile | 11 ++++++++--- mew-run | 2 +- mew.1 | 12 +++++++++--- mew.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 67 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index f6c1add..eb579e4 100644 --- a/Makefile +++ b/Makefile @@ -30,14 +30,19 @@ all: mew config.h: cp config.def.h $@ -mew.o: config.h wlr-layer-shell-unstable-v1-protocol.h xdg-shell-protocol.h +mew.o: config.h wlr-layer-shell-unstable-v1-protocol.h xdg-activation-v1-protocol.h xdg-shell-protocol.h -mew: wlr-layer-shell-unstable-v1-protocol.o xdg-shell-protocol.o mew.o - $(CC) $(LDFLAGS) -o $@ wlr-layer-shell-unstable-v1-protocol.o xdg-shell-protocol.o mew.o $(LDLIBS) +mew: wlr-layer-shell-unstable-v1-protocol.o xdg-activation-v1-protocol.o xdg-shell-protocol.o mew.o + $(CC) $(LDFLAGS) -o $@ wlr-layer-shell-unstable-v1-protocol.o xdg-activation-v1-protocol.o xdg-shell-protocol.o mew.o $(LDLIBS) WAYLAND_PROTOCOLS = `$(PKG_CONFIG) --variable=pkgdatadir wayland-protocols` WAYLAND_SCANNER = `$(PKG_CONFIG) --variable=wayland_scanner wayland-scanner` +xdg-activation-v1-protocol.h: + $(WAYLAND_SCANNER) client-header $(WAYLAND_PROTOCOLS)/staging/xdg-activation/xdg-activation-v1.xml $@ +xdg-activation-v1-protocol.c: + $(WAYLAND_SCANNER) private-code $(WAYLAND_PROTOCOLS)/staging/xdg-activation/xdg-activation-v1.xml $@ + xdg-shell-protocol.h: $(WAYLAND_SCANNER) client-header $(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@ xdg-shell-protocol.c: diff --git a/mew-run b/mew-run index 5297387..b86f66d 100755 --- a/mew-run +++ b/mew-run @@ -32,4 +32,4 @@ path() { fi } -path | mew "$@" | ${SHELL:-"/bin/sh"} & +path | mew -e "$@" diff --git a/mew.1 b/mew.1 index 81682ac..5630093 100644 --- a/mew.1 +++ b/mew.1 @@ -3,7 +3,7 @@ mew \- menu for wayland .SH SYNOPSIS .B mew -.RB [ \-biv ] +.RB [ \-beiv ] .RB [ \-l .IR lines ] .RB [ \-p @@ -28,13 +28,19 @@ to stdout and mew terminates. Entering text will narrow the items to those matching the tokens in the input. .P .B mew-run -is a script spawned by the compositor that lists programs in the user's $PATH and -runs the result in their $SHELL. +is a script that lists programs in the user's $PATH and runs the result with +.BR mew\ -e . .SH OPTIONS .TP .B \-b appear at the bottom of the screen. .TP +.B \-e +execute input or selection with +.BR /bin/sh , +accompanied by a xdg activation token in it's environment, subsequently +passing focus to the application ran. +.TP .B \-i matches menu items case insensitively. .TP diff --git a/mew.c b/mew.c index 4c59f80..a0ea22f 100644 --- a/mew.c +++ b/mew.c @@ -18,6 +18,7 @@ #include "drwl.h" #include "poolbuf.h" +#include "xdg-activation-v1-protocol.h" #include "wlr-layer-shell-unstable-v1-protocol.h" #define TEXTW(X) (drwl_font_getwidth(drw, (X)) + lrpad) @@ -66,6 +67,7 @@ static struct wl_data_device *data_device; static struct wl_data_offer *data_offer; static struct zwlr_layer_shell_v1 *layer_shell; static struct zwlr_layer_surface_v1 *layer_surface; +static struct xdg_activation_v1 *activation; static struct wl_surface *surface; static struct wl_registry *registry; static Drwl *drw; @@ -74,6 +76,7 @@ static Drwl *drw; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; +static int (*submit)(const char*) = puts; static void noop() @@ -100,6 +103,44 @@ die(const char *fmt, ...) exit(EXIT_FAILURE); } +static void +activation_token_handle_done(void *data, + struct xdg_activation_token_v1 *activation_token, const char *token) +{ + char *argv[] = {"/bin/sh", "-c", (char*)data, NULL}; + + xdg_activation_token_v1_destroy(activation_token); + + switch (fork()) { + case -1: + die("fork:"); + case 0: + setenv("XDG_ACTIVATION_TOKEN", token, 1); + execv(argv[0], argv); + die("execvp:"); + } + + running = 0; +} + +static const struct xdg_activation_token_v1_listener activation_token_listener = { + .done = activation_token_handle_done, +}; + +static int +exec_cmd(const char *text) +{ + struct xdg_activation_token_v1 *activation_token; + + activation_token = xdg_activation_v1_get_activation_token(activation); + xdg_activation_token_v1_set_surface(activation_token, surface); + xdg_activation_token_v1_add_listener(activation_token, + &activation_token_listener, (void *)text); + xdg_activation_token_v1_commit(activation_token); + + return 0; +} + static void parse_color(uint32_t *dest, const char *src) { @@ -185,6 +226,7 @@ cleanup(void) wl_data_device_release(data_device); zwlr_layer_shell_v1_destroy(layer_shell); + xdg_activation_v1_destroy(activation); wl_shm_destroy(shm); wl_compositor_destroy(compositor); wl_registry_destroy(registry); @@ -538,8 +580,8 @@ keyboard_keypress(enum wl_keyboard_key_state state, xkb_keysym_t sym, int ctrl, break; case XKB_KEY_Return: case XKB_KEY_KP_Enter: - puts((sel && !shift) ? sel->text : text); - if (!ctrl) + submit((sel && !shift) ? sel->text : text); + if (!ctrl && submit != exec_cmd) running = 0; return; case XKB_KEY_Right: @@ -741,6 +783,8 @@ registry_handle_global(void *data, struct wl_registry *registry, else if (!strcmp(interface, wl_data_device_manager_interface.name)) data_device_manager = wl_registry_bind(registry, name, &wl_data_device_manager_interface, 3); + else if (!strcmp(interface, xdg_activation_v1_interface.name)) + activation = wl_registry_bind(registry, name, &xdg_activation_v1_interface, 1); else if (!strcmp(interface, wl_seat_interface.name)) { seat = wl_registry_bind (registry, name, &wl_seat_interface, 4); wl_seat_add_listener(seat, &seat_listener, NULL); @@ -869,7 +913,7 @@ setup(void) static void usage(void) { - die("usage: mew [-biv] [-l lines] [-p prompt] [-f font]\n" + die("usage: mew [-beiv] [-l lines] [-p prompt] [-f font]\n" " [-nb color] [-nf color] [-sb color] [-sf color]"); } @@ -885,6 +929,8 @@ main(int argc, char *argv[]) exit(0); } else if (!strcmp(argv[i], "-b")) top = 0; + else if (!strcmp(argv[i], "-e")) + submit = exec_cmd; else if (!strcmp(argv[i], "-i")) { fstrncmp = strncasecmp; fstrstr = cistrstr;