fix: use ResizeObserver for terminal refit after sidebar toggle
The previous transitionend approach (v0.4.5) had a { once: true } bug:
the sidebar transitions two CSS properties (width and min-width), and if
min-width fired first, the listener self-destructed before the width event
arrived — so _refitTerminal() was never called.
Replace the fragile event-based approach with a ResizeObserver on
#terminal-container. This automatically calls _fitAddon.fit() (debounced
50ms) whenever the container dimensions change, handling sidebar toggle,
browser resize, and any future layout change. Remove the now-unnecessary
window._refitTerminal global and the broken transitionend handler.
Bumps version to 0.4.6.
This commit is contained in:
@@ -804,13 +804,6 @@ function toggleSidebar() {
|
|||||||
|
|
||||||
var collapseBtn = $('sidebar-collapse-btn');
|
var collapseBtn = $('sidebar-collapse-btn');
|
||||||
if (collapseBtn) collapseBtn.textContent = isOpen ? '\u2039' : '\u203a';
|
if (collapseBtn) collapseBtn.textContent = isOpen ? '\u2039' : '\u203a';
|
||||||
|
|
||||||
// Refit xterm.js after the sidebar CSS transition completes (0.25s ease).
|
|
||||||
// 'width' fires on desktop (flex layout); 'transform' fires on mobile (overlay).
|
|
||||||
sidebar.addEventListener('transitionend', function(e) {
|
|
||||||
if (e.propertyName !== 'width' && e.propertyName !== 'transform') return;
|
|
||||||
if (window._refitTerminal) window._refitTerminal();
|
|
||||||
}, { once: true });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ let _currentSession = null;
|
|||||||
let _vpHandler = null;
|
let _vpHandler = null;
|
||||||
let _reconnectAttempts = 0; // tracks consecutive failed reconnect attempts for backoff + ttyd respawn
|
let _reconnectAttempts = 0; // tracks consecutive failed reconnect attempts for backoff + ttyd respawn
|
||||||
let _searchAddon = null;
|
let _searchAddon = null;
|
||||||
|
let _resizeObserver = null;
|
||||||
|
|
||||||
// ─── Module-level encoding helpers ──────────────────────────────────────────
|
// ─── Module-level encoding helpers ──────────────────────────────────────────
|
||||||
// Hoisted here so the clipboard key handler (in openTerminal) can also use them.
|
// Hoisted here so the clipboard key handler (in openTerminal) can also use them.
|
||||||
@@ -357,6 +358,23 @@ function openTerminal(sessionName, remoteId, fontSize) {
|
|||||||
|
|
||||||
_term.open(container);
|
_term.open(container);
|
||||||
|
|
||||||
|
// --- Auto-refit on container resize (sidebar toggle, etc.) ---
|
||||||
|
// xterm.js FitAddon only resizes on explicit fit() calls. A ResizeObserver
|
||||||
|
// on the container handles ALL layout changes: sidebar toggle, window resize,
|
||||||
|
// and any future CSS geometry change. Debounced to coalesce rapid events
|
||||||
|
// (e.g. during CSS transition animation frames).
|
||||||
|
if (_resizeObserver) { _resizeObserver.disconnect(); _resizeObserver = null; }
|
||||||
|
if (typeof ResizeObserver !== 'undefined') {
|
||||||
|
var _roTimer = null;
|
||||||
|
_resizeObserver = new ResizeObserver(function() {
|
||||||
|
clearTimeout(_roTimer);
|
||||||
|
_roTimer = setTimeout(function() {
|
||||||
|
if (_fitAddon) try { _fitAddon.fit(); } catch (_) {}
|
||||||
|
}, 50);
|
||||||
|
});
|
||||||
|
_resizeObserver.observe(container);
|
||||||
|
}
|
||||||
|
|
||||||
// --- Clipboard integration ---
|
// --- Clipboard integration ---
|
||||||
// Copy: Ctrl+Shift+C intercepts and copies selection to system clipboard
|
// Copy: Ctrl+Shift+C intercepts and copies selection to system clipboard
|
||||||
// Paste: handled natively by xterm.js (browser paste event → hidden textarea → onData → WebSocket)
|
// Paste: handled natively by xterm.js (browser paste event → hidden textarea → onData → WebSocket)
|
||||||
@@ -504,6 +522,8 @@ function closeTerminal() {
|
|||||||
_ws = null;
|
_ws = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_resizeObserver) { _resizeObserver.disconnect(); _resizeObserver = null; }
|
||||||
|
|
||||||
if (_term) {
|
if (_term) {
|
||||||
_term.dispose();
|
_term.dispose();
|
||||||
_term = null;
|
_term = null;
|
||||||
@@ -542,13 +562,6 @@ function setTerminalFontSize(size) {
|
|||||||
|
|
||||||
window._setTerminalFontSize = setTerminalFontSize;
|
window._setTerminalFontSize = setTerminalFontSize;
|
||||||
|
|
||||||
// Refit the terminal to its container dimensions.
|
|
||||||
// Call after layout changes (e.g. sidebar toggle) that alter available space.
|
|
||||||
window._refitTerminal = function() {
|
|
||||||
if (!_fitAddon) return;
|
|
||||||
try { _fitAddon.fit(); } catch (_) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Mobile touch scroll — rAF-batched WheelEvent dispatch
|
// Mobile touch scroll — rAF-batched WheelEvent dispatch
|
||||||
// Mobile devices batch touchmove events irregularly; dispatching one WheelEvent
|
// Mobile devices batch touchmove events irregularly; dispatching one WheelEvent
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "muxplex"
|
name = "muxplex"
|
||||||
version = "0.4.5"
|
version = "0.4.6"
|
||||||
description = "Web-based tmux session dashboard — access all your tmux sessions from any browser"
|
description = "Web-based tmux session dashboard — access all your tmux sessions from any browser"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = { text = "MIT" }
|
license = { text = "MIT" }
|
||||||
|
|||||||
Reference in New Issue
Block a user