diff options
| author | Tianren Dong <tianrendong.dtr@gmail.com> | 2026-05-13 01:29:51 -0400 |
|---|---|---|
| committer | Tianren Dong <tianrendong.dtr@gmail.com> | 2026-05-13 01:29:51 -0400 |
| commit | 6ddb6007df14a865d4226d7ee16e08ff4d3c36ca (patch) | |
| tree | f9cb55e32c3991171b2f8a449de781eb30d04458 /extensions | |
| parent | 6dd4b2b0abe30ed11b0969fe838fa24f67b7d6d1 (diff) | |
pi-chrome 0.10.1: chrome_key modifiers param for trusted chords (Cmd+V etc)
Diffstat (limited to 'extensions')
3 files changed, 29 insertions, 5 deletions
diff --git a/extensions/chrome-profile-bridge/browser-extension/manifest.json b/extensions/chrome-profile-bridge/browser-extension/manifest.json index 969293a..cd5e1b5 100644 --- a/extensions/chrome-profile-bridge/browser-extension/manifest.json +++ b/extensions/chrome-profile-bridge/browser-extension/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 3, "name": "Pi Existing Chrome Profile Bridge", - "version": "0.10.0", + "version": "0.10.1", "description": "Lets Pi control tabs in this existing Chrome profile via a local bridge at 127.0.0.1.", "permissions": ["tabs", "scripting", "storage", "activeTab", "alarms", "webNavigation", "debugger"], "host_permissions": ["<all_urls>", "http://127.0.0.1:17318/*"], diff --git a/extensions/chrome-profile-bridge/browser-extension/service_worker.js b/extensions/chrome-profile-bridge/browser-extension/service_worker.js index beb2dbf..bd00b1e 100644 --- a/extensions/chrome-profile-bridge/browser-extension/service_worker.js +++ b/extensions/chrome-profile-bridge/browser-extension/service_worker.js @@ -236,18 +236,36 @@ async function trustedKey(params) { await attachDebugger(tab.id); const key = String(params.key || ""); if (!key) throw new Error("trusted.key: missing key"); + const mods = params.modifiers || {}; + const modBits = cdpModifiersFor(mods); + // Press modifiers in standard order, then key, then release in reverse. + const modOrder = []; + if (mods.metaKey) modOrder.push({ key: "Meta", code: "MetaLeft", vk: 91 }); + if (mods.ctrlKey) modOrder.push({ key: "Control", code: "ControlLeft", vk: 17 }); + if (mods.altKey) modOrder.push({ key: "Alt", code: "AltLeft", vk: 18 }); + if (mods.shiftKey) modOrder.push({ key: "Shift", code: "ShiftLeft", vk: 16 }); + for (const m of modOrder) { + await cdp(tab.id, "Input.dispatchKeyEvent", { type: "keyDown", key: m.key, code: m.code, windowsVirtualKeyCode: m.vk, modifiers: modBits }); + await sleep(rng(6, 18)); + } const info = cdpKeyInfo(key); + // When modifiers are active, browsers usually emit "rawKeyDown" (no text) so chords like Cmd+V don't insert the literal char. + const downType = modBits ? "rawKeyDown" : "keyDown"; await cdp(tab.id, "Input.dispatchKeyEvent", { - type: "keyDown", key: info.key, code: info.code, + type: downType, key: info.key, code: info.code, windowsVirtualKeyCode: info.windowsVirtualKeyCode, nativeVirtualKeyCode: info.windowsVirtualKeyCode, - text: info.text, unmodifiedText: info.text, + text: modBits ? "" : info.text, unmodifiedText: modBits ? "" : info.text, modifiers: modBits, }); await sleep(rng(25, 90)); await cdp(tab.id, "Input.dispatchKeyEvent", { type: "keyUp", key: info.key, code: info.code, - windowsVirtualKeyCode: info.windowsVirtualKeyCode, + windowsVirtualKeyCode: info.windowsVirtualKeyCode, modifiers: modBits, }); - return { trusted: true, key: info.key }; + for (const m of modOrder.reverse()) { + await sleep(rng(5, 18)); + await cdp(tab.id, "Input.dispatchKeyEvent", { type: "keyUp", key: m.key, code: m.code, windowsVirtualKeyCode: m.vk, modifiers: 0 }); + } + return { trusted: true, key: info.key, modifiers: mods }; } async function trustedType(params) { diff --git a/extensions/chrome-profile-bridge/index.ts b/extensions/chrome-profile-bridge/index.ts index 11e1a40..56bf224 100644 --- a/extensions/chrome-profile-bridge/index.ts +++ b/extensions/chrome-profile-bridge/index.ts @@ -882,6 +882,12 @@ Usage rules: promptSnippet: "Press keys in Chrome through the companion extension.", parameters: Type.Object({ key: Type.String(), + modifiers: Type.Optional(Type.Object({ + shiftKey: Type.Optional(Type.Boolean()), + ctrlKey: Type.Optional(Type.Boolean()), + altKey: Type.Optional(Type.Boolean()), + metaKey: Type.Optional(Type.Boolean()), + }, { description: "Modifier keys to hold while pressing the key (chord). Only honoured for trusted-mode presses; synthetic path ignores." })), includeSnapshot: Type.Optional(Type.Boolean({ description: "If true, include a fresh chrome_snapshot result after the keypress." })), maxElements: Type.Optional(Type.Number({ default: MAX_ELEMENTS, description: "Max elements in the included snapshot." })), targetId: Type.Optional(Type.String()), |
