Add wmenu-run executable

This commit is contained in:
adnano 2024-05-02 21:39:54 -04:00
parent 1f221a73cf
commit 41e8599392
7 changed files with 103 additions and 1 deletions

2
menu.c
View file

@ -529,6 +529,8 @@ void menu_keypress(struct menu *menu, enum wl_keyboard_key_state key_state,
puts(menu->input); puts(menu->input);
fflush(stdout); fflush(stdout);
menu->exit = true; menu->exit = true;
} else if (menu->callback) {
menu->callback(menu);
} else { } else {
char *text = menu->sel ? menu->sel->text : menu->input; char *text = menu->sel ? menu->sel->text : menu->input;
puts(text); puts(text);

1
menu.h
View file

@ -68,6 +68,7 @@ struct menu {
struct item *sel; // selected item struct item *sel; // selected item
struct page *pages; // list of pages struct page *pages; // list of pages
void (*callback)(struct menu *menu);
bool exit; bool exit;
bool failure; bool failure;
}; };

View file

@ -38,12 +38,35 @@ install_data('wmenu_run', install_dir: get_option('bindir'))
executable( executable(
'wmenu', 'wmenu',
files( files(
'main.c',
'menu.c', 'menu.c',
'pango.c', 'pango.c',
'pool-buffer.c', 'pool-buffer.c',
'render.c', 'render.c',
'wayland.c', 'wayland.c',
'wmenu.c',
),
dependencies: [
cairo,
client_protos,
pango,
pangocairo,
rt,
wayland_client,
wayland_protos,
xkbcommon,
],
install: true,
)
executable(
'wmenu-run',
files(
'menu.c',
'pango.c',
'pool-buffer.c',
'render.c',
'wayland.c',
'wmenu-run.c',
), ),
dependencies: [ dependencies: [
cairo, cairo,

View file

@ -128,6 +128,11 @@ struct xkb_state *context_get_xkb_state(struct wl_context *context) {
return context->keyboard->state; return context->keyboard->state;
} }
// Returns the XDG activation object for the context.
struct xdg_activation_v1 *context_get_xdg_activation(struct wl_context *context) {
return context->activation;
}
// Retrieves pasted text from a Wayland data offer. // Retrieves pasted text from a Wayland data offer.
bool context_paste(struct wl_context *context) { bool context_paste(struct wl_context *context) {
if (!context->data_offer) { if (!context->data_offer) {

View file

@ -13,6 +13,7 @@ struct pool_buffer *context_get_current_buffer(struct wl_context *context);
struct pool_buffer *context_get_next_buffer(struct wl_context *context, int scale); struct pool_buffer *context_get_next_buffer(struct wl_context *context, int scale);
struct wl_surface *context_get_surface(struct wl_context *context); struct wl_surface *context_get_surface(struct wl_context *context);
struct xkb_state *context_get_xkb_state(struct wl_context *context); struct xkb_state *context_get_xkb_state(struct wl_context *context);
struct xdg_activation_v1 *context_get_xdg_activation(struct wl_context *context);
bool context_paste(struct wl_context *context); bool context_paste(struct wl_context *context);
#endif #endif

70
wmenu-run.c Normal file
View file

@ -0,0 +1,70 @@
#define _POSIX_C_SOURCE 200809L
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "menu.h"
#include "wayland.h"
#include "xdg-activation-v1-client-protocol.h"
static void read_items(struct menu *menu) {
char buf[sizeof menu->input];
while (fgets(buf, sizeof buf, stdin)) {
char *p = strchr(buf, '\n');
if (p) {
*p = '\0';
}
menu_add_item(menu, strdup(buf));
}
}
struct executable {
struct menu *menu;
char *name;
};
static void activation_token_done(void *data, struct xdg_activation_token_v1 *activation_token,
const char *token) {
struct executable *exe = data;
xdg_activation_token_v1_destroy(activation_token);
menu_destroy(exe->menu);
setenv("XDG_ACTIVATION_TOKEN", token, true);
execlp(exe->name, exe->name, NULL);
fprintf(stderr, "Failed to execute selection: %s\n", strerror(errno));
free(exe->name);
free(exe);
exit(EXIT_FAILURE);
}
static const struct xdg_activation_token_v1_listener activation_token_listener = {
.done = activation_token_done,
};
static void exec(struct menu *menu) {
if (!menu->sel) {
return;
}
struct executable *exe = calloc(1, sizeof(struct executable));
exe->menu = menu;
exe->name = strdup(menu->sel->text);
struct xdg_activation_v1 *activation = context_get_xdg_activation(menu->context);
struct xdg_activation_token_v1 *activation_token = xdg_activation_v1_get_activation_token(activation);
xdg_activation_token_v1_set_surface(activation_token, context_get_surface(menu->context));
xdg_activation_token_v1_add_listener(activation_token, &activation_token_listener, exe);
xdg_activation_token_v1_commit(activation_token);
}
int main(int argc, char *argv[]) {
struct menu *menu = menu_create();
menu->callback = exec;
menu_getopts(menu, argc, argv);
read_items(menu);
int status = menu_run(menu);
menu_destroy(menu);
return status;
}

View file