@gjsify/event-bridge 0.3.12 → 0.3.14

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.
@@ -1,197 +1,318 @@
1
+ import { gdkKeyvalToCode, gdkKeyvalToKey, gdkKeyvalToLocation } from "./key-map.js";
1
2
  import Gtk from "gi://Gtk?version=4.0";
2
3
  import Gdk from "gi://Gdk?version=4.0";
3
- import {
4
- MouseEvent as OurMouseEvent,
5
- PointerEvent as OurPointerEvent,
6
- KeyboardEvent as OurKeyboardEvent,
7
- WheelEvent as OurWheelEvent,
8
- FocusEvent as OurFocusEvent
9
- } from "@gjsify/dom-events";
10
- import { gdkKeyvalToKey, gdkKeyvalToCode, gdkKeyvalToLocation } from "./key-map.js";
4
+ import { FocusEvent, KeyboardEvent, MouseEvent, PointerEvent, WheelEvent } from "@gjsify/dom-events";
5
+
6
+ //#region src/event-bridge.ts
7
+ /** Extract modifier flags from a GTK event controller's current event state. */
11
8
  function extractModifiers(controller) {
12
- const mods = controller.get_current_event_state();
13
- return {
14
- shiftKey: !!(mods & Gdk.ModifierType.SHIFT_MASK),
15
- ctrlKey: !!(mods & Gdk.ModifierType.CONTROL_MASK),
16
- altKey: !!(mods & Gdk.ModifierType.ALT_MASK),
17
- metaKey: !!(mods & Gdk.ModifierType.SUPER_MASK)
18
- };
9
+ const mods = controller.get_current_event_state();
10
+ return {
11
+ shiftKey: !!(mods & Gdk.ModifierType.SHIFT_MASK),
12
+ ctrlKey: !!(mods & Gdk.ModifierType.CONTROL_MASK),
13
+ altKey: !!(mods & Gdk.ModifierType.ALT_MASK),
14
+ metaKey: !!(mods & Gdk.ModifierType.SUPER_MASK)
15
+ };
19
16
  }
17
+ /** Map GTK button number (1=left, 2=middle, 3=right) to DOM button (0=left, 1=middle, 2=right). */
20
18
  function gtkButtonToDom(gtkButton) {
21
- if (gtkButton === 1) return 0;
22
- if (gtkButton === 2) return 1;
23
- if (gtkButton === 3) return 2;
24
- return gtkButton - 1;
19
+ if (gtkButton === 1) return 0;
20
+ if (gtkButton === 2) return 1;
21
+ if (gtkButton === 3) return 2;
22
+ return gtkButton - 1;
25
23
  }
24
+ /** Read buttons bitmask from Gdk modifier state. */
26
25
  function buttonsFromModifiers(controller) {
27
- const mods = controller.get_current_event_state();
28
- let buttons = 0;
29
- if (mods & Gdk.ModifierType.BUTTON1_MASK) buttons |= 1;
30
- if (mods & Gdk.ModifierType.BUTTON3_MASK) buttons |= 2;
31
- if (mods & Gdk.ModifierType.BUTTON2_MASK) buttons |= 4;
32
- return buttons;
26
+ const mods = controller.get_current_event_state();
27
+ let buttons = 0;
28
+ if (mods & Gdk.ModifierType.BUTTON1_MASK) buttons |= 1;
29
+ if (mods & Gdk.ModifierType.BUTTON3_MASK) buttons |= 2;
30
+ if (mods & Gdk.ModifierType.BUTTON2_MASK) buttons |= 4;
31
+ return buttons;
33
32
  }
