Streamline menu callbacks

This commit is contained in:
adnano 2024-06-09 20:30:58 -04:00
parent a0df7959f9
commit 7d717b3696
5 changed files with 42 additions and 36 deletions

15
menu.c
View file

@ -22,7 +22,7 @@
#include "wayland.h" #include "wayland.h"
// Creates and returns a new menu. // Creates and returns a new menu.
struct menu *menu_create() { struct menu *menu_create(menu_callback callback) {
struct menu *menu = calloc(1, sizeof(struct menu)); struct menu *menu = calloc(1, sizeof(struct menu));
menu->strncmp = strncmp; menu->strncmp = strncmp;
menu->font = "monospace 10"; menu->font = "monospace 10";
@ -32,6 +32,7 @@ struct menu *menu_create() {
menu->promptfg = 0xeeeeeeff; menu->promptfg = 0xeeeeeeff;
menu->selectionbg = 0x005577ff; menu->selectionbg = 0x005577ff;
menu->selectionfg = 0xeeeeeeff; menu->selectionfg = 0xeeeeeeff;
menu->callback = callback;
return menu; return menu;
} }
@ -571,18 +572,10 @@ void menu_keypress(struct menu *menu, enum wl_keyboard_key_state key_state,
case XKB_KEY_Return: case XKB_KEY_Return:
case XKB_KEY_KP_Enter: case XKB_KEY_KP_Enter:
if (shift) { if (shift) {
puts(menu->input); menu->callback(menu, menu->input, true);
fflush(stdout);
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); menu->callback(menu, text, !ctrl);
fflush(stdout);
if (!ctrl) {
menu->exit = true;
}
} }
break; break;
case XKB_KEY_Left: case XKB_KEY_Left:

7
menu.h
View file

@ -6,6 +6,9 @@
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
#include <wayland-client.h> #include <wayland-client.h>
struct menu;
typedef void (*menu_callback)(struct menu *menu, char *text, bool exit);
// A menu item. // A menu item.
struct item { struct item {
char *text; char *text;
@ -68,12 +71,12 @@ 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); menu_callback callback;
bool exit; bool exit;
bool failure; bool failure;
}; };
struct menu *menu_create(); struct menu *menu_create(menu_callback callback);
void menu_destroy(struct menu *menu); void menu_destroy(struct menu *menu);
void menu_getopts(struct menu *menu, int argc, char *argv[]); void menu_getopts(struct menu *menu, int argc, char *argv[]);
void menu_add_item(struct menu *menu, char *text, bool sort); void menu_add_item(struct menu *menu, char *text, bool sort);

View file

@ -494,11 +494,10 @@ int menu_run(struct menu *menu) {
} }
} }
bool failure = menu->failure;
context_destroy(context); context_destroy(context);
menu->context = NULL; menu->context = NULL;
if (failure) { if (menu->failure) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;

View file

@ -1,6 +1,6 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -27,46 +27,48 @@ static void read_items(struct menu *menu) {
free(path); free(path);
} }
struct executable { struct command {
struct menu *menu; struct menu *menu;
char *name; char *text;
bool exit;
}; };
static void activation_token_done(void *data, struct xdg_activation_token_v1 *activation_token, static void activation_token_done(void *data, struct xdg_activation_token_v1 *activation_token,
const char *token) { const char *token) {
struct executable *exe = data; struct command *cmd = data;
xdg_activation_token_v1_destroy(activation_token); xdg_activation_token_v1_destroy(activation_token);
menu_destroy(exe->menu);
setenv("XDG_ACTIVATION_TOKEN", token, true); int pid = fork();
char* cmd[] = {"/bin/sh", "-c", exe->name, NULL}; if (pid == 0) {
execvp(cmd[0], (char**)cmd); setenv("XDG_ACTIVATION_TOKEN", token, true);
char *argv[] = {"/bin/sh", "-c", cmd->text, NULL};
fprintf(stderr, "Failed to execute selection: %s\n", strerror(errno)); execvp(argv[0], (char**)argv);
free(exe->name); } else {
free(exe); if (cmd->exit) {
exit(EXIT_FAILURE); cmd->menu->exit = true;
}
}
} }
static const struct xdg_activation_token_v1_listener activation_token_listener = { static const struct xdg_activation_token_v1_listener activation_token_listener = {
.done = activation_token_done, .done = activation_token_done,
}; };
static void exec(struct menu *menu) { static void exec_item(struct menu *menu, char *text, bool exit) {
struct executable *exe = calloc(1, sizeof(struct executable)); struct command *cmd = calloc(1, sizeof(struct command));
exe->menu = menu; cmd->menu = menu;
exe->name = strdup(menu->input); cmd->text = strdup(text);
cmd->exit = exit;
struct xdg_activation_v1 *activation = context_get_xdg_activation(menu->context); 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); 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_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_add_listener(activation_token, &activation_token_listener, cmd);
xdg_activation_token_v1_commit(activation_token); xdg_activation_token_v1_commit(activation_token);
} }
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
struct menu *menu = menu_create(); struct menu *menu = menu_create(exec_item);
menu->callback = exec;
menu_getopts(menu, argc, argv); menu_getopts(menu, argc, argv);
read_items(menu); read_items(menu);
int status = menu_run(menu); int status = menu_run(menu);

11
wmenu.c
View file

@ -1,5 +1,6 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <string.h> #include <string.h>
#include "menu.h" #include "menu.h"
@ -16,8 +17,16 @@ static void read_items(struct menu *menu) {
} }
} }
static void print_item(struct menu *menu, char *text, bool exit) {
puts(text);
fflush(stdout);
if (exit) {
menu->exit = true;
}
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
struct menu *menu = menu_create(); struct menu *menu = menu_create(print_item);
menu_getopts(menu, argc, argv); menu_getopts(menu, argc, argv);
read_items(menu); read_items(menu);
int status = menu_run(menu); int status = menu_run(menu);