class Termisu::Event::Source::Resize

Overview

Terminal resize event source.

Monitors terminal size changes via polling and SIGWINCH signal handling. Generates Event::Resize events with old and new dimensions for efficient partial redraws.

Usage

# Create with a size provider (typically backend.size)
resize = Termisu::Event::Source::Resize.new(-> { backend.size })

loop = Termisu::Event::Loop.new
loop.add_source(resize)
loop.start

while event = loop.output.receive?
  case event
  when Termisu::Event::Resize
    puts "Terminal resized to #{event.width}x#{event.height}"
    if event.changed?
      puts "Changed from #{event.old_width}x#{event.old_height}"
    end
  end
end

Detection Strategy

Uses a hybrid approach:

  1. SIGWINCH Signal: Immediate notification when terminal is resized
  2. Polling Fallback: Periodic checks (default 100ms) as a safety net

The signal handler wakes the polling fiber immediately, providing responsive resize detection while the polling serves as a fallback for edge cases where signals might be missed.

Runtime Configuration

The poll interval can be changed while the source is running via #poll_interval=. Changes take effect on the next poll cycle.

Thread Safety

Uses Atomic(Bool) for the running state. Safe to call #start/#stop from different fibers. Uses compare_and_set for idempotent lifecycle operations - calling #start twice or #stop twice is safe.

Lifecycle

The source can be restarted after stopping. Each #start creates a fresh signal channel and reinstalls the SIGWINCH handler.

Defined in:

termisu/event/source/resize.cr

Constant Summary

DEFAULT_POLL_INTERVAL = 100.milliseconds

Default polling interval for size checks. 100ms provides reasonable responsiveness without excessive CPU usage. SIGWINCH signals trigger immediate checks regardless of this interval.

Log = Termisu::Logs::Event

Constructors

Instance Method Summary

Instance methods inherited from class Termisu::Event::Source

name : String name, running? : Bool running?, start(output : Channel(Event::Any)) : Nil start, stop : Nil stop

Constructor Detail

def self.new(size_provider : SizeProvider, poll_interval : Time::Span = DEFAULT_POLL_INTERVAL) #

Creates a new resize source.

  • size_provider - Proc that returns current terminal size as {width, height}
  • #poll_interval - Time between size checks (default: 100ms)

Example:

# Using terminal backend
resize = Termisu::Event::Source::Resize.new(-> { backend.size })

# Custom poll interval for more responsive detection
resize = Termisu::Event::Source::Resize.new(
  -> { backend.size },
  poll_interval: 50.milliseconds
)

[View source]

Instance Method Detail

def name : String #

Returns the source name for identification.


[View source]
def poll_interval : Time::Span #

Returns the current polling interval.


[View source]
def poll_interval=(value : Time::Span) #

Sets the polling interval.

The new interval takes effect on the next poll cycle. Can be changed while the source is running.


[View source]
def running? : Bool #

Returns true if the resize source is currently running.


[View source]
def start(output : Channel(Event::Any)) : Nil #

Starts monitoring for resize events.

Installs a SIGWINCH signal handler and spawns a fiber that polls for size changes. Events are sent to the output channel.

Prevents double-start with compare_and_set.


[View source]
def stop : Nil #

Stops monitoring for resize events.

Sets the running flag to false, causing the fiber to exit on its next iteration. Closes the signal channel to unblock the fiber immediately.


[View source]