]> git.wh0rd.org Git - nano.git/commitdiff
Handling a SIGWINCH (which signals a change in window size) not when it
authorBenno Schulenberg <bensberg@justemail.net>
Thu, 28 May 2015 13:02:29 +0000 (13:02 +0000)
committerBenno Schulenberg <bensberg@justemail.net>
Thu, 28 May 2015 13:02:29 +0000 (13:02 +0000)
happens but only when checking for keyboard input.  It now reports the
SIGWINCH via a special key value to the calling routine, to allow not
only the main editor but also the help viewer and the file browser to
adapt their display to the new size.
Patch by Mahyar Abbaspour, somewhat edited by Benno.

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@5228 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
src/browser.c
src/global.c
src/help.c
src/nano.c
src/nano.h
src/prompt.c
src/proto.h
src/text.c
src/winio.c

index 5d70dfe4e6f6f957c0097b66c154b2d653717617..3b1133dafa1f92d25fe5fd94fef669521fab09ac 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2015-05-28  Mahyar Abbaspour  <mahyar.abaspour@gmail.com>
+       * src/nano.c (handle_sigwinch, regenerate_screen), src/global.c,
+       src/prompt.c (do_statusbar_input, get_prompt_string, do_yesno_prompt),
+       src/browser.c (do_browser, browser_refresh), src/help.c (do_help),
+       src/winio.c (get_key_buffer, unget_input, get_input, parse_kbinput),
+       src/text.c (do_justify, do_linter), src/nano.h, src/proto.h:
+       Handle a SIGWINCH (signalling a change in window size) not when it
+       happens but only when checking for input.  Report the SIGWINCH via
+       a special key value to the calling routine, to allow not only the
+       main editor but also the help viewer and the file browser to adapt
+       their display to the new size.  (Patch edited by Benno.)
+
 2015-05-20  Devrim Gündüz  <devrim@gunduz.org>
        * doc/syntax/postgresql.nanorc: New file -- syntax highlighting for
        PostgreSQL, first posted as Savannah patch #8601.  Trimmed by Benno.
index 5cfc45a4cf335038f46cc5172df4bb868cafe8b2..ad59baf8bd17e3acca8d6b805e7744d83a6884dd 100644 (file)
@@ -41,6 +41,8 @@ static int longest = 0;
        /* The number of columns in the longest filename in the list. */
 static size_t selected = 0;
        /* The currently selected filename in the list; zero-based. */
+static char *path_save = NULL;
+       /* A copy of the current path. */
 
 /* Our main file browser function.  path is the tilde-expanded path we
  * start browsing from. */
@@ -75,6 +77,9 @@ char *do_browser(char *path, DIR *dir)
 
     path = mallocstrassn(path, get_full_path(path));
 
+    /* Save the current path in order to be used later. */
+    path_save = path;
+
     assert(path != NULL && path[strlen(path) - 1] == '/');
 
     /* Get the file list, and set longest and width in the process. */
@@ -118,6 +123,14 @@ char *do_browser(char *path, DIR *dir)
 
        kbinput = get_kbinput(edit);
 
