ntk 8.1.1 → 8.3.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/lib/app.js +339 -7
- package/lib/drawable.js +10 -0
- package/lib/events_map.js +100 -1
- package/lib/glyphdirectory.js +275 -0
- package/lib/glyphdwire.js +142 -0
- package/lib/glyphset.js +32 -5
- package/lib/index.js +25 -2
- package/lib/pictformat.js +196 -0
- package/lib/pixmap.js +166 -7
- package/lib/region.js +148 -0
- package/lib/renderingcontext_2d.js +830 -235
- package/lib/shapeglyphs.js +94 -26
- package/lib/sharedglyphs.js +433 -0
- package/lib/text/glyphs.js +204 -26
- package/lib/widgets/svgview.js +7 -5
- package/lib/window.js +218 -28
- package/lib/xembed.js +3 -1
- package/package.json +2 -2
package/lib/window.js
CHANGED
|
@@ -332,6 +332,24 @@ function warnHint(key, message) {
|
|
|
332
332
|
console.warn(`ntk: ${message} Further occurrences are not reported.`);
|
|
333
333
|
}
|
|
334
334
|
|
|
335
|
+
/**
|
|
336
|
+
* A GetGeometry reply in ntk's spelling. node-x11 calls the position `xPos`/
|
|
337
|
+
* `yPos` and the reply's root window `windowid`, neither of which is what X
|
|
338
|
+
* calls them; the `root` here is the root of the screen the drawable is on,
|
|
339
|
+
* not this window's parent.
|
|
340
|
+
*/
|
|
341
|
+
function unpackGeometry(res) {
|
|
342
|
+
return {
|
|
343
|
+
x: res.xPos,
|
|
344
|
+
y: res.yPos,
|
|
345
|
+
width: res.width,
|
|
346
|
+
height: res.height,
|
|
347
|
+
depth: res.depth,
|
|
348
|
+
borderWidth: res.borderWidth,
|
|
349
|
+
root: res.windowid
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
335
353
|
/** A Window, a Pixmap, or a bare XID — all of these name a server resource. */
|
|
336
354
|
function resourceId(value) {
|
|
337
355
|
return typeof value === 'number' ? value : (value?.id ?? 0);
|
|
@@ -404,18 +422,37 @@ export default class Window extends Drawable {
|
|
|
404
422
|
// the whole property without dropping what an earlier one set
|
|
405
423
|
this._sizeHints = null;
|
|
406
424
|
this._wmHints = null;
|
|
425
|
+
// `wnd.ready` (see the getter): resolved as soon as this wrapper knows
|
|
426
|
+
// its geometry — at the end of the constructor for a window ntk created,
|
|
427
|
+
// when GetGeometry replies for one adopted by id
|
|
407
428
|
this._readyPromiseResolve = null;
|
|
408
429
|
this._readyPromise = new Promise((resolve) => {
|
|
409
430
|
this._readyPromiseResolve = resolve;
|
|
410
431
|
});
|
|
432
|
+
// constructor round trips still outstanding, for an adopted window
|
|
433
|
+
this._readyPending = 0;
|
|
411
434
|
|
|
412
435
|
const parentId = args.parent ? args.parent.id : app.display.screen[0].root;
|
|
413
436
|
|
|
414
437
|
// double buffering (see docs/window.md): windows we created get a
|
|
415
438
|
// backing pixmap when a 2d context is requested, unless opted out
|
|
416
439
|
this._foreign = !!args.id;
|
|
440
|
+
// Adopting a window is not the same as "another client paints these
|
|
441
|
+
// pixels", though it is the safe default reading of one. The Composite
|
|
442
|
+
// overlay window and a window handed over by an embedding host (XEmbed's
|
|
443
|
+
// plug side, an `--wid` handoff) are ours completely — they are foreign
|
|
444
|
+
// only in the sense that `createWindow` did not make them, and they are
|
|
445
|
+
// exactly the windows that most want an unflickering double buffer and a
|
|
446
|
+
// vblank-paced blit. Saying so is `{ id, backingStore: true }` or
|
|
447
|
+
// `{ id, present: true }`; from there such a window behaves like any
|
|
448
|
+
// other window ntk owns (issue #294).
|
|
449
|
+
this._ownsPixels = !this._foreign || args.backingStore === true || args.present === true;
|
|
417
450
|
this._backingOptOut = args.backingStore === false;
|
|
418
451
|
this._backing = null;
|
|
452
|
+
// an adopted window has no geometry, depth or visual to build a backing
|
|
453
|
+
// pixmap from until its constructor's questions reply — see
|
|
454
|
+
// _enableBackingStoreWhenReady
|
|
455
|
+
this._backingScheduled = false;
|
|
419
456
|
// What the backing store clears to, and the window attribute it mirrors.
|
|
420
457
|
// Undefined means "nothing was asked for" — see _clearColour.
|
|
421
458
|
this._clearPixel = args.backgroundPixel;
|
|
@@ -528,11 +565,19 @@ export default class Window extends Drawable {
|
|
|
528
565
|
for (const name of forwardedXAttributes) {
|
|
529
566
|
if (args[name] !== undefined) values[name] = args[name];
|
|
530
567
|
}
|
|
568
|
+
// what setCursor compares against, so setting the cursor a window was
|
|
569
|
+
// created with is free rather than a redundant round trip
|
|
570
|
+
this._currentCursor = values.cursor;
|
|
531
571
|
// a window on a non-default visual (GLX, ARGB) also needs its own
|
|
532
572
|
// colormap and an explicit border pixel: inheriting either from a
|
|
533
573
|
// parent of a different depth is a BadMatch (X11 CreateWindow)
|
|
534
574
|
this.visual = args.visual ?? 0;
|
|
535
575
|
this.depth = args.depth ?? 0;
|
|
576
|
+
// `visual` is the CreateWindow argument, where 0 means CopyFromParent;
|
|
577
|
+
// `visualId` is the visual the pixels are actually in, which is what a
|
|
578
|
+
// picture format is picked from (issue #295). CopyFromParent is only
|
|
579
|
+
// ever the parent's, and the default parent is the root.
|
|
580
|
+
this.visualId = this.visual || args.parent?.visualId || app.display.screen[0].root_visual;
|
|
536
581
|
if (this.visual) {
|
|
537
582
|
if (values.colormap === undefined) {
|
|
538
583
|
this._ownedColormap = app.createColormap(this.visual);
|
|
@@ -549,23 +594,33 @@ export default class Window extends Drawable {
|
|
|
549
594
|
this.id = args.id;
|
|
550
595
|
this.eventMask = 0;
|
|
551
596
|
this.visual = 0;
|
|
597
|
+
// nothing is known about another client's window until it answers
|
|
598
|
+
this.visualId = 0;
|
|
552
599
|
this.depth = 0;
|
|
553
600
|
// an adopted window's geometry is not known until GetGeometry replies
|
|
554
601
|
this._deliveredGeom = null;
|
|
555
|
-
//
|
|
602
|
+
// Two questions, because a drawable's pixels take both to describe:
|
|
603
|
+
// GetGeometry for width, height and depth, GetWindowAttributes for the
|
|
604
|
+
// visual — depth alone does not name a picture format, and the windows
|
|
605
|
+
// whose format was picked wrongest are exactly these, the ones another
|
|
606
|
+
// client chose the visual for (issue #295). They go out in the same
|
|
607
|
+
// batch, so the pair costs one round trip, not two, and `ready` is the
|
|
608
|
+
// wait for both.
|
|
609
|
+
this._readyPending = 2;
|
|
556
610
|
X.GetGeometry(this.id, (err, res) => {
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
this.
|
|
611
|
+
// A window that was destroyed between the id reaching us and this
|
|
612
|
+
// request reaching the server answers BadWindow, and there is
|
|
613
|
+
// nothing to record. `ready` still resolves: adopting a window that
|
|
614
|
+
// has since gone is ordinary for a window manager, and a wait that
|
|
615
|
+
// never ends is worse than one that ends with width undefined.
|
|
616
|
+
this._readyPending--;
|
|
617
|
+
if (err) this._settleReady();
|
|
618
|
+
else this._applyGeometry(unpackGeometry(res));
|
|
619
|
+
});
|
|
620
|
+
X.GetWindowAttributes(this.id, (err, attrs) => {
|
|
621
|
+
this._readyPending--;
|
|
622
|
+
if (!err) this.visualId = attrs.visual;
|
|
623
|
+
this._settleReady();
|
|
569
624
|
});
|
|
570
625
|
}
|
|
571
626
|
|
|
@@ -630,11 +685,21 @@ export default class Window extends Drawable {
|
|
|
630
685
|
// region and an event selection it never uses. `present: true` is still
|
|
631
686
|
// honoured eagerly, for a caller who wants it up before the first paint.
|
|
632
687
|
this._presentOptOut = args.present === false;
|
|
633
|
-
if (args.present
|
|
688
|
+
if (args.present === true) {
|
|
634
689
|
// fire and forget: until the extensions answer, blits use CopyArea,
|
|
635
|
-
// which is what they would have done anyway
|
|
690
|
+
// which is what they would have done anyway. Present needs nothing of
|
|
691
|
+
// the window but its id, so an adopted one can have it up before its
|
|
692
|
+
// geometry has even replied.
|
|
636
693
|
this.enablePresent().catch((err) => this.app.options?.onXError?.(err));
|
|
637
694
|
}
|
|
695
|
+
// A window adopted with ownership declared starts its backing store now
|
|
696
|
+
// rather than waiting for the first getContext('2d'): the allocation
|
|
697
|
+
// needs the constructor's replies anyway, so starting it here means it
|
|
698
|
+
// is normally already there by the time the caller's `await wnd.ready`
|
|
699
|
+
// returns and it draws.
|
|
700
|
+
if (this._foreign && this._ownsPixels && !this._backingOptOut) {
|
|
701
|
+
this._enableBackingStoreWhenReady();
|
|
702
|
+
}
|
|
638
703
|
|
|
639
704
|
X.event_consumers[this.id] = this;
|
|
640
705
|
this.on('event', (ev) => {
|
|
@@ -717,7 +782,7 @@ export default class Window extends Drawable {
|
|
|
717
782
|
const child = new Window(app, { id: ev.wid });
|
|
718
783
|
const ntkev = { ...ev, parent: this, window: child, target: child };
|
|
719
784
|
// wait until we know that we track correct x,y,w,h values
|
|
720
|
-
child.
|
|
785
|
+
child.ready.then(() => {
|
|
721
786
|
this.emit(eventName, ntkev);
|
|
722
787
|
});
|
|
723
788
|
});
|
|
@@ -773,10 +838,82 @@ export default class Window extends Drawable {
|
|
|
773
838
|
});
|
|
774
839
|
|
|
775
840
|
if (typeof this.width !== 'undefined') {
|
|
776
|
-
this.
|
|
841
|
+
this._settleReady();
|
|
777
842
|
}
|
|
778
843
|
}
|
|
779
844
|
|
|
845
|
+
/**
|
|
846
|
+
* Resolves with this window once its geometry is known — immediately for a
|
|
847
|
+
* window ntk created (it already knows what it asked for), when the
|
|
848
|
+
* GetGeometry sent by the constructor replies for one adopted by id.
|
|
849
|
+
*
|
|
850
|
+
* Adoption is the case that needs it: until the reply lands, `width`,
|
|
851
|
+
* `height`, `x` and `y` are `undefined` and `depth` is `0`, so anything
|
|
852
|
+
* that picks a pixel format from the depth — `getContext('2d')`,
|
|
853
|
+
* `createPattern` — would pick the wrong one. Awaiting is safe
|
|
854
|
+
* unconditionally, so code that takes windows from either source need not
|
|
855
|
+
* ask which it has:
|
|
856
|
+
*
|
|
857
|
+
* const wnd = new Window(app, { id: ev.wid });
|
|
858
|
+
* await wnd.ready;
|
|
859
|
+
* const ctx = wnd.getContext('2d');
|
|
860
|
+
*
|
|
861
|
+
* The promise never rejects. A window destroyed before the reply arrives
|
|
862
|
+
* resolves all the same, with `width` still `undefined` — the request that
|
|
863
|
+
* hits the gone window is the one that reports it.
|
|
864
|
+
*/
|
|
865
|
+
get ready() {
|
|
866
|
+
return this._readyPromise;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* Ask the server where this window is now — `{ x, y, width, height, depth,
|
|
871
|
+
* borderWidth, root }`, with `x`/`y` relative to the parent, as X reports
|
|
872
|
+
* them.
|
|
873
|
+
*
|
|
874
|
+
* `wnd.x`/`y`/`width`/`height`/`depth` are kept current from the event
|
|
875
|
+
* stream and are the cheap answer; this is the round trip for the cases
|
|
876
|
+
* the events cannot cover — a window nobody selected StructureNotify on, a
|
|
877
|
+
* window ntk created with the default `depth: 0` (CopyFromParent, whose
|
|
878
|
+
* real depth only the server knows), or simply the state at a point in
|
|
879
|
+
* time. The reply is written back to those properties, and resolves
|
|
880
|
+
* `ready` if it was still pending.
|
|
881
|
+
*/
|
|
882
|
+
getGeometry() {
|
|
883
|
+
return new Promise((resolve, reject) => {
|
|
884
|
+
this.X.GetGeometry(this.id, (err, res) => {
|
|
885
|
+
if (err) return reject(err);
|
|
886
|
+
const geometry = unpackGeometry(res);
|
|
887
|
+
this._applyGeometry(geometry);
|
|
888
|
+
resolve(geometry);
|
|
889
|
+
});
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
/** Record a GetGeometry reply, and let anything waiting on it go. */
|
|
894
|
+
_applyGeometry({ x, y, width, height, depth }) {
|
|
895
|
+
this.x = x;
|
|
896
|
+
this.y = y;
|
|
897
|
+
this.width = width;
|
|
898
|
+
this.height = height;
|
|
899
|
+
this.depth = depth;
|
|
900
|
+
// Only where nothing is known yet: on an adopted window a 'resize'
|
|
901
|
+
// reports both moved and resized until there is a baseline to compare
|
|
902
|
+
// against (see _tagResize), and the event stream may already have set
|
|
903
|
+
// one — that is the delivered geometry, and this reply is not.
|
|
904
|
+
this._deliveredGeom ??= { x, y, width, height };
|
|
905
|
+
this._settleReady();
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
/**
|
|
909
|
+
* Let anything waiting on `ready` go, once the questions the constructor
|
|
910
|
+
* asked have all been answered. A window ntk created asked none.
|
|
911
|
+
*/
|
|
912
|
+
_settleReady() {
|
|
913
|
+
if (this._readyPending > 0) return;
|
|
914
|
+
this._readyPromiseResolve(this);
|
|
915
|
+
}
|
|
916
|
+
|
|
780
917
|
_forget() {
|
|
781
918
|
Window._cacheFor(this.app).delete(this.id);
|
|
782
919
|
delete this.X.event_consumers[this.id];
|
|
@@ -790,14 +927,43 @@ export default class Window extends Drawable {
|
|
|
790
927
|
* an 'expose' (and 'draw') event is emitted only when a real redraw is
|
|
791
928
|
* needed (first paint, resize). Opt out with
|
|
792
929
|
* `createWindow({ backingStore: false })`.
|
|
930
|
+
*
|
|
931
|
+
* A window adopted by id is left alone by default — another client's
|
|
932
|
+
* pixels are not ntk's to buffer — and opts in with
|
|
933
|
+
* `createWindow({ id, backingStore: true })` (see `_ownsPixels`).
|
|
793
934
|
*/
|
|
794
935
|
getContext(name, ...args) {
|
|
795
|
-
if (name === '2d' && !this._backing && !this._backingOptOut &&
|
|
796
|
-
this.
|
|
936
|
+
if (name === '2d' && !this._backing && !this._backingOptOut && this._ownsPixels) {
|
|
937
|
+
if (this._foreign) this._enableBackingStoreWhenReady();
|
|
938
|
+
else this._enableBackingStore();
|
|
797
939
|
}
|
|
798
940
|
return super.getContext(name, ...args);
|
|
799
941
|
}
|
|
800
942
|
|
|
943
|
+
/**
|
|
944
|
+
* The backing store for an adopted window, once there is something to build
|
|
945
|
+
* it out of.
|
|
946
|
+
*
|
|
947
|
+
* A pixmap needs a width, a height, a depth and a visual, and an adopted
|
|
948
|
+
* window knows none of them until `GetGeometry` and `GetWindowAttributes`
|
|
949
|
+
* reply — so the allocation waits on `ready`. A 2d context taken in the
|
|
950
|
+
* meantime draws straight to the window and re-binds itself to the pixmap
|
|
951
|
+
* when it appears (the `_backing` event), which is the same path a resize
|
|
952
|
+
* reallocation takes.
|
|
953
|
+
*/
|
|
954
|
+
_enableBackingStoreWhenReady() {
|
|
955
|
+
if (this._backingScheduled) return;
|
|
956
|
+
this._backingScheduled = true;
|
|
957
|
+
this.ready.then(() => {
|
|
958
|
+
// A window destroyed before the replies arrived still settles `ready`,
|
|
959
|
+
// with its geometry never filled in — there is no pixmap to make for
|
|
960
|
+
// one, and CreatePixmap with an undefined size is not the way to find
|
|
961
|
+
// that out.
|
|
962
|
+
if (this._destroyed || this._backing || !this.width || !this.height) return;
|
|
963
|
+
this._enableBackingStore();
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
|
|
801
967
|
_enableBackingStore() {
|
|
802
968
|
this._dirty = false;
|
|
803
969
|
this._backingValid = false;
|
|
@@ -805,7 +971,7 @@ export default class Window extends Drawable {
|
|
|
805
971
|
// Now there is a pixmap to present. Inert where the extensions are
|
|
806
972
|
// missing, so this costs a window on such a server two extension queries
|
|
807
973
|
// that node-x11 answers from its cache after the first.
|
|
808
|
-
if (!this._presentOptOut &&
|
|
974
|
+
if (!this._presentOptOut && this._ownsPixels) {
|
|
809
975
|
this.enablePresent().catch((err) => this.app.options?.onXError?.(err));
|
|
810
976
|
}
|
|
811
977
|
|
|
@@ -817,7 +983,8 @@ export default class Window extends Drawable {
|
|
|
817
983
|
// server sends them even if user code only listens to 'draw'
|
|
818
984
|
if (!(this.eventMask & x11.eventMask.Exposure)) {
|
|
819
985
|
this.eventMask |= x11.eventMask.Exposure;
|
|
820
|
-
|
|
986
|
+
// no callback: it would only buy node-x11's void-sync round trip, see setCursor
|
|
987
|
+
this.X.ChangeWindowAttributes(this.id, { eventMask: this.eventMask });
|
|
821
988
|
}
|
|
822
989
|
|
|
823
990
|
// a pure move is a ConfigureNotify too, and reallocating a backing
|
|
@@ -863,8 +1030,11 @@ export default class Window extends Drawable {
|
|
|
863
1030
|
this._clearPixel = pixel;
|
|
864
1031
|
if (this._destroyed) return this;
|
|
865
1032
|
if (this._clearGc) this.X.ChangeGC(this._clearGc, { foreground: pixel });
|
|
866
|
-
|
|
867
|
-
|
|
1033
|
+
// The window attribute half is only ours to write on a window whose
|
|
1034
|
+
// pixels are ours — an adopted one has to have said so (see _ownsPixels).
|
|
1035
|
+
if (this._ownsPixels) {
|
|
1036
|
+
// no callback: it would only buy node-x11's void-sync round trip, see setCursor
|
|
1037
|
+
this.X.ChangeWindowAttributes(this.id, { backgroundPixel: pixel });
|
|
868
1038
|
}
|
|
869
1039
|
const backing = this._backing;
|
|
870
1040
|
if (backing && this._clearGc) {
|
|
@@ -896,7 +1066,10 @@ export default class Window extends Drawable {
|
|
|
896
1066
|
parent: this,
|
|
897
1067
|
width: newW,
|
|
898
1068
|
height: newH,
|
|
899
|
-
depth
|
|
1069
|
+
depth,
|
|
1070
|
+
// it holds this window's pixels, so it is read through this window's
|
|
1071
|
+
// visual — a pixmap has none of its own (issue #295)
|
|
1072
|
+
visual: this.visualId
|
|
900
1073
|
});
|
|
901
1074
|
if (!this._clearGc) {
|
|
902
1075
|
this._clearGc = this.X.AllocID();
|
|
@@ -2997,9 +3170,19 @@ export default class Window extends Drawable {
|
|
|
2997
3170
|
* pointer stays visible
|
|
2998
3171
|
*/
|
|
2999
3172
|
setCursor(nameOrShape) {
|
|
3173
|
+
// resolved first: an unknown name has to throw whether or not the memo
|
|
3174
|
+
// below short-circuits the request
|
|
3000
3175
|
const cursor = nameOrShape == null ? 0 : this.app.cursors.get(nameOrShape);
|
|
3176
|
+
if (cursor === this._currentCursor) return this;
|
|
3177
|
+
this._currentCursor = cursor;
|
|
3001
3178
|
safeRelease(this.X, () => {
|
|
3002
|
-
|
|
3179
|
+
// no callback, deliberately: node-x11 guarantees a callback on a *void*
|
|
3180
|
+
// request eventually fires, and buys that by injecting a GetInputFocus
|
|
3181
|
+
// round trip when nothing else in the tick expects a reply (node-x11
|
|
3182
|
+
// issue #85). A callback that ignores its argument costs that round trip
|
|
3183
|
+
// per cursor change and buys nothing — an X error reaches
|
|
3184
|
+
// `client.emit('error')`, and so app's onXError hook, either way.
|
|
3185
|
+
this.X.ChangeWindowAttributes(this.id, { cursor });
|
|
3003
3186
|
});
|
|
3004
3187
|
return this;
|
|
3005
3188
|
}
|
|
@@ -3012,7 +3195,8 @@ export default class Window extends Drawable {
|
|
|
3012
3195
|
} else {
|
|
3013
3196
|
return this;
|
|
3014
3197
|
}
|
|
3015
|
-
|
|
3198
|
+
// no callback: it would only buy node-x11's void-sync round trip, see setCursor
|
|
3199
|
+
this.X.ChangeWindowAttributes(this.id, { eventMask: this.eventMask });
|
|
3016
3200
|
return this;
|
|
3017
3201
|
}
|
|
3018
3202
|
|
|
@@ -3307,7 +3491,13 @@ export default class Window extends Drawable {
|
|
|
3307
3491
|
getAttributes() {
|
|
3308
3492
|
return new Promise((resolve, reject) => {
|
|
3309
3493
|
safeRelease(this.X, () =>
|
|
3310
|
-
this.X.GetWindowAttributes(this.id, (err, attrs) =>
|
|
3494
|
+
this.X.GetWindowAttributes(this.id, (err, attrs) => {
|
|
3495
|
+
if (err) return reject(err);
|
|
3496
|
+
// the visual names the picture format (see `visualId`), and this
|
|
3497
|
+
// reply is the only place the server ever states it
|
|
3498
|
+
this.visualId = attrs.visual;
|
|
3499
|
+
resolve(attrs);
|
|
3500
|
+
})
|
|
3311
3501
|
);
|
|
3312
3502
|
});
|
|
3313
3503
|
}
|
|
@@ -3515,7 +3705,7 @@ export default class Window extends Drawable {
|
|
|
3515
3705
|
// there can be multiple screens (and roots)
|
|
3516
3706
|
const root = new Window(app, { id: tree.root });
|
|
3517
3707
|
const wrappers = [...children, root, ...(parent ? [parent] : [])];
|
|
3518
|
-
Promise.all(wrappers.map((w) => w.
|
|
3708
|
+
Promise.all(wrappers.map((w) => w.ready)).then(() => {
|
|
3519
3709
|
callback(null, { parent, root, children });
|
|
3520
3710
|
});
|
|
3521
3711
|
});
|
package/lib/xembed.js
CHANGED
|
@@ -559,7 +559,9 @@ export class XEmbedSocket extends EventEmitter {
|
|
|
559
559
|
// reparent, so its ReparentNotify does not come back to us
|
|
560
560
|
safeRelease(this.X, () => {
|
|
561
561
|
client.eventMask = 0;
|
|
562
|
-
|
|
562
|
+
// no callback: it would only buy node-x11's void-sync round trip, see
|
|
563
|
+
// Window#setCursor
|
|
564
|
+
this.X.ChangeWindowAttributes(client.id, { eventMask: 0 });
|
|
563
565
|
});
|
|
564
566
|
client.reparentTo(this.app.rootWindow(), x, y);
|
|
565
567
|
client.removeFromSaveSet();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ntk",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.3.0",
|
|
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",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"linebreak": "^1.1.0",
|
|
45
45
|
"parse-color": "^1.0.0",
|
|
46
46
|
"pngjs": "^7.0.0",
|
|
47
|
-
"x11": "^
|
|
47
|
+
"x11": "^4.0.1"
|
|
48
48
|
},
|
|
49
49
|
"optionalDependencies": {
|
|
50
50
|
"x11-dri": ">=0.2.0 <1"
|