34
33
  function attachEventControllers(widget, getElement, options) {
35
- widget.set_focusable(true);
36
- widget.set_can_focus(true);
37
- const state = { lastX: 0, lastY: 0, buttonsPressed: 0, pressedKeys: /* @__PURE__ */ new Set() };
38
- const motionCtrl = new Gtk.EventControllerMotion();
39
- motionCtrl.connect("motion", (_ctrl, x, y) => {
40
- const el = getElement();
41
- if (!el) return;
42
- const allocW = widget.get_allocated_width();
43
- const allocH = widget.get_allocated_height();
44
- const cx = Math.max(0, Math.min(x, allocW));
45
- const cy = Math.max(0, Math.min(y, allocH));
46
- const movementX = cx - state.lastX;
47
- const movementY = cy - state.lastY;
48
- const mods = extractModifiers(motionCtrl);
49
- const buttons = buttonsFromModifiers(motionCtrl);
50
- const init = { ...mods, clientX: cx, clientY: cy, offsetX: cx, offsetY: cy, screenX: cx, screenY: cy, movementX, movementY, buttons, button: 0, bubbles: true, cancelable: true };
51
- el.dispatchEvent(new OurPointerEvent("pointermove", { ...init, pointerId: 1, pointerType: "mouse", isPrimary: true }));
52
- el.dispatchEvent(new OurMouseEvent("mousemove", init));
53
- state.lastX = cx;
54
- state.lastY = cy;
55
- });
56
- motionCtrl.connect("enter", (_ctrl, x, y) => {
57
- const el = getElement();
58
- if (!el) return;
59
- state.lastX = x;
60
- state.lastY = y;
61
- const mods = extractModifiers(motionCtrl);
62
- const init = { ...mods, clientX: x, clientY: y, offsetX: x, offsetY: y, screenX: x, screenY: y, bubbles: false, cancelable: false };
63
- el.dispatchEvent(new OurPointerEvent("pointerenter", { ...init, pointerId: 1, pointerType: "mouse", isPrimary: true }));
64
- el.dispatchEvent(new OurMouseEvent("mouseenter", init));
65
- el.dispatchEvent(new OurMouseEvent("mouseover", { ...init, bubbles: true }));
66
- });
67
- motionCtrl.connect("leave", () => {
68
- const el = getElement();
69
- if (!el) return;
70
- const mods = extractModifiers(motionCtrl);
71
- const init = { ...mods, clientX: state.lastX, clientY: state.lastY, bubbles: false, cancelable: false };
72
- el.dispatchEvent(new OurPointerEvent("pointerleave", { ...init, pointerId: 1, pointerType: "mouse", isPrimary: true }));
73
- el.dispatchEvent(new OurMouseEvent("mouseleave", init));
74
- el.dispatchEvent(new OurMouseEvent("mouseout", { ...init, bubbles: true }));
75
- });
76
- widget.add_controller(motionCtrl);
77
- const clickCtrl = new Gtk.GestureClick();
78
- clickCtrl.set_button(0);
79
- clickCtrl.connect("pressed", (_ctrl, nPress, x, y) => {
80
- const el = getElement();
81
- if (!el) return;
82
- const gtkButton = clickCtrl.get_current_button();
83
- const domButton = gtkButtonToDom(gtkButton);
84
- const mods = extractModifiers(clickCtrl);
85
- state.buttonsPressed |= 1 << domButton;
86
- const init = { ...mods, clientX: x, clientY: y, offsetX: x, offsetY: y, screenX: x, screenY: y, button: domButton, buttons: state.buttonsPressed, detail: nPress, bubbles: true, cancelable: true };
87
- el.dispatchEvent(new OurPointerEvent("pointerdown", { ...init, pointerId: 1, pointerType: "mouse", isPrimary: true }));
88
- el.dispatchEvent(new OurMouseEvent("mousedown", init));
89
- widget.grab_focus();
90
- });
91
- clickCtrl.connect("released", (_ctrl, nPress, x, y) => {
92
- const el = getElement();
93
- if (!el) return;
94
- const gtkButton = clickCtrl.get_current_button();
95
- const domButton = gtkButtonToDom(gtkButton);
96
- const mods = extractModifiers(clickCtrl);
97
- state.buttonsPressed &= ~(1 << domButton);
98
- const init = { ...mods, clientX: x, clientY: y, offsetX: x, offsetY: y, screenX: x, screenY: y, button: domButton, buttons: state.buttonsPressed, detail: nPress, bubbles: true, cancelable: true };
99
- el.dispatchEvent(new OurPointerEvent("pointerup", { ...init, pointerId: 1, pointerType: "mouse", isPrimary: true }));
100
- el.dispatchEvent(new OurMouseEvent("mouseup", init));
101
- if (domButton === 0) {
102
- el.dispatchEvent(new OurMouseEvent("click", init));
103
- if (nPress === 2) {
104
- el.dispatchEvent(new OurMouseEvent("dblclick", init));
105
- }
106
- }
107
- if (domButton === 2) {
108
- el.dispatchEvent(new OurMouseEvent("contextmenu", { ...init, cancelable: true }));
109
- }
110
- });
111
- widget.add_controller(clickCtrl);
112
- const scrollCtrl = new Gtk.EventControllerScroll({
113
- flags: Gtk.EventControllerScrollFlags.BOTH_AXES
114
- });
115
- scrollCtrl.connect("scroll", (_ctrl, dx, dy) => {
116
- const el = getElement();
117
- if (!el) return;
118
- const mods = extractModifiers(scrollCtrl);
119
- const scale = 100;
120
- const init = { ...mods, clientX: state.lastX, clientY: state.lastY, offsetX: state.lastX, offsetY: state.lastY, screenX: state.lastX, screenY: state.lastY, deltaX: dx * scale, deltaY: dy * scale, deltaZ: 0, deltaMode: 0, bubbles: true, cancelable: true };
121
- el.dispatchEvent(new OurWheelEvent("wheel", init));
122
- return false;
123
- });
124
- widget.add_controller(scrollCtrl);
125
- const keyCtrl = new Gtk.EventControllerKey();
126
- keyCtrl.connect("key-pressed", (_ctrl, keyval, _keycode, modifiers) => {
127
- const el = getElement();
128
- if (!el) return false;
129
- const repeat = state.pressedKeys.has(keyval);
130
- state.pressedKeys.add(keyval);
131
- const key = gdkKeyvalToKey(keyval);
132
- const code = gdkKeyvalToCode(keyval);
133
- const location = gdkKeyvalToLocation(keyval);
134
- const init = {
135
- key,
136
- code,
137
- location,
138
- repeat,
139
- altKey: !!(modifiers & Gdk.ModifierType.ALT_MASK),
140
- ctrlKey: !!(modifiers & Gdk.ModifierType.CONTROL_MASK),
141
- metaKey: !!(modifiers & Gdk.ModifierType.SUPER_MASK),
142
- shiftKey: !!(modifiers & Gdk.ModifierType.SHIFT_MASK),
143
- keyCode: key.length === 1 ? key.toUpperCase().charCodeAt(0) : 0,
144
- which: key.length === 1 ? key.toUpperCase().charCodeAt(0) : 0,
145
- bubbles: true,
146
- cancelable: true
147
- };
148
- const keydownEvent = new OurKeyboardEvent("keydown", init);
149
- el.dispatchEvent(keydownEvent);
150
- globalThis.__gjsify_globalEventTarget?.dispatchEvent(new OurKeyboardEvent("keydown", init));
151
- return options?.captureKeys === true ? true : false;
152
- });
153
- keyCtrl.connect("key-released", (_ctrl, keyval, _keycode, modifiers) => {
154
- const el = getElement();
155
- if (!el) return;
156
- state.pressedKeys.delete(keyval);
157
- const key = gdkKeyvalToKey(keyval);
158
- const code = gdkKeyvalToCode(keyval);
159
- const location = gdkKeyvalToLocation(keyval);
160
- const init = {
161
- key,
162
- code,
163
- location,
164
- repeat: false,
165
- altKey: !!(modifiers & Gdk.ModifierType.ALT_MASK),
166
- ctrlKey: !!(modifiers & Gdk.ModifierType.CONTROL_MASK),
167
- metaKey: !!(modifiers & Gdk.ModifierType.SUPER_MASK),
168
- shiftKey: !!(modifiers & Gdk.ModifierType.SHIFT_MASK),
169
- keyCode: key.length === 1 ? key.toUpperCase().charCodeAt(0) : 0,
170
- which: key.length === 1 ? key.toUpperCase().charCodeAt(0) : 0,
171
- bubbles: true,
172
- cancelable: true
173
- };
174
- el.dispatchEvent(new OurKeyboardEvent("keyup", init));
175
- globalThis.__gjsify_globalEventTarget?.dispatchEvent(new OurKeyboardEvent("keyup", init));
176
- });
177
- widget.add_controller(keyCtrl);
178
- const focusCtrl = new Gtk.EventControllerFocus();
179
- focusCtrl.connect("enter", () => {
180
- const el = getElement();
181
- if (!el) return;
182
- el.dispatchEvent(new OurFocusEvent("focus", { bubbles: false, cancelable: false }));
183
- el.dispatchEvent(new OurFocusEvent("focusin", { bubbles: true, cancelable: false }));
184
- });
185
- focusCtrl.connect("leave", () => {
186
- const el = getElement();
187
- if (!el) return;
188
- state.pressedKeys.clear();
189
- el.dispatchEvent(new OurFocusEvent("blur", { bubbles: false, cancelable: false }));
190
- el.dispatchEvent(new OurFocusEvent("focusout", { bubbles: true, cancelable: false }));
191
- globalThis.__gjsify_globalEventTarget?.dispatchEvent(new OurFocusEvent("blur", { bubbles: false, cancelable: false }));
192
- });
193
- widget.add_controller(focusCtrl);
34
+ widget.set_focusable(true);
35
+ widget.set_can_focus(true);
36
+ const state = {
37
+ lastX: 0,
38
+ lastY: 0,
39
+ buttonsPressed: 0,
40
+ pressedKeys: new Set()
41
+ };
42
+ const motionCtrl = new Gtk.EventControllerMotion();
43
+ motionCtrl.connect("motion", (_ctrl, x, y) => {
44
+ const el = getElement();
45
+ if (!el) return;
46
+ const allocW = widget.get_allocated_width();
47
+ const allocH = widget.get_allocated_height();
48
+ const cx = Math.max(0, Math.min(x, allocW));
49
+ const cy = Math.max(0, Math.min(y, allocH));
50
+ const movementX = cx - state.lastX;
51
+ const movementY = cy - state.lastY;
52
+ const mods = extractModifiers(motionCtrl);
53
+ const buttons = buttonsFromModifiers(motionCtrl);
54
+ const init = {
55
+ ...mods,
56
+ clientX: cx,
57
+ clientY: cy,
58
+ offsetX: cx,
59
+ offsetY: cy,
60
+ screenX: cx,
61
+ screenY: cy,
62
+ movementX,
63
+ movementY,
64
+ buttons,
65
+ button: 0,
66
+ bubbles: true,
67
+ cancelable: true
68
+ };
69
+ el.dispatchEvent(new PointerEvent("pointermove", {
70
+ ...init,
71
+ pointerId: 1,
72
+ pointerType: "mouse",
73
+ isPrimary: true
74
+ }));
75
+ el.dispatchEvent(new MouseEvent("mousemove", init));
76
+ state.lastX = cx;
77
+ state.lastY = cy;
78
+ });
79
+ motionCtrl.connect("enter", (_ctrl, x, y) => {
80
+ const el = getElement();
81
+ if (!el) return;
82
+ state.lastX = x;
83
+ state.lastY = y;
84
+ const mods = extractModifiers(motionCtrl);
85
+ const init = {
86
+ ...mods,
87
+ clientX: x,
88
+ clientY: y,
89
+ offsetX: x,
90
+ offsetY: y,
91
+ screenX: x,
92
+ screenY: y,
93
+ bubbles: false,
94
+ cancelable: false
95
+ };
96
+ el.dispatchEvent(new PointerEvent("pointerenter", {
97
+ ...init,
98
+ pointerId: 1,
99
+ pointerType: "mouse",
100
+ isPrimary: true
101
+ }));
102
+ el.dispatchEvent(new MouseEvent("mouseenter", init));
103
+ el.dispatchEvent(new MouseEvent("mouseover", {
104
+ ...init,
105
+ bubbles: true
106
+ }));
107
+ });
108
+ motionCtrl.connect("leave", () => {
109
+ const el = getElement();
110
+ if (!el) return;
111
+ const mods = extractModifiers(motionCtrl);
112
+ const init = {
113
+ ...mods,
114
+ clientX: state.lastX,
115
+ clientY: state.lastY,
116
+ bubbles: false,
117
+ cancelable: false
118
+ };
119
+ el.dispatchEvent(new PointerEvent("pointerleave", {
120
+ ...init,
121
+ pointerId: 1,
122
+ pointerType: "mouse",
123
+ isPrimary: true
124
+ }));
125
+ el.dispatchEvent(new MouseEvent("mouseleave", init));
126
+ el.dispatchEvent(new MouseEvent("mouseout", {
127
+ ...init,
128
+ bubbles: true
129
+ }));
130
+ });
131
+ widget.add_controller(motionCtrl);
132
+ const clickCtrl = new Gtk.GestureClick();
133
+ clickCtrl.set_button(0);
134
+ clickCtrl.connect("pressed", (_ctrl, nPress, x, y) => {
135
+ const el = getElement();
136
+ if (!el) return;
137
+ const gtkButton = clickCtrl.get_current_button();
138
+ const domButton = gtkButtonToDom(gtkButton);
139
+ const mods = extractModifiers(clickCtrl);
140
+ state.buttonsPressed |= 1 << domButton;
141
+ const init = {
142
+ ...mods,
143
+ clientX: x,
144
+ clientY: y,
145
+ offsetX: x,
146
+ offsetY: y,
147
+ screenX: x,
148
+ screenY: y,
149
+ button: domButton,
150
+ buttons: state.buttonsPressed,
151
+ detail: nPress,
152
+ bubbles: true,
153
+ cancelable: true
154
+ };
155
+ el.dispatchEvent(new PointerEvent("pointerdown", {
156
+ ...init,
157
+ pointerId: 1,
158
+ pointerType: "mouse",
159
+ isPrimary: true
160
+ }));
161
+ el.dispatchEvent(new MouseEvent("mousedown", init));
162
+ widget.grab_focus();
163
+ });
164
+ clickCtrl.connect("released", (_ctrl, nPress, x, y) => {
165
+ const el = getElement();
166
+ if (!el) return;
167
+ const gtkButton = clickCtrl.get_current_button();
168
+ const domButton = gtkButtonToDom(gtkButton);
169
+ const mods = extractModifiers(clickCtrl);
170
+ state.buttonsPressed &= ~(1 << domButton);
171
+ const init = {
172
+ ...mods,
173
+ clientX: x,
174
+ clientY: y,
175
+ offsetX: x,
176
+ offsetY: y,
177
+ screenX: x,
178
+ screenY: y,
179
+ button: domButton,
180
+ buttons: state.buttonsPressed,
181
+ detail: nPress,
182
+ bubbles: true,
183
+ cancelable: true
184
+ };
185
+ el.dispatchEvent(new PointerEvent("pointerup", {
186
+ ...init,
187
+ pointerId: 1,
188
+ pointerType: "mouse",
189
+ isPrimary: true
190
+ }));
191
+ el.dispatchEvent(new MouseEvent("mouseup", init));
192
+ if (domButton === 0) {
193
+ el.dispatchEvent(new MouseEvent("click", init));
194
+ if (nPress === 2) {
195
+ el.dispatchEvent(new MouseEvent("dblclick", init));
196
+ }
197
+ }
198
+ if (domButton === 2) {
199
+ el.dispatchEvent(new MouseEvent("contextmenu", {
200
+ ...init,
201
+ cancelable: true
202
+ }));
203
+ }
204
+ });
205
+ widget.add_controller(clickCtrl);
206
+ const scrollCtrl = new Gtk.EventControllerScroll({ flags: Gtk.EventControllerScrollFlags.BOTH_AXES });
207
+ scrollCtrl.connect("scroll", (_ctrl, dx, dy) => {
208
+ const el = getElement();
209
+ if (!el) return;
210
+ const mods = extractModifiers(scrollCtrl);
211
+ const scale = 100;
212
+ const init = {
213
+ ...mods,
214
+ clientX: state.lastX,
215
+ clientY: state.lastY,
216
+ offsetX: state.lastX,
217
+ offsetY: state.lastY,
218
+ screenX: state.lastX,
219
+ screenY: state.lastY,
220
+ deltaX: dx * scale,
221
+ deltaY: dy * scale,
222
+ deltaZ: 0,
223
+ deltaMode: 0,
224
+ bubbles: true,
225
+ cancelable: true
226
+ };
227
+ el.dispatchEvent(new WheelEvent("wheel", init));
228
+ return false;
229
+ });
230
+ widget.add_controller(scrollCtrl);
231
+ const keyCtrl = new Gtk.EventControllerKey();
232
+ keyCtrl.connect("key-pressed", (_ctrl, keyval, _keycode, modifiers) => {
233
+ const el = getElement();
234
+ if (!el) return false;
235
+ const repeat = state.pressedKeys.has(keyval);
236
+ state.pressedKeys.add(keyval);
237
+ const key = gdkKeyvalToKey(keyval);
238
+ const code = gdkKeyvalToCode(keyval);
239
+ const location = gdkKeyvalToLocation(keyval);
240
+ const init = {
241
+ key,
242
+ code,
243
+ location,
244
+ repeat,
245
+ altKey: !!(modifiers & Gdk.ModifierType.ALT_MASK),
246
+ ctrlKey: !!(modifiers & Gdk.ModifierType.CONTROL_MASK),
247
+ metaKey: !!(modifiers & Gdk.ModifierType.SUPER_MASK),
248
+ shiftKey: !!(modifiers & Gdk.ModifierType.SHIFT_MASK),
249
+ keyCode: key.length === 1 ? key.toUpperCase().charCodeAt(0) : 0,
250
+ which: key.length === 1 ? key.toUpperCase().charCodeAt(0) : 0,
251
+ bubbles: true,
252
+ cancelable: true
253
+ };
254
+ const keydownEvent = new KeyboardEvent("keydown", init);
255
+ el.dispatchEvent(keydownEvent);
256
+ globalThis.__gjsify_globalEventTarget?.dispatchEvent(new KeyboardEvent("keydown", init));
257
+ return options?.captureKeys === true ? true : false;
258
+ });
259
+ keyCtrl.connect("key-released", (_ctrl, keyval, _keycode, modifiers) => {
260
+ const el = getElement();
261
+ if (!el) return;
262
+ state.pressedKeys.delete(keyval);
263
+ const key = gdkKeyvalToKey(keyval);
264
+ const code = gdkKeyvalToCode(keyval);
265
+ const location = gdkKeyvalToLocation(keyval);
266
+ const init = {
267
+ key,
268
+ code,
269
+ location,
270
+ repeat: false,
271
+ altKey: !!(modifiers & Gdk.ModifierType.ALT_MASK),
272
+ ctrlKey: !!(modifiers & Gdk.ModifierType.CONTROL_MASK),
273
+ metaKey: !!(modifiers & Gdk.ModifierType.SUPER_MASK),
274
+ shiftKey: !!(modifiers & Gdk.ModifierType.SHIFT_MASK),
275
+ keyCode: key.length === 1 ? key.toUpperCase().charCodeAt(0) : 0,
276
+ which: key.length === 1 ? key.toUpperCase().charCodeAt(0) : 0,
277
+ bubbles: true,
278
+ cancelable: true
279
+ };
280
+ el.dispatchEvent(new KeyboardEvent("keyup", init));
281
+ globalThis.__gjsify_globalEventTarget?.dispatchEvent(new KeyboardEvent("keyup", init));
282
+ });
283
+ widget.add_controller(keyCtrl);
284
+ const focusCtrl = new Gtk.EventControllerFocus();
285
+ focusCtrl.connect("enter", () => {
286
+ const el = getElement();
287
+ if (!el) return;
288
+ el.dispatchEvent(new FocusEvent("focus", {
289
+ bubbles: false,
290
+ cancelable: false
291
+ }));
292
+ el.dispatchEvent(new FocusEvent("focusin", {
293
+ bubbles: true,
294
+ cancelable: false
295
+ }));
296
+ });
297
+ focusCtrl.connect("leave", () => {
298
+ const el = getElement();
299
+ if (!el) return;
300
+ state.pressedKeys.clear();
301
+ el.dispatchEvent(new FocusEvent("blur", {
302
+ bubbles: false,
303
+ cancelable: false
304
+ }));
305
+ el.dispatchEvent(new FocusEvent("focusout", {
306
+ bubbles: true,
307
+ cancelable: false
308
+ }));
309
+ globalThis.__gjsify_globalEventTarget?.dispatchEvent(new FocusEvent("blur", {
310
+ bubbles: false,
311
+ cancelable: false
312
+ }));
313
+ });
314
+ widget.add_controller(focusCtrl);
194
315
  }
