react-x11 2.55.0 → 2.55.1
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/docs/elements.md +8 -6
- package/package.json +1 -1
- package/src/cocoa/app.js +11 -0
- package/src/cocoa/overlay.js +16 -1
- package/src/gloverlay.js +57 -25
- package/src/nodes/paint.js +4 -3
package/docs/elements.md
CHANGED
|
@@ -1948,9 +1948,10 @@ frame.
|
|
|
1948
1948
|
</glarea>
|
|
1949
1949
|
```
|
|
1950
1950
|
|
|
1951
|
-
- **Cocoa**: one transparent layer
|
|
1951
|
+
- **Cocoa**: one transparent layer per child, as big as the child,
|
|
1952
|
+
stacked above the surface in the children's order and composited by
|
|
1952
1953
|
Core Animation — a translucent fill, antialiased edge or shadow blends
|
|
1953
|
-
with the GL frame.
|
|
1954
|
+
with the GL frame and with the children under it.
|
|
1954
1955
|
- **X11**: one child window per child, stacked above the surface in the
|
|
1955
1956
|
children's order and cut (SHAPE) to where the child painted half its
|
|
1956
1957
|
alpha or more; the GL frame shows everywhere else. A translucent pixel
|
|
@@ -1959,10 +1960,11 @@ frame.
|
|
|
1959
1960
|
(`react-x11/test`'s server) a pane is the child's whole rectangle,
|
|
1960
1961
|
`clearColor` where unpainted.
|
|
1961
1962
|
|
|
1962
|
-
A child that only moves (its `left` or `top`)
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1963
|
+
A child that only moves (its `left` or `top`) is not repainted — on Cocoa
|
|
1964
|
+
its layer moves, and on X11 its pixels are copied and only uncovered strips
|
|
1965
|
+
are drawn; panes it passes over are untouched either way — so content
|
|
1966
|
+
panned over a scene is cheap; scroll panes among the children scroll the
|
|
1967
|
+
same way.
|
|
1966
1968
|
[`REACT_X11_NO_SCROLL_BLIT=1`](debugging.md#react_x11_no_scroll_blit1)
|
|
1967
1969
|
turns the copies off.
|
|
1968
1970
|
|
package/package.json
CHANGED
package/src/cocoa/app.js
CHANGED
|
@@ -508,6 +508,17 @@ export class CocoaApp {
|
|
|
508
508
|
return new CocoaOverlayPane(this, attributes);
|
|
509
509
|
}
|
|
510
510
|
|
|
511
|
+
/**
|
|
512
|
+
* That a `<glarea>`'s children each take a pane of their own here, as on
|
|
513
|
+
* X11, rather than one pane over the whole surface: Core Animation stacks
|
|
514
|
+
* the layers (`CocoaOverlayPane.stackAt`), and each is only as big as its
|
|
515
|
+
* child, so a minimap's viewport moving pushes the minimap's pixels and
|
|
516
|
+
* not the surface's (src/gloverlay.js).
|
|
517
|
+
*/
|
|
518
|
+
get overlaysPerChild() {
|
|
519
|
+
return true;
|
|
520
|
+
}
|
|
521
|
+
|
|
511
522
|
/**
|
|
512
523
|
* The Frame host seam (src/frame/index.js): a pane's composited region
|
|
513
524
|
* in this window. Its presence is what routes <Frame> to the shared-
|
package/src/cocoa/overlay.js
CHANGED
|
@@ -19,6 +19,10 @@ import { BackendContext2D } from '../backend/context2d.js';
|
|
|
19
19
|
import { withoutActions } from './quiet.js';
|
|
20
20
|
|
|
21
21
|
export const OVERLAY_Z = 1e7 + 1;
|
|
22
|
+
/** How far above the last each pane of a surface is stacked (`stackAt`): a
|
|
23
|
+
* thousand of them stay under the next whole number, so above every GL
|
|
24
|
+
* layer and every surface's panes above every GL frame, as before. */
|
|
25
|
+
const OVERLAY_STEP = 1 / 1024;
|
|
22
26
|
|
|
23
27
|
export class CocoaOverlayPane {
|
|
24
28
|
constructor(app, options) {
|
|
@@ -43,6 +47,8 @@ export class CocoaOverlayPane {
|
|
|
43
47
|
// show, only whatever the render server makes of that.
|
|
44
48
|
this._presented = false;
|
|
45
49
|
this._hidden = false;
|
|
50
|
+
// where it is among its surface's panes, a child each (`stackAt`)
|
|
51
|
+
this._z = OVERLAY_Z;
|
|
46
52
|
this.setState({
|
|
47
53
|
x: options.x ?? 0,
|
|
48
54
|
y: options.y ?? 0,
|
|
@@ -66,11 +72,20 @@ export class CocoaOverlayPane {
|
|
|
66
72
|
const s = this.scale;
|
|
67
73
|
this._setLayerProps({
|
|
68
74
|
frame: [rect.x / s, rect.y / s, rect.width / s, rect.height / s],
|
|
69
|
-
zPosition:
|
|
75
|
+
zPosition: this._z,
|
|
70
76
|
hidden: this._hidden || !this._presented,
|
|
71
77
|
});
|
|
72
78
|
}
|
|
73
79
|
|
|
80
|
+
/** Stacked `index` panes up from the bottom of its surface's — one a
|
|
81
|
+
* child, in the children's order (src/gloverlay.js, `restack`). */
|
|
82
|
+
stackAt(index) {
|
|
83
|
+
const z = OVERLAY_Z + Math.min(index, 1023) * OVERLAY_STEP;
|
|
84
|
+
if (z === this._z) return;
|
|
85
|
+
this._z = z;
|
|
86
|
+
this._setLayerProps({ zPosition: z });
|
|
87
|
+
}
|
|
88
|
+
|
|
74
89
|
map() {
|
|
75
90
|
this._hidden = false;
|
|
76
91
|
if (this._presented) this._setLayerProps({ hidden: false });
|
package/src/gloverlay.js
CHANGED
|
@@ -17,10 +17,18 @@
|
|
|
17
17
|
// translucent child over a GL surface?
|
|
18
18
|
//
|
|
19
19
|
// - **The Cocoa backend: yes.** Core Animation composites every layer, so
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
20
|
+
// a pane is a transparent bitmap layer above the GL layer, and a
|
|
21
|
+
// translucent background, an antialiased edge or a shadow blends with the
|
|
22
|
+
// GL frame under it. `app.createOverlayPane` is how a backend says it
|
|
23
|
+
// composites. Where it can stack its panes as well
|
|
24
|
+
// (`app.overlaysPerChild`), a pane is one per child, as on X11, holding
|
|
25
|
+
// that child alone — the layers under it show through — and as big as
|
|
26
|
+
// what the child reaches: a layer's contents are a copy of its bitmap,
|
|
27
|
+
// colour-matched to the display as it is pushed, and one the size of the
|
|
28
|
+
// surface pushed again at every step a minimap's viewport moved was a
|
|
29
|
+
// quarter of a core on a Mac. A child that only moved moves its layer,
|
|
30
|
+
// and nothing is painted. Otherwise one pane holds every child, over the
|
|
31
|
+
// whole surface.
|
|
24
32
|
// - **X11: no.** A child window is opaque without a compositor, and a
|
|
25
33
|
// compositor would not change that: it redirects top-level windows, not
|
|
26
34
|
// the children inside one. So a pane is a plain child window just big
|
|
@@ -746,8 +754,9 @@ function askShape(app) {
|
|
|
746
754
|
*/
|
|
747
755
|
class Pane {
|
|
748
756
|
/**
|
|
749
|
-
* @param node the child
|
|
750
|
-
*
|
|
757
|
+
* @param node the child a pane is kept by and holds — up to it on X11,
|
|
758
|
+
* alone where it is composited — and null for a composited pane over
|
|
759
|
+
* the whole surface, which holds every child
|
|
751
760
|
* @param overlay the panes it is one of, which `canBlit` asks about
|
|
752
761
|
*/
|
|
753
762
|
constructor(wnd, rect, transparent, node = null, overlay = null) {
|
|
@@ -842,7 +851,8 @@ class Pane {
|
|
|
842
851
|
};
|
|
843
852
|
if (!this.wnd.scrollRegion(local, dx, dy)) return false;
|
|
844
853
|
this.blitted = true;
|
|
845
|
-
|
|
854
|
+
// composited, a pane over it holds none of it
|
|
855
|
+
const panes = this.node && !this.transparent ? this.overlay?.panes : null;
|
|
846
856
|
if (panes) {
|
|
847
857
|
for (let i = panes.indexOf(this) + 1; i < panes.length; i++) {
|
|
848
858
|
panes[i].owe(rect);
|
|
@@ -867,8 +877,11 @@ export class GlOverlay {
|
|
|
867
877
|
constructor(area) {
|
|
868
878
|
this.area = area;
|
|
869
879
|
this.app = area.app;
|
|
870
|
-
//
|
|
880
|
+
// panes the backend composites, transparent, rather than child windows
|
|
871
881
|
this.composited = typeof this.app?.createOverlayPane === 'function';
|
|
882
|
+
// a pane a child: X11's, and a compositor's that stacks its panes; one
|
|
883
|
+
// pane over the whole surface elsewhere
|
|
884
|
+
this.perChild = !this.composited || this.app?.overlaysPerChild === true;
|
|
872
885
|
// bottom to top: the children's order on X11, one pane each
|
|
873
886
|
this.panes = [];
|
|
874
887
|
// X11: each child's pane, kept by the child for as long as it has one
|
|
@@ -908,7 +921,7 @@ export class GlOverlay {
|
|
|
908
921
|
const visible = shown(area) && abs.width > 0 && abs.height > 0;
|
|
909
922
|
// the surface's own rect, rounded the way its window's is
|
|
910
923
|
const surface = visible ? area._geometry() : null;
|
|
911
|
-
if (
|
|
924
|
+
if (this.perChild) return this._syncChildren(surface);
|
|
912
925
|
const rects = surface && area.paintOrder().length ? [surface] : [];
|
|
913
926
|
let changed = false;
|
|
914
927
|
while (this.panes.length > rects.length) {
|
|
@@ -929,13 +942,14 @@ export class GlOverlay {
|
|
|
929
942
|
}
|
|
930
943
|
|
|
931
944
|
/**
|
|
932
|
-
* `sync` on X11
|
|
933
|
-
*
|
|
934
|
-
*
|
|
935
|
-
*
|
|
936
|
-
*
|
|
937
|
-
*
|
|
938
|
-
* is under its
|
|
945
|
+
* `sync` on X11, and where panes composite a child each: a pane per
|
|
946
|
+
* child, kept by the child. A child that is new gets one, a child that
|
|
947
|
+
* went takes its with it, and one whose reach moved has its pane placed
|
|
948
|
+
* there — and painted whole, unless the move was the child's own and
|
|
949
|
+
* nothing else, which the window's move carries (`_settleMove` repaints
|
|
950
|
+
* what it does not). A change of order restacks them, and on X11 repaints
|
|
951
|
+
* whichever overlap another: what an X11 pane holds is what is under its
|
|
952
|
+
* child.
|
|
939
953
|
*/
|
|
940
954
|
_syncChildren(surface) {
|
|
941
955
|
const regions = surface ? childRegions(this.area, surface) : [];
|
|
@@ -981,9 +995,10 @@ export class GlOverlay {
|
|
|
981
995
|
this.panes = next;
|
|
982
996
|
if (reordered) {
|
|
983
997
|
this.restack();
|
|
984
|
-
if (!made) {
|
|
998
|
+
if (!made && !this.composited) {
|
|
985
999
|
// what each pane holds is its child and what is under it: a new
|
|
986
|
-
// order is new contents wherever two of them meet
|
|
1000
|
+
// order is new contents wherever two of them meet — on X11, where a
|
|
1001
|
+
// pane is opaque; a composited one holds its child alone
|
|
987
1002
|
for (const pane of next) {
|
|
988
1003
|
if (
|
|
989
1004
|
next.some(
|
|
@@ -1041,7 +1056,11 @@ export class GlOverlay {
|
|
|
1041
1056
|
* Cocoa backend the layer's zPosition is the whole of it.
|
|
1042
1057
|
*/
|
|
1043
1058
|
restack() {
|
|
1044
|
-
if (this.composited)
|
|
1059
|
+
if (this.composited) {
|
|
1060
|
+
// a composited pane a child is stacked by the backend, in order
|
|
1061
|
+
this.panes.forEach((pane, i) => pane.wnd.stackAt?.(i));
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1045
1064
|
const X = this.app?.X;
|
|
1046
1065
|
if (typeof X?.ConfigureWindow !== 'function') return;
|
|
1047
1066
|
let below = this.area.window?.id ?? null;
|
|
@@ -1085,7 +1104,7 @@ export class GlOverlay {
|
|
|
1085
1104
|
if (!root || root.destroyed || root._paneDamage === FULL_DAMAGE) {
|
|
1086
1105
|
return true;
|
|
1087
1106
|
}
|
|
1088
|
-
if (
|
|
1107
|
+
if (this.perChild) {
|
|
1089
1108
|
// Each child's move is its own pane's to settle: carried by the
|
|
1090
1109
|
// window's move where its pane went with it, moved on the pane where
|
|
1091
1110
|
// the pane stayed — cut to the surface, say, which a box bigger than
|
|
@@ -1135,6 +1154,9 @@ export class GlOverlay {
|
|
|
1135
1154
|
* - The panes under it hold nothing of it, and are owed nothing.
|
|
1136
1155
|
*/
|
|
1137
1156
|
_settleCarried({ node, reach, dx, dy }, reaches) {
|
|
1157
|
+
// a composited pane holds its child alone, and the layer's move carried
|
|
1158
|
+
// all of it: nothing is owed anywhere
|
|
1159
|
+
if (this.composited) return;
|
|
1138
1160
|
const panes = this.panes;
|
|
1139
1161
|
const at = panes.indexOf(this.byNode.get(node));
|
|
1140
1162
|
const own = panes[at];
|
|
@@ -1231,10 +1253,15 @@ export class GlOverlay {
|
|
|
1231
1253
|
for (const piece of outside(was, dest)) add(piece);
|
|
1232
1254
|
if (now) for (const piece of outside(now, dest)) add(piece);
|
|
1233
1255
|
// the children whose pixels the pane holds: every other one on a pane
|
|
1234
|
-
// over the whole surface,
|
|
1235
|
-
//
|
|
1256
|
+
// over the whole surface, on X11 the ones under this child — the panes
|
|
1257
|
+
// over it are owed the copy by `Pane.blit` — and none on a composited
|
|
1258
|
+
// pane a child
|
|
1236
1259
|
const order = area.paintOrder();
|
|
1237
|
-
const upTo = own
|
|
1260
|
+
const upTo = !own
|
|
1261
|
+
? order.length
|
|
1262
|
+
: this.composited
|
|
1263
|
+
? 0
|
|
1264
|
+
: order.indexOf(node);
|
|
1238
1265
|
for (let i = 0; i < upTo; i++) {
|
|
1239
1266
|
const other = order[i];
|
|
1240
1267
|
if (other === node) continue;
|
|
@@ -1324,8 +1351,13 @@ export class GlOverlay {
|
|
|
1324
1351
|
}
|
|
1325
1352
|
root._paintDamage = pass;
|
|
1326
1353
|
// an X11 pane holds its child and what is under it, and never
|
|
1327
|
-
// what is over it — the pane over it holds that (see the header)
|
|
1328
|
-
|
|
1354
|
+
// what is over it — the pane over it holds that (see the header);
|
|
1355
|
+
// a composited pane a child holds its child alone
|
|
1356
|
+
area._paintChildren(
|
|
1357
|
+
ctx,
|
|
1358
|
+
pane.node,
|
|
1359
|
+
pane.transparent && pane.node !== null,
|
|
1360
|
+
);
|
|
1329
1361
|
} finally {
|
|
1330
1362
|
root._paintDamage = null;
|
|
1331
1363
|
ctx.restore();
|
package/src/nodes/paint.js
CHANGED
|
@@ -337,9 +337,10 @@ export class NodePaint {
|
|
|
337
337
|
/**
|
|
338
338
|
* The children, in paint order — or those up to and including `upTo`: an
|
|
339
339
|
* X11 pane over a `<glarea>` holds its own child and what is under it,
|
|
340
|
-
* never what is over it (src/gloverlay.js, `_paintPane`)
|
|
340
|
+
* never what is over it (src/gloverlay.js, `_paintPane`) — or `upTo` alone
|
|
341
|
+
* (`only`), which a composited pane a child holds.
|
|
341
342
|
*/
|
|
342
|
-
_paintChildren(ctx, upTo = null) {
|
|
343
|
+
_paintChildren(ctx, upTo = null, only = false) {
|
|
343
344
|
// A retained presenter replays a node's `paint` into a visual of that
|
|
344
345
|
// node's own — its children have visuals of their own, so it sets this
|
|
345
346
|
// for the duration of the call (src/cocoa/presenter.js, `paintSelf`).
|
|
@@ -348,7 +349,7 @@ export class NodePaint {
|
|
|
348
349
|
let order = this.paintOrder();
|
|
349
350
|
if (upTo !== null) {
|
|
350
351
|
const at = order.indexOf(upTo);
|
|
351
|
-
if (at !== -1) order = order.slice(0, at + 1);
|
|
352
|
+
if (at !== -1) order = only ? [upTo] : order.slice(0, at + 1);
|
|
352
353
|
}
|
|
353
354
|
if (order.length === 0) return;
|
|
354
355
|
if (!this.clipsChildren()) {
|