ntk 6.6.0 → 6.6.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/lib/window.js +68 -4
- package/package.json +1 -1
package/lib/window.js
CHANGED
|
@@ -348,6 +348,9 @@ export default class Window extends Drawable {
|
|
|
348
348
|
this._foreign = !!args.id;
|
|
349
349
|
this._backingOptOut = args.backingStore === false;
|
|
350
350
|
this._backing = null;
|
|
351
|
+
// What the backing store clears to, and the window attribute it mirrors.
|
|
352
|
+
// Undefined means "nothing was asked for" — see _clearColour.
|
|
353
|
+
this._clearPixel = args.backgroundPixel;
|
|
351
354
|
this._dirty = false;
|
|
352
355
|
this._presentPending = false;
|
|
353
356
|
|
|
@@ -696,9 +699,60 @@ export default class Window extends Drawable {
|
|
|
696
699
|
});
|
|
697
700
|
}
|
|
698
701
|
|
|
702
|
+
/**
|
|
703
|
+
* The pixel the backing store's unpainted area is cleared to.
|
|
704
|
+
*
|
|
705
|
+
* A pixmap's contents start *undefined* — whatever was in that memory — so
|
|
706
|
+
* something has to be written before it can be presented, and the same goes
|
|
707
|
+
* for the region a grow adds. What that something is follows the window's
|
|
708
|
+
* own `backgroundPixel`, which is exactly what the server would paint into
|
|
709
|
+
* exposed area on a window with no backing store. Without one: transparent
|
|
710
|
+
* for a depth-32 ARGB window, and the screen's white otherwise.
|
|
711
|
+
*/
|
|
712
|
+
_clearColour() {
|
|
713
|
+
if (this._clearPixel !== undefined) return this._clearPixel;
|
|
714
|
+
const depth = this.depth || this.display.screen[0].root_depth;
|
|
715
|
+
return depth === 32 ? 0 : this.display.screen[0].white_pixel;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* The window's background colour, as an X pixel value.
|
|
720
|
+
*
|
|
721
|
+
* A double-buffered window has two of them and they have to agree: the X
|
|
722
|
+
* window attribute the server paints into exposed area, and the colour the
|
|
723
|
+
* backing store clears to. Setting one and not the other is why a resize
|
|
724
|
+
* could show white on a window that draws itself dark.
|
|
725
|
+
*
|
|
726
|
+
* The backing store's *headroom* — the area a future grow will expand
|
|
727
|
+
* into, which by definition holds nothing yet — is recoloured too, so a
|
|
728
|
+
* later resize does not expose the previous colour.
|
|
729
|
+
*/
|
|
730
|
+
setBackgroundPixel(pixel) {
|
|
731
|
+
this._clearPixel = pixel;
|
|
732
|
+
if (this._destroyed) return this;
|
|
733
|
+
if (this._clearGc) this.X.ChangeGC(this._clearGc, { foreground: pixel });
|
|
734
|
+
if (!this._foreign) {
|
|
735
|
+
this.X.ChangeWindowAttributes(this.id, { backgroundPixel: pixel }, () => {});
|
|
736
|
+
}
|
|
737
|
+
const backing = this._backing;
|
|
738
|
+
if (backing && this._clearGc) {
|
|
739
|
+
const rects = [];
|
|
740
|
+
if (backing.width > this.width) {
|
|
741
|
+
rects.push(this.width, 0, backing.width - this.width, backing.height);
|
|
742
|
+
}
|
|
743
|
+
if (backing.height > this.height) {
|
|
744
|
+
rects.push(0, this.height, this.width, backing.height - this.height);
|
|
745
|
+
}
|
|
746
|
+
if (rects.length) this.X.PolyFillRectangle(backing.id, this._clearGc, rects);
|
|
747
|
+
}
|
|
748
|
+
return this;
|
|
749
|
+
}
|
|
750
|
+
|
|
699
751
|
// grow-only backing pixmap (re)allocation, with headroom (see
|
|
700
|
-
// BACKING_GRANULARITY)
|
|
701
|
-
//
|
|
752
|
+
// BACKING_GRANULARITY). What is already drawn is carried across and only
|
|
753
|
+
// the region the grow adds is cleared (see _clearColour) — clearing the
|
|
754
|
+
// whole pixmap made the *entire* window flash the clear colour between a
|
|
755
|
+
// resize and the redraw, not just the new strip.
|
|
702
756
|
_allocBacking(w, h) {
|
|
703
757
|
const cur = this._backing;
|
|
704
758
|
if (cur && cur.width >= w && cur.height >= h) return;
|
|
@@ -715,11 +769,21 @@ export default class Window extends Drawable {
|
|
|
715
769
|
if (!this._clearGc) {
|
|
716
770
|
this._clearGc = this.X.AllocID();
|
|
717
771
|
this.X.CreateGC(this._clearGc, pixmap.id, {
|
|
718
|
-
foreground:
|
|
772
|
+
foreground: this._clearColour(),
|
|
719
773
|
graphicsExposures: 0
|
|
720
774
|
});
|
|
721
775
|
}
|
|
722
|
-
|
|
776
|
+
if (cur) {
|
|
777
|
+
// The new pixmap is strictly larger, so the old content lands at the
|
|
778
|
+
// same coordinates and only the L-shaped remainder is new.
|
|
779
|
+
this.X.CopyArea(cur.id, pixmap.id, this._clearGc, 0, 0, 0, 0, cur.width, cur.height);
|
|
780
|
+
const rects = [];
|
|
781
|
+
if (newW > cur.width) rects.push(cur.width, 0, newW - cur.width, newH);
|
|
782
|
+
if (newH > cur.height) rects.push(0, cur.height, cur.width, newH - cur.height);
|
|
783
|
+
if (rects.length) this.X.PolyFillRectangle(pixmap.id, this._clearGc, rects);
|
|
784
|
+
} else {
|
|
785
|
+
this.X.PolyFillRectangle(pixmap.id, this._clearGc, [0, 0, newW, newH]);
|
|
786
|
+
}
|
|
723
787
|
if (cur) cur.destroy();
|
|
724
788
|
this._backing = pixmap;
|
|
725
789
|
this._backingValid = false;
|