195
- export {
196
- attachEventControllers
197
- };
316
+
317
+ //#endregion
318
+ export { attachEventControllers };
package/lib/esm/index.js CHANGED
@@ -1,8 +1,4 @@
1
+ import { gdkKeyvalToCode, gdkKeyvalToKey, gdkKeyvalToLocation } from "./key-map.js";
1
2
  import { attachEventControllers } from "./event-bridge.js";
2
- import { gdkKeyvalToKey, gdkKeyvalToCode, gdkKeyvalToLocation } from "./key-map.js";
3
- export {
4
- attachEventControllers,
5
- gdkKeyvalToCode,
6
- gdkKeyvalToKey,
7
- gdkKeyvalToLocation
8
- };
3
+
4
+ export { attachEventControllers, gdkKeyvalToCode, gdkKeyvalToKey, gdkKeyvalToLocation };
@@ -1,192 +1,203 @@
1
1
  import Gdk from "gi://Gdk?version=4.0";
2
+
3
+ //#region src/key-map.ts
2
4
  const SPECIAL_KEYS = {
3
- Return: "Enter",
4
- KP_Enter: "Enter",
5
- Tab: "Tab",
6
- ISO_Left_Tab: "Tab",
7
- BackSpace: "Backspace",
8
- Escape: "Escape",
9
- Delete: "Delete",
10
- KP_Delete: "Delete",
11
- Insert: "Insert",
12
- KP_Insert: "Insert",
13
- Home: "Home",
14
- KP_Home: "Home",
15
- End: "End",
16
- KP_End: "End",
17
- Page_Up: "PageUp",
18
- KP_Page_Up: "PageUp",
19
- Page_Down: "PageDown",
20
- KP_Page_Down: "PageDown",
21
- Left: "ArrowLeft",
22
- KP_Left: "ArrowLeft",
23
- Up: "ArrowUp",
24
- KP_Up: "ArrowUp",
25
- Right: "ArrowRight",
26
- KP_Right: "ArrowRight",
27
- Down: "ArrowDown",
28
- KP_Down: "ArrowDown",
29
- Shift_L: "Shift",
30
- Shift_R: "Shift",
31
- Control_L: "Control",
32
- Control_R: "Control",
33
- Alt_L: "Alt",
34
- Alt_R: "Alt",
35
- Super_L: "Meta",
36
- Super_R: "Meta",
37
- Meta_L: "Meta",
38
- Meta_R: "Meta",
39
- Caps_Lock: "CapsLock",
40
- Num_Lock: "NumLock",
41
- Scroll_Lock: "ScrollLock",
42
- Print: "PrintScreen",
43
- Pause: "Pause",
44
- Menu: "ContextMenu",
45
- space: " ",
46
- F1: "F1",
47
- F2: "F2",
48
- F3: "F3",
49
- F4: "F4",
50
- F5: "F5",
51
- F6: "F6",
52
- F7: "F7",
53
- F8: "F8",
54
- F9: "F9",
55
- F10: "F10",
56
- F11: "F11",
57
- F12: "F12",
58
- KP_Add: "+",
59
- KP_Subtract: "-",
60
- KP_Multiply: "*",
61
- KP_Divide: "/",
62
- KP_Decimal: ".",
63
- KP_Separator: ",",
64
- KP_0: "0",
65
- KP_1: "1",
66
- KP_2: "2",
67
- KP_3: "3",
68
- KP_4: "4",
69
- KP_5: "5",
70
- KP_6: "6",
71
- KP_7: "7",
72
- KP_8: "8",
73
- KP_9: "9"
5
+ Return: "Enter",
6
+ KP_Enter: "Enter",
7
+ Tab: "Tab",
8
+ ISO_Left_Tab: "Tab",
9
+ BackSpace: "Backspace",
10
+ Escape: "Escape",
11
+ Delete: "Delete",
12
+ KP_Delete: "Delete",
13
+ Insert: "Insert",
14
+ KP_Insert: "Insert",
15
+ Home: "Home",
16
+ KP_Home: "Home",
17
+ End: "End",
18
+ KP_End: "End",
19
+ Page_Up: "PageUp",
20
+ KP_Page_Up: "PageUp",
21
+ Page_Down: "PageDown",
22
+ KP_Page_Down: "PageDown",
23
+ Left: "ArrowLeft",
24
+ KP_Left: "ArrowLeft",
25
+ Up: "ArrowUp",
26
+ KP_Up: "ArrowUp",
27
+ Right: "ArrowRight",
28
+ KP_Right: "ArrowRight",
29
+ Down: "ArrowDown",
30
+ KP_Down: "ArrowDown",
31
+ Shift_L: "Shift",
32
+ Shift_R: "Shift",
33
+ Control_L: "Control",
34
+ Control_R: "Control",
35
+ Alt_L: "Alt",
36
+ Alt_R: "Alt",
37
+ Super_L: "Meta",
38
+ Super_R: "Meta",
39
+ Meta_L: "Meta",
40
+ Meta_R: "Meta",
41
+ Caps_Lock: "CapsLock",
42
+ Num_Lock: "NumLock",
43
+ Scroll_Lock: "ScrollLock",
44
+ Print: "PrintScreen",
45
+ Pause: "Pause",
46
+ Menu: "ContextMenu",
47
+ space: " ",
48
+ F1: "F1",
49
+ F2: "F2",
50
+ F3: "F3",
51
+ F4: "F4",
52
+ F5: "F5",
53
+ F6: "F6",
54
+ F7: "F7",
55
+ F8: "F8",
56
+ F9: "F9",
57
+ F10: "F10",
58
+ F11: "F11",
59
+ F12: "F12",
60
+ KP_Add: "+",
61
+ KP_Subtract: "-",
62
+ KP_Multiply: "*",
63
+ KP_Divide: "/",
64
+ KP_Decimal: ".",
65
+ KP_Separator: ",",
66
+ KP_0: "0",
67
+ KP_1: "1",
68
+ KP_2: "2",
69
+ KP_3: "3",
70
+ KP_4: "4",
71
+ KP_5: "5",
72
+ KP_6: "6",
73
+ KP_7: "7",
74
+ KP_8: "8",
75
+ KP_9: "9"
74
76
  };
