forked from RepoMirrors/bemenu
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.
This commit is contained in:
parent
b688425bf3
commit
56231f8119
@ -130,15 +130,17 @@ read_items_to_menu_from_path(struct bm_menu *menu)
|
|||||||
static inline void ignore_ret(int useless, ...) { (void)useless; }
|
static inline void ignore_ret(int useless, ...) { (void)useless; }
|
||||||
|
|
||||||
static void
|
static void
|
||||||
launch(const char *bin)
|
launch(const struct client *client, const char *bin)
|
||||||
{
|
{
|
||||||
if (!bin)
|
if (!bin)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fork() == 0) {
|
if (!client->fork || fork() == 0) {
|
||||||
|
if (client->fork) {
|
||||||
setsid();
|
setsid();
|
||||||
ignore_ret(0, freopen("/dev/null", "w", stdout));
|
ignore_ret(0, freopen("/dev/null", "w", stdout));
|
||||||
ignore_ret(0, freopen("/dev/null", "w", stderr));
|
ignore_ret(0, freopen("/dev/null", "w", stderr));
|
||||||
|
}
|
||||||
|
|
||||||
char **tokens;
|
char **tokens;
|
||||||
if (!(tokens = tokenize_quoted_to_argv(bin, NULL, NULL)))
|
if (!(tokens = tokenize_quoted_to_argv(bin, NULL, NULL)))
|
||||||
@ -150,10 +152,9 @@ launch(const char *bin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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(client, bm_item_get_text(item));
|
||||||
launch(text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -48,9 +48,10 @@ read_items_to_menu_from_stdin(struct bm_menu *menu)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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 : ""));
|
printf("%s\n", (text ? text : ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +174,8 @@ usage(FILE *out, const char *name)
|
|||||||
" -P, --prefix text to show before highlighted item.\n"
|
" -P, --prefix text to show before highlighted item.\n"
|
||||||
" -I, --index select item at index automatically.\n"
|
" -I, --index select item at index automatically.\n"
|
||||||
" --scrollbar display scrollbar. (always, autohide)\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"
|
"Use BEMENU_BACKEND env variable to force backend:\n"
|
||||||
" curses ncurses based terminal 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' },
|
{ "prefix", required_argument, 0, 'P' },
|
||||||
{ "scrollbar", required_argument, 0, 0x100 },
|
{ "scrollbar", required_argument, 0, 0x100 },
|
||||||
{ "ifne", no_argument, 0, 0x115 },
|
{ "ifne", no_argument, 0, 0x115 },
|
||||||
|
{ "fork", required_argument, 0, 0x116 },
|
||||||
|
|
||||||
{ "bottom", no_argument, 0, 'b' },
|
{ "bottom", no_argument, 0, 'b' },
|
||||||
{ "grab", no_argument, 0, 'f' },
|
{ "grab", no_argument, 0, 'f' },
|
||||||
@ -291,6 +293,9 @@ do_getopt(struct client *client, int *argc, char **argv[])
|
|||||||
case 0x115:
|
case 0x115:
|
||||||
client->ifne = true;
|
client->ifne = true;
|
||||||
break;
|
break;
|
||||||
|
case 0x116:
|
||||||
|
client->force_fork = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'b':
|
case 'b':
|
||||||
client->bottom = true;
|
client->bottom = true;
|
||||||
@ -376,12 +381,14 @@ parse_args(struct client *client, int *argc, char **argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct bm_menu*
|
struct bm_menu*
|
||||||
menu_with_options(const struct client *client)
|
menu_with_options(struct client *client)
|
||||||
{
|
{
|
||||||
struct bm_menu *menu;
|
struct bm_menu *menu;
|
||||||
if (!(menu = bm_menu_new(NULL)))
|
if (!(menu = bm_menu_new(NULL)))
|
||||||
return 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_font(menu, client->font);
|
||||||
bm_menu_set_line_height(menu, client->line_height);
|
bm_menu_set_line_height(menu, client->line_height);
|
||||||
bm_menu_set_title(menu, client->title);
|
bm_menu_set_title(menu, client->title);
|
||||||
@ -408,7 +415,7 @@ menu_with_options(const struct client *client)
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum bm_run_result
|
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_set_highlighted_index(menu, client->selected);
|
||||||
bm_menu_grab_keyboard(menu, true);
|
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) {
|
if (status == BM_RUN_RESULT_SELECTED) {
|
||||||
uint32_t i, count;
|
uint32_t i, count;
|
||||||
struct bm_item **items = bm_menu_get_selected_items(menu, &count);
|
struct bm_item **items = bm_menu_get_selected_items(menu, &count);
|
||||||
for (i = 0; i < count; ++i) {
|
for (i = 0; i < count; ++i) item_cb(client, items[i]);
|
||||||
const char *text = bm_item_get_text(items[i]);
|
|
||||||
item_cb(items[i], text);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
@ -20,13 +20,14 @@ struct client {
|
|||||||
bool wrap;
|
bool wrap;
|
||||||
bool ifne;
|
bool ifne;
|
||||||
bool no_overlap;
|
bool no_overlap;
|
||||||
|
bool force_fork, fork;
|
||||||
};
|
};
|
||||||
|
|
||||||
char* cstrcopy(const char *str, size_t size);
|
char* cstrcopy(const char *str, size_t size);
|
||||||
char** tokenize_quoted_to_argv(const char *str, char *argv0, int *out_argc);
|
char** tokenize_quoted_to_argv(const char *str, char *argv0, int *out_argc);
|
||||||
void parse_args(struct client *client, int *argc, char **argv[]);
|
void parse_args(struct client *client, int *argc, char **argv[]);
|
||||||
struct bm_menu* menu_with_options(const struct client *client);
|
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)(struct bm_item *item, const char *text));
|
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_ */
|
#endif /* _BM_COMMON_H_ */
|
||||||
|
|
||||||
|
@ -252,6 +252,14 @@ void bm_menu_free_items(struct bm_menu *menu);
|
|||||||
* @name Menu Properties
|
* @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.
|
* Set userdata pointer to bm_menu instance.
|
||||||
* Userdata will be carried unmodified by the instance.
|
* Userdata will be carried unmodified by the instance.
|
||||||
|
@ -139,6 +139,13 @@ bm_menu_free_items(struct bm_menu *menu)
|
|||||||
free(menu->filter_item);
|
free(menu->filter_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct bm_renderer*
|
||||||
|
bm_menu_get_renderer(struct bm_menu *menu)
|
||||||
|
{
|
||||||
|
assert(menu);
|
||||||
|
return menu->renderer;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bm_menu_set_userdata(struct bm_menu *menu, void *userdata)
|
bm_menu_set_userdata(struct bm_menu *menu, void *userdata)
|
||||||
{
|
{
|
||||||
|
@ -91,6 +91,11 @@ Show scrollbar only when necessary.
|
|||||||
.B \-\-ifne
|
.B \-\-ifne
|
||||||
Only displays the menu when there are items.
|
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
|
.SS Backend-specific Options
|
||||||
|
|
||||||
These options are only available on backends specified in the parentheses
|
These options are only available on backends specified in the parentheses
|
||||||
|
Loading…
Reference in New Issue
Block a user