ntk 7.3.1 → 7.3.3

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/lib/gl.js CHANGED
@@ -32,8 +32,11 @@ import { nodeRequire } from './builtin.js';
32
32
  * - `GL_NO_DRIVER` — the addon loaded but the GPU libraries it needs are
33
33
  * missing (`libgbm`, `libEGL`, `libGLESv2`), or this is not Linux.
34
34
  * - `GL_NO_DEVICE` — no readable DRM render node (`/dev/dri/renderD*`).
35
- * - `GL_REMOTE_DISPLAY` — the connection cannot carry descriptors: a TCP or
36
- * forwarded display, so there is no way to hand the server a buffer.
35
+ * - `GL_REMOTE_DISPLAY` — a TCP or forwarded display, so there is no local
36
+ * socket to hand the server a buffer down.
37
+ * - `GL_NO_FD_PASSING` — the display is local, but this JavaScript runtime
38
+ * cannot send a descriptor over the socket. Bun is the case in the field;
39
+ * x11 does it through a Node internal Bun does not implement.
37
40
  * - `GL_NO_DRI3` — the server has no DRI3/Present (Xvfb, Xephyr, XQuartz).
38
41
  * - `GL_IMPORT_FAILED` — the server refused the buffer; usually client and
39
42
  * server on different DRM devices.
@@ -45,6 +48,7 @@ export const GLError = {
45
48
  NO_DRIVER: 'GL_NO_DRIVER',
46
49
  NO_DEVICE: 'GL_NO_DEVICE',
47
50
  REMOTE_DISPLAY: 'GL_REMOTE_DISPLAY',
51
+ NO_FD_PASSING: 'GL_NO_FD_PASSING',
48
52
  NO_DRI3: 'GL_NO_DRI3',
49
53
  IMPORT_FAILED: 'GL_IMPORT_FAILED',
50
54
  CONTEXT_FAILED: 'GL_CONTEXT_FAILED'
@@ -235,6 +239,14 @@ export function canPassDescriptors(display) {
235
239
 
236
240
  const displayName = () => globalThis.process?.env?.DISPLAY || 'the X server';
237
241
 
242
+ /** What is running this, for an error that is about the runtime. */
243
+ const runtimeName = () => {
244
+ const versions = globalThis.process?.versions;
245
+ if (versions?.bun) return `Bun (${versions.bun})`;
246
+ if (versions?.deno) return `Deno (${versions.deno})`;
247
+ return versions?.node ? `Node (${versions.node})` : 'JavaScript runtime';
248
+ };
249
+
238
250
  const requireExt = (X, name) =>
239
251
  new Promise((resolve) => X.require(name, (err, ext) => resolve(err ? null : ext)));
240
252
 
@@ -266,14 +278,29 @@ export function glCapabilities(app) {
266
278
  if (policy.mode === 'off') {
267
279
  return fail(GLError.DISABLED, "glPolicy is 'off', so no GL context will be created");
268
280
  }
269
- if (!canPassDescriptors(app.display)) {
281
+ if (!app.display.isLocalSocket) {
270
282
  return fail(
271
283
  GLError.REMOTE_DISPLAY,
272
- 'this X connection is not a local socket that can pass descriptors, and DRI3 works by passing one',
284
+ 'this X connection is not a local socket, and DRI3 works by passing a descriptor down one',
273
285
  'Direct rendering is local-only by construction. Over a network, indirect GLX is\n' +
274
286
  'the backend that can work at all — leave glPolicy at its default.'
275
287
  );
276
288
  }
289
+ if (!canPassDescriptors(app.display)) {
290
+ // The socket is local; what is missing is the ability to send a
291
+ // descriptor along it. x11 does that through Node's internal
292
+ // `process.binding('pipe_wrap')`, so a runtime that does not implement
293
+ // it lands here — Bun, today. Saying "not a local socket" would send
294
+ // the reader off to check their DISPLAY, which is fine.
295
+ return fail(
296
+ GLError.NO_FD_PASSING,
297
+ `this ${runtimeName()} cannot pass file descriptors over the X socket, and DRI3 works by passing one`,
298
+ 'The connection is local; the runtime is what cannot carry the descriptor.\n' +
299
+ "x11 sends one through Node's process.binding('pipe_wrap'), which Bun does\n" +
300
+ 'not implement. Run under Node for direct rendering, or leave glPolicy at its\n' +
301
+ 'default and use indirect GLX, which needs no descriptor passing at all.'
302
+ );
303
+ }
277
304
 
278
305
  const client = probeDirect(policy);
279
306
  if (!client.ok) return fail(client.code, client.message, client.hint);
@@ -291,9 +318,10 @@ export function glCapabilities(app) {
291
318
  }
292
319
  if (!DRI3.fdCapable) {
293
320
  return fail(
294
- GLError.REMOTE_DISPLAY,
321
+ GLError.NO_FD_PASSING,
295
322
  'the x11 client cannot send descriptors on this connection (DRI3.fdCapable is false)',
296
- 'x11 builds an fd-capable socket for local displays unless `shm: false` was passed\nto createClient.'
323
+ 'x11 builds an fd-capable socket for local displays unless `shm: false` was passed\n' +
324
+ 'to createClient, and needs a runtime that can pass descriptors — see above.'
297
325
  );
298
326
  }
299
327
 
@@ -2965,15 +2965,21 @@ class RenderingContext2d {
2965
2965
  rect.h,
2966
2966
  ]);
2967
2967
  }
2968
+ // The scratch mask is surface-sized and surface-aligned — the coverage
2969
+ // went into it at (dx, dy) — and so is a gradient source, so both are
2970
+ // sampled at the destination offset. Reading either from (0, 0) draws a
2971
+ // dw x dh window out of the wrong part of a full-surface picture: for
2972
+ // the mask that is the region just cleared to zero, so nothing paints at
2973
+ // all unless dx and dy are both zero.
2968
2974
  R.Composite(
2969
2975
  op,
2970
2976
  this._backgroundPicture.id,
2971
2977
  this.fillMask.id,
2972
2978
  this.picture.id,
2973
- 0,
2974
- 0,
2975
- 0,
2976
- 0,
2979
+ dx,
2980
+ dy,
2981
+ dx,
2982
+ dy,
2977
2983
  dx,
2978
2984
  dy,
2979
2985
  dw,
@@ -2996,13 +3002,16 @@ class RenderingContext2d {
2996
3002
  rect.h,
2997
3003
  ]);
2998
3004
  }
3005
+ // the source is a 1x1 repeating solid (offset irrelevant) or the fill
3006
+ // picture, which for a gradient is surface-aligned: same offset as the
3007
+ // destination, exactly as in _fillPolys
2999
3008
  R.Composite(
3000
3009
  op,
3001
3010
  this._coverageSource().id,
3002
3011
  picture.id,
3003
3012
  this.picture.id,
3004
- 0,
3005
- 0,
3013
+ dx,
3014
+ dy,
3006
3015
  mx,
3007
3016
  my,
3008
3017
  dx,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ntk",
3
- "version": "7.3.1",
3
+ "version": "7.3.3",
4
4
  "description": "Desktop UI toolkit for X11 with canvas-like 2d and OpenGL rendering",
5
5
  "author": "Andrey Sidorov <sidorares@yandex.ru>",
6
6
  "license": "MIT",