75
77
  const SPECIAL_CODES = {
76
- Return: "Enter",
77
- KP_Enter: "NumpadEnter",
78
- Tab: "Tab",
79
- ISO_Left_Tab: "Tab",
80
- BackSpace: "Backspace",
81
- Escape: "Escape",
82
- Delete: "Delete",
83
- KP_Delete: "NumpadDecimal",
84
- Insert: "Insert",
85
- KP_Insert: "Numpad0",
86
- Home: "Home",
87
- KP_Home: "Numpad7",
88
- End: "End",
89
- KP_End: "Numpad1",
90
- Page_Up: "PageUp",
91
- KP_Page_Up: "Numpad9",
92
- Page_Down: "PageDown",
93
- KP_Page_Down: "Numpad3",
94
- Left: "ArrowLeft",
95
- KP_Left: "Numpad4",
96
- Up: "ArrowUp",
97
- KP_Up: "Numpad8",
98
- Right: "ArrowRight",
99
- KP_Right: "Numpad6",
100
- Down: "ArrowDown",
101
- KP_Down: "Numpad2",
102
- Shift_L: "ShiftLeft",
103
- Shift_R: "ShiftRight",
104
- Control_L: "ControlLeft",
105
- Control_R: "ControlRight",
106
- Alt_L: "AltLeft",
107
- Alt_R: "AltRight",
108
- Super_L: "MetaLeft",
109
- Super_R: "MetaRight",
110
- Meta_L: "MetaLeft",
111
- Meta_R: "MetaRight",
112
- Caps_Lock: "CapsLock",
113
- Num_Lock: "NumLock",
114
- Scroll_Lock: "ScrollLock",
115
- Print: "PrintScreen",
116
- Pause: "Pause",
117
- Menu: "ContextMenu",
118
- space: "Space",
119
- F1: "F1",
120
- F2: "F2",
121
- F3: "F3",
122
- F4: "F4",
123
- F5: "F5",
124
- F6: "F6",
125
- F7: "F7",
126
- F8: "F8",
127
- F9: "F9",
128
- F10: "F10",
129
- F11: "F11",
130
- F12: "F12",
131
- KP_Add: "NumpadAdd",
132
- KP_Subtract: "NumpadSubtract",
133
- KP_Multiply: "NumpadMultiply",
134
- KP_Divide: "NumpadDivide",
135
- KP_Decimal: "NumpadDecimal",
136
- KP_Separator: "NumpadComma",
137
- KP_0: "Numpad0",
138
- KP_1: "Numpad1",
139
- KP_2: "Numpad2",
140
- KP_3: "Numpad3",
141
- KP_4: "Numpad4",
142
- KP_5: "Numpad5",
143
- KP_6: "Numpad6",
144
- KP_7: "Numpad7",
145
- KP_8: "Numpad8",
146
- KP_9: "Numpad9"
78
+ Return: "Enter",
79
+ KP_Enter: "NumpadEnter",
80
+ Tab: "Tab",
81
+ ISO_Left_Tab: "Tab",
82
+ BackSpace: "Backspace",
83
+ Escape: "Escape",
84
+ Delete: "Delete",
85
+ KP_Delete: "NumpadDecimal",
86
+ Insert: "Insert",
87
+ KP_Insert: "Numpad0",
88
+ Home: "Home",
89
+ KP_Home: "Numpad7",
90
+ End: "End",
91
+ KP_End: "Numpad1",
92
+ Page_Up: "PageUp",
93
+ KP_Page_Up: "Numpad9",
94
+ Page_Down: "PageDown",
95
+ KP_Page_Down: "Numpad3",
96
+ Left: "ArrowLeft",
97
+ KP_Left: "Numpad4",
98
+ Up: "ArrowUp",
99
+ KP_Up: "Numpad8",
100
+ Right: "ArrowRight",
101
+ KP_Right: "Numpad6",
102
+ Down: "ArrowDown",
103
+ KP_Down: "Numpad2",
104
+ Shift_L: "ShiftLeft",
105
+ Shift_R: "ShiftRight",
106
+ Control_L: "ControlLeft",
107
+ Control_R: "ControlRight",
108
+ Alt_L: "AltLeft",
109
+ Alt_R: "AltRight",
110
+ Super_L: "MetaLeft",
111
+ Super_R: "MetaRight",
112
+ Meta_L: "MetaLeft",
113
+ Meta_R: "MetaRight",
114
+ Caps_Lock: "CapsLock",
115
+ Num_Lock: "NumLock",
116
+ Scroll_Lock: "ScrollLock",
117
+ Print: "PrintScreen",
118
+ Pause: "Pause",
119
+ Menu: "ContextMenu",
120
+ space: "Space",
121
+ F1: "F1",
122
+ F2: "F2",
123
+ F3: "F3",
124
+ F4: "F4",
125
+ F5: "F5",
126
+ F6: "F6",
127
+ F7: "F7",
128
+ F8: "F8",
129
+ F9: "F9",
130
+ F10: "F10",
131
+ F11: "F11",
132
+ F12: "F12",
133
+ KP_Add: "NumpadAdd",
134
+ KP_Subtract: "NumpadSubtract",
135
+ KP_Multiply: "NumpadMultiply",
136
+ KP_Divide: "NumpadDivide",
137
+ KP_Decimal: "NumpadDecimal",
138
+ KP_Separator: "NumpadComma",
139
+ KP_0: "Numpad0",
140
+ KP_1: "Numpad1",
141
+ KP_2: "Numpad2",
142
+ KP_3: "Numpad3",
143
+ KP_4: "Numpad4",
144
+ KP_5: "Numpad5",
145
+ KP_6: "Numpad6",
146
+ KP_7: "Numpad7",
147
+ KP_8: "Numpad8",
148
+ KP_9: "Numpad9"
147
149
  };
