gui: Catch SIGWINCH.
authorAndre Noll <maan@tuebingen.mpg.de>
Sat, 23 Sep 2017 17:48:40 +0000 (19:48 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Sat, 28 Oct 2017 17:53:37 +0000 (19:53 +0200)
Commit 9775f534 from more than three years ago removed the signal
handler for SIGWINCH on the grounds that it is unnecessary and
simplifies the gui menu code that was in preparation back then.

However, the gui menu feature was never merged and handling SIGWINCH in
the input task does have a disadvantage: since KEY_RESIZE is generated
by the curses library, select(2) (which watches STDIN_FILENO) does
not notice that wgetch(3) would not block or return ERR any more
after SIGWINCH was received. Hence the window will only be refreshed
after select(2) returns for another reason. This can delay the window
update for up to one second.

This patch gets rid of the delay by reintroducing the signal handler
for SIGWINCH, effectively reverting the above mentioned commit.

gui.c

diff --git a/gui.c b/gui.c
index 6882a31..69a9243 100644 (file)
--- a/gui.c
+++ b/gui.c
@@ -941,6 +941,14 @@ static int signal_post_select(struct sched *s, __a_unused void *context)
        switch (ret) {
        case SIGTERM:
                die(EXIT_FAILURE, "only the good die young (caught SIGTERM)\n");
+       case SIGWINCH:
+               PARA_NOTICE_LOG("got SIGWINCH\n");
+               if (curses_active()) {
+                       shutdown_curses();
+                       init_curses();
+                       redraw_bot_win();
+               }
+               return 1;
        case SIGINT:
                return 1;
        case SIGUSR1:
@@ -1146,14 +1154,8 @@ static int input_post_select(__a_unused struct sched *s,
        ret = wgetch(top.win);
        if (ret == ERR)
                return 0;
-       if (ret == KEY_RESIZE) {
-               if (curses_active()) {
-                       shutdown_curses();
-                       init_curses();
-                       redraw_bot_win();
-               }
+       if (ret == KEY_RESIZE) /* already handled in signal_post_select() */
                return 0;
-       }
        if (exs == EXEC_IDLE)
                handle_command(ret);
        else if (exec_pid > 0)
@@ -1456,6 +1458,7 @@ static int setup_tasks_and_schedule(void)
        para_install_sighandler(SIGTERM);
        para_install_sighandler(SIGCHLD);
        para_install_sighandler(SIGUSR1);
+       para_install_sighandler(SIGWINCH);
        signal_task->task = task_register(&(struct task_info) {
                .name = "signal",
                .pre_select = signal_pre_select,