ntk 6.1.0 → 6.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.
- package/lib/widgets/htmlview.js +4 -2
- package/lib/widgets/markdownview.js +4 -2
- package/lib/window.js +56 -5
- package/package.json +1 -1
package/lib/widgets/htmlview.js
CHANGED
|
@@ -105,8 +105,10 @@ export default class HtmlView {
|
|
|
105
105
|
if (this.window) {
|
|
106
106
|
this._ctx = this.window.getContext('2d');
|
|
107
107
|
this.window.on('expose', () => this.render());
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
// a move is a ConfigureNotify too; re-laying out a document per step
|
|
109
|
+
// of a window drag is exactly what ev.resized is for
|
|
110
|
+
this.window.on('resize', (ev) => {
|
|
111
|
+
if (ev.resized) this._layoutWidth = -1;
|
|
110
112
|
});
|
|
111
113
|
this.window.on('mousedown', (ev) => {
|
|
112
114
|
if (ev.keycode === 4 || ev.keycode === 5) {
|
|
@@ -74,8 +74,10 @@ export default class MarkdownView {
|
|
|
74
74
|
if (this.window) {
|
|
75
75
|
this._ctx = this.window.getContext('2d');
|
|
76
76
|
this.window.on('expose', () => this.render());
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
// a move is a ConfigureNotify too; re-laying out a document per step
|
|
78
|
+
// of a window drag is exactly what ev.resized is for
|
|
79
|
+
this.window.on('resize', (ev) => {
|
|
80
|
+
if (ev.resized) this._layoutWidth = -1; // invalidate
|
|
79
81
|
});
|
|
80
82
|
this.window.on('mousedown', (ev) => {
|
|
81
83
|
if (ev.keycode !== 1 || !this.onLink) return; // left button only
|
package/lib/window.js
CHANGED
|
@@ -386,6 +386,10 @@ export default class Window extends Drawable {
|
|
|
386
386
|
this.height = args.height ?? 800;
|
|
387
387
|
this.x = args.x ?? 0;
|
|
388
388
|
this.y = args.y ?? 0;
|
|
389
|
+
// the baseline 'resize' compares against (see _tagResize): what the
|
|
390
|
+
// window was asked to be, so the window manager's first ConfigureNotify
|
|
391
|
+
// reports only what it actually overrode
|
|
392
|
+
this._deliveredGeom = { x: this.x, y: this.y, width: this.width, height: this.height };
|
|
389
393
|
const values = {
|
|
390
394
|
// NorthWest bit gravity: keep the old content anchored during
|
|
391
395
|
// resize instead of discarding it (less flicker between the resize
|
|
@@ -419,6 +423,8 @@ export default class Window extends Drawable {
|
|
|
419
423
|
this.eventMask = 0;
|
|
420
424
|
this.visual = 0;
|
|
421
425
|
this.depth = 0;
|
|
426
|
+
// an adopted window's geometry is not known until GetGeometry replies
|
|
427
|
+
this._deliveredGeom = null;
|
|
422
428
|
// populate width and height
|
|
423
429
|
X.GetGeometry(this.id, (err, res) => {
|
|
424
430
|
if (!err) {
|
|
@@ -427,6 +433,10 @@ export default class Window extends Drawable {
|
|
|
427
433
|
this.x = res.xPos;
|
|
428
434
|
this.y = res.yPos;
|
|
429
435
|
this.depth = res.depth;
|
|
436
|
+
// nothing was known about this window until now, so until this
|
|
437
|
+
// reply lands a 'resize' reports both moved and resized (see
|
|
438
|
+
// _tagResize) rather than guessing
|
|
439
|
+
this._deliveredGeom ??= { x: this.x, y: this.y, width: this.width, height: this.height };
|
|
430
440
|
}
|
|
431
441
|
this._readyPromiseResolve();
|
|
432
442
|
});
|
|
@@ -523,6 +533,7 @@ export default class Window extends Drawable {
|
|
|
523
533
|
// deliver buffered state events before a discrete one so handlers see
|
|
524
534
|
// them in the order they happened (a drag sees the move, then the up)
|
|
525
535
|
this._flushCoalesced();
|
|
536
|
+
if (eventName === 'resize') this._tagResize(ntkev);
|
|
526
537
|
this.emit(eventName, ntkev);
|
|
527
538
|
// a WM_DELETE_WINDOW ClientMessage is the window manager *asking*, and
|
|
528
539
|
// 'close' is that question in a form an application can answer
|
|
@@ -628,8 +639,6 @@ export default class Window extends Drawable {
|
|
|
628
639
|
this._dirty = false;
|
|
629
640
|
this._backingValid = false;
|
|
630
641
|
this._presentScheduled = false;
|
|
631
|
-
this._backedW = this.width;
|
|
632
|
-
this._backedH = this.height;
|
|
633
642
|
|
|
634
643
|
this._presentGc = this.X.AllocID();
|
|
635
644
|
this.X.CreateGC(this._presentGc, this.id, { graphicsExposures: 0 });
|
|
@@ -642,10 +651,11 @@ export default class Window extends Drawable {
|
|
|
642
651
|
this.X.ChangeWindowAttributes(this.id, { eventMask: this.eventMask }, () => {});
|
|
643
652
|
}
|
|
644
653
|
|
|
654
|
+
// a pure move is a ConfigureNotify too, and reallocating a backing
|
|
655
|
+
// pixmap per step of a window drag is the bug this flag exists to spare
|
|
656
|
+
// everyone (see _tagResize)
|
|
645
657
|
this.on('resize', (ev) => {
|
|
646
|
-
if (ev.
|
|
647
|
-
this._backedW = ev.width;
|
|
648
|
-
this._backedH = ev.height;
|
|
658
|
+
if (!ev.resized) return;
|
|
649
659
|
this._allocBacking(ev.width, ev.height);
|
|
650
660
|
this._backingValid = false;
|
|
651
661
|
this._requestRedraw();
|
|
@@ -875,6 +885,46 @@ export default class Window extends Drawable {
|
|
|
875
885
|
this._scheduleFrame();
|
|
876
886
|
}
|
|
877
887
|
|
|
888
|
+
/**
|
|
889
|
+
* Say what a 'resize' actually changed.
|
|
890
|
+
*
|
|
891
|
+
* 'resize' is ConfigureNotify, which fires for pure moves and for
|
|
892
|
+
* reparents as much as for size changes — under an opaque-move window
|
|
893
|
+
* manager a window drag is one per pointer step. Every consumer used to
|
|
894
|
+
* rediscover that by keeping its own copy of the last size (this library
|
|
895
|
+
* included, in the backing-store listener), and one that didn't paid a
|
|
896
|
+
* full relayout per step of a drag.
|
|
897
|
+
*
|
|
898
|
+
* So the delivered event says which it was:
|
|
899
|
+
*
|
|
900
|
+
* - `ev.resized` — the size differs from the last delivered event's
|
|
901
|
+
* - `ev.moved` — the position does
|
|
902
|
+
* - `ev.previous` — that event's `{x, y, width, height}`, for a delta;
|
|
903
|
+
* null on an adopted window whose geometry is not known yet, where
|
|
904
|
+
* both flags read true because nothing can be ruled out
|
|
905
|
+
*
|
|
906
|
+
* Measured against the last *delivered* event, not the last raw one, so
|
|
907
|
+
* that coalescing cannot swallow a change: a frame that merges two moves
|
|
908
|
+
* and a resize reports both, where per-hop flags would report only the
|
|
909
|
+
* final hop. The merged raw events in `ev.coalesced` are not tagged for
|
|
910
|
+
* that reason — the flags are a property of the delivery.
|
|
911
|
+
*
|
|
912
|
+
* Position is compared as reported. A reparenting window manager sends
|
|
913
|
+
* real ConfigureNotify in frame coordinates and synthetic ones in root
|
|
914
|
+
* coordinates (ICCCM 4.2.3), so a frame's own offset can read as a move
|
|
915
|
+
* on the first event after the switch. That is the safe direction —
|
|
916
|
+
* spurious work, never missed work — and the alternative is a
|
|
917
|
+
* TranslateCoordinates round trip per event, which is the cost this flag
|
|
918
|
+
* exists to avoid.
|
|
919
|
+
*/
|
|
920
|
+
_tagResize(ev) {
|
|
921
|
+
const prev = this._deliveredGeom;
|
|
922
|
+
ev.previous = prev;
|
|
923
|
+
ev.moved = !prev || ev.x !== prev.x || ev.y !== prev.y;
|
|
924
|
+
ev.resized = !prev || ev.width !== prev.width || ev.height !== prev.height;
|
|
925
|
+
this._deliveredGeom = { x: ev.x, y: ev.y, width: ev.width, height: ev.height };
|
|
926
|
+
}
|
|
927
|
+
|
|
878
928
|
_flushCoalesced() {
|
|
879
929
|
const pending = this._frame.pending;
|
|
880
930
|
if (!pending.size) return;
|
|
@@ -884,6 +934,7 @@ export default class Window extends Drawable {
|
|
|
884
934
|
const ev = pending.get(name);
|
|
885
935
|
if (ev) {
|
|
886
936
|
pending.delete(name);
|
|
937
|
+
if (name === 'resize') this._tagResize(ev);
|
|
887
938
|
this.emit(name, ev);
|
|
888
939
|
}
|
|
889
940
|
}
|