Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Handling curses window resizes with Curses.pm

by Llew_Llaw_Gyffes (Scribe)
on Sep 08, 2016 at 16:44 UTC ( [id://1171416]=perlquestion: print w/replies, xml ) Need Help??

Llew_Llaw_Gyffes has asked for the wisdom of the Perl Monks concerning the following question:

O wise brethren,

I have a threaded multi-window curses application. (Yes, I know many of you are already scratching your heads and asking "Why?" Suffice it to say that the design decision was made to further my knowledge of Perl, and because it was a challenge, and because a multithreaded Perl ICB client was a cool thing to create.)

Now, one of my long-documented bugs that I have been unable to solve is that the application failed to handle SIGWINCH gracefully. Or at all, in fact. When the terminal size was changed, the usual result was that it would crash. I and several other people investigated as deeply as we could, and eventually concluded that it appeared something was breaking deep within Curses.pm, and I abandoned my attempts to handle SIGWINCH and documented it as a known bug.

However, Curses.pm just updated, for the first time in quite some time. And now at least SOME SIGWINCH handling works. Column resizes of the controlling xterm are now handled correctly with no intervention required on my part, but lines resizing does not work correctly. My application creates three curses windows, as follows:

$read_size = LINES() - ($write_size + 1); $output_window = newwin ($read_size, 0, 0, 0); scrollok ($output_window, 1); idlok ($output_window, 1); $input_window = newwin ($write_size, 0, $read_size + 1, 0); scrollok ($input_window, 1); idlok ($input_window, 1); $status_line = newwin (1, 0, $read_size, 0); set_init_status ($output_window, $input_window, $status_line, $options{server});

As should be evident, resizing the terminal vertically should cause only the size of $output_window to change. In practice, the curses window heights do not seem to change when the terminal is resized, and if this causes the status line to be "pushed off the bottom" of the terminal by a terminal height reduction, it is broken and does not work when brought back onscreen again by a terminal height increase. Since the terminal itself does not know how my window sizes are to be managed, I clearly need to handle SIGWINCH myself to correctly resize the output window and move the status line and input window up or down accordingly. My first step should presumably be to call resizeterm(newlines, newcols). resizeterm( ) will call resize_term( ), which will do things like update LINES and COLS, after which I can recalculate my window sizes and make appropriate calls to wresize( ). To know when I need to do this, my reading leads me to understand I should be looking for a KEY_RESIZE event. I'm doing so like this in the thread that handles input:

ReadMode 3; while ($input_thread_running > 0 && !$ret) { until (defined($key = ReadKey(0))) # wait for input { resize_input_window($input_window) if ($sizechanged); } if ($key == ERR) { threads->yield; } elsif ($key eq KEY_RESIZE) { set_resize_flag(); threads->yield; } elsif (($key eq "\n") or ($key eq "\r")) # return/n +ewline { ...

The resize flag should then trigger each thread to update its own window.

There are two problems here. First, I don't appear to be receiving KEY_RESIZE events. Secondly, I don't know what newlines/newcols to pass to resizeterm( ), and I can't even check whether the terminal really WAS resized because is_term_resized( ) is not supported in Curses.pm.

Can anyone offer guidance on how I should be accomplishing what I'm trying to do here?

Replies are listed 'Best First'.
Re: Handling curses window resizes with Curses.pm
by Anonymous Monk on Sep 08, 2016 at 20:40 UTC
    use sleep or usleep instead of yield
      Tried using threads->sleep in the KEY_RESIZE handler, did not help. I'm still not receiving KEY_RESIZE events. Only horizontal resize is working properly, and it is working without me doing anything. Vertical resize does not work at all, either automatically or if I try to trap either KEY_RESIZE or SIGWINCH.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1171416]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (5)
As of 2024-04-19 13:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found