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);
+ });
}
/**