@gjsify/gtk-runtime-darwin-arm64 0.20.0 → 0.22.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/gtk/manifest.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "platform": "darwin-arm64",
3
+ "windowing": false,
3
4
  "generatedFrom": "/opt/homebrew",
4
5
  "dylibs": 45,
5
6
  "typelibs": 38,
6
7
  "libBytes": 29101712,
7
8
  "typelibBytes": 2342100,
9
+ "dataBytes": 0,
8
10
  "totalBytes": 31443812,
9
11
  "dylibList": [
10
12
  "libX11.6.dylib",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/gtk-runtime-darwin-arm64",
3
- "version": "0.20.0",
3
+ "version": "0.22.0",
4
4
  "description": "Batteries-included, relocated GTK/GObject-Introspection runtime bundle for macOS arm64 — lets @gjsify/node-gi load gi:// namespaces (GLib/GObject/Gio/cairo/Pango/Graphene/Gdk) with NO Homebrew GTK. Platform-gated (darwin/arm64 only).",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -74,6 +74,23 @@ const SEED_PATTERNS = [
74
74
  /^libgtk-4\..*\.dylib$/, // provides the Gdk typelib's backing library
75
75
  ];
76
76
 
77
+ // WINDOWING superset (opt-in via --windowing): also bundle libadwaita, whose dylib
78
+ // backs the Adw-1 typelib, AND libgtksourceview-5, whose dylib backs the GtkSource-5
79
+ // typelib. The display-free conformance closure never touches Adwaita OR GtkSource,
80
+ // so they are NOT base seeds — but the batteries-included bundle ships their TYPELIBS,
81
+ // so without the dylibs a real `new Adw.Application()` / `new GtkSource.View()` fails
82
+ // with "Failed to load shared library '…'" (→ the type is not a constructible
83
+ // GObject). libgtksourceview backs the Learn6502 editor (a GtkSource.View subclass) —
84
+ // the app-gnome node-gi port. This is exactly what the macOS GTK-GUI proof
85
+ // (macos-gtk-windowing) needs; the recursive otool walk pulls each seed's transitive
86
+ // deps + relocates them like any other seed. Mirrors the win32 --windowing superset
87
+ // (WINDOWING_SEED_PATTERNS there). NB: GtkSource's runtime DATA (language-specs /
88
+ // styles under share/gtksourceview-5) is a separate concern; the darwin bundle has no
89
+ // share/ DATA step yet, so GtkSource CONSTRUCTS here but syntax-highlighting language
90
+ // files are not bundled (tracked follow-up; the win32 bundle DOES ship them).
91
+ const WINDOWING = process.argv.includes('--windowing');
92
+ const WINDOWING_SEED_PATTERNS = [/^libadwaita-1\..*\.dylib$/, /^libgtksourceview-5\..*\.dylib$/];
93
+
77
94
  function isSystemPath(p) {
78
95
  return p.startsWith('/usr/lib/') || p.startsWith('/System/');
79
96
  }
@@ -112,8 +129,9 @@ function resolveInBrew(leaf) {
112
129
  }
113
130
 
114
131
  // --- 1. discover the closure ----------------------------------------------
115
- console.log(`build-gtk-runtime: brew prefix ${brewPrefix}`);
116
- const seeds = readdirSync(brewLib).filter((f) => SEED_PATTERNS.some((re) => re.test(f)));
132
+ console.log(`build-gtk-runtime: brew prefix ${brewPrefix}${WINDOWING ? ' (windowing superset — + libadwaita + libgtksourceview)' : ' (display-free)'}`);
133
+ const seedPatterns = WINDOWING ? [...SEED_PATTERNS, ...WINDOWING_SEED_PATTERNS] : SEED_PATTERNS;
134
+ const seeds = readdirSync(brewLib).filter((f) => seedPatterns.some((re) => re.test(f)));
117
135
  if (seeds.length === 0) {
118
136
  console.error('build-gtk-runtime: no seed libraries found — is the GTK stack installed?');
119
137
  process.exit(1);
@@ -177,6 +195,84 @@ if (existsSync(brewTypelibs)) {
177
195
  }
178
196
  console.log(`build-gtk-runtime: copied ${typelibCount} typelibs`);
179
197
 
198
+ // --- 3b. WINDOWING data (schemas / icons / gtksource) ---------------------
199
+ // The runtime DATA a REAL app needs beyond the dylibs+typelibs: compiled GSettings
200
+ // schemas (Gio.Settings — a HARD startup blocker without them), the Adwaita/hicolor
201
+ // icon themes, and GtkSource's language-specs/styles. These are plain files (no dylib
202
+ // relocation), located at runtime via GSETTINGS_SCHEMA_DIR / XDG_DATA_DIRS (node-gi's
203
+ // gtk-runtime.js maybeWireGtkWindowingEnv keys on the gschemas.compiled marker). Gated
204
+ // on --windowing; the display-free bundle is byte-unchanged. NB the gdk-pixbuf image
205
+ // LOADERS (needed to render SVG symbolic icons) are NOT bundled yet — they are dylibs
206
+ // that need @loader_path relocation from a NESTED dir (unlike win32's plain DLL copy);
207
+ // tracked follow-up, so symbolic icons may be blank until then.
208
+ const windowing = { schemas: false, iconThemes: [], gtksource: false };
209
+ if (WINDOWING) {
210
+ const brewShare = join(brewPrefix, 'share');
211
+ const findTool = (leaf) => {
212
+ const inBrew = join(brewPrefix, 'bin', leaf);
213
+ return existsSync(inBrew) ? inBrew : leaf; // fall back to PATH
214
+ };
215
+
216
+ // 3b-a. Compiled GSettings schemas + (re)compile gschemas.compiled — also the
217
+ // windowing-data marker node-gi's loader detects.
218
+ const schemasSrc = join(brewShare, 'glib-2.0', 'schemas');
219
+ if (existsSync(schemasSrc)) {
220
+ const schemasOut = join(OUT, 'share', 'glib-2.0', 'schemas');
221
+ mkdirSync(schemasOut, { recursive: true });
222
+ for (const f of readdirSync(schemasSrc)) {
223
+ if (f.endsWith('.xml') || f.endsWith('.gschema.override') || f === 'gschemas.compiled') {
224
+ copyFileSync(join(schemasSrc, f), join(schemasOut, f));
225
+ }
226
+ }
227
+ try {
228
+ execFileSync(findTool('glib-compile-schemas'), [schemasOut]);
229
+ } catch (err) {
230
+ console.warn(`build-gtk-runtime: WARNING — glib-compile-schemas failed: ${err?.message ?? err}`);
231
+ }
232
+ windowing.schemas = existsSync(join(schemasOut, 'gschemas.compiled'));
233
+ console.log(`build-gtk-runtime: GSettings schemas ${windowing.schemas ? 'compiled' : 'copied (no gschemas.compiled!)'}`);
234
+ } else {
235
+ console.warn(`build-gtk-runtime: WARNING — ${schemasSrc} missing; GSettings schemas NOT bundled (Gio.Settings will fail)`);
236
+ }
237
+
238
+ // 3b-b. Icon themes (Adwaita symbolic + hicolor) + caches, loaded from
239
+ // XDG_DATA_DIRS/icons/<theme>/.
240
+ const updateIconCache = findTool('gtk4-update-icon-cache');
241
+ for (const theme of ['Adwaita', 'hicolor']) {
242
+ const themeSrc = join(brewShare, 'icons', theme);
243
+ if (!existsSync(themeSrc)) continue;
244
+ cpSync(themeSrc, join(OUT, 'share', 'icons', theme), { recursive: true });
245
+ try {
246
+ execFileSync(updateIconCache, ['-q', '-t', '-f', join(OUT, 'share', 'icons', theme)]);
247
+ } catch {
248
+ // an existing icon-theme.cache from the copy is a usable fallback
249
+ }
250
+ windowing.iconThemes.push(theme);
251
+ }
252
+ console.log(
253
+ windowing.iconThemes.length
254
+ ? `build-gtk-runtime: icon themes ${windowing.iconThemes.join(', ')}`
255
+ : 'build-gtk-runtime: WARNING — no Adwaita/hicolor icon theme under share/icons',
256
+ );
257
+
258
+ // 3b-c. GtkSource-5 language-specs + styles (the editor's syntax highlighting).
259
+ const gtksourceSrc = join(brewShare, 'gtksourceview-5');
260
+ if (existsSync(gtksourceSrc)) {
261
+ let copied = 0;
262
+ for (const sub of ['language-specs', 'styles']) {
263
+ const subSrc = join(gtksourceSrc, sub);
264
+ if (existsSync(subSrc)) {
265
+ cpSync(subSrc, join(OUT, 'share', 'gtksourceview-5', sub), { recursive: true });
266
+ copied += readdirSync(subSrc).length;
267
+ }
268
+ }
269
+ windowing.gtksource = copied > 0;
270
+ console.log(`build-gtk-runtime: GtkSource-5 data ${windowing.gtksource ? `bundled (${copied} files)` : 'empty'}`);
271
+ } else {
272
+ console.warn(`build-gtk-runtime: WARNING — ${gtksourceSrc} missing; GtkSource-5 data NOT bundled`);
273
+ }
274
+ }
275
+
180
276
  // --- 4. optional: relocate a copy of the node-gi addon --------------------
181
277
  // The addon (built against Homebrew) carries absolute /opt/homebrew refs. Rewrite
182
278
  // them to @rpath/<leaf> + add an rpath to the SIBLING bundle so it loads the
@@ -219,15 +315,20 @@ function dirSize(dir) {
219
315
  }
220
316
  const libBytes = dirSize(libOut);
221
317
  const typelibBytes = dirSize(typelibOut);
318
+ const shareOut = join(OUT, 'share');
319
+ const dataBytes = WINDOWING && existsSync(shareOut) ? dirSize(shareOut) : 0;
222
320
  const manifest = {
223
321
  platform: 'darwin-arm64',
322
+ windowing: WINDOWING,
224
323
  generatedFrom: brewPrefix,
225
324
  dylibs: bundledLeaves.size,
226
325
  typelibs: typelibCount,
227
326
  libBytes,
228
327
  typelibBytes,
229
- totalBytes: libBytes + typelibBytes,
328
+ dataBytes,
329
+ totalBytes: libBytes + typelibBytes + dataBytes,
230
330
  dylibList: [...bundledLeaves].sort(),
331
+ ...(WINDOWING ? { windowingData: windowing } : {}),
231
332
  };
232
333
  writeFileSync(join(OUT, 'manifest.json'), JSON.stringify(manifest, null, 2));
233
334