mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-02 22:52:58 +00:00
Allow Backspace in custom keyboard shortcuts (#5224)
Capture modified Backspace shortcuts in the editor while keeping bare Backspace as the erase-last-combo key. Cover the reported Mac chord, its Windows Ctrl equivalent, and the erase behavior in the desktop renderer suite. Closes #5215 Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com>
This commit is contained in:
@@ -377,8 +377,7 @@ export function KeyboardShortcutsSection() {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const key = event.key ?? "";
|
||||
if (key === "Backspace") {
|
||||
if (event.code === "Backspace" && heldModifiersFromEvent(event) === null) {
|
||||
setCapturedCombos((current) => (current.length > 0 ? current.slice(0, -1) : current));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -14,10 +14,13 @@ const SHORTCUTS_ROW = "show-shortcuts";
|
||||
* daemon is left unmanaged so the app talks to the E2E daemon instead of trying
|
||||
* to start one of its own.
|
||||
*/
|
||||
async function installDesktopBridge(page: Page): Promise<void> {
|
||||
await page.addInitScript(() => {
|
||||
async function installDesktopBridge(
|
||||
page: Page,
|
||||
platform: "darwin" | "win32" = "darwin",
|
||||
): Promise<void> {
|
||||
await page.addInitScript((desktopPlatform) => {
|
||||
window.paseoDesktop = {
|
||||
platform: "darwin",
|
||||
platform: desktopPlatform,
|
||||
events: { on: () => () => {} },
|
||||
invoke: async (command: string) => {
|
||||
if (command === "get_desktop_settings") {
|
||||
@@ -29,11 +32,11 @@ async function installDesktopBridge(page: Page): Promise<void> {
|
||||
return null;
|
||||
},
|
||||
};
|
||||
});
|
||||
}, platform);
|
||||
}
|
||||
|
||||
async function openShortcutsSettings(page: Page) {
|
||||
await installDesktopBridge(page);
|
||||
async function openShortcutsSettings(page: Page, platform: "darwin" | "win32" = "darwin") {
|
||||
await installDesktopBridge(page, platform);
|
||||
await gotoAppShell(page);
|
||||
await openSettings(page);
|
||||
await openSettingsSection(page, "shortcuts");
|
||||
@@ -67,6 +70,38 @@ async function closeRowMenu(page: Page) {
|
||||
await expect(page.getByTestId(`shortcut-bind-${SHORTCUTS_ROW}`)).toHaveCount(0);
|
||||
}
|
||||
|
||||
async function clearShortcut(page: Page, label: string, action: string) {
|
||||
await page.getByRole("button", { name: `Actions for ${label}` }).click();
|
||||
await page.getByTestId(`shortcut-clear-${action}`).click();
|
||||
}
|
||||
|
||||
async function captureShortcut(page: Page, label: string, action: string, keys: string) {
|
||||
await page.getByRole("button", { name: `Actions for ${label}` }).click();
|
||||
await page.getByTestId(`shortcut-bind-${action}`).click();
|
||||
await page.keyboard.press(keys);
|
||||
}
|
||||
|
||||
async function expectInterruptShortcut(page: Page, chord: string) {
|
||||
const row = page.getByText("Interrupt agent", { exact: true }).locator("..");
|
||||
await expect(row.getByText(chord, { exact: true })).toBeVisible();
|
||||
}
|
||||
|
||||
async function finishInterruptCapture(page: Page, action: "Done" | "Cancel") {
|
||||
const row = page.getByText("Interrupt agent", { exact: true }).locator("..");
|
||||
await row.getByRole("button", { name: action }).click();
|
||||
}
|
||||
|
||||
async function eraseLastCapturedCombo(page: Page, firstCombo: string, secondCombo: string) {
|
||||
await captureShortcut(page, "Interrupt agent", "agent-interrupt", "Alt+K");
|
||||
await page.keyboard.press("Alt+J");
|
||||
await expectInterruptShortcut(page, firstCombo);
|
||||
await expectInterruptShortcut(page, secondCombo);
|
||||
await page.keyboard.press("Backspace");
|
||||
await expectInterruptShortcut(page, firstCombo);
|
||||
const row = page.getByText("Interrupt agent", { exact: true }).locator("..");
|
||||
await expect(row.getByText(secondCombo, { exact: true })).toHaveCount(0);
|
||||
}
|
||||
|
||||
test("unassigning a shortcut leaves it inert until it is reset", async ({ page }) => {
|
||||
await openShortcutsSettings(page);
|
||||
|
||||
@@ -146,3 +181,35 @@ test("unassigning a shortcut leaves it inert until it is reset", async ({ page }
|
||||
await page.keyboard.press("Escape");
|
||||
await expect(dialog).not.toBeVisible({ timeout: 10_000 });
|
||||
});
|
||||
|
||||
for (const { platform, keys, label, firstCombo, secondCombo } of [
|
||||
{
|
||||
platform: "darwin",
|
||||
keys: "Meta+Shift+Backspace",
|
||||
label: "⇧⌘⌫",
|
||||
firstCombo: "⌥K",
|
||||
secondCombo: "⌥J",
|
||||
},
|
||||
{
|
||||
platform: "win32",
|
||||
keys: "Control+Shift+Backspace",
|
||||
label: "Ctrl+Shift+⌫",
|
||||
firstCombo: "Alt+K",
|
||||
secondCombo: "Alt+J",
|
||||
},
|
||||
] as const) {
|
||||
test(`binds modified Backspace and erases a combo with bare Backspace on ${platform}`, async ({
|
||||
page,
|
||||
}) => {
|
||||
await openShortcutsSettings(page, platform);
|
||||
await clearShortcut(page, "Archive workspace", "archive-workspace");
|
||||
await captureShortcut(page, "Interrupt agent", "agent-interrupt", keys);
|
||||
await expectInterruptShortcut(page, label);
|
||||
await finishInterruptCapture(page, "Done");
|
||||
await expectInterruptShortcut(page, label);
|
||||
|
||||
await eraseLastCapturedCombo(page, firstCombo, secondCombo);
|
||||
await finishInterruptCapture(page, "Cancel");
|
||||
await expectInterruptShortcut(page, label);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user