From 55fa7593444a57ef1e75db2efef470ee86e9e2cc Mon Sep 17 00:00:00 2001 From: MacRimi Date: Sat, 22 Nov 2025 20:58:06 +0100 Subject: [PATCH] Update AppImage --- AppImage/app/terminal.css | 30 ++++--- AppImage/components/terminal-panel.tsx | 119 +++++++++++-------------- 2 files changed, 69 insertions(+), 80 deletions(-) diff --git a/AppImage/app/terminal.css b/AppImage/app/terminal.css index d497c3d..57dcca7 100644 --- a/AppImage/app/terminal.css +++ b/AppImage/app/terminal.css @@ -1,28 +1,27 @@ -/* Aggressively force remove all xterm.js internal padding and margins */ +/* Removed negative left positioning that was causing misalignment */ +/* Force xterm.js to have no padding or margin */ .xterm { padding: 0 !important; margin: 0 !important; - /* Move content left to compensate for xterm's internal 2px padding */ - position: relative; - left: -2px !important; + width: 100% !important; + height: 100% !important; } .xterm-viewport { padding: 0 !important; margin: 0 !important; - left: -2px !important; + width: 100% !important; } .xterm-screen { padding: 0 !important; margin: 0 !important; - left: -2px !important; + width: 100% !important; } .xterm-rows { padding: 0 !important; margin: 0 !important; - left: -2px !important; } .xterm-helpers { @@ -30,22 +29,29 @@ margin: 0 !important; } -/* Target the canvas element that has the hardcoded padding */ +/* Target the canvas element */ .xterm canvas { padding: 0 !important; margin: 0 !important; - left: -2px !important; - position: relative; } -/* Ensure terminal container has no padding or overflow */ +/* Ensure all text layers have no padding */ +.xterm-cursor-layer, +.xterm-text-layer, +.xterm-selection-layer, +.xterm-link-layer { + padding: 0 !important; + margin: 0 !important; +} + +/* Ensure terminal container has no padding */ [class*="terminal-container"] { padding: 0 !important; margin: 0 !important; overflow: hidden !important; } -/* Fix any potential scrollbar offset */ +/* Hide scrollbar */ .xterm .xterm-viewport::-webkit-scrollbar { width: 0px !important; } diff --git a/AppImage/components/terminal-panel.tsx b/AppImage/components/terminal-panel.tsx index 55c8b6d..e5c6291 100644 --- a/AppImage/components/terminal-panel.tsx +++ b/AppImage/components/terminal-panel.tsx @@ -133,11 +133,15 @@ export const TerminalPanel: React.FC = ({ websocketUrl, onCl const [searchResults, setSearchResults] = useState([]) const [useOnline, setUseOnline] = useState(true) - const containerRefs = useRef<{ [key: string]: HTMLDivElement | null }>({}) + const containerRefs = useRef>(new Map()) const setContainerRef = useCallback( (id: string) => (el: HTMLDivElement | null) => { - containerRefs.current[id] = el + if (el) { + containerRefs.current.set(id, el) + } else { + containerRefs.current.delete(id) + } }, [], ) @@ -263,12 +267,12 @@ export const TerminalPanel: React.FC = ({ websocketUrl, onCl return filtered }) - delete containerRefs.current[id] // Clean up the ref + containerRefs.current.delete(id) // Clean up the ref } useEffect(() => { terminals.forEach((terminal) => { - const container = containerRefs.current[terminal.id] + const container = containerRefs.current.get(terminal.id) if (!terminal.term && container) { initializeTerminal(terminal, container) } @@ -283,8 +287,8 @@ export const TerminalPanel: React.FC = ({ websocketUrl, onCl ]).then(([Terminal, FitAddon]) => [Terminal, FitAddon]) const term = new Terminal({ - fontFamily: "'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Monaco', 'Menlo', 'Ubuntu Mono', monospace", - fontSize: isMobile ? 11 : 13, + fontFamily: "'Menlo', 'Monaco', 'Courier New', monospace", + fontSize: 14, cursorBlink: true, scrollback: 2000, disableStdin: false, @@ -294,24 +298,25 @@ export const TerminalPanel: React.FC = ({ websocketUrl, onCl background: "#000000", foreground: "#ffffff", cursor: "#ffffff", - cursorAccent: "#000000", - black: "#2e3436", - red: "#cc0000", - green: "#4e9a06", - yellow: "#c4a000", - blue: "#3465a4", - magenta: "#75507b", - cyan: "#06989a", - white: "#d3d7cf", - brightBlack: "#555753", - brightRed: "#ef2929", - brightGreen: "#8ae234", - brightYellow: "#fce94f", - brightBlue: "#729fcf", - brightMagenta: "#ad7fa8", - brightCyan: "#34e2e2", - brightWhite: "#eeeeec", + selection: "rgba(255, 255, 255, 0.3)", + black: "#000000", + red: "#ff5555", + green: "#50fa7b", + yellow: "#f1fa8c", + blue: "#bd93f9", + magenta: "#ff79c6", + cyan: "#8be9fd", + white: "#bbbbbb", + brightBlack: "#555555", + brightRed: "#ff5555", + brightGreen: "#50fa7b", + brightYellow: "#f1fa8c", + brightBlue: "#bd93f9", + brightMagenta: "#ff79c6", + brightCyan: "#8be9fd", + brightWhite: "#ffffff", }, + allowProposedApi: true, }) const fitAddon = new FitAddon() @@ -319,51 +324,38 @@ export const TerminalPanel: React.FC = ({ websocketUrl, onCl term.open(container) + container.style.padding = "0" + container.style.margin = "0" + const removeXtermPadding = () => { - const xtermElement = container.querySelector(".xterm") as HTMLElement - const xtermViewport = container.querySelector(".xterm-viewport") as HTMLElement - const xtermScreen = container.querySelector(".xterm-screen") as HTMLElement - const xtermRows = container.querySelector(".xterm-rows") as HTMLElement - const xtermCanvas = container.querySelectorAll(".xterm canvas") + const xtermElement = container.querySelector(".xterm") + const viewport = container.querySelector(".xterm-viewport") + const screen = container.querySelector(".xterm-screen") if (xtermElement) { - xtermElement.style.padding = "0" - xtermElement.style.margin = "0" - xtermElement.style.position = "relative" - xtermElement.style.left = "-2px" + ;(xtermElement as HTMLElement).style.padding = "0" + ;(xtermElement as HTMLElement).style.margin = "0" } - if (xtermViewport) { - xtermViewport.style.padding = "0" - xtermViewport.style.margin = "0" - xtermViewport.style.left = "-2px" + if (viewport) { + ;(viewport as HTMLElement).style.padding = "0" + ;(viewport as HTMLElement).style.margin = "0" } - if (xtermScreen) { - xtermScreen.style.padding = "0" - xtermScreen.style.margin = "0" - xtermScreen.style.left = "-2px" + if (screen) { + ;(screen as HTMLElement).style.padding = "0" + ;(screen as HTMLElement).style.margin = "0" } - if (xtermRows) { - xtermRows.style.padding = "0" - xtermRows.style.margin = "0" - xtermRows.style.left = "-2px" - } - xtermCanvas.forEach((canvas) => { - const canvasEl = canvas as HTMLElement - canvasEl.style.padding = "0" - canvasEl.style.margin = "0" - canvasEl.style.position = "relative" - canvasEl.style.left = "-2px" - }) } - // Remove padding immediately removeXtermPadding() + setTimeout(removeXtermPadding, 100) - // Remove padding again after a short delay to ensure it applies setTimeout(() => { - removeXtermPadding() - fitAddon.fit() - }, 100) + try { + fitAddon.fit() + } catch (error) { + console.error("[v0] Error fitting terminal:", error) + } + }, 50) const wsUrl = websocketUrl || getWebSocketUrl() const ws = new WebSocket(wsUrl) @@ -607,11 +599,9 @@ export const TerminalPanel: React.FC = ({ websocketUrl, onCl
@@ -636,14 +626,7 @@ export const TerminalPanel: React.FC = ({ websocketUrl, onCl )}
-
+
))}