From a36793563cac9bd7df74b7497a8dae7ddf6fb1ca Mon Sep 17 00:00:00 2001 From: Vantz Stockwell Date: Mon, 30 Mar 2026 12:14:02 -0400 Subject: [PATCH] fix: WKWebView cursor/selection focus, theme restore on startup, status bar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cursor blink + selection (ROOT CAUSE FOUND): - xterm.js v6 uses DOM renderer, not canvas. Cursor blink and selection both require CSS focus classes set by the hidden textarea's focus event. - WKWebView doesn't focus elements with opacity:0, width:0, height:0, left:-9999em — the textarea never receives focus, classes never toggle. - Fix: Override .xterm-helper-textarea to left:0, top:0, width:1px, height:1px, opacity:0.01 — within viewport, non-zero, focusable. Theme restoration on startup: - sessionStore.activeTheme started as null on every launch - ThemePicker saved active_theme to settings but nobody restored it - Added theme restoration to MainLayout onMounted — reads active_theme setting, fetches theme from backend, calls setTheme() before any terminals open Status bar: - h-10 (40px) to match toolbar height for visual balance Selection colors: - Solid #264f78 (VS Code selection blue) instead of rgba transparency Co-Authored-By: Claude Opus 4.6 (1M context) --- src/assets/css/terminal.css | 16 ++++++++++------ src/components/common/StatusBar.vue | 2 +- src/layouts/MainLayout.vue | 13 +++++++++++++ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/assets/css/terminal.css b/src/assets/css/terminal.css index fe38fb2..1733b22 100644 --- a/src/assets/css/terminal.css +++ b/src/assets/css/terminal.css @@ -20,12 +20,16 @@ height: 100%; } -/* Selection styling — xterm.js v6 handles selection via canvas renderer. - No CSS override needed; colors come from terminal.options.theme. */ - -/* Cursor styling */ -.terminal-container .xterm-cursor-layer { - z-index: 4; +/* WKWebView focus fix: xterm.js hides its helper textarea with opacity: 0, + width/height: 0, left: -9999em. macOS WKWebView doesn't reliably focus + elements with zero dimensions positioned off-screen. Override to keep it + within the viewport with non-zero dimensions so focus events fire. */ +.terminal-container .xterm .xterm-helper-textarea { + left: 0 !important; + top: 0 !important; + width: 1px !important; + height: 1px !important; + opacity: 0.01 !important; } /* Scrollbar inside terminal */ diff --git a/src/components/common/StatusBar.vue b/src/components/common/StatusBar.vue index 8e37aa2..2582ea7 100644 --- a/src/components/common/StatusBar.vue +++ b/src/components/common/StatusBar.vue @@ -1,5 +1,5 @@