150
+ /**
151
+ * Convert a Gdk keyval to a DOM `key` string.
152
+ * Uses special-key lookup table, falls back to Gdk.keyval_to_unicode for printable chars.
153
+ */
148
154
  function gdkKeyvalToKey(keyval) {
149
- const name = Gdk.keyval_name(keyval);
150
- if (name && SPECIAL_KEYS[name]) return SPECIAL_KEYS[name];
151
- const unicode = Gdk.keyval_to_unicode(keyval);
152
- if (unicode > 0) return String.fromCodePoint(unicode);
153
- return name ?? "Unidentified";
155
+ const name = Gdk.keyval_name(keyval);
156
+ if (name && SPECIAL_KEYS[name]) return SPECIAL_KEYS[name];
157
+ const unicode = Gdk.keyval_to_unicode(keyval);
158
+ if (unicode > 0) return String.fromCodePoint(unicode);
159
+ return name ?? "Unidentified";
154
160
  }
161
+ /**
162
+ * Convert a Gdk keyval to a DOM `code` string.
163
+ */
155
164
  function gdkKeyvalToCode(keyval) {
156
- const name = Gdk.keyval_name(keyval);
157
- if (name && SPECIAL_CODES[name]) return SPECIAL_CODES[name];
158
- const unicode = Gdk.keyval_to_unicode(keyval);
159
- if (unicode >= 97 && unicode <= 122) return "Key" + String.fromCodePoint(unicode - 32);
160
- if (unicode >= 65 && unicode <= 90) return "Key" + String.fromCodePoint(unicode);
161
- if (unicode >= 48 && unicode <= 57) return "Digit" + String.fromCodePoint(unicode);
162
- if (name) {
163
- const punct = {
164
- minus: "Minus",
165
- equal: "Equal",
166
- bracketleft: "BracketLeft",
167
- bracketright: "BracketRight",
168
- backslash: "Backslash",
169
- semicolon: "Semicolon",
170
- apostrophe: "Quote",
171
- grave: "Backquote",
172
- comma: "Comma",
173
- period: "Period",
174
- slash: "Slash"
175
- };
176
- if (punct[name]) return punct[name];
177
- }
178
- return name ?? "Unidentified";
165
+ const name = Gdk.keyval_name(keyval);
166
+ if (name && SPECIAL_CODES[name]) return SPECIAL_CODES[name];
167
+ const unicode = Gdk.keyval_to_unicode(keyval);
168
+ if (unicode >= 97 && unicode <= 122) return "Key" + String.fromCodePoint(unicode - 32);
169
+ if (unicode >= 65 && unicode <= 90) return "Key" + String.fromCodePoint(unicode);
170
+ if (unicode >= 48 && unicode <= 57) return "Digit" + String.fromCodePoint(unicode);
171
+ if (name) {
172
+ const punct = {
173
+ minus: "Minus",
174
+ equal: "Equal",
175
+ bracketleft: "BracketLeft",
176
+ bracketright: "BracketRight",
177
+ backslash: "Backslash",
178
+ semicolon: "Semicolon",
179
+ apostrophe: "Quote",
180
+ grave: "Backquote",
181
+ comma: "Comma",
182
+ period: "Period",
183
+ slash: "Slash"
184
+ };
185
+ if (punct[name]) return punct[name];
186
+ }
187
+ return name ?? "Unidentified";
179
188
  }
