@matjash/pixi-native-win32-x64 0.1.2 → 0.2.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.
@@ -2778,7 +2778,7 @@ type PresentMode = "fifo" | "fifoRelaxed" | "immediate" | "mailbox";
2778
2778
 
2779
2779
  interface Renderer {
2780
2780
  getPreferredFormat(): GPUTextureFormat;
2781
- getAlphaMode(): 'opaque' | 'premultiplied';
2781
+ getAlphaMode(): 'opaque' | 'premultiplied' | 'inherit';
2782
2782
  getCurrentTexture(): GPUTexture;
2783
2783
  getCurrentTextureView(): GPUTextureView;
2784
2784
  swap();
@@ -2839,6 +2839,8 @@ interface WebGPU {
2839
2839
  adapter: GPUAdapter;
2840
2840
  device: GPUDevice;
2841
2841
  renderer: Renderer;
2842
+ requestedAlphaMode: "opaque" | "premultiplied";
2843
+ alphaMode: "opaque" | "premultiplied" | "inherit";
2842
2844
  };
2843
2845
  destroy(context: object);
2844
2846
  }
@@ -1,11 +1,46 @@
1
- export interface NativeWindowApi {
2
- setTransparent(nativeData: Uint8Array, transparent: boolean): void;
3
- waitForCompositorFrame(timeoutMs?: number): Promise<boolean>;
4
- create(
5
- nativeData: Uint8Array,
6
- onFrame: () => void,
7
- onState: (active: boolean) => void,
8
- ): ModalFrameController;
1
+ export interface NativeSurfaceDescriptor {
2
+ readonly version: 1;
3
+ readonly api: "win32" | "x11" | "wayland";
4
+ readonly window: Buffer;
5
+ readonly display?: Buffer;
6
+ readonly instance?: Buffer;
7
+ readonly eglWindow?: Buffer;
8
+ }
9
+
10
+ export interface NativeWindowOptions {
11
+ readonly title: string;
12
+ readonly width: number;
13
+ readonly height: number;
14
+ readonly resizable: boolean;
15
+ readonly borderless: boolean;
16
+ readonly transparent: boolean;
17
+ readonly x?: number;
18
+ readonly y?: number;
19
+ readonly graphics: "webgpu" | "webgl";
20
+ }
21
+
22
+ export interface NativeWindow {
23
+ readonly id: number;
24
+ readonly x: number;
25
+ readonly y: number;
26
+ readonly pixelWidth: number;
27
+ readonly pixelHeight: number;
28
+ readonly display: { readonly frequency: number };
29
+ readonly destroyed: boolean;
30
+ readonly surface: NativeSurfaceDescriptor;
31
+ readonly videoDriver: string;
32
+ readonly transparent: boolean;
33
+ pollEvents(): void;
34
+ setPosition(x: number, y: number): void;
35
+ minimize(): void;
36
+ maximize(): void;
37
+ restore(): void;
38
+ makeGlCurrent(): boolean;
39
+ setGlSwapInterval(interval: number): boolean;
40
+ swapGl(): boolean;
41
+ glVersion(): string;
42
+ on(event: string, listener: (event: Record<string, unknown>) => void): this;
43
+ destroy(): void;
9
44
  }
10
45
 
11
46
  export interface ModalFrameController {
@@ -13,5 +48,16 @@ export interface ModalFrameController {
13
48
  detach(): void;
14
49
  }
15
50
 
51
+ export interface NativeWindowApi {
52
+ createWindow(options: NativeWindowOptions): NativeWindow;
53
+ pollEvents(): void;
54
+ waitForCompositorFrame(timeoutMs?: number): Promise<boolean>;
55
+ createModalFrameController(
56
+ nativeData: Buffer,
57
+ onFrame: () => void,
58
+ onState: (active: boolean) => void,
59
+ ): ModalFrameController;
60
+ }
61
+
16
62
  declare const nativeWindow: NativeWindowApi;
17
63
  export = nativeWindow;
@@ -1,6 +1,8 @@
1
- const Fs = require("fs");
1
+ const { EventEmitter } = require("node:events");
2
+ const Fs = require("node:fs");
2
3
  const { createRequire } = require("node:module");
3
4
  const { getBindingPath } = require("../binding-path.js");
5
+ const { normalizeSdlKeyName } = require("./key-mapping.js");
4
6
 
5
7
  const requireNative = createRequire(__filename);
6
8
  const bindingPath = getBindingPath();
@@ -11,22 +13,89 @@ if (!Fs.existsSync(bindingPath)) {
11
13
  }
12
14
 
13
15
  const binding = requireNative(bindingPath);
16
+ const windows = new Map();
17
+ let waylandPositionWarned = false;
14
18
 
15
- const setTransparent = (nativeData, transparent) => {
16
- binding.setTransparent(nativeData, transparent);
19
+ class NativeWindow extends EventEmitter {
20
+ constructor(options) {
21
+ super();
22
+ this._nativeWindow = new binding.NativeSdlWindow(options);
23
+ windows.set(this._nativeWindow.id, this);
24
+ }
25
+
26
+ get id() { return this._nativeWindow.id; }
27
+ get x() { return this._nativeWindow.x; }
28
+ get y() { return this._nativeWindow.y; }
29
+ get pixelWidth() { return this._nativeWindow.pixelWidth; }
30
+ get pixelHeight() { return this._nativeWindow.pixelHeight; }
31
+ get display() { return { frequency: this._nativeWindow.refreshRate }; }
32
+ get destroyed() { return this._nativeWindow.destroyed; }
33
+ get surface() { return this._nativeWindow.surface; }
34
+ get videoDriver() { return this._nativeWindow.videoDriver; }
35
+ get transparent() { return this._nativeWindow.transparent; }
36
+
37
+ pollEvents() { pollEvents(); }
38
+
39
+ setPosition(x, y) {
40
+ if (this._nativeWindow.setPosition(x, y)) return;
41
+ if (!waylandPositionWarned) {
42
+ waylandPositionWarned = true;
43
+ console.warn(
44
+ "[pixi-native] SDL3 Wayland ignores absolute toplevel window positioning.",
45
+ );
46
+ }
47
+ }
48
+
49
+ minimize() { this._nativeWindow.minimize(); }
50
+ maximize() { this._nativeWindow.maximize(); }
51
+ restore() { this._nativeWindow.restore(); }
52
+ makeGlCurrent() { return this._nativeWindow.makeGlCurrent(); }
53
+ setGlSwapInterval(interval) { return this._nativeWindow.setGlSwapInterval(interval); }
54
+ swapGl() { return this._nativeWindow.swapGl(); }
55
+ glVersion() { return this._nativeWindow.glVersion(); }
56
+
57
+ destroy() {
58
+ if (this.destroyed) return;
59
+ windows.delete(this.id);
60
+ this._nativeWindow.destroy();
61
+ this.removeAllListeners();
62
+ }
63
+ }
64
+
65
+ const emitNativeEvent = (window, event) => {
66
+ const { kind, windowId, superKey, ...payload } = event;
67
+ if (kind === "keyDown" || kind === "keyUp") {
68
+ payload.key = normalizeSdlKeyName(payload.key);
69
+ }
70
+ window.emit(kind, { ...payload, type: kind, super: superKey });
71
+ };
72
+
73
+ const pollEvents = () => {
74
+ for (const event of binding.pollEvents()) {
75
+ if (event.kind === "quit") {
76
+ for (const window of [...windows.values()]) {
77
+ emitNativeEvent(window, { ...event, kind: "close" });
78
+ }
79
+ continue;
80
+ }
81
+ const window = windows.get(event.windowId);
82
+ if (window) emitNativeEvent(window, event);
83
+ }
17
84
  };
18
85
 
86
+ const createWindow = (options) => new NativeWindow(options);
19
87
  const waitForCompositorFrame = (timeoutMs) =>
20
88
  binding.waitForCompositorFrame(timeoutMs);
21
-
22
- const create = (nativeData, onFrame, onState) => {
23
- const controller = new binding.ModalFrameController(
24
- nativeData,
25
- onFrame,
26
- onState,
27
- );
89
+ const createModalFrameController = (nativeData, onFrame, onState) => {
90
+ const controller = new binding.ModalFrameController(nativeData, onFrame, onState);
28
91
  controller.attach();
29
92
  return controller;
30
93
  };
31
94
 
32
- module.exports = { create, setTransparent, waitForCompositorFrame };
95
+ module.exports = {
96
+ NativeWindow,
97
+ createWindow,
98
+ createModalFrameController,
99
+ pollEvents,
100
+ waitForCompositorFrame,
101
+ };
@@ -0,0 +1,32 @@
1
+ const SDL_KEY_NAMES = Object.freeze({
2
+ Up: "up",
3
+ Down: "down",
4
+ Left: "left",
5
+ Right: "right",
6
+ Space: "space",
7
+ Return: "return",
8
+ Escape: "escape",
9
+ Backspace: "backspace",
10
+ Tab: "tab",
11
+ "Left Ctrl": "ctrl",
12
+ "Right Ctrl": "ctrl",
13
+ "Left Shift": "shift",
14
+ "Right Shift": "shift",
15
+ "Left Alt": "alt",
16
+ "Right Alt": "alt",
17
+ "Left GUI": "gui",
18
+ "Right GUI": "gui",
19
+ });
20
+
21
+ /** Preserves the key names exposed by the previous @kmamal/sdl adapter. */
22
+ const normalizeSdlKeyName = (name) => {
23
+ if (typeof name !== "string") return name;
24
+ const mapped = SDL_KEY_NAMES[name];
25
+ if (mapped) return mapped;
26
+ if (/^[A-Z]$/.test(name) || /^F\d{1,2}$/.test(name)) {
27
+ return name.toLowerCase();
28
+ }
29
+ return name;
30
+ };
31
+
32
+ module.exports = { normalizeSdlKeyName };