From 26ec1dfbe8643aa59b30f2110fbcaf9ed20435ca Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Tue, 12 May 2026 13:49:23 +0000 Subject: [PATCH] fix: backend-size (TIOCGWINSZ), kitty keyboard enable, Wayland clipboard, SIGWINCH handler --- backend/modern.lisp | 17 ++++++++++++++--- src/components/input-package.lisp | 2 ++ src/components/input.lisp | 14 ++++++++++++++ src/components/mouse.lisp | 9 +++++++-- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/backend/modern.lisp b/backend/modern.lisp index 23c620a..1cf7bc1 100644 --- a/backend/modern.lisp +++ b/backend/modern.lisp @@ -140,18 +140,20 @@ as a fallback when a keyword is not in *named-colors*.") (make-instance 'modern-backend :output-stream (or output-stream *standard-output*))) (defmethod initialize-backend ((b modern-backend)) - ;; Enter raw mode, enable mouse, bracketed paste + ;; Enter raw mode, enable mouse, bracketed paste, kitty keyboard (backend-write b (format nil "~C[?1049h" #\Esc)) ; alt screen (backend-write b (format nil "~C[?1000h" #\Esc)) ; mouse basic (backend-write b (format nil "~C[?1002h" #\Esc)) ; mouse drag (backend-write b (format nil "~C[?1006h" #\Esc)) ; SGR mouse (backend-write b (format nil "~C[?2004h" #\Esc)) ; bracketed paste + (backend-write b (format nil "~C[?u" #\Esc)) ; kitty keyboard (cursor-hide b) (finish-output (backend-output-stream b)) b) (defmethod shutdown-backend ((b modern-backend)) (cursor-show b) + (backend-write b (format nil "~C[?u" #\Esc)) ; restore default keyboard (backend-write b (format nil "~C[?2004l" #\Esc)) ; disable bracketed paste (backend-write b (format nil "~C[?1006l" #\Esc)) ; disable SGR mouse (backend-write b (format nil "~C[?1002l" #\Esc)) @@ -161,8 +163,17 @@ as a fallback when a keyword is not in *named-colors*.") (values)) (defmethod backend-size ((b modern-backend)) - ;; Default fallback — real implementation queries terminal - (values 80 24)) + ;; Query actual terminal dimensions via TIOCGWINSZ ioctl + (let* ((+tiocgwinsz+ 21523) ; 0x5413 on Linux + (winsize (sb-alien:make-alien sb-alien:unsigned-short 4))) + (unwind-protect + (progn + (sb-unix:unix-ioctl (sb-sys:fd-stream-fd (backend-output-stream b)) + +tiocgwinsz+ + winsize) + (values (sb-alien:deref winsize 1) ;; cols + (sb-alien:deref winsize 0))) ;; rows + (sb-alien:free-alien winsize)))) (defmethod backend-write ((b modern-backend) string) (let ((stream (backend-output-stream b))) diff --git a/src/components/input-package.lisp b/src/components/input-package.lisp index 852926d..5d5224f 100644 --- a/src/components/input-package.lisp +++ b/src/components/input-package.lisp @@ -15,6 +15,8 @@ #:with-raw-terminal ;; Event reading #:read-event + ;; Terminal resize flag + #:*terminal-resized-p* ;; TextInput #:text-input #:make-text-input #:text-input-value #:text-input-cursor diff --git a/src/components/input.lisp b/src/components/input.lisp index 5158dd9..029706b 100644 --- a/src/components/input.lisp +++ b/src/components/input.lisp @@ -318,6 +318,20 @@ key event rather than blocking indefinitely." (t (make-key-event :key :unknown :code b :raw (string (code-char b))))))) +;;; --------------------------------------------------------------------------- +;;; SIGWINCH handler for terminal resize +;;; --------------------------------------------------------------------------- +(defvar *terminal-resized-p* nil + "Set to T by SIGWINCH handler when terminal is resized. +Applications should check and clear this flag each frame.") + +#+sbcl +(eval-when (:load-toplevel :execute) + (sb-sys:enable-interrupt sb-posix:sigwinch + (lambda (signal info context) + (declare (ignore signal info context)) + (setf *terminal-resized-p* t)))) + ;;; --------------------------------------------------------------------------- ;;; Backend integration ;;; --------------------------------------------------------------------------- diff --git a/src/components/mouse.lisp b/src/components/mouse.lisp index db68be7..facd028 100644 --- a/src/components/mouse.lisp +++ b/src/components/mouse.lisp @@ -49,8 +49,13 @@ Components without a layout-node or position return nil." (when *selection* (sel-text *selection*))) (defun copy-to-clipboard (text) - #+linux (sb-ext:run-program "xclip" (list "-selection" "clipboard") - :input text :wait nil) + #+linux + (cond + ((sb-ext:posix-getenv "WAYLAND_DISPLAY") + (sb-ext:run-program "wl-copy" nil :input text :wait nil)) + (t + (sb-ext:run-program "xclip" (list "-selection" "clipboard") + :input text :wait nil))) #+darwin (sb-ext:run-program "pbcopy" nil :input text :wait nil)) ;;; --- Selection tracking (mouse drag) ---------------------------------------