Streamline menu callbacks
This commit is contained in:
parent
a0df7959f9
commit
7d717b3696
5 changed files with 42 additions and 36 deletions
15
menu.c
15
menu.c
|
@ -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
7
menu.h
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
40
wmenu-run.c
40
wmenu-run.c
|
@ -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);
|
|
||||||
|
|
||||||
|
int pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
setenv("XDG_ACTIVATION_TOKEN", token, true);
|
setenv("XDG_ACTIVATION_TOKEN", token, true);
|
||||||
char* cmd[] = {"/bin/sh", "-c", exe->name, NULL};
|
char *argv[] = {"/bin/sh", "-c", cmd->text, NULL};
|
||||||
execvp(cmd[0], (char**)cmd);
|
execvp(argv[0], (char**)argv);
|
||||||
|
} else {
|
||||||
fprintf(stderr, "Failed to execute selection: %s\n", strerror(errno));
|
if (cmd->exit) {
|
||||||
free(exe->name);
|
cmd->menu->exit = true;
|
||||||
free(exe);
|
}
|
||||||
exit(EXIT_FAILURE);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
11
wmenu.c
|
@ -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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue