wmenu-run.c - wmenu - [fork] efficient dynamic menu for wayland
(HTM) git clone https://git.drkhsh.at/wmenu.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
wmenu-run.c (2116B)
---
1 #define _POSIX_C_SOURCE 200809L
2 #include <dirent.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7
8 #include "menu.h"
9 #include "wayland.h"
10 #include "xdg-activation-v1-client-protocol.h"
11
12 static void read_items(struct menu *menu) {
13 char *path = strdup(getenv("PATH"));
14 for (char *p = strtok(path, ":"); p != NULL; p = strtok(NULL, ":")) {
15 DIR *dir = opendir(p);
16 if (dir == NULL) {
17 continue;
18 }
19 for (struct dirent *ent = readdir(dir); ent != NULL; ent = readdir(dir)) {
20 if (ent->d_name[0] == '.') {
21 continue;
22 }
23 menu_add_item(menu, strdup(ent->d_name));
24 }
25 closedir(dir);
26 }
27 menu_sort_and_deduplicate(menu);
28 free(path);
29 }
30
31 struct command {
32 struct menu *menu;
33 char *text;
34 bool exit;
35 };
36
37 static void activation_token_done(void *data, struct xdg_activation_token_v1 *activation_token,
38 const char *token) {
39 struct command *cmd = data;
40 xdg_activation_token_v1_destroy(activation_token);
41
42 int pid = fork();
43 if (pid == 0) {
44 setenv("XDG_ACTIVATION_TOKEN", token, true);
45 char *argv[] = {"/bin/sh", "-c", cmd->text, NULL};
46 execvp(argv[0], (char**)argv);
47 } else {
48 if (cmd->exit) {
49 cmd->menu->exit = true;
50 }
51 }
52 }
53
54 static const struct xdg_activation_token_v1_listener activation_token_listener = {
55 .done = activation_token_done,
56 };
57
58 static void exec_item(struct menu *menu, char *text, bool exit) {
59 struct command *cmd = calloc(1, sizeof(struct command));
60 cmd->menu = menu;
61 cmd->text = strdup(text);
62 cmd->exit = exit;
63
64 struct xdg_activation_v1 *activation = context_get_xdg_activation(menu->context);
65 struct xdg_activation_token_v1 *activation_token = xdg_activation_v1_get_activation_token(activation);
66 xdg_activation_token_v1_set_surface(activation_token, context_get_surface(menu->context));
67 xdg_activation_token_v1_add_listener(activation_token, &activation_token_listener, cmd);
68 xdg_activation_token_v1_commit(activation_token);
69 }
70
71 int main(int argc, char *argv[]) {
72 struct menu *menu = menu_create(exec_item);
73 menu_getopts(menu, argc, argv);
74 read_items(menu);
75 int status = menu_run(menu);
76 menu_destroy(menu);
77 return status;
78 }