189
+ /**
190
+ * Determine the DOM KeyboardEvent.location from a Gdk keyval.
191
+ * 0=STANDARD, 1=LEFT, 2=RIGHT, 3=NUMPAD
192
+ */
180
193
  function gdkKeyvalToLocation(keyval) {
181
- const name = Gdk.keyval_name(keyval);
182
- if (!name) return 0;
183
- if (name.startsWith("KP_")) return 3;
184
- if (name.endsWith("_L")) return 1;
185
- if (name.endsWith("_R")) return 2;
186
- return 0;
194
+ const name = Gdk.keyval_name(keyval);
195
+ if (!name) return 0;
196
+ if (name.startsWith("KP_")) return 3;
197
+ if (name.endsWith("_L")) return 1;
198
+ if (name.endsWith("_R")) return 2;
199
+ return 0;
187
200
  }
188
- export {
189
- gdkKeyvalToCode,
190
- gdkKeyvalToKey,
191
- gdkKeyvalToLocation
192
- };
201
+
202
+ //#endregion
203
+ export { gdkKeyvalToCode, gdkKeyvalToKey, gdkKeyvalToLocation };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/event-bridge",
3
- "version": "0.3.12",
3
+ "version": "0.3.14",
4
4
  "description": "Bridge GTK event controllers to standard DOM events (MouseEvent, KeyboardEvent, etc.)",
