diff options
author | Jari Vetoniemi <mailroxas@gmail.com> | 2017-02-14 19:14:08 +0200 |
---|---|---|
committer | Jari Vetoniemi <mailroxas@gmail.com> | 2017-02-14 19:20:44 +0200 |
commit | 208af51c0eaf66b61c9890f556f2087520f2d07c (patch) | |
tree | 33bef8d05c96ef652cce90b12a8929922348d946 /lib | |
parent | 91d929ecf477668c2672e305ed725976a3efbc9c (diff) | |
download | bemenu-208af51c0eaf66b61c9890f556f2087520f2d07c.tar.gz bemenu-208af51c0eaf66b61c9890f556f2087520f2d07c.tar.bz2 bemenu-208af51c0eaf66b61c9890f556f2087520f2d07c.zip |
clients: Make -f option show menu immediately
Diffstat (limited to 'lib')
-rw-r--r-- | lib/renderers/curses/curses.c | 81 |
1 files changed, 66 insertions, 15 deletions
diff --git a/lib/renderers/curses/curses.c b/lib/renderers/curses/curses.c index 7d30391..3b9563d 100644 --- a/lib/renderers/curses/curses.c +++ b/lib/renderers/curses/curses.c @@ -32,9 +32,53 @@ 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) { if (curses.buffer) { @@ -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.stdscr) { - curses.old_stdin = dup(STDIN_FILENO); - curses.old_stdout = dup(STDOUT_FILENO); - - freopen(TTY, "w", stdout); - freopen(TTY, "r", stdin); + if (curses.should_terminate) { + terminate(); + curses.should_terminate = false; + } + if (!curses.stdscr) { + 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)); |