diff --git a/frontend/src/js/app.js b/frontend/src/js/app.js index 958ff23..f3ec615 100644 --- a/frontend/src/js/app.js +++ b/frontend/src/js/app.js @@ -519,6 +519,12 @@ this.splitPanes.refitAll(); }, 100), ); + + window.addEventListener("focus", () => { + requestAnimationFrame(() => { + this._focusVisibleTerminal(); + }); + }); } // ── Split pane ───────────────────────────────────────────────── @@ -1214,6 +1220,16 @@ } } + /** + * Focuses the currently visible xterm instance if one is active. + * @private + */ + _focusVisibleTerminal() { + const sessionId = this.state.activeSessionId; + if (!sessionId) return; + this.terminals.focusTerminal(sessionId); + } + /** * Shows a simple text-input prompt modal (replaces window.prompt which * is unavailable in WKWebView). diff --git a/frontend/src/js/profiles.js b/frontend/src/js/profiles.js index b9d54f5..bf430d1 100644 --- a/frontend/src/js/profiles.js +++ b/frontend/src/js/profiles.js @@ -984,7 +984,6 @@ * Renders a collapsible form section. * @param {string} title * @param {HTMLElement[]} fields - * @param {boolean} [startCollapsed=false] * @returns {HTMLElement} * @private */ @@ -997,15 +996,14 @@ _renderTOTPSection(profile) { const section = createElement("div", "form-section"); const header = createElement("div", "form-section-header"); - let collapsed = true; + let collapsed = false; header.innerHTML = ` - ▸ + ▾ TOTP / 2FA `; const content = createElement("div", "form-section-content"); - content.style.display = "none"; const helpText = createElement("div", "form-help", { textContent: @@ -1178,13 +1176,17 @@ })(); } - header.addEventListener("mousedown", (e) => e.preventDefault()); - header.addEventListener("click", () => { + const toggleSection = () => { collapsed = !collapsed; content.style.display = collapsed ? "none" : "block"; header.querySelector(".form-section-chevron").textContent = collapsed ? "▸" : "▾"; + }; + header.addEventListener("mousedown", (e) => { + if (e.button !== 0) return; + e.preventDefault(); + toggleSection(); }); section.appendChild(header); @@ -1202,15 +1204,14 @@ _renderLoginScriptSection(prefix, steps) { const section = createElement("div", "form-section"); const header = createElement("div", "form-section-header"); - let collapsed = true; + let collapsed = false; header.innerHTML = ` - ▸ + ▾ Login Script `; const content = createElement("div", "form-section-content"); - content.style.display = "none"; const helpText = createElement("div", "form-help", { textContent: @@ -1396,13 +1397,17 @@ addRow.appendChild(addSendBtn); content.appendChild(addRow); - header.addEventListener("mousedown", (e) => e.preventDefault()); - header.addEventListener("click", () => { + const toggleSection = () => { collapsed = !collapsed; content.style.display = collapsed ? "none" : "block"; header.querySelector(".form-section-chevron").textContent = collapsed ? "▸" : "▾"; + }; + header.addEventListener("mousedown", (e) => { + if (e.button !== 0) return; + e.preventDefault(); + toggleSection(); }); section.appendChild(header); @@ -1410,10 +1415,10 @@ return section; } - _renderSection(title, fields, startCollapsed = false) { + _renderSection(title, fields) { const section = createElement("div", "form-section"); const header = createElement("div", "form-section-header"); - let collapsed = startCollapsed; + let collapsed = false; header.innerHTML = ` ${collapsed ? "▸" : "▾"} @@ -1429,15 +1434,18 @@ } } - // Prevent mousedown from starting a text selection gesture in WKWebView, - // which would swallow the first click and require a double-click. - header.addEventListener("mousedown", (e) => e.preventDefault()); - header.addEventListener("click", () => { + const toggleSection = () => { collapsed = !collapsed; content.style.display = collapsed ? "none" : "block"; header.querySelector(".form-section-chevron").textContent = collapsed ? "▸" : "▾"; + }; + // Handle toggle on mousedown to avoid first-click swallowing in WKWebView. + header.addEventListener("mousedown", (e) => { + if (e.button !== 0) return; + e.preventDefault(); + toggleSection(); }); section.appendChild(header); diff --git a/frontend/src/js/tabs.js b/frontend/src/js/tabs.js index 04bae0d..7e193b9 100644 --- a/frontend/src/js/tabs.js +++ b/frontend/src/js/tabs.js @@ -118,6 +118,9 @@ // Fit the terminal for the newly active session this.app.terminals.fitActive(); + requestAnimationFrame(() => { + this.app.terminals.focusTerminal(sessionId); + }); } /**