5
5
  "type": "module",
6
6
  "module": "lib/esm/index.js",
@@ -30,15 +30,15 @@
30
30
  "bridge"
31
31
  ],
32
32
  "dependencies": {
33
- "@girs/gdk-4.0": "^4.0.0-4.0.0-rc.9",
34
- "@girs/gjs": "^4.0.0-rc.9",
35
- "@girs/glib-2.0": "^2.88.0-4.0.0-rc.9",
36
- "@girs/gtk-4.0": "^4.23.0-4.0.0-rc.9",
37
- "@gjsify/dom-events": "^0.3.12"
33
+ "@girs/gdk-4.0": "4.0.0-4.0.0-rc.9",
34
+ "@girs/gjs": "4.0.0-rc.9",
35
+ "@girs/glib-2.0": "2.88.0-4.0.0-rc.9",
36
+ "@girs/gtk-4.0": "4.23.0-4.0.0-rc.9",
37
+ "@gjsify/dom-events": "^0.3.14"
38
38
  },
39
39
  "devDependencies": {
40
- "@gjsify/cli": "^0.3.12",
41
- "@gjsify/unit": "^0.3.12",
40
+ "@gjsify/cli": "^0.3.14",
41
+ "@gjsify/unit": "^0.3.14",
42
42
  "@types/node": "^25.6.0",
43
43
  "typescript": "^6.0.3"
44
44
  }