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"
|
" (...) At end of help indicates the backend support for option.\n\n"
|
||||||
|
|
||||||
" -b, --bottom appears at the bottom of the screen. (x)\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"
|
" -m, --monitor index of monitor where menu will appear. (x)\n"
|
||||||
" --fn defines the font to be used ('name [size]'). (wx)\n"
|
" --fn defines the font to be used ('name [size]'). (wx)\n"
|
||||||
" --tb defines the title background color. (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)
|
for (uint32_t i = 0; i < BM_COLOR_LAST; ++i)
|
||||||
bm_menu_set_color(menu, i, client->colors[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_grab_keyboard(menu, true);
|
||||||
|
bm_menu_render(menu);
|
||||||
|
bm_menu_set_filter(menu, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,52 @@ static struct curses {
|
|||||||
size_t blen;
|
size_t blen;
|
||||||
int old_stdin;
|
int old_stdin;
|
||||||
int old_stdout;
|
int old_stdout;
|
||||||
|
bool polled_once;
|
||||||
|
bool should_terminate;
|
||||||
} curses;
|
} 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
|
static void
|
||||||
terminate(void)
|
terminate(void)
|
||||||
{
|
{
|
||||||
@ -46,16 +90,10 @@ terminate(void)
|
|||||||
if (!curses.stdscr)
|
if (!curses.stdscr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
freopen(TTY, "w", stdout);
|
reopen_stdin_stdout();
|
||||||
|
|
||||||
refresh();
|
refresh();
|
||||||
endwin();
|
endwin();
|
||||||
|
restore_stdin_stdout();
|
||||||
dup2(curses.old_stdin, STDIN_FILENO);
|
|
||||||
dup2(curses.old_stdout, STDOUT_FILENO);
|
|
||||||
close(curses.old_stdin);
|
|
||||||
close(curses.old_stdout);
|
|
||||||
|
|
||||||
curses.stdscr = NULL;
|
curses.stdscr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,13 +177,14 @@ draw_line(int32_t pair, int32_t y, const char *fmt, ...)
|
|||||||
static void
|
static void
|
||||||
render(const struct bm_menu *menu)
|
render(const struct bm_menu *menu)
|
||||||
{
|
{
|
||||||
|
if (curses.should_terminate) {
|
||||||
|
terminate();
|
||||||
|
curses.should_terminate = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!curses.stdscr) {
|
if (!curses.stdscr) {
|
||||||
curses.old_stdin = dup(STDIN_FILENO);
|
store_stdin_stdout();
|
||||||
curses.old_stdout = dup(STDOUT_FILENO);
|
reopen_stdin_stdout();
|
||||||
|
|
||||||
freopen(TTY, "w", stdout);
|
|
||||||
freopen(TTY, "r", stdin);
|
|
||||||
|
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
|
|
||||||
if ((curses.stdscr = initscr()) == NULL)
|
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));
|
move(0, title_len + (menu->curses_cursor < ccols ? menu->curses_cursor : ccols));
|
||||||
refresh();
|
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
|
static uint32_t
|
||||||
@ -240,8 +288,9 @@ poll_key(const struct bm_menu *menu, uint32_t *unicode)
|
|||||||
(void)menu;
|
(void)menu;
|
||||||
assert(unicode);
|
assert(unicode);
|
||||||
*unicode = 0;
|
*unicode = 0;
|
||||||
|
curses.polled_once = true;
|
||||||
|
|
||||||
if (!curses.stdscr)
|
if (!curses.stdscr || curses.should_terminate)
|
||||||
return BM_KEY_NONE;
|
return BM_KEY_NONE;
|
||||||
|
|
||||||
get_wch((wint_t*)unicode);
|
get_wch((wint_t*)unicode);
|
||||||
@ -360,6 +409,8 @@ constructor(struct bm_menu *menu)
|
|||||||
assert(!curses.stdscr && "bemenu supports only one curses instance");
|
assert(!curses.stdscr && "bemenu supports only one curses instance");
|
||||||
|
|
||||||
memset(&curses, 0, sizeof(curses));
|
memset(&curses, 0, sizeof(curses));
|
||||||
|
curses.old_stdin = -1;
|
||||||
|
curses.old_stdout = -1;
|
||||||
|
|
||||||
struct sigaction action;
|
struct sigaction action;
|
||||||
memset(&action, 0, sizeof(struct sigaction));
|
memset(&action, 0, sizeof(struct sigaction));
|
||||||
|
Loading…
Reference in New Issue
Block a user