ntk 8.12.11 → 8.12.13

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.
@@ -3640,7 +3640,17 @@ class RenderingContext2d {
3640
3640
  const y = Math.min(...ys);
3641
3641
  const w = Math.max(...xs) - x;
3642
3642
  const h = Math.max(...ys) - y;
3643
- if (!(w > 0 && h > 0)) return null;
3643
+ // A rectangle of no area is still one, and clips everything: what a box
3644
+ // of no height clips its content to, a menu at `max-height: 0`. Taken
3645
+ // for a path, it built the mask the size of the surface, and every
3646
+ // rectangle clipped inside it was intersected into that mask; the
3647
+ // intersection of an empty one is empty, and every consumer draws
3648
+ // nothing through that, as where two rectangles do not meet.
3649
+ if (!(w > 0 && h > 0)) {
3650
+ return Number.isFinite(w) && Number.isFinite(h)
3651
+ ? { x: 0, y: 0, w: 0, h: 0 }
3652
+ : null;
3653
+ }
3644
3654
  // Server clip rectangles are integers, so a fractional edge could only
3645
3655
  // be honoured by rounding — which would differ from the mask path's
3646
3656
  // antialiased edge by up to a pixel. Rare, so leave those to the mask
package/lib/window.js CHANGED
@@ -1560,6 +1560,7 @@ export default class Window extends Drawable {
1560
1560
 
1561
1561
  _runFrame() {
1562
1562
  const f = this._frame;
1563
+ const startedAt = performance.now();
1563
1564
  if (
1564
1565
  !f.pending.size &&
1565
1566
  !f.rafCbs.length &&
@@ -1601,7 +1602,7 @@ export default class Window extends Drawable {
1601
1602
  // that drew nothing has to fall back to the timer, or nothing would ever
1602
1603
  // run the next frame.
1603
1604
  if (!this._clockOnPresent()) this._armFence();
1604
- this._armTimer();
1605
+ this._armTimer(startedAt);
1605
1606
  }
1606
1607
 
1607
1608
  /**
@@ -2156,8 +2157,14 @@ export default class Window extends Drawable {
2156
2157
  * and arming one would only cap the rate the display just set. An explicit
2157
2158
  * `frameInterval` is honoured in both, since a cap the caller asked for
2158
2159
  * applies whatever ends the frame.
2160
+ *
2161
+ * The period runs from the start of the frame (`startedAt`), not from its
2162
+ * end: a frame's own work is part of its period, not a pause owed after it.
2163
+ * Counted from the end, a window whose frames took 3 ms drew one every 19
2164
+ * under a 16.7 ms interval — a GL map panned by an animation, whose window
2165
+ * is on the fence, ran at 51 frames a second on a 60 Hz panel.
2159
2166
  */
2160
- _armTimer() {
2167
+ _armTimer(startedAt = performance.now()) {
2161
2168
  const f = this._frame;
2162
2169
  if (f.timer) return;
2163
2170
  let period = this.frameInterval;
@@ -2169,7 +2176,7 @@ export default class Window extends Drawable {
2169
2176
  f.timer = setTimeout(() => {
2170
2177
  f.timer = null;
2171
2178
  if (f.pending.size || f.rafCbs.length || f.needsRedraw) this._scheduleFrame();
2172
- }, period);
2179
+ }, Math.max(0, period - (performance.now() - startedAt)));
2173
2180
  if (typeof f.timer.unref === 'function') f.timer.unref();
2174
2181
  }
2175
2182
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ntk",
3
- "version": "8.12.11",
3
+ "version": "8.12.13",
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",