@nativedesktop/test 0.4.39 → 0.4.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +3 -3
  2. package/src/cursor.ts +34 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nativedesktop/test",
3
- "version": "0.4.39",
3
+ "version": "0.4.40",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/FormalSnake/NativeDesktop#readme",
@@ -22,7 +22,7 @@
22
22
  ".": "./src/index.ts"
23
23
  },
24
24
  "dependencies": {
25
- "@nativedesktop/host": "0.4.39",
26
- "@nativedesktop/react": "0.4.39"
25
+ "@nativedesktop/host": "0.4.40",
26
+ "@nativedesktop/react": "0.4.40"
27
27
  }
28
28
  }
package/src/cursor.ts CHANGED
@@ -96,6 +96,26 @@ export class Cursor {
96
96
  await this.send({ op: "scroll", dx: delta.dx ?? 0, dy: delta.dy ?? 0 });
97
97
  }
98
98
 
99
+ /** Presses one key chord on the real keyboard, "Meta+=" or "Control+Shift+t":
100
+ * whatever has keyboard focus gets it the way it gets a physical key, so a
101
+ * page, the menu bar and Chromium's accelerators all see it. */
102
+ async press(chord: string): Promise<void> {
103
+ const parts = chord.split("+");
104
+ // "Meta++" is the plus key: an empty trailing part means the separator.
105
+ const key = (parts.at(-1) === "" ? "+" : parts.at(-1)!).toLowerCase();
106
+ const modifiers = parts.slice(0, -1).filter((m) => m !== "").map((m) => {
107
+ const name = MODIFIERS[m.toLowerCase()];
108
+ if (!name) throw new Error(`app.cursor.press: unknown modifier "${m}" in "${chord}"`);
109
+ return name;
110
+ });
111
+ const keyCode = MAC_KEY_CODES[key];
112
+ // A printable key goes by its character, which the helper finds on the
113
+ // current keyboard layout; the key code is the US position, the fallback.
114
+ const char = key.length === 1 ? key : undefined;
115
+ if (keyCode === undefined && char === undefined) throw new Error(`app.cursor.press: no key code for "${key}" in "${chord}"`);
116
+ await this.send({ op: "key", keyCode, char, modifiers });
117
+ }
118
+
99
119
  /** The cursor's current position in global logical points. */
100
120
  async position(): Promise<{ x: number; y: number }> {
101
121
  const r = await this.send({ op: "position" });
@@ -157,6 +177,20 @@ export class Cursor {
157
177
  }
158
178
  }
159
179
 
180
+ const MODIFIERS: Record<string, string> = {
181
+ meta: "command", cmd: "command", command: "command",
182
+ shift: "shift", alt: "option", option: "option", control: "control", ctrl: "control",
183
+ };
184
+
185
+ /// macOS virtual key codes (HIToolbox Events.h, ANSI layout).
186
+ const MAC_KEY_CODES: Record<string, number> = {
187
+ a: 0, s: 1, d: 2, f: 3, h: 4, g: 5, z: 6, x: 7, c: 8, v: 9, b: 11, q: 12, w: 13, e: 14, r: 15,
188
+ y: 16, t: 17, "1": 18, "2": 19, "3": 20, "4": 21, "6": 22, "5": 23, "=": 24, "+": 24, "9": 25,
189
+ "7": 26, "-": 27, "8": 28, "0": 29, "]": 30, o: 31, u: 32, "[": 33, i: 34, p: 35, enter: 36,
190
+ l: 37, j: 38, "'": 39, k: 40, ";": 41, "\\": 42, ",": 43, "/": 44, n: 45, m: 46, ".": 47,
191
+ tab: 48, space: 49, "`": 50, backspace: 51, escape: 53, left: 123, right: 124, down: 125, up: 126,
192
+ };
193
+
160
194
  async function* readLines(stream: ReadableStream<Uint8Array>): AsyncGenerator<string> {
161
195
  const decoder = new TextDecoder();
162
196
  let buf = "";