keyspy 1.0.0
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.
- package/LICENSE +21 -0
- package/README.md +287 -0
- package/build/index.d.ts +53 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +149 -0
- package/build/ts/MacKeyServer.d.ts +45 -0
- package/build/ts/MacKeyServer.d.ts.map +1 -0
- package/build/ts/MacKeyServer.js +159 -0
- package/build/ts/WinKeyServer.d.ts +30 -0
- package/build/ts/WinKeyServer.d.ts.map +1 -0
- package/build/ts/WinKeyServer.js +88 -0
- package/build/ts/X11KeyServer.d.ts +45 -0
- package/build/ts/X11KeyServer.d.ts.map +1 -0
- package/build/ts/X11KeyServer.js +159 -0
- package/build/ts/_data/MacGlobalKeyLookup.d.ts +3 -0
- package/build/ts/_data/MacGlobalKeyLookup.d.ts.map +1 -0
- package/build/ts/_data/MacGlobalKeyLookup.js +155 -0
- package/build/ts/_data/WinGlobalKeyLookup.d.ts +6 -0
- package/build/ts/_data/WinGlobalKeyLookup.d.ts.map +1 -0
- package/build/ts/_data/WinGlobalKeyLookup.js +181 -0
- package/build/ts/_data/X11GlobalKeyLookup.d.ts +3 -0
- package/build/ts/_data/X11GlobalKeyLookup.d.ts.map +1 -0
- package/build/ts/_data/X11GlobalKeyLookup.js +144 -0
- package/build/ts/_types/IConfig.d.ts +15 -0
- package/build/ts/_types/IConfig.d.ts.map +1 -0
- package/build/ts/_types/IConfig.js +3 -0
- package/build/ts/_types/IGlobalKey.d.ts +19 -0
- package/build/ts/_types/IGlobalKey.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKey.js +3 -0
- package/build/ts/_types/IGlobalKeyDownMap.d.ts +5 -0
- package/build/ts/_types/IGlobalKeyDownMap.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKeyDownMap.js +3 -0
- package/build/ts/_types/IGlobalKeyEvent.d.ts +17 -0
- package/build/ts/_types/IGlobalKeyEvent.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKeyEvent.js +3 -0
- package/build/ts/_types/IGlobalKeyListener.d.ts +14 -0
- package/build/ts/_types/IGlobalKeyListener.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKeyListener.js +3 -0
- package/build/ts/_types/IGlobalKeyListenerRaw.d.ts +7 -0
- package/build/ts/_types/IGlobalKeyListenerRaw.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKeyListenerRaw.js +3 -0
- package/build/ts/_types/IGlobalKeyLookup.d.ts +9 -0
- package/build/ts/_types/IGlobalKeyLookup.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKeyLookup.js +3 -0
- package/build/ts/_types/IGlobalKeyResult.d.ts +12 -0
- package/build/ts/_types/IGlobalKeyResult.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKeyResult.js +3 -0
- package/build/ts/_types/IGlobalKeyServer.d.ts +16 -0
- package/build/ts/_types/IGlobalKeyServer.d.ts.map +1 -0
- package/build/ts/_types/IGlobalKeyServer.js +3 -0
- package/build/ts/_types/IMacConfig.d.ts +10 -0
- package/build/ts/_types/IMacConfig.d.ts.map +1 -0
- package/build/ts/_types/IMacConfig.js +3 -0
- package/build/ts/_types/IWindowsConfig.d.ts +10 -0
- package/build/ts/_types/IWindowsConfig.d.ts.map +1 -0
- package/build/ts/_types/IWindowsConfig.js +3 -0
- package/build/ts/_types/IX11Config.d.ts +10 -0
- package/build/ts/_types/IX11Config.d.ts.map +1 -0
- package/build/ts/_types/IX11Config.js +3 -0
- package/build/ts/isSpawnEventSupported.d.ts +6 -0
- package/build/ts/isSpawnEventSupported.d.ts.map +1 -0
- package/build/ts/isSpawnEventSupported.js +18 -0
- package/package.json +80 -0
- package/scripts/download-binaries.js +191 -0
@@ -0,0 +1,159 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.MacKeyServer = void 0;
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
8
|
+
const MacGlobalKeyLookup_1 = require("./_data/MacGlobalKeyLookup");
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
10
|
+
const sudo_prompt_1 = __importDefault(require("sudo-prompt"));
|
11
|
+
const isSpawnEventSupported_1 = require("./isSpawnEventSupported");
|
12
|
+
const sPath = "../../bin/MacKeyServer";
|
13
|
+
/** Use this class to listen to key events on Mac OS */
|
14
|
+
class MacKeyServer {
|
15
|
+
/**
|
16
|
+
* Creates a new key server for mac
|
17
|
+
* @param listener The callback to report key events to
|
18
|
+
* @param config Additional optional configuration for the server
|
19
|
+
*/
|
20
|
+
constructor(listener, config = {}) {
|
21
|
+
this.running = false;
|
22
|
+
this.restarting = false;
|
23
|
+
this.listener = listener;
|
24
|
+
this.config = config;
|
25
|
+
}
|
26
|
+
/**
|
27
|
+
* Start the Key server and listen for keypresses
|
28
|
+
* @param skipPerms Whether to skip attempting to add permissions
|
29
|
+
*/
|
30
|
+
start(skipPerms) {
|
31
|
+
var _a, _b;
|
32
|
+
this.running = true;
|
33
|
+
const serverPath = this.config.serverPath || node_path_1.default.join(__dirname, sPath);
|
34
|
+
this.proc = (0, node_child_process_1.execFile)(serverPath);
|
35
|
+
if (this.config.onInfo)
|
36
|
+
(_a = this.proc.stderr) === null || _a === void 0 ? void 0 : _a.on("data", (data) => { var _a, _b; return (_b = (_a = this.config).onInfo) === null || _b === void 0 ? void 0 : _b.call(_a, data.toString()); });
|
37
|
+
const onError = this.config.onError;
|
38
|
+
if (onError)
|
39
|
+
this.proc.on("close", (code) => {
|
40
|
+
if (!this.restarting && this.running)
|
41
|
+
onError(code);
|
42
|
+
});
|
43
|
+
(_b = this.proc.stdout) === null || _b === void 0 ? void 0 : _b.on("data", (data) => {
|
44
|
+
var _a;
|
45
|
+
const events = this._getEventData(data);
|
46
|
+
for (const { event, eventId } of events) {
|
47
|
+
const stopPropagation = !!this.listener(event);
|
48
|
+
(_a = this.proc.stdin) === null || _a === void 0 ? void 0 : _a.write(`${stopPropagation ? "1" : "0"},${eventId}\n`);
|
49
|
+
}
|
50
|
+
});
|
51
|
+
return this.handleStartup(skipPerms !== null && skipPerms !== void 0 ? skipPerms : false);
|
52
|
+
}
|
53
|
+
/**
|
54
|
+
* Deals with the startup process of the server, possibly adding perms if required and restarting
|
55
|
+
* @param skipPerms Whether to skip attempting to add permissions
|
56
|
+
*/
|
57
|
+
handleStartup(skipPerms) {
|
58
|
+
return new Promise((res, rej) => {
|
59
|
+
let errored = false;
|
60
|
+
const serverPath = this.config.serverPath || node_path_1.default.join(__dirname, sPath);
|
61
|
+
// If setup fails, try adding permissions
|
62
|
+
this.proc.on("error", async (err) => {
|
63
|
+
errored = true;
|
64
|
+
if (skipPerms) {
|
65
|
+
rej(err);
|
66
|
+
}
|
67
|
+
else {
|
68
|
+
try {
|
69
|
+
this.restarting = true;
|
70
|
+
this.proc.kill();
|
71
|
+
await this.addPerms(serverPath);
|
72
|
+
// If the server was stopped in between, just act as if it was started successfully
|
73
|
+
if (!this.running) {
|
74
|
+
res();
|
75
|
+
return;
|
76
|
+
}
|
77
|
+
res(this.start(true));
|
78
|
+
}
|
79
|
+
catch (e) {
|
80
|
+
rej(e);
|
81
|
+
}
|
82
|
+
finally {
|
83
|
+
this.restarting = false;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
});
|
87
|
+
if ((0, isSpawnEventSupported_1.isSpawnEventSupported)())
|
88
|
+
this.proc.on("spawn", res);
|
89
|
+
// A timed fallback if the spawn event is not supported
|
90
|
+
else
|
91
|
+
setTimeout(() => {
|
92
|
+
if (!errored)
|
93
|
+
res();
|
94
|
+
}, 200);
|
95
|
+
});
|
96
|
+
}
|
97
|
+
/**
|
98
|
+
* Makes sure that the given path is executable
|
99
|
+
* @param path The path to add the perms to
|
100
|
+
*/
|
101
|
+
addPerms(path) {
|
102
|
+
const options = {
|
103
|
+
name: "Global key listener",
|
104
|
+
};
|
105
|
+
return new Promise((res, err) => {
|
106
|
+
sudo_prompt_1.default.exec(`chmod +x "${path}"`, options, (error, _stdout, stderr) => {
|
107
|
+
if (error) {
|
108
|
+
err(error);
|
109
|
+
return;
|
110
|
+
}
|
111
|
+
if (stderr) {
|
112
|
+
err(stderr);
|
113
|
+
return;
|
114
|
+
}
|
115
|
+
res();
|
116
|
+
});
|
117
|
+
});
|
118
|
+
}
|
119
|
+
/** Stop the Key server */
|
120
|
+
stop() {
|
121
|
+
var _a;
|
122
|
+
this.running = false;
|
123
|
+
(_a = this.proc.stdout) === null || _a === void 0 ? void 0 : _a.pause();
|
124
|
+
this.proc.kill();
|
125
|
+
}
|
126
|
+
/**
|
127
|
+
* Obtains a IGlobalKeyEvent from stdout buffer data
|
128
|
+
* @param data Data from stdout
|
129
|
+
* @returns The standardized key event data
|
130
|
+
*/
|
131
|
+
_getEventData(data) {
|
132
|
+
const sData = data.toString();
|
133
|
+
const lines = sData.trim().split(/\n/);
|
134
|
+
return lines.map((line) => {
|
135
|
+
const lineData = line.replace(/\s+/, "");
|
136
|
+
const [mouseKeyboard, downUp, sKeyCode, sLocationX, sLocationY, eventId] = lineData.split(",");
|
137
|
+
const isMouse = mouseKeyboard === "MOUSE";
|
138
|
+
const isDown = downUp === "DOWN";
|
139
|
+
const keyCode = Number.parseInt(sKeyCode, 10);
|
140
|
+
const locationX = Number.parseFloat(sLocationX);
|
141
|
+
const locationY = Number.parseFloat(sLocationY);
|
142
|
+
const key = MacGlobalKeyLookup_1.MacGlobalKeyLookup[isMouse ? 0xffff0000 + keyCode : keyCode];
|
143
|
+
return {
|
144
|
+
event: {
|
145
|
+
vKey: keyCode,
|
146
|
+
rawKey: key,
|
147
|
+
name: key === null || key === void 0 ? void 0 : key.standardName,
|
148
|
+
state: isDown ? "DOWN" : "UP",
|
149
|
+
scanCode: keyCode,
|
150
|
+
location: [locationX, locationY],
|
151
|
+
_raw: sData,
|
152
|
+
},
|
153
|
+
eventId,
|
154
|
+
};
|
155
|
+
});
|
156
|
+
}
|
157
|
+
}
|
158
|
+
exports.MacKeyServer = MacKeyServer;
|
159
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWFjS2V5U2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RzL01hY0tleVNlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQSwyREFBaUU7QUFHakUsbUVBQWdFO0FBQ2hFLDBEQUE2QjtBQUU3Qiw4REFBK0I7QUFDL0IsbUVBQWdFO0FBQ2hFLE1BQU0sS0FBSyxHQUFHLHdCQUF3QixDQUFDO0FBRXZDLHVEQUF1RDtBQUN2RCxNQUFhLFlBQVk7SUFRdkI7Ozs7T0FJRztJQUNILFlBQVksUUFBK0IsRUFBRSxTQUFxQixFQUFFO1FBUjVELFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDaEIsZUFBVSxHQUFHLEtBQUssQ0FBQztRQVF6QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksS0FBSyxDQUFDLFNBQW1COztRQUM5QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUVwQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsSUFBSSxtQkFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFekUsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFBLDZCQUFRLEVBQUMsVUFBVSxDQUFDLENBQUM7UUFDakMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU07WUFDcEIsTUFBQSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sMENBQUUsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLGVBQUMsT0FBQSxNQUFBLE1BQUEsSUFBSSxDQUFDLE1BQU0sRUFBQyxNQUFNLG1EQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFBLEVBQUEsQ0FBQyxDQUFDO1FBQ2hGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FB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
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import type { IGlobalKeyServer } from "./_types/IGlobalKeyServer";
|
2
|
+
import type { IGlobalKeyEvent } from "./_types/IGlobalKeyEvent";
|
3
|
+
import type { IGlobalKeyListenerRaw } from "./_types/IGlobalKeyListenerRaw";
|
4
|
+
import type { IWindowsConfig } from "./_types/IWindowsConfig";
|
5
|
+
/** Use this class to listen to key events on Windows OS */
|
6
|
+
export declare class WinKeyServer implements IGlobalKeyServer {
|
7
|
+
protected listener: IGlobalKeyListenerRaw;
|
8
|
+
private proc;
|
9
|
+
protected config: IWindowsConfig;
|
10
|
+
/**
|
11
|
+
* Creates a new key server for windows
|
12
|
+
* @param listener The callback to report key events to
|
13
|
+
* @param windowsConfig The optional windows configuration
|
14
|
+
*/
|
15
|
+
constructor(listener: IGlobalKeyListenerRaw, config?: IWindowsConfig);
|
16
|
+
/** Start the Key server and listen for keypresses */
|
17
|
+
start(): Promise<void>;
|
18
|
+
/** Stop the Key server */
|
19
|
+
stop(): void;
|
20
|
+
/**
|
21
|
+
* Obtains a IGlobalKeyEvent from stdout buffer data
|
22
|
+
* @param data Data from stdout
|
23
|
+
* @returns The standardized key event data
|
24
|
+
*/
|
25
|
+
protected _getEventData(data: Buffer | string): {
|
26
|
+
event: IGlobalKeyEvent;
|
27
|
+
eventId: string;
|
28
|
+
}[];
|
29
|
+
}
|
30
|
+
//# sourceMappingURL=WinKeyServer.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"WinKeyServer.d.ts","sourceRoot":"","sources":["../../src/ts/WinKeyServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAG5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAI9D,2DAA2D;AAC3D,qBAAa,YAAa,YAAW,gBAAgB;IACnD,SAAS,CAAC,QAAQ,EAAE,qBAAqB,CAAC;IAC1C,OAAO,CAAC,IAAI,CAAe;IAE3B,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC;IAEjC;;;;OAIG;gBACgB,QAAQ,EAAE,qBAAqB,EAAE,MAAM,GAAE,cAAmB;IAK/E,qDAAqD;IACxC,KAAK;IAyBlB,0BAA0B;IACnB,IAAI;IAKX;;;;OAIG;IACH,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG;QAAE,KAAK,EAAE,eAAe,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE;CAiC9F"}
|
@@ -0,0 +1,88 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.WinKeyServer = void 0;
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
8
|
+
const WinGlobalKeyLookup_1 = require("./_data/WinGlobalKeyLookup");
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
10
|
+
const isSpawnEventSupported_1 = require("./isSpawnEventSupported");
|
11
|
+
const sPath = "../../bin/WinKeyServer.exe";
|
12
|
+
/** Use this class to listen to key events on Windows OS */
|
13
|
+
class WinKeyServer {
|
14
|
+
/**
|
15
|
+
* Creates a new key server for windows
|
16
|
+
* @param listener The callback to report key events to
|
17
|
+
* @param windowsConfig The optional windows configuration
|
18
|
+
*/
|
19
|
+
constructor(listener, config = {}) {
|
20
|
+
this.listener = listener;
|
21
|
+
this.config = config;
|
22
|
+
}
|
23
|
+
/** Start the Key server and listen for keypresses */
|
24
|
+
async start() {
|
25
|
+
var _a, _b;
|
26
|
+
const serverPath = this.config.serverPath || node_path_1.default.join(__dirname, sPath);
|
27
|
+
this.proc = (0, node_child_process_1.execFile)(serverPath, { maxBuffer: Number.POSITIVE_INFINITY });
|
28
|
+
if (this.config.onInfo)
|
29
|
+
(_a = this.proc.stderr) === null || _a === void 0 ? void 0 : _a.on("data", (data) => { var _a, _b; return (_b = (_a = this.config).onInfo) === null || _b === void 0 ? void 0 : _b.call(_a, data.toString()); });
|
30
|
+
if (this.config.onError)
|
31
|
+
this.proc.on("close", this.config.onError);
|
32
|
+
(_b = this.proc.stdout) === null || _b === void 0 ? void 0 : _b.on("data", (data) => {
|
33
|
+
var _a;
|
34
|
+
const events = this._getEventData(data);
|
35
|
+
for (const { event, eventId } of events) {
|
36
|
+
const stopPropagation = !!this.listener(event);
|
37
|
+
(_a = this.proc.stdin) === null || _a === void 0 ? void 0 : _a.write(`${stopPropagation ? "1" : "0"},${eventId}\n`);
|
38
|
+
}
|
39
|
+
});
|
40
|
+
return new Promise((res, err) => {
|
41
|
+
this.proc.on("error", err);
|
42
|
+
if ((0, isSpawnEventSupported_1.isSpawnEventSupported)())
|
43
|
+
this.proc.on("spawn", res);
|
44
|
+
// A timed fallback if the spawn event is not supported
|
45
|
+
else
|
46
|
+
setTimeout(res, 200);
|
47
|
+
});
|
48
|
+
}
|
49
|
+
/** Stop the Key server */
|
50
|
+
stop() {
|
51
|
+
var _a;
|
52
|
+
(_a = this.proc.stdout) === null || _a === void 0 ? void 0 : _a.pause();
|
53
|
+
this.proc.kill();
|
54
|
+
}
|
55
|
+
/**
|
56
|
+
* Obtains a IGlobalKeyEvent from stdout buffer data
|
57
|
+
* @param data Data from stdout
|
58
|
+
* @returns The standardized key event data
|
59
|
+
*/
|
60
|
+
_getEventData(data) {
|
61
|
+
const sData = data.toString();
|
62
|
+
const lines = sData.trim().split(/\n/);
|
63
|
+
return lines.map((line) => {
|
64
|
+
const lineData = line.replace(/\s+/, "");
|
65
|
+
const [_mouseKeyboard, downUp, sKeyCode, sScanCode, sLocationX, sLocationY, eventId] = lineData.split(",");
|
66
|
+
const isDown = downUp === "DOWN";
|
67
|
+
const keyCode = Number.parseInt(sKeyCode, 10);
|
68
|
+
const scanCode = Number.parseInt(sScanCode, 10);
|
69
|
+
const locationX = Number.parseFloat(sLocationX);
|
70
|
+
const locationY = Number.parseFloat(sLocationY);
|
71
|
+
const key = WinGlobalKeyLookup_1.WinGlobalKeyLookup[keyCode];
|
72
|
+
return {
|
73
|
+
event: {
|
74
|
+
vKey: keyCode,
|
75
|
+
rawKey: key,
|
76
|
+
name: key === null || key === void 0 ? void 0 : key.standardName,
|
77
|
+
state: isDown ? "DOWN" : "UP",
|
78
|
+
scanCode: scanCode,
|
79
|
+
location: [locationX, locationY],
|
80
|
+
_raw: sData,
|
81
|
+
},
|
82
|
+
eventId,
|
83
|
+
};
|
84
|
+
});
|
85
|
+
}
|
86
|
+
}
|
87
|
+
exports.WinKeyServer = WinKeyServer;
|
88
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV2luS2V5U2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RzL1dpbktleVNlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQSwyREFBaUU7QUFHakUsbUVBQWdFO0FBQ2hFLDBEQUE2QjtBQUU3QixtRUFBZ0U7QUFDaEUsTUFBTSxLQUFLLEdBQUcsNEJBQTRCLENBQUM7QUFFM0MsMkRBQTJEO0FBQzNELE1BQWEsWUFBWTtJQU12Qjs7OztPQUlHO0lBQ0gsWUFBbUIsUUFBK0IsRUFBRSxTQUF5QixFQUFFO1FBQzdFLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxxREFBcUQ7SUFDOUMsS0FBSyxDQUFDLEtBQUs7O1FBQ2hCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxJQUFJLG1CQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN6RSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUEsNkJBQVEsRUFBQyxVQUFVLEVBQUUsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQztRQUMxRSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTTtZQUNwQixNQUFBLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSwwQ0FBRSxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUUsZUFBQyxPQUFBLE1BQUEsTUFBQSxJQUFJLENBQUMsTUFBTSxFQUFDLE1BQU0sbURBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUEsRUFBQSxDQUFDLENBQUM7UUFDaEYsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU87WUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxD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
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import type { IGlobalKeyServer } from "./_types/IGlobalKeyServer";
|
2
|
+
import type { IGlobalKeyListenerRaw } from "./_types/IGlobalKeyListenerRaw";
|
3
|
+
import type { IGlobalKeyEvent } from "./_types/IGlobalKeyEvent";
|
4
|
+
import type { IX11Config } from "./_types/IX11Config";
|
5
|
+
/** Use this class to listen to key events on X11 */
|
6
|
+
export declare class X11KeyServer implements IGlobalKeyServer {
|
7
|
+
protected listener: IGlobalKeyListenerRaw;
|
8
|
+
private proc;
|
9
|
+
private config;
|
10
|
+
private running;
|
11
|
+
private restarting;
|
12
|
+
/**
|
13
|
+
* Creates a new key server for x11
|
14
|
+
* @param listener The callback to report key events to
|
15
|
+
* @param config Additional optional configuration for the server
|
16
|
+
*/
|
17
|
+
constructor(listener: IGlobalKeyListenerRaw, config?: IX11Config);
|
18
|
+
/**
|
19
|
+
* Start the Key server and listen for keypresses
|
20
|
+
* @param skipPerms Whether to skip attempting to add permissions
|
21
|
+
*/
|
22
|
+
start(skipPerms?: boolean): Promise<void>;
|
23
|
+
/**
|
24
|
+
* Deals with the startup process of the server, possibly adding perms if required and restarting
|
25
|
+
* @param skipPerms Whether to skip attempting to add permissions
|
26
|
+
*/
|
27
|
+
protected handleStartup(skipPerms: boolean): Promise<void>;
|
28
|
+
/**
|
29
|
+
* Makes sure that the given path is executable
|
30
|
+
* @param path The path to add the perms to
|
31
|
+
*/
|
32
|
+
protected addPerms(path: string): Promise<void>;
|
33
|
+
/** Stop the Key server */
|
34
|
+
stop(): void;
|
35
|
+
/**
|
36
|
+
* Obtains a IGlobalKeyEvent from stdout buffer data
|
37
|
+
* @param data Data from stdout
|
38
|
+
* @returns The standardized key event data
|
39
|
+
*/
|
40
|
+
protected _getEventData(data: Buffer): {
|
41
|
+
event: IGlobalKeyEvent;
|
42
|
+
eventId: string;
|
43
|
+
}[];
|
44
|
+
}
|
45
|
+
//# sourceMappingURL=X11KeyServer.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"X11KeyServer.d.ts","sourceRoot":"","sources":["../../src/ts/X11KeyServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAGhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAKtD,oDAAoD;AACpD,qBAAa,YAAa,YAAW,gBAAgB;IACnD,SAAS,CAAC,QAAQ,EAAE,qBAAqB,CAAC;IAC1C,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,MAAM,CAAa;IAE3B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;IAE3B;;;;OAIG;gBACS,QAAQ,EAAE,qBAAqB,EAAE,MAAM,GAAE,UAAe;IAKpE;;;OAGG;IACI,KAAK,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BhD;;;OAGG;IACH,SAAS,CAAC,aAAa,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAwC1D;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB/C,0BAA0B;IACnB,IAAI;IAMX;;;;OAIG;IACH,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,eAAe,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE;CAiCrF"}
|
@@ -0,0 +1,159 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.X11KeyServer = void 0;
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
8
|
+
const X11GlobalKeyLookup_1 = require("./_data/X11GlobalKeyLookup");
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
10
|
+
const sudo_prompt_1 = __importDefault(require("sudo-prompt"));
|
11
|
+
const isSpawnEventSupported_1 = require("./isSpawnEventSupported");
|
12
|
+
const sPath = "../../bin/X11KeyServer";
|
13
|
+
/** Use this class to listen to key events on X11 */
|
14
|
+
class X11KeyServer {
|
15
|
+
/**
|
16
|
+
* Creates a new key server for x11
|
17
|
+
* @param listener The callback to report key events to
|
18
|
+
* @param config Additional optional configuration for the server
|
19
|
+
*/
|
20
|
+
constructor(listener, config = {}) {
|
21
|
+
this.running = false;
|
22
|
+
this.restarting = false;
|
23
|
+
this.listener = listener;
|
24
|
+
this.config = config;
|
25
|
+
}
|
26
|
+
/**
|
27
|
+
* Start the Key server and listen for keypresses
|
28
|
+
* @param skipPerms Whether to skip attempting to add permissions
|
29
|
+
*/
|
30
|
+
start(skipPerms) {
|
31
|
+
var _a, _b;
|
32
|
+
this.running = true;
|
33
|
+
const serverPath = this.config.serverPath || node_path_1.default.join(__dirname, sPath);
|
34
|
+
this.proc = (0, node_child_process_1.execFile)(serverPath);
|
35
|
+
if (this.config.onInfo)
|
36
|
+
(_a = this.proc.stderr) === null || _a === void 0 ? void 0 : _a.on("data", (data) => { var _a, _b; return (_b = (_a = this.config).onInfo) === null || _b === void 0 ? void 0 : _b.call(_a, data.toString()); });
|
37
|
+
const onError = this.config.onError;
|
38
|
+
if (onError)
|
39
|
+
this.proc.on("close", (code) => {
|
40
|
+
if (!this.restarting && this.running)
|
41
|
+
onError(code);
|
42
|
+
});
|
43
|
+
(_b = this.proc.stdout) === null || _b === void 0 ? void 0 : _b.on("data", (data) => {
|
44
|
+
var _a;
|
45
|
+
const events = this._getEventData(data);
|
46
|
+
for (const { event, eventId } of events) {
|
47
|
+
const stopPropagation = !!this.listener(event);
|
48
|
+
(_a = this.proc.stdin) === null || _a === void 0 ? void 0 : _a.write(`${stopPropagation ? "1" : "0"},${eventId}\n`);
|
49
|
+
}
|
50
|
+
});
|
51
|
+
return this.handleStartup(skipPerms !== null && skipPerms !== void 0 ? skipPerms : false);
|
52
|
+
}
|
53
|
+
/**
|
54
|
+
* Deals with the startup process of the server, possibly adding perms if required and restarting
|
55
|
+
* @param skipPerms Whether to skip attempting to add permissions
|
56
|
+
*/
|
57
|
+
handleStartup(skipPerms) {
|
58
|
+
return new Promise((res, rej) => {
|
59
|
+
let errored = false;
|
60
|
+
const serverPath = this.config.serverPath || node_path_1.default.join(__dirname, sPath);
|
61
|
+
// If setup fails, try adding permissions
|
62
|
+
this.proc.on("error", async (err) => {
|
63
|
+
errored = true;
|
64
|
+
if (skipPerms) {
|
65
|
+
rej(err);
|
66
|
+
}
|
67
|
+
else {
|
68
|
+
try {
|
69
|
+
this.restarting = true;
|
70
|
+
this.proc.kill();
|
71
|
+
await this.addPerms(serverPath);
|
72
|
+
// If the server was stopped in between, just act as if it was started successfully
|
73
|
+
if (!this.running) {
|
74
|
+
res();
|
75
|
+
return;
|
76
|
+
}
|
77
|
+
res(this.start(true));
|
78
|
+
}
|
79
|
+
catch (e) {
|
80
|
+
rej(e);
|
81
|
+
}
|
82
|
+
finally {
|
83
|
+
this.restarting = false;
|
84
|
+
}
|
85
|
+
}
|
86
|
+
});
|
87
|
+
if ((0, isSpawnEventSupported_1.isSpawnEventSupported)())
|
88
|
+
this.proc.on("spawn", res);
|
89
|
+
// A timed fallback if the spawn event is not supported
|
90
|
+
else
|
91
|
+
setTimeout(() => {
|
92
|
+
if (!errored)
|
93
|
+
res();
|
94
|
+
}, 200);
|
95
|
+
});
|
96
|
+
}
|
97
|
+
/**
|
98
|
+
* Makes sure that the given path is executable
|
99
|
+
* @param path The path to add the perms to
|
100
|
+
*/
|
101
|
+
addPerms(path) {
|
102
|
+
const options = {
|
103
|
+
name: "Global key listener",
|
104
|
+
};
|
105
|
+
return new Promise((res, err) => {
|
106
|
+
sudo_prompt_1.default.exec(`chmod +x "${path}"`, options, (error, _stdout, stderr) => {
|
107
|
+
if (error) {
|
108
|
+
err(error);
|
109
|
+
return;
|
110
|
+
}
|
111
|
+
if (stderr) {
|
112
|
+
err(stderr);
|
113
|
+
return;
|
114
|
+
}
|
115
|
+
res();
|
116
|
+
});
|
117
|
+
});
|
118
|
+
}
|
119
|
+
/** Stop the Key server */
|
120
|
+
stop() {
|
121
|
+
var _a;
|
122
|
+
this.running = false;
|
123
|
+
(_a = this.proc.stdout) === null || _a === void 0 ? void 0 : _a.pause();
|
124
|
+
this.proc.kill();
|
125
|
+
}
|
126
|
+
/**
|
127
|
+
* Obtains a IGlobalKeyEvent from stdout buffer data
|
128
|
+
* @param data Data from stdout
|
129
|
+
* @returns The standardized key event data
|
130
|
+
*/
|
131
|
+
_getEventData(data) {
|
132
|
+
const sData = data.toString();
|
133
|
+
const lines = sData.trim().split(/\n/);
|
134
|
+
return lines.map((line) => {
|
135
|
+
const lineData = line.replace(/\s+/, "");
|
136
|
+
const [mouseKeyboard, downUp, sKeyCode, sLocationX, sLocationY, eventId] = lineData.split(",");
|
137
|
+
const isMouse = mouseKeyboard === "MOUSE";
|
138
|
+
const isDown = downUp === "DOWN";
|
139
|
+
const keyCode = Number.parseInt(sKeyCode, 10);
|
140
|
+
const locationX = Number.parseFloat(sLocationX);
|
141
|
+
const locationY = Number.parseFloat(sLocationY);
|
142
|
+
const key = X11GlobalKeyLookup_1.X11GlobalKeyLookup[isMouse ? 0xffff0000 + keyCode : keyCode - 8];
|
143
|
+
return {
|
144
|
+
event: {
|
145
|
+
vKey: keyCode,
|
146
|
+
rawKey: key,
|
147
|
+
name: key === null || key === void 0 ? void 0 : key.standardName,
|
148
|
+
state: isDown ? "DOWN" : "UP",
|
149
|
+
scanCode: keyCode,
|
150
|
+
location: [locationX, locationY],
|
151
|
+
_raw: sData,
|
152
|
+
},
|
153
|
+
eventId,
|
154
|
+
};
|
155
|
+
});
|
156
|
+
}
|
157
|
+
}
|
158
|
+
exports.X11KeyServer = X11KeyServer;
|
159
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiWDExS2V5U2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RzL1gxMUtleVNlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQSwyREFBaUU7QUFHakUsbUVBQWdFO0FBQ2hFLDBEQUE2QjtBQUU3Qiw4REFBK0I7QUFDL0IsbUVBQWdFO0FBQ2hFLE1BQU0sS0FBSyxHQUFHLHdCQUF3QixDQUFDO0FBRXZDLG9EQUFvRDtBQUNwRCxNQUFhLFlBQVk7SUFRdkI7Ozs7T0FJRztJQUNILFlBQVksUUFBK0IsRUFBRSxTQUFxQixFQUFFO1FBUjVELFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDaEIsZUFBVSxHQUFHLEtBQUssQ0FBQztRQVF6QixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN2QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksS0FBSyxDQUFDLFNBQW1COztRQUM5QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUVwQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsSUFBSSxtQkFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFekUsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFBLDZCQUFRLEVBQUMsVUFBVSxDQUFDLENBQUM7UUFDakMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU07WUFDcEIsTUFBQSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sMENBQUUsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLGVBQUMsT0FBQSxNQUFBLE1BQUEsSUFBSSxDQUFDLE1BQU0sRUFBQyxNQUFNLG1EQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFBLEVBQUEsQ0FBQyxDQUFDO1FBQ2hGLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FB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
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"MacGlobalKeyLookup.d.ts","sourceRoot":"","sources":["../../../src/ts/_data/MacGlobalKeyLookup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAcnE,eAAO,MAAM,kBAAkB,EAAE,gBA4IhC,CAAC"}
|