diff --git a/org/channel-tui-main.org b/org/channel-tui-main.org index ac5e2c3..fc20b34 100644 --- a/org/channel-tui-main.org +++ b/org/channel-tui-main.org @@ -963,62 +963,36 @@ Returns T on success, nil on failure. Does NOT wait or retry." (setf (cl-tty.select:select-filter sel) (subseq f 0 (1- f)))))))) (on-key ch)))))))) - ;; Keyboard reader: poll with 0.1s timeout via listen (no sb-ext:timeout) - (dotimes (_ 10) - (when (listen *standard-input*) - (let* ((raw-ch (read-char-no-hang *standard-input* nil nil)) - (code (and raw-ch (char-code raw-ch))) - (esc-seq (and (= code 27) - (let ((b nil) (t2 nil)) - (dotimes (_ 20) - (when (listen *standard-input*) - (setq b (read-char *standard-input* nil nil)) - (return)) - (sleep 0.001)) - (and b (char= b #\[) - (progn - (dotimes (_ 15) - (when (listen *standard-input*) - (setq t2 (read-char *standard-input* nil nil)) - (return)) - (sleep 0.001)) - t) - (case (and t2 (char-code t2)) - (65 :up) (66 :down) - (67 :right) (68 :left) - (72 :home) (70 :end) - (otherwise :escape))))))) - (when raw-ch - (when esc-seq - (add-msg :system (format nil "* CSI: ~s *" esc-seq))) - (queue-event - (list :type :key - :payload (list :code code - :ch (or esc-seq - (cond - ((= code 13) :enter) - ((= code 10) :enter) - ((= code 27) :escape) - ((= code 9) :tab) - ((or (= code 127) (= code 8)) :backspace) - ((and (>= code 1) (<= code 26)) - (intern - (string-upcase - (format nil "CTRL-~a" - (code-char (+ #x60 code)))) - :keyword)) - (t code))))))) - (return))) - (sleep 0.01)) - ;; Check for terminal resize (SIGWINCH sets this flag) - (when (boundp 'cl-tty.input::*terminal-resized-p*) - (when cl-tty.input::*terminal-resized-p* - (setf cl-tty.input::*terminal-resized-p* nil) - (multiple-value-setq (w h) (cl-tty.backend:backend-size be)) - (setq w (or (and (numberp w) (> w 0) w) 80) - h (or (and (numberp h) (> h 0) h) 24)) - (setf (st :dirty) (list t t t)))) - ;; Guard w and h before render (resize or other code may have set them to nil) + ;; Keyboard reader via cl-tty.input:read-event (handles CSI/UTF-8/resize) + (let ((ev (cl-tty.input:read-event be :timeout 0.1))) + (when ev + (if (eq ev :resize) + (progn + (multiple-value-setq (w h) (cl-tty.backend:backend-size be)) + (setq w (or (and (numberp w) (> w 0) w) 80) + h (or (and (numberp h) (> h 0) h) 24)) + (setf (st :dirty) (list t t t))) + (let* ((key (cl-tty.input:key-event-key ev)) + (code (cl-tty.input:key-event-code ev)) + (ctrl (cl-tty.input:key-event-ctrl ev)) + (ch (cond + ((member key + '(:up :down :right :left :escape :enter :tab + :backspace :home :end :delete + :page-up :page-down :insert)) + key) + (ctrl + (ignore-errors + (intern (format nil "CTRL-~a" key) :keyword))) + ((or (eq key :codepoint) code) + (or code 0)) + (t nil)))) + + (when ch + (queue-event + (list :type :key + :payload (list :code (or code 0) :ch ch)))))))) + ;; Guard w and h before render (resize or other code may have set them to nil) (setq w (or (and (numberp w) (> w 0) w) 80) h (or (and (numberp h) (> h 0) h) 24)) (when (and (or (first (st :dirty)) (second (st :dirty)) (third (st :dirty)))