Search code examples
pythonasciimatics

How to detect screen resize under Asciimatics


This little snippet will display the h x w in the bottom right-hand corner of the screen.

from asciimatics.screen import Screen
import time

def print_dims(screen):
    (h, w) = screen.dimensions
    screen.print_at("%3d x %3d" % (h, w), w - 12, h - 1, Screen.COLOUR_BLUE, Screen.A_NORMAL)

def demo(screen):
    print_dims(screen)
    while True:
        if screen.has_resized():   # never triggered
            print_dims(screen)
        ev = screen.get_key()
        if ev in (ord('Q'), ord('q')):
            return
        time.sleep(0.1)
        screen.refresh()

Screen.wrapper(demo)

Situation

The first call to print_dims() works fine.

When I resize the window, everything on the screen is simply blanked out. The screen.has_resized() inside the loop is never triggered. But the program is still running because a 'Q' will exit correctly.

Python is running on a Linux VM, and I am using ssh/iTerm2 from MacOS (TERM="xterm-256color") to access the Linux VM.

Request for Assistance

At this point, I need a sanity check.

I don't know if something is wrong with my code, with my terminal program, or if curses wasn't compiled with resize signals. iTerm2 on MacOS is probably ok, because when I run vim in another window and resize the iTerm2 window, vim does recognize the resize.

Has anyone gotten their system to detect a screen.has_resize() within asciimatics? If so, please share your snippet and share your environment so I can narrow down exactly what I'm doing wrong.

Thank you.


Solution

  • It's a subtle issue here... The Screen will maintain its dimensions until you recreate it. Your code is being triggered, but printing the same thing to the double buffer and so is not updated on the refresh.

    You just need to allow the Screen object to be resized. For example...

    from asciimatics.screen import Screen
    import time
    import sys
    
    def print_dims(screen):
        (h, w) = screen.dimensions
        screen.print_at("%3d x %3d" % (h, w), w - 12, h - 1, Screen.COLOUR_BLUE, Screen.A_NORMAL)
    
    def demo(screen):
        print_dims(screen)
        while True:
            if screen.has_resized():
                return
            print_dims(screen)
            ev = screen.get_key()
            if ev in (ord('Q'), ord('q')):
                sys.exit(0)
            time.sleep(0.1)
            screen.refresh()
    
    def main():
        while True:
            Screen.wrapper(demo)
    
    main()