From 4edc3ddd5b96cfbed6f39282eb6410073d9173fa Mon Sep 17 00:00:00 2001 From: vasilito Date: Fri, 19 Jun 2026 19:06:02 +0300 Subject: [PATCH] =?UTF-8?q?tlc:=20revert=20to=20blocking-read=20event=20lo?= =?UTF-8?q?op=20=E2=80=94=20fix=20terminal=20resize=20on=20Redox?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The poll-based event loop (rustix::event::poll with 200ms timeout) broke terminal size detection on Redox. When tui.size() returned (0,0) via unwrap_or_default() after a failed dup(1,"winsize"), the size-change check would clear the screen and render nothing. Ratatui's draw() already calls autoresize() on every frame, which queries backend.size() and resizes buffers automatically. The manual size check and poll-based wake-up were redundant and harmful. Reverted to the original blocking-read approach that worked on Redox: stdin.lock().events_and_raw().next() → process key → render() Resize is detected on the next keypress via ratatui's built-in autoresize. --- local/recipes/tui/tlc/source/src/app.rs | 40 +++++-------------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/local/recipes/tui/tlc/source/src/app.rs b/local/recipes/tui/tlc/source/src/app.rs index ac7a0060a4..023997c30e 100644 --- a/local/recipes/tui/tlc/source/src/app.rs +++ b/local/recipes/tui/tlc/source/src/app.rs @@ -13,7 +13,6 @@ use std::io::Write; use std::time::Duration; use anyhow::Result; -use rustix::event::{poll, PollFd, PollFlags, Timespec}; use termion::event::{Event as TermEvent, Key as TermKey}; use termion::input::TermReadEventsAndRaw; @@ -54,25 +53,13 @@ impl Application { // Initial paint. render(&mut tui, &mut fm)?; - let mut last_size = tui.size(); - - // Stdin fd for poll — obtained without locking so the subshell - // can still read from stdin when we drop into CTRL+O. - let stdin = std::io::stdin(); - let poll_timeout = - Timespec::try_from(Duration::from_millis(200)).unwrap_or_default(); - - // Main event loop — MC-style resize detection via poll timeout. - // poll() wakes every 200ms even without key input, letting us - // detect terminal resize without requiring a keypress. + // Main event loop — blocking stdin, raw mode is active. + // + // Ratatui's `draw()` calls `autoresize()` on every frame, which + // queries `backend.size()` and resizes buffers if the terminal + // dimensions changed. This means resize is detected automatically + // on the next keypress after a resize — no SIGWINCH or poll needed. loop { - let cur_size = tui.size(); - if cur_size != last_size { - last_size = cur_size; - let _ = tui.terminal_mut().clear(); - render(&mut tui, &mut fm)?; - } - // Handle pending external execution (subshell or command line) // before reading the next key. This runs every iteration // regardless of which code path set the flag. @@ -81,20 +68,7 @@ impl Application { render(&mut tui, &mut fm)?; } - // Poll stdin with 200ms timeout. On timeout (no key), loop - // back and re-check terminal size. On data, read the key. - let mut poll_fds = [PollFd::new(&stdin, PollFlags::IN)]; - match poll(&mut poll_fds, Some(&poll_timeout)) { - Ok(0) => continue, - Ok(_) => { - if !poll_fds[0].revents().contains(PollFlags::IN) { - continue; - } - } - Err(_) => continue, - } - - // Data available on stdin — read the key event. + let stdin = std::io::stdin(); let mut events = stdin.lock().events_and_raw(); let (event, raw) = match events.next() { Some(Ok(pair)) => pair,