wmenu/wmenu-run.c

79 lines
2.1 KiB
C
Raw Normal View History

2024-05-02 21:39:54 -04:00
#define _POSIX_C_SOURCE 200809L
2024-05-03 19:10:28 -04:00
#include <dirent.h>
2024-06-09 20:30:58 -04:00
#include <stdio.h>
2024-05-02 21:39:54 -04:00
#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) {
2024-05-03 19:31:11 -04:00
char *path = strdup(getenv("PATH"));
2024-05-03 19:10:28 -04:00
for (char *p = strtok(path, ":"); p != NULL; p = strtok(NULL, ":")) {
DIR *dir = opendir(p);
if (dir == NULL) {
continue;
2024-05-02 21:39:54 -04:00
}
2024-05-03 19:10:28 -04:00
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));
2024-05-03 19:10:28 -04:00
}
closedir(dir);
2024-05-02 21:39:54 -04:00
}
menu_sort_and_deduplicate(menu);
2024-05-03 19:31:11 -04:00
free(path);
2024-05-02 21:39:54 -04:00
}
2024-06-09 20:30:58 -04:00
struct command {
2024-05-02 21:39:54 -04:00
struct menu *menu;
2024-06-09 20:30:58 -04:00
char *text;
bool exit;
2024-05-02 21:39:54 -04:00
};
static void activation_token_done(void *data, struct xdg_activation_token_v1 *activation_token,
const char *token) {
2024-06-09 20:30:58 -04:00
struct command *cmd = data;
2024-05-02 21:39:54 -04:00
xdg_activation_token_v1_destroy(activation_token);
2024-06-09 20:30:58 -04:00
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;
}
}
2024-05-02 21:39:54 -04:00
}
static const struct xdg_activation_token_v1_listener activation_token_listener = {
.done = activation_token_done,
};
2024-06-09 20:30:58 -04:00
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;
2024-05-02 21:39:54 -04:00
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));
2024-06-09 20:30:58 -04:00
xdg_activation_token_v1_add_listener(activation_token, &activation_token_listener, cmd);
2024-05-02 21:39:54 -04:00
xdg_activation_token_v1_commit(activation_token);
}
int main(int argc, char *argv[]) {
2024-06-09 20:30:58 -04:00
struct menu *menu = menu_create(exec_item);
2024-05-02 21:39:54 -04:00
menu_getopts(menu, argc, argv);
read_items(menu);
int status = menu_run(menu);
menu_destroy(menu);
return status;
}