mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-22 17:22:47 +00:00
fix(app): preserve button focus during deferred terminal autofocus
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed retained terminals not regaining keyboard focus after switching back to their workspace, including when an overlay or another input delays focus until it is released.
|
||||
- Fixed retained terminals not regaining keyboard focus after switching back to their workspace, including when an overlay or another input delays focus until it is released, without taking focus from a newly focused button.
|
||||
|
||||
## 0.11.0-beta.5 - 2026-10-06
|
||||
|
||||
|
||||
@@ -102,4 +102,23 @@ test.describe("retained terminal tab streams", () => {
|
||||
output: "OVERLAY_FOCUS_OK",
|
||||
});
|
||||
});
|
||||
|
||||
test("deferred terminal focus does not steal focus from a button", async ({ page }) => {
|
||||
const first = await harness.createTerminal({ name: "button-first" });
|
||||
const other = await harness.createOtherWorkspace();
|
||||
const second = await other.createTerminal({ name: "button-second" });
|
||||
await harness.openTerminal(page, { terminalId: first.id });
|
||||
await other.openTerminal(page, { terminalId: second.id });
|
||||
await harness.switchToWorkspaceByShortcut(page);
|
||||
await harness.expectTerminalFocused(page);
|
||||
await harness.rememberWorkspaceForHistoryReturn(page);
|
||||
await other.switchToWorkspaceByShortcut(page);
|
||||
const overlay = await openCommandCenter(page);
|
||||
await harness.returnToWorkspaceThroughHistory(page);
|
||||
await expect(overlay.getByTestId("command-center-input")).toBeFocused();
|
||||
await harness.closeOverlayAndFocusButtonBeforeRetry(page);
|
||||
await expect(page.getByTestId("sidebar-search")).toBeFocused();
|
||||
await page.keyboard.press("Enter");
|
||||
await expect(overlay).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -164,6 +164,22 @@ export class TerminalE2EHarness {
|
||||
await expect(page).toHaveURL(new RegExp(`/workspace/${this.workspaceId}`));
|
||||
}
|
||||
|
||||
async closeOverlayAndFocusButtonBeforeRetry(page: Page): Promise<void> {
|
||||
await page.clock.install();
|
||||
await page.clock.pauseAt(new Date());
|
||||
await page.keyboard.press("Escape");
|
||||
await expect(page.getByTestId("command-center-panel")).toBeHidden();
|
||||
await page.getByTestId("sidebar-search").focus();
|
||||
await page.clock.runFor(100);
|
||||
await page.clock.resume();
|
||||
await page.evaluate(
|
||||
() =>
|
||||
new Promise<void>((resolve) =>
|
||||
requestAnimationFrame(() => requestAnimationFrame(() => resolve())),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
async expectTerminalFocused(page: Page): Promise<void> {
|
||||
await expect(
|
||||
this.terminalSurface(page).filter({ visible: true }).locator(".xterm-helper-textarea"),
|
||||
|
||||
@@ -408,6 +408,7 @@ export function TerminalPane({
|
||||
let retryFrame: number | null = null;
|
||||
function stopRetrying(): void {
|
||||
document.removeEventListener("focusout", scheduleRetry);
|
||||
document.removeEventListener("focusin", stopRetrying);
|
||||
unsubscribeOverlayChanges();
|
||||
if (retryFrame !== null) window.cancelAnimationFrame(retryFrame);
|
||||
}
|
||||
@@ -421,6 +422,8 @@ export function TerminalPane({
|
||||
}
|
||||
const unsubscribeOverlayChanges = subscribeWebOverlayChanges(scheduleRetry);
|
||||
document.addEventListener("focusout", scheduleRetry);
|
||||
// A new focus owner wins over a deferred workspace autofocus request.
|
||||
document.addEventListener("focusin", stopRetrying);
|
||||
return stopRetrying;
|
||||
}, [
|
||||
isMobile,
|
||||
|
||||
Reference in New Issue
Block a user