fix: add blocking-read-based CSI 18t terminal size query fallback
%query-terminal-size uses blocking read-char on an fd 0 stream to read the terminal's response to \033[18t. This works even when unix-simple-poll on fd 0 returns NIL (unlike read-char-no-hang). Added as fallback in both modern and simple backends.
This commit is contained in:
@@ -1,5 +1,37 @@
|
||||
(in-package :cl-tty.backend)
|
||||
|
||||
(defun %query-terminal-size ()
|
||||
"Query terminal size via ANSI CSI 18 t using blocking read.
|
||||
Returns (values cols rows) or nil."
|
||||
(ignore-errors
|
||||
(let* ((saved (sb-sys:make-fd-stream 0 :input t :buffering :none))
|
||||
(response (make-array 0 :element-type 'character
|
||||
:fill-pointer 0 :adjustable t)))
|
||||
(format t "~C[18t" #\Esc)
|
||||
(force-output)
|
||||
;; Blocking read-char loop — the response arrives immediately
|
||||
(loop with deadline = (+ (get-internal-real-time)
|
||||
(* internal-time-units-per-second 0.5))
|
||||
while (< (get-internal-real-time) deadline)
|
||||
do (let ((ch (read-char saved nil nil)))
|
||||
(when ch
|
||||
(vector-push-extend ch response)
|
||||
(when (char= ch #\t) (return)))))
|
||||
(when (>= (length response) 8)
|
||||
(let* ((str (subseq response 1))
|
||||
(start (or (position #\[ str) 0))
|
||||
(after (subseq str (1+ start)))
|
||||
(semi (position #\; after)))
|
||||
(when semi
|
||||
(let* ((cols-start (1+ semi))
|
||||
(cols-end (position #\t after :start cols-start))
|
||||
(rows (parse-integer (subseq after 0 semi) :junk-allowed t))
|
||||
(cols (when cols-end
|
||||
(parse-integer (subseq after cols-start cols-end)
|
||||
:junk-allowed t))))
|
||||
(when (and rows cols (> rows 0) (> cols 0))
|
||||
(values cols rows)))))))))
|
||||
|
||||
(defclass backend () ())
|
||||
|
||||
(defgeneric initialize-backend (backend)
|
||||
|
||||
@@ -175,6 +175,7 @@ as a fallback when a keyword is not in *named-colors*.")
|
||||
(values (sb-alien:deref winsize 1) ;; cols
|
||||
(sb-alien:deref winsize 0))) ;; rows
|
||||
(sb-alien:free-alien winsize))))
|
||||
(%query-terminal-size)
|
||||
(values 80 24)))
|
||||
|
||||
(defmethod backend-write ((b modern-backend) string)
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
(values (sb-alien:deref winsize 1)
|
||||
(sb-alien:deref winsize 0)))
|
||||
(sb-alien:free-alien winsize))))
|
||||
(%query-terminal-size)
|
||||
(values 80 24)))
|
||||
|
||||
(defmethod backend-write ((b simple-backend) string)
|
||||
|
||||
Reference in New Issue
Block a user