diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | Doc/Zsh/mod_curses.yo | 18 | ||||
-rw-r--r-- | Src/Modules/curses.c | 69 | ||||
-rw-r--r-- | configure.ac | 2 |
4 files changed, 92 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog index 40972a0b9..2b10f6d79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2017-03-05 Barton E. Schaefer <schaefer@zsh.org> + + * Sebastian: 40726: Doc/Zsh/mod_curses.yo, Src/Modules/curses.c, + configure.ac: add "zcurses resize" for sane terminal size change + 2017-03-04 Barton E. Schaefer <schaefer@zsh.org> * Sebastian: 40781: Src/params.c, Test/A06assign.ztst: optimize diff --git a/Doc/Zsh/mod_curses.yo b/Doc/Zsh/mod_curses.yo index 72dc4094a..6e4831abe 100644 --- a/Doc/Zsh/mod_curses.yo +++ b/Doc/Zsh/mod_curses.yo @@ -27,7 +27,8 @@ xitem(tt(zcurses) tt(scroll) var(targetwin) [ tt(on) | tt(off) | [tt(+)|tt(-)]va xitem(tt(zcurses) tt(input) var(targetwin) [ var(param) [ var(kparam) [ var(mparam) ] ] ]) xitem(tt(zcurses) tt(mouse) [ tt(delay) var(num) | [tt(+)|tt(-)]tt(motion) ]) xitem(tt(zcurses) tt(timeout) var(targetwin) var(intval)) -item(tt(zcurses) tt(querychar) var(targetwin) [ var(param) ])( +xitem(tt(zcurses) tt(querychar) var(targetwin) [ var(param) ]) +item(tt(zcurses) tt(resize) var(height) var(width) [ tt(endwin) | tt(nosave) | tt(endwin_nosave) ])( Manipulate curses windows. All uses of this command should be bracketed by `tt(zcurses init)' to initialise use of curses, and `tt(zcurses end)' to end it; omitting `tt(zcurses end)' can cause @@ -211,6 +212,21 @@ second is the color pair in the usual var(fg_col)tt(/)var(bg_col) notation, or tt(0) if color is not supported. Any attributes other than color that apply to the character, as set with the subcommand tt(attr), appear as additional elements. + +The subcommand tt(resize) resizes tt(stdscr) and all windows to given +dimensions (windows that stick out from the new dimensions are resized +down). The underlying curses extension (tt(resize_term call)) can be +unavailable. To verify, zeroes can be used for var(height) and +var(width). If the result of the subcommand is tt(0), resize_term is +available (tt(2) otherwise). Tests show that resizing can be normally +accomplished by calling tt(zcurses end) and tt(zcurses refresh). The +tt(resize) subcommand is provided for versatility. Multiple system +configurations have been checked and tt(zcurses end) and tt(zcurses +refresh) are still needed for correct terminal state after resize. To +invoke them with tt(resize), use var(endwin) argument. Using +var(nosave) argument will cause new terminal state to not be saved +internally by tt(zcurses). This is also provided for versatility and +should normally be not needed. ) enditem() diff --git a/Src/Modules/curses.c b/Src/Modules/curses.c index d9c19bdb1..a60dfcbf8 100644 --- a/Src/Modules/curses.c +++ b/Src/Modules/curses.c @@ -1490,6 +1490,74 @@ zccmd_touch(const char *nam, char **args) return ret; } +static int +zccmd_resize(const char *nam, char **args) +{ +#ifdef HAVE_RESIZE_TERM + int y, x, do_endwin=0, do_save=1; + LinkNode stdscr_win = zcurses_getwindowbyname("stdscr"); + + if (stdscr_win) { + y = atoi(args[0]); + x = atoi(args[1]); + if (args[2]) { + if (0 == strcmp(args[2], "endwin")) { + do_endwin=1; + } else if (0 == strcmp(args[2], "endwin_nosave")) { + do_endwin=1; + do_save=0; + } else if (0 == strcmp(args[2], "nosave")) { + do_save=0; + } else { + zwarnnam(nam, "`resize' expects `endwin', `nosave' or `endwin_nosave' for third argument, if given"); + } + } + + if (y == 0 && x == 0 && args[2] == NULL) { + // Special case to just test that curses has resize_term. #ifdef + // HAVE_RESIZE_TERM will result in return value 2 if resize_term + // is not available. + return 0; + } else { + // Without this call some window moves are innacurate. Tested on + // OS X ncurses 5.4, Homebrew ncursesw 6.0-2, Arch Linux ncursesw + // 6.0, Ubuntu 14.04 ncurses 5.9, FreeBSD ncursesw.so.8 + // + // On the other hand, the whole resize goal can be (from tests) + // accomplished by calling endwin and refresh. But to secure any + // future problems, resize_term is provided, and it is featured + // with endwin, so that users have multiple options. + if (do_endwin) { + endwin(); + } + + if( resize_term( y, x ) == OK ) { + // Things work without this, but we need to get out from + // endwin (i.e. call refresh), and in theory store new + // curses state (the resize might have changed it), which + // should be presented to terminal only after refresh. + if (do_endwin || do_save) { + ZCWin w; + w = (ZCWin)getdata(stdscr_win); + wnoutrefresh(w->win); + doupdate(); + } + + if (do_save) { + gettyinfo(&curses_tty_state); + } + return 0; + } else { + return 1; + } + } + } else { + return 1; + } +#else + return 2; +#endif +} /********************* Main builtin handler @@ -1523,6 +1591,7 @@ bin_zcurses(char *nam, char **args, UNUSED(Options ops), UNUSED(int func)) {"mouse", zccmd_mouse, 0, -1}, {"querychar", zccmd_querychar, 1, 2}, {"touch", zccmd_touch, 1, -1}, + {"resize", zccmd_resize, 2, 3}, {NULL, (zccmd_t)0, 0, 0} }; diff --git a/configure.ac b/configure.ac index 0551a69f0..911cc4547 100644 --- a/configure.ac +++ b/configure.ac @@ -1309,7 +1309,7 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \ putenv getenv setenv unsetenv xw\ brk sbrk \ pathconf sysconf \ - tgetent tigetflag tigetnum tigetstr setupterm initscr \ + tgetent tigetflag tigetnum tigetstr setupterm initscr resize_term \ getcchar setcchar waddwstr wget_wch win_wch use_default_colors \ pcre_compile pcre_study pcre_exec \ nl_langinfo \ |