Search code examples
perlterminalcurses

How to Reanimate if Terminal Size Changes using Curses


I am writing a perl script to display an animation in the terminal using the Curses library and I cannot get it to reanimate when the terminal size is changed. The goal is to have the animation restart from the middle of the terminal when the terminal is resized.

Here is the code I've tried, but it never redraws the entity even if the terminal size changes:

#!/usr/bin/env perl

use Term::Animation;
use Term::Animation::Entity;
use Curses;

# Declaration of $anim1 and addition of entity

my ($width, $height, $assumed_size) = $anim1->screen_size();

while (1) {
    # Animate the current frame
    $anim1->animate();

    # Check for terminal resize and update if necessary
    my ($new_width, $new_height) = $anim1->screen_size();
    if ($new_width != $width || $new_height != $height) {
        
        # Update terminal size variables
        $width = $new_width;
        $height = $new_height;

        # Update entity position based on new terminal size
        my $entity->{position} = [$height / 2 - 7, $width / 2 - 25, 0];
        
        # Redraw all entities
        $anim1->update_term_size();
    }

    # Handle user input
    my $input = getch();
    if ($input && $input eq 'c') {
        last; # Exit the loop if 'c' is pressed
    }
}

Solution

  • In the terminal curses library the function to call to change the terminal size is resize_term() or resizeterm().

    This function is implemented in the Perl Curses module used by Term::Animation, but this function is never, ever used in the code of Term::Animation.

    In fact the author put this in the module code:

    sub update_term_size {
            my $self = shift;
            # dunno how portable this is. i should probably be using
            # resizeterm.
            endwin();
            refresh();
            ($self->{WIDTH}, $self->{HEIGHT}, $self->{ASSUMED_SIZE}) = _get_term_size($self->{WIN});
    }
    

    In other words: It seems that the author of this module never implemented resizing.