forked from RepoMirrors/bemenu
clients: Make -f option show menu immediately
This commit is contained in:
parent
91d929ecf4
commit
208af51c0e
@ -82,7 +82,7 @@ usage(FILE *out, const char *name)
|
||||
" (...) At end of help indicates the backend support for option.\n\n"
|
||||
|
||||
" -b, --bottom appears at the bottom of the screen. (x)\n"
|
||||
" -f, --grab grabs the keyboard before reading stdin. (x)\n"
|
||||
" -f, --grab show the menu before reading stdin. (wx)\n"
|
||||
" -m, --monitor index of monitor where menu will appear. (x)\n"
|
||||
" --fn defines the font to be used ('name [size]'). (wx)\n"
|
||||
" --tb defines the title background color. (wx)\n"
|
||||
@ -264,8 +264,12 @@ menu_with_options(struct client *client)
|
||||
for (uint32_t i = 0; i < BM_COLOR_LAST; ++i)
|
||||
bm_menu_set_color(menu, i, client->colors[i]);
|
||||
|
||||
if (client->grab)
|
||||
if (client->grab) {
|
||||
bm_menu_set_filter(menu, "Loading...");
|
||||
bm_menu_grab_keyboard(menu, true);
|
||||
bm_menu_render(menu);
|
||||
bm_menu_set_filter(menu, NULL);
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
@ -32,8 +32,52 @@ static struct curses {
|
||||
size_t blen;
|
||||
int old_stdin;
|
||||
int old_stdout;
|
||||
bool polled_once;
|
||||
bool should_terminate;
|
||||
} curses;
|
||||
|
||||
static void
|
||||
reopen_stdin(void)
|
||||
{
|
||||
freopen(TTY, "r", stdin);
|
||||
}
|
||||
|
||||
static void
|
||||
reopen_stdin_stdout(void)
|
||||
{
|
||||
reopen_stdin();
|
||||
freopen(TTY, "w", stdout);
|
||||
}
|
||||
|
||||
static void
|
||||
store_stdin_stdout(void)
|
||||
{
|
||||
curses.old_stdin = dup(STDIN_FILENO);
|
||||
curses.old_stdout = dup(STDOUT_FILENO);
|
||||
}
|
||||
|
||||
static void
|
||||
restore_stdin(void)
|
||||
{
|
||||
if (curses.old_stdin != -1) {
|
||||
dup2(curses.old_stdin, STDIN_FILENO);
|
||||
close(curses.old_stdin);
|
||||
curses.old_stdin = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
restore_stdin_stdout(void)
|
||||
{
|
||||
restore_stdin();
|
||||
|
||||
if (curses.old_stdout != -1) {
|
||||
dup2(curses.old_stdout, STDOUT_FILENO);
|
||||
close(curses.old_stdout);
|
||||
curses.old_stdout = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
terminate(void)
|
||||
{
|
||||
@ -46,16 +90,10 @@ terminate(void)
|
||||
if (!curses.stdscr)
|
||||
return;
|
||||
|
||||
freopen(TTY, "w", stdout);
|
||||
|
||||
reopen_stdin_stdout();
|
||||
refresh();
|
||||
endwin();
|
||||
|
||||
dup2(curses.old_stdin, STDIN_FILENO);
|
||||
dup2(curses.old_stdout, STDOUT_FILENO);
|
||||
close(curses.old_stdin);
|
||||
close(curses.old_stdout);
|
||||
|
||||
restore_stdin_stdout();
|
||||
curses.stdscr = NULL;
|
||||
}
|
||||
|
||||
@ -139,13 +177,14 @@ draw_line(int32_t pair, int32_t y, const char *fmt, ...)
|
||||
static void
|
||||
render(const struct bm_menu *menu)
|
||||
{
|
||||
if (curses.should_terminate) {
|
||||
terminate();
|
||||
curses.should_terminate = false;
|
||||
}
|
||||
|
||||
if (!curses.stdscr) {
|
||||
curses.old_stdin = dup(STDIN_FILENO);
|
||||
curses.old_stdout = dup(STDOUT_FILENO);
|
||||
|
||||
freopen(TTY, "w", stdout);
|
||||
freopen(TTY, "r", stdin);
|
||||
|
||||
store_stdin_stdout();
|
||||
reopen_stdin_stdout();
|
||||
setlocale(LC_CTYPE, "");
|
||||
|
||||
if ((curses.stdscr = initscr()) == NULL)
|
||||
@ -225,6 +264,15 @@ render(const struct bm_menu *menu)
|
||||
|
||||
move(0, title_len + (menu->curses_cursor < ccols ? menu->curses_cursor : ccols));
|
||||
refresh();
|
||||
|
||||
// Make it possible to read stdin even after rendering
|
||||
// Only make it impossible to read original stdin after poll_key is called once
|
||||
// This is mainly to make -f work even on curses backend
|
||||
if (!curses.polled_once) {
|
||||
reopen_stdin();
|
||||
restore_stdin();
|
||||
curses.should_terminate = true;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
@ -240,8 +288,9 @@ poll_key(const struct bm_menu *menu, uint32_t *unicode)
|
||||
(void)menu;
|
||||
assert(unicode);
|
||||
*unicode = 0;
|
||||
curses.polled_once = true;
|
||||
|
||||
if (!curses.stdscr)
|
||||
if (!curses.stdscr || curses.should_terminate)
|
||||
return BM_KEY_NONE;
|
||||
|
||||
get_wch((wint_t*)unicode);
|
||||
@ -360,6 +409,8 @@ constructor(struct bm_menu *menu)
|
||||
assert(!curses.stdscr && "bemenu supports only one curses instance");
|
||||
|
||||
memset(&curses, 0, sizeof(curses));
|
||||
curses.old_stdin = -1;
|
||||
curses.old_stdout = -1;
|
||||
|
||||
struct sigaction action;
|
||||
memset(&action, 0, sizeof(struct sigaction));
|
||||
|
Loading…
Reference in New Issue
Block a user