aboutsummaryrefslogtreecommitdiff
path: root/extensions
diff options
context:
space:
mode:
authorTianren Dong <tianrendong.dtr@gmail.com>2026-05-13 01:29:51 -0400
committerTianren Dong <tianrendong.dtr@gmail.com>2026-05-13 01:29:51 -0400
commit6ddb6007df14a865d4226d7ee16e08ff4d3c36ca (patch)
treef9cb55e32c3991171b2f8a449de781eb30d04458 /extensions
parent6dd4b2b0abe30ed11b0969fe838fa24f67b7d6d1 (diff)
pi-chrome 0.10.1: chrome_key modifiers param for trusted chords (Cmd+V etc)
Diffstat (limited to 'extensions')
-rw-r--r--extensions/chrome-profile-bridge/browser-extension/manifest.json2
-rw-r--r--extensions/chrome-profile-bridge/browser-extension/service_worker.js26
-rw-r--r--extensions/chrome-profile-bridge/index.ts6
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()),