summaryrefslogtreecommitdiff
path: root/wmenu/wmenu-run.c
diff options
context:
space:
mode:
authorcoasteen <coasteen@proton.me>2026-07-09 10:42:28 +0330
committercoasteen <coasteen@proton.me>2026-07-09 10:42:28 +0330
commit8cbadb61604667b407b53ee1258433994fa4765a (patch)
tree97765fb29418fd6278fcb4cbb9760893afaf7a58 /wmenu/wmenu-run.c
Diffstat (limited to 'wmenu/wmenu-run.c')
-rwxr-xr-xwmenu/wmenu-run.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/wmenu/wmenu-run.c b/wmenu/wmenu-run.c
new file mode 100755
index 0000000..1b7b8c1
--- /dev/null
+++ b/wmenu/wmenu-run.c
@@ -0,0 +1,78 @@
+#define _POSIX_C_SOURCE 200809L
+#include <dirent.h>
+#include <stdio.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 *path = strdup(getenv("PATH"));
+ for (char *p = strtok(path, ":"); p != NULL; p = strtok(NULL, ":")) {
+ DIR *dir = opendir(p);
+ if (dir == NULL) {
+ continue;
+ }
+ for (struct dirent *ent = readdir(dir); ent != NULL; ent = readdir(dir)) {
+ if (ent->d_name[0] == '.') {
+ continue;
+ }
+ menu_add_item(menu, strdup(ent->d_name));
+ }
+ closedir(dir);
+ }
+ menu_sort_and_deduplicate(menu);
+ free(path);
+}
+
+struct command {
+ struct menu *menu;
+ char *text;
+ bool exit;
+};
+
+static void activation_token_done(void *data, struct xdg_activation_token_v1 *activation_token,
+ const char *token) {
+ struct command *cmd = data;
+ xdg_activation_token_v1_destroy(activation_token);
+
+ int pid = fork();
+ if (pid == 0) {
+ setenv("XDG_ACTIVATION_TOKEN", token, true);
+ char *argv[] = {"/bin/sh", "-c", cmd->text, NULL};
+ execvp(argv[0], (char**)argv);
+ } else {
+ if (cmd->exit) {
+ cmd->menu->exit = true;
+ }
+ }
+}
+
+static const struct xdg_activation_token_v1_listener activation_token_listener = {
+ .done = activation_token_done,
+};
+
+static void exec_item(struct menu *menu, char *text, bool exit) {
+ struct command *cmd = calloc(1, sizeof(struct command));
+ cmd->menu = menu;
+ cmd->text = strdup(text);
+ cmd->exit = exit;
+
+ 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, cmd);
+ xdg_activation_token_v1_commit(activation_token);
+}
+
+int main(int argc, char *argv[]) {
+ struct menu *menu = menu_create(exec_item);
+ menu_getopts(menu, argc, argv);
+ read_items(menu);
+ int status = menu_run(menu);
+ menu_destroy(menu);
+ return status;
+}