fix: use blocking read-char via listen for reliable input

read-char-no-hang on fd 0 streams never returns data because
sb-unix:unix-simple-poll on fd 0 returns NIL in this SBCL
environment. Switched to (listen tty) + (read-char tty) which
blocks until a key is pressed — correct interactive TUI behavior.
Also switched from (open "/dev/tty") to
(sb-sys:make-fd-stream 0 :input t :buffering :none) to directly
read from stdin.
This commit is contained in:
2026-05-14 09:02:02 -04:00
parent 11cb466d4f
commit 1884372660
2 changed files with 22 additions and 18 deletions

View File

@@ -864,7 +864,7 @@
(add-msg :system "* Swank unavailable *"))))
(cl-tty.input:with-raw-terminal
(cl-tty.backend:with-terminal (be w h)
(let ((tty (open "/dev/tty" :direction :input)))
(let ((tty (sb-sys:make-fd-stream 0 :input t :buffering :none)))
;; Initial render
(cl-tty.backend:backend-clear be)
(view-status be w h)
@@ -887,8 +887,12 @@
(setf cl-tty.input::*terminal-resized-p* nil)
(multiple-value-setq (w h) (cl-tty.backend:backend-size be))
(setf (st :dirty) (list t t t))))
;; Read key input from /dev/tty (non-blocking)
(let ((raw-ch (read-char-no-hang tty nil nil)))
;; Read key input from fd 0 (blocking via listen + read-char)
;; Note: sb-unix:unix-simple-poll on fd 0 returns NIL in this
;; SBCL environment, so read-char-no-hang never fires. Use
;; blocking read-char instead — the TUI loop sleeps 0.1s
;; between renders anyway.
(let ((raw-ch (when (listen tty) (read-char tty nil nil))))
(when raw-ch
(let ((code (char-code raw-ch)))
(let ((ch (cond

View File

@@ -908,7 +908,7 @@ Event handlers + daemon I/O + main loop.
(add-msg :system "* Swank unavailable *"))))
(cl-tty.input:with-raw-terminal
(cl-tty.backend:with-terminal (be w h)
(let ((tty (open "/dev/tty" :direction :input)))
(let ((tty (sb-sys:make-fd-stream 0 :input t :buffering :none)))
;; Initial render
(cl-tty.backend:backend-clear be)
(view-status be w h)
@@ -931,8 +931,8 @@ Event handlers + daemon I/O + main loop.
(setf cl-tty.input::*terminal-resized-p* nil)
(multiple-value-setq (w h) (cl-tty.backend:backend-size be))
(setf (st :dirty) (list t t t))))
;; Read key input from /dev/tty (non-blocking)
(let ((raw-ch (read-char-no-hang tty nil nil)))
;; Read key input from fd 0 (blocking via listen + read-char)
(let ((raw-ch (when (listen tty) (read-char tty nil nil))))
(when raw-ch
(let ((code (char-code raw-ch)))
(let ((ch (cond