Skip to content

Latest commit

 

History

History
212 lines (157 loc) · 10.5 KB

File metadata and controls

212 lines (157 loc) · 10.5 KB

Open issues — node-x11 and ntk

Triage notes, refreshed whenever the picture has moved enough to mislead. Audited 2026-07-31 against node-x11 722a0df (v3.4.0 released) and ntk 7016021 (#130/#131/#132 merged). Covers both repos, because they are worked on together and half the entries below only make sense as a pair.

Previous pass was 2026-07-25 and covered node-x11 only. Since then five of its ten entries closed — #85 and #195 by the flow-control work, #171 and #183 on 2026-07-26, and #179 today — and four new issues were filed (#243–#246). Everything below has been re-checked against current code rather than carried forward.


Since the audit, #244 (output buffering) has been implemented — opt-in bufferRequests, see "Buffering the output" in docs/README.md.

node-x11 — 8 open

Worth doing next

#243 — FamilyWild cookies never match, and a failed match silently drops auth (2026-07-31)

Verified against current master. parseXauth writes cookie.type; the match loop at lib/auth.js:97 tests typeToName[cookie.family], a property nothing ever sets. typeToName[undefined] is never 'Wild', so the wildcard branch is dead and only the exact (type, address) pair can match. When nothing matches — wild-only file, hostname mismatch in a container, stale entry — lib/auth.js:101 falls through to { authName: '', authData: '' } and connects anonymously, so the only symptom is the server's generic "Authorization required" with nothing saying a cookie file was read.

Two-line logic fix plus a diagnostic. Reproducible with no X server at all, since the failure is in cookie selection. Top pick.

#245 — XISelectEvents and XI2 event delivery (2026-07-31)

lib/ext/xinput.js implements four requests — XI1 GetExtensionVersion and ListInputDevices, XI2 XIQueryVersion and XIQueryDevice — and no XISelectEvents (46), no GenericEvent parser. So a client can enumerate devices in detail, including the Scroll classes the reply parser already decodes, and never hear from them. All input arrives as core events, where a touchpad's smooth scroll is flattened into button 4/5 presses and touch, pressure and tilt do not exist.

The delivery half is already built: geEventParsers keyed by extension major opcode (lib/xcore.js:167), dispatch at :349, and lib/ext/present.js:180 as the worked example of an extension registering its parser. Largest item here, but well-scoped and additive.

#246 — ESM bundling throws at runtime (2026-07-31)

esbuild --format=esm builds cleanly and the bundle then throws Dynamic require of "events" is not supported — the worst failure shape, because it surfaces at deploy. Node itself is fine both ways; this is purely bundler output. node:-prefixed requires do not help.

Split it: the exports map is three lines, no behaviour change, and removes the deprecated directory-main — fold it into any other PR. The real fix is converting lib/ to ESM sources, which is a major, and the tempting shortcut does not work: a thin ESM wrapper over CJS still require()s builtins underneath, which is the exact failing construct.

Old, and closeable rather than workable

#152 — X11 Server (2017)

Someone trying to write an X server, stuck on the handshake reply. The thing they wanted now exists: lib/xserver/ is a working pure-JS X server with RENDER, its own DESIGN.md, and hermetic test suites in both repos. Answer with a pointer and close.

#91 — Grabbed key events not reaching an nw.js app (2015)

Environment-specific, and the reported behaviour is what a keyboard grab is for: grabbed input goes to the grabbing client, not the app's own window. Too little information to resolve; close as stale.

#62 — Arbitrary polygon rendering example (2014)

Wants a triangulation library glued to Render.AddTraps/Triangles. Note ntk solved the underlying problem in lib/trapezoid.js — polygon to trapezoids, non-zero and even-odd, used for every 2d path fill and vector glyph — so this is now only an example, and arguably one that belongs in ntk.

#50 — Shaders (2014)

ProgramString/BindProgram (ARB assembly) landed with #218. Missing: ProgramEnvParameter*/ProgramLocalParameter* render opcodes and an example. GLSL over indirect GLX was never standardized, so ARB assembly is the ceiling — worth saying in the issue so it stops reading as open-ended.

#51 — GL evaluator functions (2014)

Map1/Map2/EvalCoord/EvalMesh/MapGrid still absent from lib/ext/glxrender.js — re-checked, zero hits. Niche legacy GL, well specified, low priority.


ntk — 17 open

Three PRs merged today closed #126 and #117 and left #118 partly done. What remains splits cleanly into one real bug, a text/render batch, a clipboard batch, and a tail of old idea-issues.

Worth doing next

ntk#116 — keysym by XKB group and shift level

symInd = capital ? 1 : 0 reaches only levels 1–2 of group 1, so on Linux a non-Latin layout never types — and a layout switch fires no MappingNotify, so the existing refresh cannot see it. The group bits are already arriving in ev.buttons 13–14; no XKB extension calls needed for the common case. AltGr (levels 3–4) is unreachable for the same reason, which the code's own TODO admits.

Highest user-facing impact of anything open in either repo. Caveat for this machine: XQuartz takes the other path entirely — it rewrites the keymap and fires MappingNotify rather than using groups — so the payoff cannot be confirmed locally without a Linux box.

ntk#118 — remaining: _NET_WM_ICON

Items 1, 3, 4 and 6 shipped in #131 (the WM_PROTOCOLS clobber, setWmHints, setPid, the position/size flags) and item 2 in #130 (the ClientMessage helper). Only item 5 is left, and it is a pixel-format decision rather than a property-writer one: EWMH wants non-premultiplied ARGB in CARD32s, ntk's getImageData hands back BGRA, canvas ImageData is RGBA. Pick a convention first, then it is twenty lines.

ntk#36 — a named close-request event

Still real, and now small. addProtocol('WM_DELETE_WINDOW') opts in and the request arrives as a generic 'message'; what is missing is the ergonomic half the issue actually asks for — a named event, and the issue's own suggestion of onBeforeUnload is worth keeping. Natural follow-on to #131.

Batches

Text/render: #125 one-write-per-frame, #124 maxLines/ellipsis, #123 half-leading, #122 downscale before upload. #124 and #123 are self-contained TextLayout work with obvious tests; #122 is perf, deferred.

#125 has shrunk to a one-liner now that node-x11 buffers output: measured against the current client, createClient({ bufferRequests: … }) alone takes a 2000-request ntk frame from 2003 writes to 1–2, because _runFrame() emits a frame in one synchronous run and ends with the frame fence's GetInputFocus, whose reply gate flushes exactly at the frame boundary. The X.flush() at _present() the issue proposes is therefore redundant, and it would pin one write per window-frame — where flushOnReply: false plus the end-of-tick flush lets several windows' frames in one tick coalesce into a single write. What is left for ntk: pass the option through and size maxSize to a frame (16 KB default = ~5 writes for a 72 KB frame, 256 KB = 1); tcpNoDelay already defaults to on with buffering.

Clipboard: #120 XFixes selection-changed events, #119 INCR on the write side plus required targets. #119 closes a limitation lib/clipboard.js documents in its own header, so it is honest work with a known shape.

Fonts: #121 a first-class bundled-fonts option. The FontSource seam already exists — StaticFontSource is the browser-safe implementation — so this is largely packaging a default set rather than new architecture.

Resolved or superseded — close these

ntk#106 — drop the mermaid dependency

Done, by removal rather than injection: feat!: drop mermaid diagram rendering (#113, in 4.0.0). grep mermaid package.json lib/ is empty. The issue asked for a configureTex-style injection seam and got deletion instead, so close with that note rather than silently.

ntk#31 — set window class / "all the EWMH stuff besides the title"

Done. setClass has shipped for a while; as of #131/#132 the EWMH surface covers window type, states, transient-for, hints, protocols and pid. Close pointing at the Window manager hints section of docs/window.md.

ntk#19 — implement basic ICCCM

Done, including the API sketched in your own comment on it — createWindow({ icon, transientFor, maxWidth }) and setHints() both work as written there. Close pointing at #131.

ntk#4 — layout managers

Superseded. The answer turned out to be yoga-layout, used by HtmlView and re-exported from lib/index.js so downstream renderers share one WASM instance. Cassowary is not coming.

ntk#17 — widgets via Zebra

Superseded. Zebra is unmaintained, and ntk grew its own widget layer — HtmlView, MarkdownView, SvgView, TexView.

Leave open, low priority

  • ntk#37 — "attention" event, a 2018 speculative idea about predicting clicks. Unrelated to the ICCCM urgency hint despite the name; needs a decision on whether it is wanted at all before it is worth scoping.
  • ntk#22 — text editor example. Genuinely useful as a demo of the text stack, and cheap once #124 lands.