From f8ae4ac817661114dcf58dcea1d3d9f5b5c614bc Mon Sep 17 00:00:00 2001 From: Amr Gharbeia Date: Sat, 16 May 2026 17:50:08 -0400 Subject: [PATCH] =?UTF-8?q?fix:=20terminal=20cursor=20instead=20of=20softw?= =?UTF-8?q?are-drawn=20=E2=96=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaced software cursor (draw-text █ every frame) with native terminal cursor (position-cursor using cursor-move + cursor-style). Terminal handles blinking natively at 500ms — no redraw needed for cursor updates. - position-cursor: computed input insertion point from state, calls cursor-move + cursor-style (:block :blink t) + cursor-show. - Called from main loop every frame after (sleep 0.1), outside redraw's begin-sync/end-sync. No flicker. --- org/channel-tui-main.org | 5 ++++- org/channel-tui-state.org | 1 + org/channel-tui-view.org | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/org/channel-tui-main.org b/org/channel-tui-main.org index d69a3a6..c41c28a 100644 --- a/org/channel-tui-main.org +++ b/org/channel-tui-main.org @@ -1067,7 +1067,10 @@ Returns T on success, nil on failure. Does NOT wait or retry." (format nil "> ~a" (or filter "")) (theme-color :input-prompt) bg-p)) (cl-tty.backend:end-sync be)) - (sleep 0.1))) + (sleep 0.1) + ;; Show terminal cursor at input position every frame + (unless (st :dialog-stack) + (passepartout.channel-tui:position-cursor be w h)))) (progn (disconnect-daemon))))) #+END_SRC diff --git a/org/channel-tui-state.org b/org/channel-tui-state.org index a5a3585..5642452 100644 --- a/org/channel-tui-state.org +++ b/org/channel-tui-state.org @@ -23,6 +23,7 @@ All state mutation flows through event handlers in the controller. (:export :tui-main :st :add-msg :now :input-string :queue-event :drain-queue :init-state :view-status :view-chat :view-input :redraw + :position-cursor :input-panel-top :on-key :on-daemon-msg :send-daemon :connect-daemon :disconnect-daemon diff --git a/org/channel-tui-view.org b/org/channel-tui-view.org index a4bcb07..367f47d 100644 --- a/org/channel-tui-view.org +++ b/org/channel-tui-view.org @@ -326,6 +326,22 @@ Returns a list of strings, one per line." (view-sidebar fb w h)) (cl-tty.backend:end-sync fb) (setf (st :dirty) (list nil nil nil)))) + +(defun position-cursor (fb w h) + "Position terminal cursor at the input insertion point. +Terminal handles the blinking — we just set position and style once per frame." + (let* ((sw (if (sidebar-visible-p w) (or (st :sidebar-width) 42) 0)) + (cw (- w sw)) + (hpad 2) + (text (input-string)) + (pos (or (st :cursor-pos) 0)) + (prompt-w (- cw (* 2 hpad) 2)) + (display-start (max 0 (- pos (1- prompt-w)))) + (cx (+ hpad 2 (- pos display-start))) + (cy (- h 6))) + (cl-tty.backend:cursor-move fb cx cy) + (cl-tty.backend:cursor-style fb :block :blink t) + (cl-tty.backend:cursor-show fb))) #+END_SRC * Implementation — v0.7.0 additions