From 56231f81190ac8dc139aa2e7b7776964fda16c78 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sat, 8 Feb 2020 13:21:36 +0200 Subject: [PATCH] bemenu-run: add --fork option Make terminal backends not fork by default. Use this option to fork again on curses. For non terminal backends this option is no-op. --- client/bemenu-run.c | 17 +++++++++-------- client/bemenu.c | 5 +++-- client/common/common.c | 18 +++++++++++------- client/common/common.h | 5 +++-- lib/bemenu.h | 8 ++++++++ lib/menu.c | 7 +++++++ man/bemenu.1 | 5 +++++ 7 files changed, 46 insertions(+), 19 deletions(-) diff --git a/client/bemenu-run.c b/client/bemenu-run.c index 602dd6e..a419de4 100644 --- a/client/bemenu-run.c +++ b/client/bemenu-run.c @@ -130,15 +130,17 @@ read_items_to_menu_from_path(struct bm_menu *menu) static inline void ignore_ret(int useless, ...) { (void)useless; } static void -launch(const char *bin) +launch(const struct client *client, const char *bin) { if (!bin) return; - if (fork() == 0) { - setsid(); - ignore_ret(0, freopen("/dev/null", "w", stdout)); - ignore_ret(0, freopen("/dev/null", "w", stderr)); + if (!client->fork || fork() == 0) { + if (client->fork) { + setsid(); + ignore_ret(0, freopen("/dev/null", "w", stdout)); + ignore_ret(0, freopen("/dev/null", "w", stderr)); + } char **tokens; if (!(tokens = tokenize_quoted_to_argv(bin, NULL, NULL))) @@ -150,10 +152,9 @@ launch(const char *bin) } static void -item_cb(struct bm_item *item, const char *text) +item_cb(const struct client *client, struct bm_item *item) { - (void)item; // may be null - launch(text); + launch(client, bm_item_get_text(item)); } int diff --git a/client/bemenu.c b/client/bemenu.c index 429169d..97f0621 100644 --- a/client/bemenu.c +++ b/client/bemenu.c @@ -48,9 +48,10 @@ read_items_to_menu_from_stdin(struct bm_menu *menu) } static void -item_cb(struct bm_item *item, const char *text) +item_cb(const struct client *client, struct bm_item *item) { - (void)item; // may be null + (void)client; + const char *text = bm_item_get_text(item); printf("%s\n", (text ? text : "")); } diff --git a/client/common/common.c b/client/common/common.c index 9e2ebab..96e7d3a 100644 --- a/client/common/common.c +++ b/client/common/common.c @@ -174,7 +174,8 @@ usage(FILE *out, const char *name) " -P, --prefix text to show before highlighted item.\n" " -I, --index select item at index automatically.\n" " --scrollbar display scrollbar. (always, autohide)\n" - " --ifne only display menu if there are items.\n\n" + " --ifne only display menu if there are items.\n" + " --fork always fork. (bemenu-run)\n\n" "Use BEMENU_BACKEND env variable to force backend:\n" " curses ncurses based terminal backend\n" @@ -226,6 +227,7 @@ do_getopt(struct client *client, int *argc, char **argv[]) { "prefix", required_argument, 0, 'P' }, { "scrollbar", required_argument, 0, 0x100 }, { "ifne", no_argument, 0, 0x115 }, + { "fork", required_argument, 0, 0x116 }, { "bottom", no_argument, 0, 'b' }, { "grab", no_argument, 0, 'f' }, @@ -291,6 +293,9 @@ do_getopt(struct client *client, int *argc, char **argv[]) case 0x115: client->ifne = true; break; + case 0x116: + client->force_fork = true; + break; case 'b': client->bottom = true; @@ -376,12 +381,14 @@ parse_args(struct client *client, int *argc, char **argv[]) } struct bm_menu* -menu_with_options(const struct client *client) +menu_with_options(struct client *client) { struct bm_menu *menu; if (!(menu = bm_menu_new(NULL))) return NULL; + client->fork = (client->force_fork || (bm_renderer_get_priorty(bm_menu_get_renderer(menu)) != BM_PRIO_TERMINAL)); + bm_menu_set_font(menu, client->font); bm_menu_set_line_height(menu, client->line_height); bm_menu_set_title(menu, client->title); @@ -408,7 +415,7 @@ menu_with_options(const struct client *client) } enum bm_run_result -run_menu(const struct client *client, struct bm_menu *menu, void (*item_cb)(struct bm_item *item, const char *text)) +run_menu(const struct client *client, struct bm_menu *menu, void (*item_cb)(const struct client *client, struct bm_item *item)) { bm_menu_set_highlighted_index(menu, client->selected); bm_menu_grab_keyboard(menu, true); @@ -427,10 +434,7 @@ run_menu(const struct client *client, struct bm_menu *menu, void (*item_cb)(stru if (status == BM_RUN_RESULT_SELECTED) { uint32_t i, count; struct bm_item **items = bm_menu_get_selected_items(menu, &count); - for (i = 0; i < count; ++i) { - const char *text = bm_item_get_text(items[i]); - item_cb(items[i], text); - } + for (i = 0; i < count; ++i) item_cb(client, items[i]); } return status; diff --git a/client/common/common.h b/client/common/common.h index cd5526e..70ecd5c 100644 --- a/client/common/common.h +++ b/client/common/common.h @@ -20,13 +20,14 @@ struct client { bool wrap; bool ifne; bool no_overlap; + bool force_fork, fork; }; char* cstrcopy(const char *str, size_t size); char** tokenize_quoted_to_argv(const char *str, char *argv0, int *out_argc); void parse_args(struct client *client, int *argc, char **argv[]); -struct bm_menu* menu_with_options(const struct client *client); -enum bm_run_result run_menu(const struct client *client, struct bm_menu *menu, void (*item_cb)(struct bm_item *item, const char *text)); +struct bm_menu* menu_with_options(struct client *client); +enum bm_run_result run_menu(const struct client *client, struct bm_menu *menu, void (*item_cb)(const struct client *client, struct bm_item *item)); #endif /* _BM_COMMON_H_ */ diff --git a/lib/bemenu.h b/lib/bemenu.h index d5e1c61..965e1a0 100644 --- a/lib/bemenu.h +++ b/lib/bemenu.h @@ -252,6 +252,14 @@ void bm_menu_free_items(struct bm_menu *menu); * @name Menu Properties * @{ */ +/** + * Get the renderer from the bm_menu instance. + * + * @param menu bm_menu instance which renderer to get. + * @return Pointer to bm_renderer instance. + */ +const struct bm_renderer* bm_menu_get_renderer(struct bm_menu *menu); + /** * Set userdata pointer to bm_menu instance. * Userdata will be carried unmodified by the instance. diff --git a/lib/menu.c b/lib/menu.c index 071dd19..8eaf965 100644 --- a/lib/menu.c +++ b/lib/menu.c @@ -139,6 +139,13 @@ bm_menu_free_items(struct bm_menu *menu) free(menu->filter_item); } +const struct bm_renderer* +bm_menu_get_renderer(struct bm_menu *menu) +{ + assert(menu); + return menu->renderer; +} + void bm_menu_set_userdata(struct bm_menu *menu, void *userdata) { diff --git a/man/bemenu.1 b/man/bemenu.1 index e50a946..e3ecb18 100644 --- a/man/bemenu.1 +++ b/man/bemenu.1 @@ -91,6 +91,11 @@ Show scrollbar only when necessary. .B \-\-ifne Only displays the menu when there are items. +.TP +.B \-\-fork +Always fork. (bemenu-run) +By default terminal backends won't fork. + .SS Backend-specific Options These options are only available on backends specified in the parentheses