Handling a SIGWINCH (which signals a change in window size) not when it
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
Этот коммит содержится в:
родитель
c5710d0ef8
Коммит
75d64e677e
12
ChangeLog
12
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.
|
||||
|
@ -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);
|
||||
|
@ -30,12 +30,8 @@
|
||||
|
||||
/* 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;
|
||||
|
16
src/help.c
16
src/help.c
@ -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;
|
||||
|
36
src/nano.c
36
src/nano.c
@ -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();
|
||||
|
@ -117,7 +117,7 @@
|
||||
#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)
|
||||
|
33
src/prompt.c
33
src/prompt.c
@ -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)
|
||||
|
@ -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
|
||||
|
35
src/text.c
35
src/text.c
@ -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;
|
||||
|
||||
|
52
src/winio.c
52
src/winio.c
@ -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
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user