+#ifndef NANO_TINY
+       if (kbinput == KEY_WINCH) {
+           kbinput = ERR;
+           curs_set(0);
+           continue;
+       }
+#endif
+
 #ifndef DISABLE_MOUSE
        if (kbinput == KEY_MOUSE) {
            int mouse_x, mouse_y;
@@ -156,6 +169,8 @@ char *do_browser(char *path, DIR *dir)
        } else if (func == do_help_void) {
 #ifndef DISABLE_HELP
            do_help_void();
+           /* Perhaps the window dimensions have changed. */
+           browser_refresh();
            curs_set(0);
 #else
            nano_disabled_msg();
@@ -547,6 +562,11 @@ void browser_refresh(void)
     char *foo;
        /* The additional information that we'll display about a file. */
 
+    /* Perhaps window dimensions have changed; reinitialize the browser. */
+    browser_init(path_save, opendir(path_save));
+    qsort(filelist, filelist_len, sizeof(char *), diralphasort);
+
+    titlebar(path_save);
     blank_edit();
 
     wmove(edit, 0, 0);
index c93b78c4ea849ea886265ffd93ea075a4315571c..614e46d6cef4f862e64c7cefb16066b156b43644 100644 (file)
 
 /* Global variables. */
 #ifndef NANO_TINY
-sigjmp_buf jump_buf;
-       /* Used to return to either main() or the unjustify routine in
-        * do_justify() after a SIGWINCH. */
-bool jump_buf_main = FALSE;
-       /* Have we set jump_buf so that we return to main() after a
-        * SIGWINCH? */
+volatile sig_atomic_t sigwinch_counter = 0;
+       /* Is incremented by the handler whenever a SIGWINCH occurs. */
 #endif
 
 bool meta_key;
index a14fcbc90c4b508c372453f64c67012be2f1b9f5..c6821a43e4f94df3518cd6f89ad71365839507f4 100644 (file)
@@ -72,10 +72,13 @@ void do_help(void (*refresh_func)(void))
     bottombars(MHELP);
     wnoutrefresh(bottomwin);
 
+    while (TRUE) {
+       size_t i;
+
     /* Get the last line of the help text. */
     ptr = help_text;
 
-    for (; *ptr != '\0'; last_line++) {
+    for (last_line = 0; *ptr != '\0'; last_line++) {
        ptr += help_line_len(ptr);
        if (*ptr == '\n')
            ptr++;
@@ -83,9 +86,6 @@ void do_help(void (*refresh_func)(void))
     if (last_line > 0)
        last_line--;
 
-    while (TRUE) {
-       size_t i;
-
        /* Display the help text if we don't have a key, or if the help
         * text has moved. */
        if (kbinput == ERR || line != old_line) {
@@ -117,6 +117,14 @@ void do_help(void (*refresh_func)(void))
 
        kbinput = get_kbinput(edit);
 
+#ifndef NANO_TINY
+       if (kbinput == KEY_WINCH) {
+           kbinput = ERR;
+           curs_set(0);
+           continue;
+       }
+#endif
+
 #ifndef DISABLE_MOUSE
        if (kbinput == KEY_MOUSE) {
            int mouse_x, mouse_y;
index 137f33c4202f6d0307794c7cce1cb9bf6b369b7b..6cb9127d40fc2da987460848f8b60babd7c64648 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <stdio.h>
 #include <stdarg.h>
-#include <signal.h>
 #include <unistd.h>
 #include <string.h>
 #include <fcntl.h>
@@ -1245,7 +1244,6 @@ void signal_init(void)
     /* Trap SIGWINCH because we want to handle window resizes. */
     act.sa_handler = handle_sigwinch;
     sigaction(SIGWINCH, &act, NULL);
-    allow_pending_sigwinch(FALSE);
 #endif
 
     /* Trap normal suspend (^Z) so we can handle it ourselves. */
@@ -1343,6 +1341,13 @@ RETSIGTYPE do_continue(int signal)
 #ifndef NANO_TINY
 /* Handler for SIGWINCH (window size change). */
 RETSIGTYPE handle_sigwinch(int signal)
+{
+    /* Let the input routine know that a SIGWINCH has occurred. */
+    sigwinch_counter++;
+}
+
+/* Reinitialize and redraw the screen completely. */
+void regenerate_screen(void)
 {
     const char *tty = ttyname(0);
     int fd, result = 0;
@@ -1367,10 +1372,6 @@ RETSIGTYPE handle_sigwinch(int signal)
     LINES = win.ws_row;
 #endif
 
-    /* If we've partitioned the filestruct, unpartition it now. */
-    if (filepart != NULL)
-       unpartition_filestruct(&filepart);
-
 #ifdef USE_SLANG
     /* Slang curses emulation brain damage, part 1: If we just do what
      * curses does here, it'll only work properly if the resize made the
@@ -1397,14 +1398,7 @@ RETSIGTYPE handle_sigwinch(int signal)
     window_init();
 
     /* Redraw the contents of the windows that need it. */
-    blank_statusbar();
-    wnoutrefresh(bottomwin);
-    currmenu = MMAIN;
     total_refresh();
-
-    /* Jump back to either main() or the unjustify routine in
-     * do_justify(). */
-    siglongjmp(jump_buf, 1);
 }
 
 /* If allow is TRUE, block any SIGWINCH signals that we get, so that we
@@ -1599,6 +1593,11 @@ int do_input(bool allow_funcs)
     /* Read in a character. */
     input = get_kbinput(edit);
 
+#ifndef NANO_TINY
+    if (input == KEY_WINCH)
+       return KEY_WINCH;
+#endif
+
 #ifndef DISABLE_MOUSE
     if (func_key && input == KEY_MOUSE) {
        /* We received a mouse click. */
@@ -2798,17 +2797,6 @@ int main(int argc, char **argv)
        reset_cursor();
        wnoutrefresh(edit);
 
-#ifndef NANO_TINY
-       if (!jump_buf_main) {
-           /* If we haven't already, we're going to set jump_buf so
-            * that we return here after a SIGWINCH.  Indicate this. */
-           jump_buf_main = TRUE;
-
-           /* Return here after a SIGWINCH. */
-           sigsetjmp(jump_buf, 1);
-       }
-#endif
-
        /* Just in case we were at the statusbar prompt, make sure the
         * statusbar cursor position is reset. */
        do_prompt_abort();
index ffd7d22d2b7630c92b9a449be330584e6d2b8043..33c4e5305e8de7fa3f63242346b22c44ea298cd4 100644 (file)
 #include <regex.h>
 #endif
 #ifndef NANO_TINY
-#include <setjmp.h>
+#include <signal.h>
 #endif
 #include <assert.h>
 
@@ -571,6 +571,9 @@ enum
 #define CONTROL_RIGHT 554
 
 #ifndef NANO_TINY
+/* An imaginary key for when we get a SIGWINCH (window resize). */
+#define KEY_WINCH -2
+
 /* Extra bits for the undo function. */
 #define UNdel_del              (1<<0)
 #define UNdel_backspace                (1<<1)
index 38178df7ba6f0d8cdc38f5ea57b1254f1c4a3b17..aa5ddafd0966e98ccb910b61efd23753d3162ab1 100644 (file)
@@ -66,6 +66,11 @@ int do_statusbar_input(bool *ran_func, bool *finished,
     /* Read in a character. */
     input = get_kbinput(bottomwin);
 
+#ifndef NANO_TINY
+    if (input == KEY_WINCH)
+       return KEY_WINCH;
+#endif
+
 #ifndef DISABLE_MOUSE
     /* If we got a mouse click and it was on a shortcut, read in the
      * shortcut character. */
@@ -794,6 +799,14 @@ functionptrtype get_prompt_string(int *actual, bool allow_tabs,
        kbinput = do_statusbar_input(&ran_func, &finished, refresh_func);
        assert(statusbar_x <= strlen(answer));
 
+#ifndef NANO_TINY
+    if (kbinput == KEY_WINCH) {
+       refresh_func();
+       update_statusbar_line(answer, statusbar_x);
+       continue;
+    }
+#endif
+
        func = func_from_key(&kbinput);
 
        if (func == do_cancel || func == do_enter_void)
@@ -1055,6 +1068,13 @@ int do_yesno_prompt(bool all, const char *msg)
     nostr = _("Nn");
     allstr = _("Aa");
 
+    do {
+       int kbinput;
+       functionptrtype func;
+#ifndef DISABLE_MOUSE
+       int mouse_x, mouse_y;
+#endif
+
     if (!ISSET(NO_HELP)) {
        char shortstr[3];
                /* Temp string for Yes, No, All. */
@@ -1098,15 +1118,14 @@ int do_yesno_prompt(bool all, const char *msg)
     wnoutrefresh(edit);
     wnoutrefresh(bottomwin);
 
-    do {
-       int kbinput;
-       functionptrtype func;
-#ifndef DISABLE_MOUSE
-       int mouse_x, mouse_y;
-#endif
-
        currmenu = MYESNO;
        kbinput = get_kbinput(bottomwin);
+
+#ifndef NANO_TINY
+       if (kbinput == KEY_WINCH)
+           continue;
+#endif
+
        func = func_from_key(&kbinput);
 
        if (func == do_cancel)
index 337211d8a1b7f1ba653197d4f87723c73a574d52..ca571da15646a31823a1071ca15335801ee18eed 100644 (file)
@@ -28,8 +28,7 @@
 
 /* All external variables.  See global.c for their descriptions. */
 #ifndef NANO_TINY
-extern sigjmp_buf jump_buf;
-extern bool jump_buf_main;
+extern volatile sig_atomic_t sigwinch_counter;
 #endif
 
 extern bool meta_key;
@@ -478,6 +477,7 @@ RETSIGTYPE do_suspend(int signal);
 RETSIGTYPE do_continue(int signal);
 #ifndef NANO_TINY
 RETSIGTYPE handle_sigwinch(int signal);
+void regenerate_screen(void);
 void allow_pending_sigwinch(bool allow);
 void do_toggle(int flag);
 #endif
index 245d0e64386e0273f65e5591d5cc699377235c99..76524faa703151393b6967ed9a4a2c1baa08983c 100644 (file)
@@ -1922,10 +1922,6 @@ void do_justify(bool full_justify)
     if (full_justify)
        openfile->current = openfile->fileage;
 
-#ifndef NANO_TINY
-    allow_pending_sigwinch(FALSE);
-#endif
-
     while (TRUE) {
        size_t i;
            /* Generic loop variable. */
@@ -2207,17 +2203,6 @@ void do_justify(bool full_justify)
 
     edit_refresh();
 
-#ifndef NANO_TINY
-    /* We're going to set jump_buf so that we return here after a
-     * SIGWINCH instead of to main().  Indicate this. */
-    jump_buf_main = FALSE;
-
-    /* Return here after a SIGWINCH. */
-    sigsetjmp(jump_buf, 1);
-#endif
-
-    statusbar(_("Can now UnJustify!"));
-
     /* If constant cursor position display is on, make sure the current
      * cursor position will be properly displayed on the statusbar. */
     if (ISSET(CONST_UPDATE))
@@ -2229,7 +2214,15 @@ void do_justify(bool full_justify)
 
     /* Now get a keystroke and see if it's unjustify.  If not, put back
      * the keystroke and return. */
-    kbinput = do_input(FALSE);
+#ifndef NANO_TINY
+    do {
+#endif
+       statusbar(_("Can now UnJustify!"));
+       kbinput = do_input(FALSE);
+#ifndef NANO_TINY
+    } while (kbinput == KEY_WINCH);
+#endif
+
     func = func_from_key(&kbinput);
 
     if (func == do_uncut_text) {
@@ -2295,10 +2288,6 @@ void do_justify(bool full_justify)
     /* Display the shortcut list with UnCut. */
     uncutfunc->desc = uncut_tag;
     display_main_list();
-
-#ifndef NANO_TINY
-    allow_pending_sigwinch(TRUE);
-#endif
 }
 
 /* Justify the current paragraph. */
@@ -3183,6 +3172,12 @@ void do_linter(void)
        }
 
        kbinput = get_kbinput(bottomwin);
+
+#ifndef NANO_TINY
+       if (kbinput == KEY_WINCH)
+           continue;
+#endif
+
        func = func_from_key(&kbinput);
        tmplint = curlint;
 
index d57f7970b33f915e1496e78291030ff4d9c838c2..d94a5bab8e955aaf0b54a135f827fa59b74301e9 100644 (file)
@@ -41,6 +41,8 @@ static bool disable_cursorpos = FALSE;
        /* Should we temporarily disable constant cursor position
         * display? */
 
+static sig_atomic_t sigwinch_counter_save = 0;
+
 /* Control character compatibility:
  *
  * - NANO_BACKSPACE_KEY is Ctrl-H, which is Backspace under ASCII, ANSI,
@@ -112,10 +114,6 @@ void get_key_buffer(WINDOW *win)
     if (key_buffer != NULL)
        return;
 
-#ifndef NANO_TINY
-    allow_pending_sigwinch(TRUE);
-#endif
-
     /* Just before reading in the first character, display any pending
      * screen updates. */
     doupdate();
@@ -125,8 +123,17 @@ void get_key_buffer(WINDOW *win)
     if (nodelay_mode) {
        if ((input = wgetch(win)) == ERR)
            return;
-    } else
+    } else {
        while ((input = wgetch(win)) == ERR) {
+#ifndef NANO_TINY
+           /* Did we get SIGWINCH since we were last here? */
+           if (sigwinch_counter != sigwinch_counter_save) {
+               sigwinch_counter_save = sigwinch_counter;
+               regenerate_screen();
+               input = KEY_WINCH;
+               break;
+           } else
+#endif
            errcount++;
 
            /* If we've failed to get a character MAX_BUF_SIZE times in a
@@ -137,10 +144,7 @@ void get_key_buffer(WINDOW *win)
            if (errcount == MAX_BUF_SIZE)
                handle_hupterm(0);
        }
-
-#ifndef NANO_TINY
-    allow_pending_sigwinch(FALSE);
-#endif
+    }
 
     /* Increment the length of the keystroke buffer, and save the value
      * of the keystroke at the end of it. */
@@ -148,14 +152,17 @@ void get_key_buffer(WINDOW *win)
     key_buffer = (int *)nmalloc(sizeof(int));
     key_buffer[0] = input;
 
+#ifndef NANO_TINY
+    /* If we got SIGWINCH, get out immediately since the win argument is
+     * no longer valid. */
+    if (input == KEY_WINCH)
+       return;
+#endif
+
     /* Read in the remaining characters using non-blocking input. */
     nodelay(win, TRUE);
 
     while (TRUE) {
-#ifndef NANO_TINY
-       allow_pending_sigwinch(TRUE);
-#endif
-
        input = wgetch(win);
 
        /* If there aren't any more characters, stop reading. */
@@ -168,10 +175,6 @@ void get_key_buffer(WINDOW *win)
        key_buffer = (int *)nrealloc(key_buffer, key_buffer_len *
                sizeof(int));
        key_buffer[key_buffer_len - 1] = input;
-
-#ifndef NANO_TINY
-       allow_pending_sigwinch(FALSE);
-#endif
     }
 
     /* Switch back to waiting mode for input. */
@@ -191,11 +194,6 @@ size_t get_key_buffer_len(void)
 /* Add the keystrokes in input to the keystroke buffer. */
 void unget_input(int *input, size_t input_len)
 {
-#ifndef NANO_TINY
-    allow_pending_sigwinch(TRUE);
-    allow_pending_sigwinch(FALSE);
-#endif
-
     /* If input is empty, get out. */
     if (input_len == 0)
        return;
@@ -249,11 +247,6 @@ int *get_input(WINDOW *win, size_t input_len)
 {
     int *input;
 
-#ifndef NANO_TINY
-    allow_pending_sigwinch(TRUE);
-    allow_pending_sigwinch(FALSE);
-#endif
-
     if (key_buffer_len == 0) {
        if (win != NULL) {
            get_key_buffer(win);
@@ -643,6 +636,11 @@ int parse_kbinput(WINDOW *win)
                retval = sc_seq_or(do_next_word_void, 0);
 #endif
                break;
+#ifndef NANO_TINY
+           case KEY_WINCH:
+               retval = KEY_WINCH;
+               break;
+#endif
        }
 
        /* If our result is an extended keypad value (i.e. a value