5

On Arch --enable-sigwinch isn't compiled into ncurses. According to this forum post it can be used to detect a terminal resize. Getting them to turn that option on doesn't seem to be available without some resistance is there another means general purpose means of detecting a terminal resize for C?

1
  • I don't have the patience right now or the energy to write an answer but depending on the design of your program and what you need to do you can start the program first by calling getmaxyx() and then each iteration in the loop (or whatever) call it again but with a different pair of y/x variables. Then if they differ you know it's been resized.
    – Pryftan
    Jan 15, 2020 at 14:34

1 Answer 1

4

Quoting from INSTALL:

    --enable-sigwinch
        Compile support for ncurses' SIGWINCH handler.  If your application has
        its own SIGWINCH handler, ncurses will not use its own.  The ncurses
        handler causes wgetch() to return KEY_RESIZE when the screen-size
        changes.  This option is the default, unless you have disabled the
        extended functions.

If it's not there, it was disabled. In principle, you could do as shown in the recently removed (long-obsolete) CAN_RESIZE section of the test/view.c file. The ncurses library does a better job than that; the example was added in July 1995. The comment refers to SunOS 4:

/*
 * This uses functions that are "unsafe", but it seems to work on SunOS. 
 * Usually: the "unsafe" refers to the functions that POSIX lists which may be
 * called from a signal handler.  Those do not include buffered I/O, which is
 * used for instance in wrefresh().  To be really portable, you should use the
 * KEY_RESIZE return (which relies on ncurses' sigwinch handler).
 *
 * The 'wrefresh(curscr)' is needed to force the refresh to start from the top
 * of the screen -- some xterms mangle the bitmap while resizing.
 */

A contemporary equivalent would just set a flag in the signal handler, as done in the library:

#if USE_SIGWINCH
static void
handle_SIGWINCH(int sig GCC_UNUSED)
{
    _nc_globals.have_sigwinch = 1;
# if USE_PTHREADS_EINTR
    if (_nc_globals.read_thread) {
    if (!pthread_equal(pthread_self(), _nc_globals.read_thread))
        pthread_kill(_nc_globals.read_thread, SIGWINCH);
    _nc_globals.read_thread = 0;
    }
# endif
}
#endif /* USE_SIGWINCH */

By the way, the package script doesn't show that the feature is disabled:

  ./configure --prefix=/usr --mandir=/usr/share/man \
    --with-pkg-config-libdir=/usr/lib/pkgconfig \
    --with-static --with-normal --without-debug --without-ada \
    --enable-widec --enable-pc-files --with-cxx-binding --with-cxx-static \
    --with-shared --with-cxx-shared

Referring back to the library, it initializes its SIGWINCH handler if the signal is the default (unset) value:

#if USE_SIGWINCH
        CatchIfDefault(SIGWINCH, handle_SIGWINCH);
#endif

If there's already a SIGWINCH handler, ncurses won't do anything.

1
  • Oh, I was just overwriting my test window. Yeah, it's enabled.
    – ZeroPhase
    Oct 23, 2017 at 23:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.