From 9fe0ac2c6e9aea60a611172b0d659c3009cba006 Mon Sep 17 00:00:00 2001 From: Adam Jeniski Date: Wed, 21 Jan 2026 10:51:45 -0500 Subject: [PATCH] fix exit app --- src/tui/core.clj | 16 ++++++++++------ src/tui/simple.clj | 7 ++++--- src/tui/terminal.clj | 6 ++++++ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/tui/core.clj b/src/tui/core.clj index 9f70c57..d21f447 100644 --- a/src/tui/core.clj +++ b/src/tui/core.clj @@ -82,13 +82,16 @@ ;; === Input Loop === (defn- start-input-loop! "Start thread that reads input and puts messages on channel. - Uses thread instead of go-loop because input reading is blocking I/O." + Uses polling with timeout to allow clean shutdown when running? becomes false." [msg-chan running?] (async/thread (loop [] (when @running? - (when-let [key-msg (input/read-key)] - (>!! msg-chan key-msg)) + (if (term/input-ready?) + (when-let [key-msg (input/read-key)] + (>!! msg-chan key-msg)) + ;; No input ready, sleep briefly and check running? again + (Thread/sleep 10)) (recur))))) ;; === Main Run Loop === @@ -101,11 +104,11 @@ - :view - (fn [model] hiccup) (required) - :init-cmd - Initial command to run - :fps - Target frames per second (default 60) - - :alt-screen - Use alternate screen buffer (default false) + - :alt-screen - Use alternate screen buffer (default true) Returns the final model." [{:keys [init update view init-cmd fps alt-screen] - :or {fps 60 alt-screen false}}] + :or {fps 60 alt-screen true}}] (let [msg-chan (chan 256) running? (atom true) frame-time (/ 1000 fps)] @@ -167,7 +170,8 @@ (when alt-screen (term/exit-alt-screen!)) (term/restore!) (term/close-input!) - (println))))) + (println) + (flush))))) ;; === Convenience Macros === (defmacro defapp diff --git a/src/tui/simple.clj b/src/tui/simple.clj index fa0d1b5..6dcfdfe 100644 --- a/src/tui/simple.clj +++ b/src/tui/simple.clj @@ -28,11 +28,11 @@ - :init - Initial model (required) - :update - (fn [model msg] [new-model cmd]) (required) - :view - (fn [model] hiccup) (required) - - :alt-screen - Use alternate screen buffer (default false) + - :alt-screen - Use alternate screen buffer (default true) Returns the final model." [{:keys [init update view alt-screen] - :or {alt-screen false}}] + :or {alt-screen true}}] ;; Setup terminal (term/raw-mode!) @@ -62,7 +62,8 @@ (when alt-screen (term/exit-alt-screen!)) (term/restore!) (term/close-input!) - (println)))) + (println) + (flush)))) ;; Re-export render (def render render/render) diff --git a/src/tui/terminal.clj b/src/tui/terminal.clj index 2bf4883..74e6488 100644 --- a/src/tui/terminal.clj +++ b/src/tui/terminal.clj @@ -103,6 +103,12 @@ (.close r) (reset! tty-reader nil))) +(defn input-ready? + "Check if input is available without blocking." + [] + (when-let [r @tty-reader] + (.ready r))) + (defn read-char "Read a single character. Blocking." []