@gjsify/gtk-host 0.52.0 → 0.54.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/README.md CHANGED
@@ -783,17 +783,16 @@ root.render(createElement('GtkBox', null, createElement('GtkLabel', { label: 'hi
783
783
 
784
784
  ```
785
785
  --define 'process.env.NODE_ENV="production"'
786
- --exclude-globals navigator
787
786
  ```
788
787
 
789
788
  `react-reconciler/index.js` picks its bundle from `process.env.NODE_ENV`, and the
790
789
  development one reaches for `document`, `HTMLCanvasElement` and `Path2D`, which
791
790
  makes `--globals auto` inject the GTK-backed DOM registers and pull `gi://Gdk`,
792
- `GdkPixbuf`, `Pango` and `PangoCairo` into a bundle that needs none of them. Even
793
- the production `scheduler` carries `typeof navigator !== 'undefined' &&
794
- navigator.scheduling`, dead code under GJS but still a free identifier the
795
- detector answers with the same register. With both flags the bundle loads with no
796
- `document` and no `navigator`, and a vector asserts exactly that.
791
+ `GdkPixbuf`, `Pango` and `PangoCairo` into a bundle that needs none of them. With
792
+ the define the bundle loads with no `document`, and a vector asserts exactly that.
793
+ The production `scheduler` still reads `navigator.scheduling` behind a `typeof`
794
+ guard; that reference now injects Node's DOM-free `navigator` from
795
+ `@gjsify/node-globals`, so it no longer needs `--exclude-globals navigator`.
797
796
 
798
797
  `react` and `react-reconciler` are OPTIONAL peer dependencies, like `solid-js` and
799
798
  `@vue/runtime-core`.
@@ -838,6 +837,54 @@ host's own `coerce()` path. A member the installed library lacks is accepted onl
838
837
  if the GIR says it arrived in a newer release — `GtkApplicationWindow::save-state`
839
838
  is GTK 4.24 and the check runs on 4.22.4.
840
839
 
840
+ ### A class the running GTK does not have
841
+
842
+ The table is generated from **one platform's GIR**, and a platform does not build every
843
+ class that GIR describes: GTK does not build its Unix print stack on Windows, so
844
+ `GtkPrintUnixDialog` and `GtkPageSetupUnixDialog` are rows whose class no Windows
845
+ `Gtk-4.0.typelib` registers (#1446 — six assertions of this suite failed on the first
846
+ GTK-bearing Windows leg, all of them this). The rows **stay**, for two measured
847
+ reasons. The GIR says they exist in that release, and the generator reads one GIR pool
848
+ with no second platform to compare against — a platform claim derived from a NAME
849
+ (`*Unix*`) breaks precisely when it matters, on the next absent class nobody spelled
850
+ that way, and a surface should not assert what it has not measured. And the two rows
851
+ are correct on the two platforms that do build them.
852
+
853
+ What the table must never do is hand a caller a class that resolved to `undefined`.
854
+ `classOf(descriptor)` is the one place that asks the only question answerable here — does
855
+ the **running** typelib have this class — and `requireClass(descriptor)` is that answer as
856
+ a named refusal (`err.absentClass`, code `absent-class`). Every read of a row's class
857
+ goes through it: `materialize`, `setProp`, `setEventHandler`, `setAccessibility`, the two
858
+ text-sink paths and the construction probe. So an omitted class is refused **by name at
859
+ the call that needed it**, instead of dying as
860
+ `Cannot read properties of undefined (reading 'list_properties')` or `… (reading '$gtype')`
861
+ — the two messages that arrived as six failures naming two classes between them.
862
+
863
+ A test that can only run where the defect is never runs, so the absent-class path is
864
+ **simulated** in `generated.spec.ts`: a descriptor whose `ctor()` answers `undefined` —
865
+ which is literally what `Gtk.PrintUnixDialog` is on a host that does not build it — driven
866
+ through every one of those paths, each expected to refuse with the same code and the
867
+ row's name. The sweeps that walk the whole table ask `classOf`/`hasClass` and treat an
868
+ absent row as *not a row*; `descriptorProblems()` says nothing about a class it cannot
869
+ resolve, and `explains every class the installed library does not have` is where an
870
+ absence is weighed against the library version **and printed by name** — the half that was
871
+ missing, and the reason those six took a hand to attribute.
872
+
873
+ The type surfaces (`generated/props.ts`) keep both dialogs, deliberately: they describe
874
+ the GIR's release, and `gjsify tsc` cannot check a type surface against an installed
875
+ typelib (rule 5 of the section above). A renderer on a platform that lacks the class meets
876
+ the runtime refusal at the call, not a compile error.
877
+
878
+ **The obvious oracle is wrong, and that is measured.** `GObject.type_from_name` is the
879
+ one-call version of "is this class installed" and it answers in the direction that costs
880
+ a *working* row: on gjs 1.88.1 / Homebrew GTK 4.24.0 `type_from_name('GtkPrintUnixDialog')`
881
+ answers **0** while `Gtk.PrintUnixDialog` is present and constructs — a typelib registers a
882
+ class when the namespace member is first **read**, not when the typelib loads. So a table
883
+ filtered by `type_from_name` drops two rows that are really there, on the platform that has
884
+ them. A row's own `ctor()` *is* that read, which is why it answers correctly in both
885
+ directions; an oracle over the whole table has to force the registration of every class it
886
+ walks, where a row is only ever asked about when something is about to use it.
887
+
841
888
  ### A base that leaves the namespace
842
889
 
843
890
  The generator reads `@girs/<ns>/vocabulary` (ADR 0029) for Gtk and Adw — the only two that
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";import{adderSlots as e,addressOf as t,classPlacementKind as n,isUnparented as r,placementOf as i,unhandledPlacement as a,unhandledPolicy as o}from"../policies.js";import{installAccessibilityBackend as s,withAtContext as c}from"./at-context.js";import{describeLogRecord as l,installDiagnosticsGate as u,isEnvironmentDiagnostic as d}from"./diagnostics.js";import{descendants as f,dumpTree as p,findDescendant as m,gtkChildTypes as h,gtkChildren as g}from"./tree.js";import{windowChromeCensus as _,windowChromeProblems as v}from"./window-chrome.js";import{buildSharedTree as y}from"./shared-tree-builder.js";import{BUILTIN_DESCRIPTORS as b}from"../descriptors/index.js";import x from"gi://GObject?version=2.0";function methodsOf(e){switch(e.kind){case`none`:case`uncurated`:return[];case`single`:return[e.set];case`ordered`:return e.after?[e.append,e.after,e.remove]:[e.append,e.remove];case`indexed`:return[e.insert,e.remove];case`slotted`:return e.remove?[...Object.values(e.slots),e.remove]:Object.values(e.slots);case`keyed`:return[e.add,e.remove];case`coords`:return[e.attach,e.remove];default:return o(e)}}function placementMethodsOf(e){switch(e.kind){case`parented`:return[];case`portal`:case`toplevel`:return[e.present,e.close];default:return a(e)}}function presentArityOf(e){switch(e.kind){case`parented`:return null;case`portal`:return 1;case`toplevel`:return 0;default:return a(e)}}function descriptorProblems(e=b){let t=[];for(let r of e){let e;try{e=r.ctor()}catch(e){t.push({gtype:r.gtype,problem:`ctor() threw: ${e.message}`});continue}if(!e)continue;let a=x.type_name(e.$gtype);a!==r.gtype&&t.push({gtype:r.gtype,problem:`ctor() is ${a}, not ${r.gtype}`});for(let n of methodsOf(r.children))typeof e.prototype[n]!=`function`&&t.push({gtype:r.gtype,problem:`declares children.${n}(), which ${a} does not have`});let o=i(r);for(let n of placementMethodsOf(o))typeof e.prototype[n]!=`function`&&t.push({gtype:r.gtype,problem:`declares placement.${n}(), which ${a} does not have`});let s=presentArityOf(o);if(s!==null&&o.kind!==`parented`){let n=e.prototype[o.present];typeof n==`function`&&n.length!==s&&t.push({gtype:r.gtype,problem:`placement.${o.present}() takes ${n.length} argument(s) on ${a}, and a ${o.kind} is presented with exactly ${s}`})}let c=e.prototype.present,l=n(e.$gtype,c);if(l&&o.kind===`parented`&&typeof c==`function`&&t.push({gtype:r.gtype,problem:l===`toplevel`?`implements Gtk.Root and declares no placement, so a parent would take it as an ordinary child — which GTK accepts at exit 0, leaving a root with a parent; it needs placement: { kind: 'toplevel', … }`:`has a present() that takes a parent and declares no placement, so a parent would call its adder on it — which is g_error() and aborts the process; it needs placement: { kind: 'portal', … }`}),r.textSink){let n=e.list_properties().find(e=>e.get_name()===r.textSink);n?(n.flags&x.ParamFlags.WRITABLE)===0?t.push({gtype:r.gtype,problem:`declares a READ-ONLY textSink "${r.textSink}"`}):x.type_is_a(n.value_type,x.TYPE_STRING)||t.push({gtype:r.gtype,problem:`declares textSink "${r.textSink}", which is ${x.type_name(n.value_type)}, not a string`}):t.push({gtype:r.gtype,problem:`declares textSink "${r.textSink}", which ${a} does not have`})}if(r.children.kind===`indexed`&&r.children.perLineCap!==void 0){let n=r.children.perLineCap,i=e.list_properties().find(e=>e.get_name()===n);i?(i.flags&x.ParamFlags.WRITABLE)===0?t.push({gtype:r.gtype,problem:`declares a READ-ONLY perLineCap "${n}"`}):x.type_is_a(i.value_type,x.TYPE_UINT)||t.push({gtype:r.gtype,problem:`declares perLineCap "${n}", which is ${x.type_name(i.value_type)}, not a count`}):t.push({gtype:r.gtype,problem:`declares perLineCap "${n}", which ${a} does not have`})}t.push(...policyProblems(r,e,a))}return t}function policyProblems(t,n,r){let i=[],a=n.prototype,o=t.children,requireGetter=(e,n)=>{let o=e.replace(/^set_/,`get_`);typeof a[o]!=`function`&&i.push({gtype:t.gtype,problem:`${n} uses ${e}() but ${r} has no ${o}(), so removal cannot check whether this child is still the one in place`})};if(o.kind===`single`&&requireGetter(o.set,`children.set`),o.kind===`slotted`){for(let[e,t]of Object.entries(o.slots))t.startsWith(`set_`)&&requireGetter(t,`slot "${e}"`);for(let e of Object.keys(o.wrapSlots??{}))e in o.slots||i.push({gtype:t.gtype,problem:`wrapSlots names "${e}", which is not one of ${Object.keys(o.slots).join(`, `)}`});o.defaultSlot in o.slots||i.push({gtype:t.gtype,problem:`defaultSlot "${o.defaultSlot}" is not one of ${Object.keys(o.slots).join(`, `)}`});let n=e(o);n.length>0&&!o.remove&&i.push({gtype:t.gtype,problem:`slot(s) ${n.map(e=>`"${e}"`).join(`, `)} are adder-backed, so removal needs a "remove" method and this policy names none`})}if(o.kind===`ordered`&&o.reorder===`native`&&!o.after&&i.push({gtype:t.gtype,problem:`claims reorder: 'native' with no "after" method — reorderMode() would tell an adapter the wrong thing`}),o.kind===`keyed`){let e=a[o.add],n=o.titled?3:1;typeof e==`function`&&e.length!==n&&i.push({gtype:t.gtype,problem:`titled: ${o.titled} implies ${o.add}() takes ${n} argument(s), but ${r}'s takes ${e.length}`})}return i}function addressesOf(e){let n=[];for(let i=e.first;i;i=i.next)i.kind===`element`&&i.widget&&!r(i)&&n.push(t(i));return n}export{addressesOf,y as buildSharedTree,f as descendants,l as describeLogRecord,descriptorProblems,p as dumpTree,m as findDescendant,h as gtkChildTypes,g as gtkChildren,s as installAccessibilityBackend,u as installDiagnosticsGate,d as isEnvironmentDiagnostic,methodsOf,placementMethodsOf,presentArityOf,_ as windowChromeCensus,v as windowChromeProblems,c as withAtContext};
1
+ import"../_virtual/_rolldown/runtime.js";import{classOf as e}from"../registry.js";import{adderSlots as t,addressOf as n,classPlacementKind as r,isUnparented as i,placementOf as a,unhandledPlacement as o,unhandledPolicy as s}from"../policies.js";import{installAccessibilityBackend as c,withAtContext as l}from"./at-context.js";import{describeLogRecord as u,installDiagnosticsGate as d,isEnvironmentDiagnostic as f}from"./diagnostics.js";import{descendants as p,dumpTree as m,findDescendant as h,gtkChildTypes as g,gtkChildren as _}from"./tree.js";import{windowChromeCensus as v,windowChromeProblems as y}from"./window-chrome.js";import{buildSharedTree as b}from"./shared-tree-builder.js";import{BUILTIN_DESCRIPTORS as x}from"../descriptors/index.js";import S from"gi://GObject?version=2.0";function methodsOf(e){switch(e.kind){case`none`:case`uncurated`:return[];case`single`:return[e.set];case`ordered`:return e.after?[e.append,e.after,e.remove]:[e.append,e.remove];case`indexed`:return[e.insert,e.remove];case`slotted`:return e.remove?[...Object.values(e.slots),e.remove]:Object.values(e.slots);case`keyed`:return[e.add,e.remove];case`coords`:return[e.attach,e.remove];default:return s(e)}}function placementMethodsOf(e){switch(e.kind){case`parented`:return[];case`portal`:case`toplevel`:return[e.present,e.close];default:return o(e)}}function presentArityOf(e){switch(e.kind){case`parented`:return null;case`portal`:return 1;case`toplevel`:return 0;default:return o(e)}}function descriptorProblems(t=x){let n=[];for(let i of t){let t;try{t=e(i)}catch(e){n.push({gtype:i.gtype,problem:`ctor() threw: ${e.message}`});continue}if(!t)continue;let o=S.type_name(t.$gtype);o!==i.gtype&&n.push({gtype:i.gtype,problem:`ctor() is ${o}, not ${i.gtype}`});for(let e of methodsOf(i.children))typeof t.prototype[e]!=`function`&&n.push({gtype:i.gtype,problem:`declares children.${e}(), which ${o} does not have`});let s=a(i);for(let e of placementMethodsOf(s))typeof t.prototype[e]!=`function`&&n.push({gtype:i.gtype,problem:`declares placement.${e}(), which ${o} does not have`});let c=presentArityOf(s);if(c!==null&&s.kind!==`parented`){let e=t.prototype[s.present];typeof e==`function`&&e.length!==c&&n.push({gtype:i.gtype,problem:`placement.${s.present}() takes ${e.length} argument(s) on ${o}, and a ${s.kind} is presented with exactly ${c}`})}let l=t.prototype.present,u=r(t.$gtype,l);if(u&&s.kind===`parented`&&typeof l==`function`&&n.push({gtype:i.gtype,problem:u===`toplevel`?`implements Gtk.Root and declares no placement, so a parent would take it as an ordinary child — which GTK accepts at exit 0, leaving a root with a parent; it needs placement: { kind: 'toplevel', … }`:`has a present() that takes a parent and declares no placement, so a parent would call its adder on it — which is g_error() and aborts the process; it needs placement: { kind: 'portal', … }`}),i.textSink){let e=t.list_properties().find(e=>e.get_name()===i.textSink);e?(e.flags&S.ParamFlags.WRITABLE)===0?n.push({gtype:i.gtype,problem:`declares a READ-ONLY textSink "${i.textSink}"`}):S.type_is_a(e.value_type,S.TYPE_STRING)||n.push({gtype:i.gtype,problem:`declares textSink "${i.textSink}", which is ${S.type_name(e.value_type)}, not a string`}):n.push({gtype:i.gtype,problem:`declares textSink "${i.textSink}", which ${o} does not have`})}if(i.children.kind===`indexed`&&i.children.perLineCap!==void 0){let e=i.children.perLineCap,r=t.list_properties().find(t=>t.get_name()===e);r?(r.flags&S.ParamFlags.WRITABLE)===0?n.push({gtype:i.gtype,problem:`declares a READ-ONLY perLineCap "${e}"`}):S.type_is_a(r.value_type,S.TYPE_UINT)||n.push({gtype:i.gtype,problem:`declares perLineCap "${e}", which is ${S.type_name(r.value_type)}, not a count`}):n.push({gtype:i.gtype,problem:`declares perLineCap "${e}", which ${o} does not have`})}n.push(...policyProblems(i,t,o))}return n}function policyProblems(e,n,r){let i=[],a=n.prototype,o=e.children,requireGetter=(t,n)=>{let o=t.replace(/^set_/,`get_`);typeof a[o]!=`function`&&i.push({gtype:e.gtype,problem:`${n} uses ${t}() but ${r} has no ${o}(), so removal cannot check whether this child is still the one in place`})};if(o.kind===`single`&&requireGetter(o.set,`children.set`),o.kind===`slotted`){for(let[e,t]of Object.entries(o.slots))t.startsWith(`set_`)&&requireGetter(t,`slot "${e}"`);for(let t of Object.keys(o.wrapSlots??{}))t in o.slots||i.push({gtype:e.gtype,problem:`wrapSlots names "${t}", which is not one of ${Object.keys(o.slots).join(`, `)}`});o.defaultSlot in o.slots||i.push({gtype:e.gtype,problem:`defaultSlot "${o.defaultSlot}" is not one of ${Object.keys(o.slots).join(`, `)}`});let n=t(o);n.length>0&&!o.remove&&i.push({gtype:e.gtype,problem:`slot(s) ${n.map(e=>`"${e}"`).join(`, `)} are adder-backed, so removal needs a "remove" method and this policy names none`})}if(o.kind===`ordered`&&o.reorder===`native`&&!o.after&&i.push({gtype:e.gtype,problem:`claims reorder: 'native' with no "after" method — reorderMode() would tell an adapter the wrong thing`}),o.kind===`keyed`){let t=a[o.add],n=o.titled?3:1;typeof t==`function`&&t.length!==n&&i.push({gtype:e.gtype,problem:`titled: ${o.titled} implies ${o.add}() takes ${n} argument(s), but ${r}'s takes ${t.length}`})}return i}function addressesOf(e){let t=[];for(let r=e.first;r;r=r.next)r.kind===`element`&&r.widget&&!i(r)&&t.push(n(r));return t}export{addressesOf,b as buildSharedTree,p as descendants,u as describeLogRecord,descriptorProblems,m as dumpTree,h as findDescendant,g as gtkChildTypes,_ as gtkChildren,c as installAccessibilityBackend,d as installDiagnosticsGate,f as isEnvironmentDiagnostic,methodsOf,placementMethodsOf,presentArityOf,v as windowChromeCensus,y as windowChromeProblems,l as withAtContext};
package/lib/esm/errors.js CHANGED
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";var GtkHostError=class extends Error{constructor(e,t){super(t),this.code=e,this.name=`GtkHostError`}};const e={unknownTag:e=>new GtkHostError(`unknown-tag`,`No descriptor registered for <${e}>. Register one with registerWidget({ gtype: '${e}', … }). Being a real GType in the installed typelib is not enough on its own.`),missingConstructProp:(e,t)=>new GtkHostError(`missing-construct-prop`,`<${e}> cannot be constructed without ${t}. In the installed library this is not an exception but a g_error(): the process ABORTS (SIGABRT, exit 134, core dump) with no catch and no diagnostic, so the host refuses here while a refusal is still reportable. Author ${t} on the element.`),unknownProp:(e,t)=>new GtkHostError(`unknown-prop`,`<${e}> has no property "${t}". Check the spelling against the installed GTK (camelCase and kebab-case both resolve), or bind it as a signal with on${t[0]?.toUpperCase()}${t.slice(1)}.`),readOnlyProp:(e,t)=>new GtkHostError(`read-only-prop`,`<${e}>.${t} is read-only in the installed GTK. Writing it is a silent no-op in GObject, so this host refuses it instead of dropping the value.`),noAccessor:(e,t,n)=>new GtkHostError(`no-accessor`,`<${e}>.${t} has to be written through its JS accessor — a null or a list cannot be handed to set_property, which guesses a GType and finds none — and GJS installed no "${n}" on this object. Assigning it anyway would create a plain JS property: no GObject write, no error, and notify::${t} never fires.`),badDetailedAction:(e,t,n)=>new GtkHostError(`bad-detailed-action`,`The menu item "${e}" names the action ${JSON.stringify(t)}, which GIO cannot parse: ${n}. In the installed GIO this is not an exception but a g_error() inside g_menu_item_set_detailed_action: the process ABORTS (SIGABRT, exit 134) with no catch and no diagnostic, so the host refuses here while a refusal is still reportable. A detailed action name is "app.act", "app.act::target" or "app.act(variant)".`),badListModel:(e,t,n)=>new GtkHostError(`bad-list-model`,`<${e}>.${t} is a Gio.ListModel and got ${n}. Write the portable list model — an array of strings or of { value, label } descriptors (ADR 0046) — or a real Gio.ListModel. Anything else reaches set_property as a value GObject cannot store: a CRITICAL at exit 0 and an EMPTY list, which a reader cannot tell from "no items yet".`),listModelMismatch:(e,t,n)=>new GtkHostError(`list-model-mismatch`,`<${e}>.${t} is a ${n}, and the portable list model becomes a Gtk.StringList — a Gio.ListModel, not a ${n}. GObject would turn that write into NULL without a diagnostic and leave the widget empty at exit 0. Wrap it yourself (Gtk.NoSelection.new(new Gtk.StringList({ strings }))), or use @gjsify/gtk-host/list for a factory-driven view.`),badAdjustment:(e,t,n)=>new GtkHostError(`bad-adjustment`,`<${e}>.${t} is a Gtk.Adjustment and got ${n}. Write the portable adjustment — an object naming any of value, lower, upper, stepIncrement, pageIncrement, pageSize (ADR 0047) — or a real Gtk.Adjustment. A bare number is refused on purpose: it would be the value, and value is a property of its own on every widget that takes an adjustment, so ${t}={3} and value={3} would be two spellings of one write.`),badAccessibility:(e,t)=>new GtkHostError(`bad-accessibility`,`<${e}> accessibility takes an object of ARIA names and got ${t}. Write accessibility={{ label: "Save", "row-index": 3 }} — one object, the names GTK's own accessibility block uses — or null to clear everything it set.`),unknownAria:(e,t)=>new GtkHostError(`unknown-aria`,`<${e}> accessibility has no name "${t}". The names are GTK's three ARIA tables — the members of GtkAccessibleProperty, GtkAccessibleState and GtkAccessibleRelation, kebab-spelled (label, has-popup, checked, row-index) — and they are NOT the widget's properties: "orientation" is settable on a GtkLabel that implements no GtkOrientable at all.`),ariaNotInstalled:(e,t,n)=>new GtkHostError(`aria-not-installed`,`<${e}> accessibility names "${t}", which this package's table has and the installed GTK's ${n} does not — it arrived in a newer release. Upgrade GTK, or drop the name: writing it anyway is two criticals and an unset slot at exit 0.`),badAriaValue:(e,t,n,r)=>new GtkHostError(`bad-aria-value`,`<${e}> accessibility "${t}" is typed ${n} in GTK's ARIA table and got ${r}. GTK builds no GValue of its own here — it reads back the one the caller passed with a fixed g_value_get_* — so a wrong type is a critical at exit 0 and nothing readable in the slot; measured, the slot still reports as SET afterwards for two of the three types it was tried on, which is why presence is not an oracle here. GJS guesses the GValue type from a NUMBER's integrality: 3 is an int and 3.5 a double, so a double slot written 3 goes missing and an integer slot written 3.5 does too.`),badAriaEnum:(e,t,n,r)=>new GtkHostError(`bad-aria-enum`,`<${e}> accessibility "${t}" expects ${r}, and "${n}" is not one of its values. The ARIA tables type these slots themselves and disagree with the widget where it matters: checked is a GtkAccessibleTristate, so "true" is a nick and the boolean true is a wrong GValue GTK drops without a word.`),ariaReference:(e,t)=>new GtkHostError(`aria-reference`,`<${e}> accessibility "${t}" points at ANOTHER widget, and this host has no way to name one: there is no id prop, and a framework ref is resolved after these props are applied. Set the relation imperatively for now — ref={(w) => w.update_relation([Gtk.AccessibleRelation.${t.toUpperCase().replace(/-/g,`_`)}], [Gtk.AccessibleList.new_from_list([other])])} — where you already hold both widgets.`),notAccessible:e=>new GtkHostError(`not-accessible`,`<${e}> is not a Gtk.Accessible, so accessibility has nowhere to go on it. Not every row of the generated table is a widget — the list carriers are plain GObjects that HOLD one — and those have no update_property at all (measured on Gtk.StringList). Put the accessibility on the widget that renders.`),badEnum:(e,t,n,r)=>new GtkHostError(`bad-enum`,`<${e}>.${t} expects ${r}, and "${n}" is not one of its values. Note that GObject accepts the wrong string SILENTLY — the property would have kept its old value.`),unknownSignal:(e,t,n)=>new GtkHostError(`unknown-signal`,`<${e}> emits no signal "${n}" (bound as ${t}). Check the spelling against the installed GTK, or use the escape hatch on:<raw-signal-name> if the name is irregular.`),signalTaken:(e,t,n,r)=>new GtkHostError(`signal-taken`,`<${e}> already binds "${r}" through ${n}, so ${t} would silently replace it — GObject has one handler per connect, and this host keeps one per signal name. Use one spelling, or combine the two callbacks yourself.`),eventModifier:(e,t)=>new GtkHostError(`event-modifier`,`${e} carries the DOM listener modifier ".${t}", which has no GObject meaning: a signal is emitted on one object and does not propagate through a tree, so there is no capture phase and nothing to be passive about. Drop the modifier (${e.slice(0,e.length-t.length)}); for GTK4's own propagation phases set "propagation-phase" on a Gtk.EventController instead.`),badString:(e,t,n)=>new GtkHostError(`bad-string`,`<${e}>.${t} is a string property and got a ${n}. Numbers and booleans are stringified; anything else has no unambiguous spelling, and GObject would have thrown from inside the next rebuild.`),badBoolean:(e,t,n)=>new GtkHostError(`bad-boolean`,`<${e}>.${t} is a boolean and got the string "${n}". JS truthiness would make "false" mean TRUE — the exact silent-wrong-value this host exists to refuse. Pass a real boolean.`),badFlags:(e,t,n,r)=>new GtkHostError(`bad-flags`,`<${e}>.${t} is the flags type ${r}, and "${n}" names a member it does not have. Join the member nicks with "|" ("spellcheck|lowercase"), or pass the numeric value. GObject would have dropped the string silently.`),blankFlags:(e,t,n,r)=>new GtkHostError(`blank-flags`,`<${e}>.${t} is the flags type ${r}, and "${n}" has an empty member. GTK reads an empty flags string as 0 — every flag cleared, no diagnostic — so this host refuses it. Drop the stray "|", or write the members you mean.`),textNotAccepted:(e,t)=>new GtkHostError(`text-not-accepted`,`<${e}> has no text sink, so the text ${JSON.stringify(t.slice(0,32))} has nowhere to go. Wrap it in a widget that takes text (<GtkLabel>), or set the property directly.`),unclaimedChild:(e,t)=>new GtkHostError(`unclaimed-child`,`<${e}> declares children: { kind: 'none' }, so it cannot adopt <${t}>. Fix one of three things: give the parent a child policy, wrap the child in a container, or set the child on a property (e.g. a "child" or "content" property).`),unknownSlot:(e,t,n)=>new GtkHostError(`unknown-slot`,`<${e}> has no slot "${t}". Known slots: ${n.length>0?n.join(`, `):`none — it declares no slot names`}.`),slotNeedsRemove:(e,t,n)=>new GtkHostError(`slot-needs-remove`,`<${e}> puts children into slot "${t}" with ${n}() and its policy names no "remove" method, so this child cannot be taken out again. A set_-prefixed slot is emptied by writing null back through the setter and needs nothing; an adder-backed one needs children.remove. Add it to the descriptor.`),rejectedChild:(e,t,n)=>new GtkHostError(`rejected-child`,`<${e}> refused <${t}>: ${n}. The container accepts only certain child types (e.g. AdwPreferencesPage takes AdwPreferencesGroup); the descriptor cannot know that, GTK does.`),uncuratedPlacement:(e,t)=>new GtkHostError(`uncurated-placement`,`<${e}> comes from the GENERATED table, which knows the tag but not how the widget adopts a child, so it cannot take <${t}>. Guessing is the one thing that is not available here: \`add\`, \`append\` and \`set_child\` all exist somewhere in GTK and calling the wrong one is a warning at exit 0. Add a curated policy for ${e} in descriptors/, or mount into a container that has one.`),siblingCycle:e=>new GtkHostError(`sibling-cycle`,`The child list of <${e}> does not terminate. A renderer linked a node to itself or into a loop; the host refuses to walk it rather than spin. This is a host or adapter bug, not an application one — please report it with the reordering that produced it.`),notAWidget:e=>new GtkHostError(`not-a-widget`,`<${e}> is not a Gtk.Widget, so it cannot be placed as a child. Non-widget GObjects (controllers, filters, models) attach to a property, not to a parent.`),occupiedSlot:(e,t,n)=>new GtkHostError(`occupied-slot`,`<${e}> already holds a child the application put there, and ${n}() takes only ONE — placing <${t}> would unparent it. GTK does that silently: no throw, no warning, exit 0, and the application's own widget is simply gone. Mount into a container of your own inside <${e}>, or clear the existing child first (${n}(null)) if replacing it is the intent.`),placementMethodMissing:(e,t,n,r)=>new GtkHostError(`placement-method-missing`,`<${e}> declares placement: { kind: '${t}', ${r}: '${n}' } and the installed class has no ${n}(). A node with this placement is placed by calling that method on the node itself — nothing goes into the parent — so without it the node can never reach the screen and never leave it. Fix the descriptor, or drop the placement and give the widget an ordinary child policy.`),unparentableChild:(e,t,n,r)=>new GtkHostError(`unparentable-child`,`<${e}> cannot adopt <${t}>: ${r}. In the installed libraries placing it anyway is not an exception — it is either a g_error() that ABORTS the process (SIGABRT, exit 134, no catch, no diagnostic) or an acceptance at exit 0 that leaves a root inside a child list — so the host refuses here while a refusal is still reportable. Declare placement: { kind: '${n}', … } on the descriptor for <${t}> so the host places it the way the library does, or, if this widget really is an ordinary child, say so with placement: { kind: 'parented' }.`),notAnElement:e=>new GtkHostError(`not-an-element`,`Only an element node owns a widget, and this node is a ${e}. A text node's content lives in its PARENT's text sink and an anchor owns nothing at all — neither has a widget to hand back. Ask the parent element instead.`),destroyedNode:e=>new GtkHostError(`destroyed-node`,`<${e}> was destroyed, so its widget is gone. Asking again would MATERIALISE a fresh, propertyless, unparented widget — \`destroy\` clears props and layout precisely so a destroyed element cannot look re-materialisable — and a caller holding that widget would be looking at nothing on screen.`),notAHostParent:e=>new GtkHostError(`not-a-host-parent`,`insert() needs a host element as the parent and got ${e}. A raw widget cannot be one: the shadow tree lives in the host's own fields, so writing them onto a GObject wrapper renders nothing and reports nothing — Vue's <Teleport to="someWidget"> hands the widget through verbatim and landed exactly here. Wrap it with adopt(widget) first, which is what mountRoot() does.`)};export{GtkHostError,e as err};
1
+ import"./_virtual/_rolldown/runtime.js";var GtkHostError=class extends Error{constructor(e,t){super(t),this.code=e,this.name=`GtkHostError`}};const e={unknownTag:e=>new GtkHostError(`unknown-tag`,`No descriptor registered for <${e}>. Register one with registerWidget({ gtype: '${e}', … }). Being a real GType in the installed typelib is not enough on its own.`),absentClass:e=>new GtkHostError(`absent-class`,`<${e}> is in the widget table and the running GTK has no class for it. The table is generated from one GIR, on one host, and a platform omits what it does not build — GTK does not build its Unix print dialogs on Windows, so no typelib there registers them. Use a widget this GTK really has (the portable print dialog is GtkPrintDialog, not GtkPrintUnixDialog), and expect the same refusal for any class a future platform drops.`),missingConstructProp:(e,t)=>new GtkHostError(`missing-construct-prop`,`<${e}> cannot be constructed without ${t}. In the installed library this is not an exception but a g_error(): the process ABORTS (SIGABRT, exit 134, core dump) with no catch and no diagnostic, so the host refuses here while a refusal is still reportable. Author ${t} on the element.`),unknownProp:(e,t)=>new GtkHostError(`unknown-prop`,`<${e}> has no property "${t}". Check the spelling against the installed GTK (camelCase and kebab-case both resolve), or bind it as a signal with on${t[0]?.toUpperCase()}${t.slice(1)}.`),readOnlyProp:(e,t)=>new GtkHostError(`read-only-prop`,`<${e}>.${t} is read-only in the installed GTK. Writing it is a silent no-op in GObject, so this host refuses it instead of dropping the value.`),noAccessor:(e,t,n)=>new GtkHostError(`no-accessor`,`<${e}>.${t} has to be written through its JS accessor — a null or a list cannot be handed to set_property, which guesses a GType and finds none — and GJS installed no "${n}" on this object. Assigning it anyway would create a plain JS property: no GObject write, no error, and notify::${t} never fires.`),badDetailedAction:(e,t,n)=>new GtkHostError(`bad-detailed-action`,`The menu item "${e}" names the action ${JSON.stringify(t)}, which GIO cannot parse: ${n}. In the installed GIO this is not an exception but a g_error() inside g_menu_item_set_detailed_action: the process ABORTS (SIGABRT, exit 134) with no catch and no diagnostic, so the host refuses here while a refusal is still reportable. A detailed action name is "app.act", "app.act::target" or "app.act(variant)".`),badListModel:(e,t,n)=>new GtkHostError(`bad-list-model`,`<${e}>.${t} is a Gio.ListModel and got ${n}. Write the portable list model — an array of strings or of { value, label } descriptors (ADR 0046) — or a real Gio.ListModel. Anything else reaches set_property as a value GObject cannot store: a CRITICAL at exit 0 and an EMPTY list, which a reader cannot tell from "no items yet".`),listModelMismatch:(e,t,n)=>new GtkHostError(`list-model-mismatch`,`<${e}>.${t} is a ${n}, and the portable list model becomes a Gtk.StringList — a Gio.ListModel, not a ${n}. GObject would turn that write into NULL without a diagnostic and leave the widget empty at exit 0. Wrap it yourself (Gtk.NoSelection.new(new Gtk.StringList({ strings }))), or use @gjsify/gtk-host/list for a factory-driven view.`),badAdjustment:(e,t,n)=>new GtkHostError(`bad-adjustment`,`<${e}>.${t} is a Gtk.Adjustment and got ${n}. Write the portable adjustment — an object naming any of value, lower, upper, stepIncrement, pageIncrement, pageSize (ADR 0047) — or a real Gtk.Adjustment. A bare number is refused on purpose: it would be the value, and value is a property of its own on every widget that takes an adjustment, so ${t}={3} and value={3} would be two spellings of one write.`),badAccessibility:(e,t)=>new GtkHostError(`bad-accessibility`,`<${e}> accessibility takes an object of ARIA names and got ${t}. Write accessibility={{ label: "Save", "row-index": 3 }} — one object, the names GTK's own accessibility block uses — or null to clear everything it set.`),unknownAria:(e,t)=>new GtkHostError(`unknown-aria`,`<${e}> accessibility has no name "${t}". The names are GTK's three ARIA tables — the members of GtkAccessibleProperty, GtkAccessibleState and GtkAccessibleRelation, kebab-spelled (label, has-popup, checked, row-index) — and they are NOT the widget's properties: "orientation" is settable on a GtkLabel that implements no GtkOrientable at all.`),ariaNotInstalled:(e,t,n)=>new GtkHostError(`aria-not-installed`,`<${e}> accessibility names "${t}", which this package's table has and the installed GTK's ${n} does not — it arrived in a newer release. Upgrade GTK, or drop the name: writing it anyway is two criticals and an unset slot at exit 0.`),badAriaValue:(e,t,n,r)=>new GtkHostError(`bad-aria-value`,`<${e}> accessibility "${t}" is typed ${n} in GTK's ARIA table and got ${r}. GTK builds no GValue of its own here — it reads back the one the caller passed with a fixed g_value_get_* — so a wrong type is a critical at exit 0 and nothing readable in the slot; measured, the slot still reports as SET afterwards for two of the three types it was tried on, which is why presence is not an oracle here. GJS guesses the GValue type from a NUMBER's integrality: 3 is an int and 3.5 a double, so a double slot written 3 goes missing and an integer slot written 3.5 does too.`),badAriaEnum:(e,t,n,r)=>new GtkHostError(`bad-aria-enum`,`<${e}> accessibility "${t}" expects ${r}, and "${n}" is not one of its values. The ARIA tables type these slots themselves and disagree with the widget where it matters: checked is a GtkAccessibleTristate, so "true" is a nick and the boolean true is a wrong GValue GTK drops without a word.`),ariaReference:(e,t)=>new GtkHostError(`aria-reference`,`<${e}> accessibility "${t}" points at ANOTHER widget, and this host has no way to name one: there is no id prop, and a framework ref is resolved after these props are applied. Set the relation imperatively for now — ref={(w) => w.update_relation([Gtk.AccessibleRelation.${t.toUpperCase().replace(/-/g,`_`)}], [Gtk.AccessibleList.new_from_list([other])])} — where you already hold both widgets.`),notAccessible:e=>new GtkHostError(`not-accessible`,`<${e}> is not a Gtk.Accessible, so accessibility has nowhere to go on it. Not every row of the generated table is a widget — the list carriers are plain GObjects that HOLD one — and those have no update_property at all (measured on Gtk.StringList). Put the accessibility on the widget that renders.`),badEnum:(e,t,n,r)=>new GtkHostError(`bad-enum`,`<${e}>.${t} expects ${r}, and "${n}" is not one of its values. Note that GObject accepts the wrong string SILENTLY — the property would have kept its old value.`),unknownSignal:(e,t,n)=>new GtkHostError(`unknown-signal`,`<${e}> emits no signal "${n}" (bound as ${t}). Check the spelling against the installed GTK, or use the escape hatch on:<raw-signal-name> if the name is irregular.`),signalTaken:(e,t,n,r)=>new GtkHostError(`signal-taken`,`<${e}> already binds "${r}" through ${n}, so ${t} would silently replace it — GObject has one handler per connect, and this host keeps one per signal name. Use one spelling, or combine the two callbacks yourself.`),eventModifier:(e,t)=>new GtkHostError(`event-modifier`,`${e} carries the DOM listener modifier ".${t}", which has no GObject meaning: a signal is emitted on one object and does not propagate through a tree, so there is no capture phase and nothing to be passive about. Drop the modifier (${e.slice(0,e.length-t.length)}); for GTK4's own propagation phases set "propagation-phase" on a Gtk.EventController instead.`),badString:(e,t,n)=>new GtkHostError(`bad-string`,`<${e}>.${t} is a string property and got a ${n}. Numbers and booleans are stringified; anything else has no unambiguous spelling, and GObject would have thrown from inside the next rebuild.`),badBoolean:(e,t,n)=>new GtkHostError(`bad-boolean`,`<${e}>.${t} is a boolean and got the string "${n}". JS truthiness would make "false" mean TRUE — the exact silent-wrong-value this host exists to refuse. Pass a real boolean.`),badFlags:(e,t,n,r)=>new GtkHostError(`bad-flags`,`<${e}>.${t} is the flags type ${r}, and "${n}" names a member it does not have. Join the member nicks with "|" ("spellcheck|lowercase"), or pass the numeric value. GObject would have dropped the string silently.`),blankFlags:(e,t,n,r)=>new GtkHostError(`blank-flags`,`<${e}>.${t} is the flags type ${r}, and "${n}" has an empty member. GTK reads an empty flags string as 0 — every flag cleared, no diagnostic — so this host refuses it. Drop the stray "|", or write the members you mean.`),textNotAccepted:(e,t)=>new GtkHostError(`text-not-accepted`,`<${e}> has no text sink, so the text ${JSON.stringify(t.slice(0,32))} has nowhere to go. Wrap it in a widget that takes text (<GtkLabel>), or set the property directly.`),unclaimedChild:(e,t)=>new GtkHostError(`unclaimed-child`,`<${e}> declares children: { kind: 'none' }, so it cannot adopt <${t}>. Fix one of three things: give the parent a child policy, wrap the child in a container, or set the child on a property (e.g. a "child" or "content" property).`),unknownSlot:(e,t,n)=>new GtkHostError(`unknown-slot`,`<${e}> has no slot "${t}". Known slots: ${n.length>0?n.join(`, `):`none — it declares no slot names`}.`),slotNeedsRemove:(e,t,n)=>new GtkHostError(`slot-needs-remove`,`<${e}> puts children into slot "${t}" with ${n}() and its policy names no "remove" method, so this child cannot be taken out again. A set_-prefixed slot is emptied by writing null back through the setter and needs nothing; an adder-backed one needs children.remove. Add it to the descriptor.`),rejectedChild:(e,t,n)=>new GtkHostError(`rejected-child`,`<${e}> refused <${t}>: ${n}. The container accepts only certain child types (e.g. AdwPreferencesPage takes AdwPreferencesGroup); the descriptor cannot know that, GTK does.`),uncuratedPlacement:(e,t)=>new GtkHostError(`uncurated-placement`,`<${e}> comes from the GENERATED table, which knows the tag but not how the widget adopts a child, so it cannot take <${t}>. Guessing is the one thing that is not available here: \`add\`, \`append\` and \`set_child\` all exist somewhere in GTK and calling the wrong one is a warning at exit 0. Add a curated policy for ${e} in descriptors/, or mount into a container that has one.`),siblingCycle:e=>new GtkHostError(`sibling-cycle`,`The child list of <${e}> does not terminate. A renderer linked a node to itself or into a loop; the host refuses to walk it rather than spin. This is a host or adapter bug, not an application one — please report it with the reordering that produced it.`),notAWidget:e=>new GtkHostError(`not-a-widget`,`<${e}> is not a Gtk.Widget, so it cannot be placed as a child. Non-widget GObjects (controllers, filters, models) attach to a property, not to a parent.`),occupiedSlot:(e,t,n)=>new GtkHostError(`occupied-slot`,`<${e}> already holds a child the application put there, and ${n}() takes only ONE — placing <${t}> would unparent it. GTK does that silently: no throw, no warning, exit 0, and the application's own widget is simply gone. Mount into a container of your own inside <${e}>, or clear the existing child first (${n}(null)) if replacing it is the intent.`),placementMethodMissing:(e,t,n,r)=>new GtkHostError(`placement-method-missing`,`<${e}> declares placement: { kind: '${t}', ${r}: '${n}' } and the installed class has no ${n}(). A node with this placement is placed by calling that method on the node itself — nothing goes into the parent — so without it the node can never reach the screen and never leave it. Fix the descriptor, or drop the placement and give the widget an ordinary child policy.`),unparentableChild:(e,t,n,r)=>new GtkHostError(`unparentable-child`,`<${e}> cannot adopt <${t}>: ${r}. In the installed libraries placing it anyway is not an exception — it is either a g_error() that ABORTS the process (SIGABRT, exit 134, no catch, no diagnostic) or an acceptance at exit 0 that leaves a root inside a child list — so the host refuses here while a refusal is still reportable. Declare placement: { kind: '${n}', … } on the descriptor for <${t}> so the host places it the way the library does, or, if this widget really is an ordinary child, say so with placement: { kind: 'parented' }.`),notAnElement:e=>new GtkHostError(`not-an-element`,`Only an element node owns a widget, and this node is a ${e}. A text node's content lives in its PARENT's text sink and an anchor owns nothing at all — neither has a widget to hand back. Ask the parent element instead.`),destroyedNode:e=>new GtkHostError(`destroyed-node`,`<${e}> was destroyed, so its widget is gone. Asking again would MATERIALISE a fresh, propertyless, unparented widget — \`destroy\` clears props and layout precisely so a destroyed element cannot look re-materialisable — and a caller holding that widget would be looking at nothing on screen.`),notAHostParent:e=>new GtkHostError(`not-a-host-parent`,`insert() needs a host element as the parent and got ${e}. A raw widget cannot be one: the shadow tree lives in the host's own fields, so writing them onto a GObject wrapper renders nothing and reports nothing — Vue's <Teleport to="someWidget"> hands the widget through verbatim and landed exactly here. Wrap it with adopt(widget) first, which is what mountRoot() does.`)};export{GtkHostError,e as err};
package/lib/esm/fonts.js CHANGED
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{isFontFace as e,resolveFontSources as t}from"./font-dir.js";import{describeFontFamilyMatch as n,matchFontFamilies as r,matchFontFamily as i}from"./font-families.js";import{ADWAITA_UI_FONT_FAMILY as a,GNOME_UI_FONT_POINT_SIZE as o,UI_FONT_POLICIES as s,planUiFont as c,planUiFontPolicy as l}from"./ui-font.js";import u from"gi://Gtk?version=4.0";import d from"gi://Gio?version=2.0";import f from"gi://GLib?version=2.0";import p from"gi://PangoCairo?version=1.0";function isUnsupportedByFontMap(e){return e instanceof f.Error&&e.matches(d.io_error_quark(),d.IOErrorEnum.NOT_SUPPORTED)}function initFonts(e={}){let i=t({...e,env:{GJSIFY_FONT_DIR:f.getenv(`GJSIFY_FONT_DIR`)??void 0,GJSIFY_GTK_RUNTIME_FONT_DIR:f.getenv(`GJSIFY_GTK_RUNTIME_FONT_DIR`)??void 0}}),a=i.find(e=>e.origin===`app`)?.dir,o=[],s=[],c=[],l=[],u=e.expectedFamilies??[];if(i.length===0&&u.length===0)return{dir:a,sources:o,uiFont:void 0,registered:s,declined:c,failed:l,families:[],matches:[]};let m=p.FontMap.get_default(),h=i.length===0?[]:familyNames(m);for(let e of i){let t=[],n=[],r=[],i=[];collectFaces(d.File.new_for_path(e.dir),t,i);for(let e of t.sort())try{m.add_font_file(e),n.push(e)}catch(t){if(isUnsupportedByFontMap(t)){r.push(e);continue}i.push({path:e,message:messageOf(t)})}s.push(...n),c.push(...r),l.push(...i),o.push({...e,registered:n,declined:r,failed:i})}let g=familyNames(m),_=i.length===0?[]:g.filter(e=>!h.includes(e)).sort(),v=r(u,g);captureUiFontBaseline();let y=e.uiFont===void 0?void 0:applyUiFontPolicy(e.uiFont);for(let e of l)console.warn(`initFonts: ${e.path} could not be read as an application font (${e.message}). Text asking for a family this application ships will render in a substituted one.`);for(let e of v)e.kind!==`exact`&&console.warn(`initFonts: ${n(e)}`);return{dir:a,sources:o,uiFont:y,registered:s,declined:c,failed:l,families:_,matches:v}}let m=!1,h;function captureUiFontBaseline(){if(m)return h;let e=u.Settings.get_default();if(e!==null)return h=e.gtk_font_name??void 0,m=!0,h}function uiFontBaseline(){return captureUiFontBaseline()}function applyUiFontPolicy(e){let t=typeof e==`string`?{policy:e}:e,n=t.settings===void 0?u.Settings.get_default():t.settings;if(n===null)return console.warn("applyUiFontPolicy: no Gtk.Settings — the toolkit is not initialised yet, so the policy was NOT applied. Call this after Gtk.init() (or from an application's `startup`), which is still before any window is built."),{next:void 0,kind:`uninitialised`,family:void 0,size:void 0};let r=captureUiFontBaseline(),i=l({...t,family:t.family??resolvedAdwaitaFamily(t.policy),current:n.gtk_font_name??void 0,baseline:r});return i.next===void 0||(n.gtk_font_name=i.next),i}function resolvedAdwaitaFamily(e){if(e!==`adwaita`)return;let t=adwaitaUiFontAvailability();if(t.match.family!==void 0)return t.match.family;console.warn(`applyUiFontPolicy: "${t.family}" is ${t.match.kind} on this font map, so asking for it will render in a substituted family. Register the runtime bundle's faces with initFonts() first, and check adwaitaUiFontAvailability() before offering this policy.`)}function adwaitaUiFontAvailability(e=a){let t=i(e,familyNames(p.FontMap.get_default()));return{family:e,match:t,available:t.kind!==`absent`}}function familyNames(e){return e.list_families().map(e=>e.get_name())}function collectFaces(t,n,r){try{let i=t.enumerate_children(`standard::name,standard::type`,d.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,null);for(let t=i.next_file(null);t!==null;t=i.next_file(null)){let a=i.get_child(t),o=a.get_path();o!==null&&(t.get_file_type()===d.FileType.DIRECTORY?collectFaces(a,n,r):e(t.get_name())&&n.push(o))}}catch(e){r.push({path:t.get_path()??``,message:messageOf(e)})}}function messageOf(e){return e instanceof f.Error||e instanceof Error?e.message:String(e)}export{a as ADWAITA_UI_FONT_FAMILY,o as GNOME_UI_FONT_POINT_SIZE,s as UI_FONT_POLICIES,adwaitaUiFontAvailability,applyUiFontPolicy,n as describeFontFamilyMatch,initFonts,isUnsupportedByFontMap,r as matchFontFamilies,i as matchFontFamily,c as planUiFont,l as planUiFontPolicy,t as resolveFontSources,uiFontBaseline};
1
+ import"./_virtual/_rolldown/runtime.js";import{isFontFace as e,resolveFontSources as t}from"./font-dir.js";import{describeFontFamilyMatch as n,matchFontFamilies as r,matchFontFamily as i}from"./font-families.js";import{ADWAITA_UI_FONT_FAMILY as a,GNOME_UI_FONT_POINT_SIZE as o,UI_FONT_POLICIES as s,planUiFont as c,planUiFontPolicy as l}from"./ui-font.js";import u from"gi://Gtk?version=4.0";import d from"gi://Gio?version=2.0";import f from"gi://GLib?version=2.0";import p from"gi://PangoCairo?version=1.0";import{CAIRO_FONT_TYPE_FT as m,fontErrorMessage as h,fontMapFamilies as g,isUnsupportedByFontMap as _,registerFontFaces as v}from"@gjsify/utils/font-map";function initFonts(e={}){let i=t({...e,env:{GJSIFY_FONT_DIR:f.getenv(`GJSIFY_FONT_DIR`)??void 0,GJSIFY_GTK_RUNTIME_FONT_DIR:f.getenv(`GJSIFY_GTK_RUNTIME_FONT_DIR`)??void 0}}),a=i.find(e=>e.origin===`app`)?.dir,o=[],s=[],c=[],l=[],u=[],m=e.expectedFamilies??[];if(i.length===0&&m.length===0)return{dir:a,sources:o,uiFont:void 0,registered:s,declined:c,unreachable:l,failed:u,families:[],matches:[],fontconfigFallback:!1};let h=[],_=p.FontMap.get_default(),y=i.map(e=>({source:e,registered:[],declined:[],unreachable:[],failed:[]})),b=!1;for(let e of y){let t=[];collectFaces(d.File.new_for_path(e.source.dir),t,e.failed);let n=v(t.sort(),_);(h.length===0||n.fontconfigFallback)&&(h=n.before),n.fontconfigFallback&&(b=!0),n.map!==void 0&&(_=n.map),e.registered.push(...n.registered),e.declined.push(...n.declined),e.unreachable.push(...n.unreachable),e.failed.push(...n.failed)}for(let e of y)s.push(...e.registered),c.push(...e.declined),l.push(...e.unreachable),u.push(...e.failed),o.push({...e.source,registered:e.registered,declined:e.declined,unreachable:e.unreachable,failed:e.failed});let x=g(_),S=i.length===0?[]:x.filter(e=>!h.includes(e)).sort(),C=r(m,x);captureUiFontBaseline();let w=e.uiFont===void 0?void 0:applyUiFontPolicy(e.uiFont);for(let e of u)console.warn(`initFonts: ${e.path} could not be read as an application font (${e.message}). Text asking for a family this application ships will render in a substituted one.`);for(let e of l)console.warn(`initFonts: ${e} is registered and its family is on the font map, but text asking for it will still render substituted: the font map had already resolved that family to the fallback and the cached answer cannot be invalidated. Call initFonts() before any text is laid out.`);for(let e of C)e.kind!==`exact`&&console.warn(`initFonts: ${n(e)}`);return{dir:a,sources:o,uiFont:w,registered:s,declined:c,unreachable:l,failed:u,families:S,matches:C,fontconfigFallback:b}}let y=!1,b;function captureUiFontBaseline(){if(y)return b;let e=u.Settings.get_default();if(e!==null)return b=e.gtk_font_name??void 0,y=!0,b}function uiFontBaseline(){return captureUiFontBaseline()}function applyUiFontPolicy(e){let t=typeof e==`string`?{policy:e}:e,n=t.settings===void 0?u.Settings.get_default():t.settings;if(n===null)return console.warn("applyUiFontPolicy: no Gtk.Settings — the toolkit is not initialised yet, so the policy was NOT applied. Call this after Gtk.init() (or from an application's `startup`), which is still before any window is built."),{next:void 0,kind:`uninitialised`,family:void 0,size:void 0};let r=captureUiFontBaseline(),i=l({...t,family:t.family??resolvedAdwaitaFamily(t.policy),current:n.gtk_font_name??void 0,baseline:r});return i.next===void 0||(n.gtk_font_name=i.next),i}function resolvedAdwaitaFamily(e){if(e!==`adwaita`)return;let t=adwaitaUiFontAvailability();if(t.match.family!==void 0)return t.match.family;console.warn(`applyUiFontPolicy: "${t.family}" is ${t.match.kind} on this font map, so asking for it will render in a substituted family. Register the runtime bundle's faces with initFonts() first, and check adwaitaUiFontAvailability() before offering this policy.`)}function adwaitaUiFontAvailability(e=a){let t=i(e,g(p.FontMap.get_default()));return{family:e,match:t,available:t.kind!==`absent`}}function collectFaces(t,n,r){try{let i=t.enumerate_children(`standard::name,standard::type`,d.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,null);for(let t=i.next_file(null);t!==null;t=i.next_file(null)){let a=i.get_child(t),o=a.get_path();o!==null&&(t.get_file_type()===d.FileType.DIRECTORY?collectFaces(a,n,r):e(t.get_name())&&n.push(o))}}catch(e){r.push({path:t.get_path()??``,message:h(e)})}}export{a as ADWAITA_UI_FONT_FAMILY,m as CAIRO_FONT_TYPE_FT,o as GNOME_UI_FONT_POINT_SIZE,s as UI_FONT_POLICIES,adwaitaUiFontAvailability,applyUiFontPolicy,n as describeFontFamilyMatch,initFonts,_ as isUnsupportedByFontMap,r as matchFontFamilies,i as matchFontFamily,c as planUiFont,l as planUiFontPolicy,t as resolveFontSources,uiFontBaseline};
package/lib/esm/host.js CHANGED
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{GtkHostError as e,err as t}from"./errors.js";import{reconcileStringList as n}from"./list-model.js";import{coerce as r,isConstructOnly as i,paramSpecs as a,removedValue as o,requireSpec as s,toPropertyName as c}from"./props.js";import{applyAccessibilityPlan as l,isAccessibleClass as u,planAccessibility as d}from"./accessibility.js";import{beginHostWrite as f,clearHandlers as p,endHostWrite as m,isEventProp as h,setHandler as g,toSignalName as _}from"./signals.js";import{addressOf as v,closeOutsideParent as y,detachOutsideParent as b,insertChild as x,isUnparented as S,makeDetachedContainer as C,makeWrapper as w,outsideParentOf as T,placeOutsideParent as E,refuseUnknownSlot as D,refuseUnparentable as O,removeChild as k,setterSlotOf as A,setterSlots as j,slotOccupant as M}from"./policies.js";import{lookupWidget as N,nearestRegistered as P}from"./registry.js";import F from"gi://GObject?version=2.0";function createElement(e,t){let n={kind:`element`,descriptor:N(e),widget:null,wrapper:null,slot:null,parent:null,prev:null,next:null,first:null,last:null,handlers:new Map,listeners:new Map,props:{},layout:null,accessibility:null,textFromChildren:!1,attached:!1,destroyed:!1,foreign:[],portalWatch:null};if(t)for(let[e,r]of Object.entries(t))setProp(n,e,r);return n}const createText=e=>({kind:`text`,data:e,parent:null,prev:null,next:null}),createAnchor=(e=``)=>({kind:`anchor`,data:e,parent:null,prev:null,next:null}),isText=e=>e.kind===`text`;function releaseWidget(e){let t=e.widget?T(e.descriptor):null;t&&y(e,t),e.widget=null,e.wrapper=null}function materialize(e){if(e.widget)return e.widget;for(let n of e.descriptor.requiresProps??[])if(!(n in e.props))throw t.missingConstructProp(e.descriptor.gtype,n);let n=e.descriptor.ctor(),i=a(n,e.descriptor.gtype),o={};for(let[t,n]of Object.entries(e.props))o[t]=r(s(i,e.descriptor.gtype,t),n,e.descriptor.gtype);f(null);try{e.widget=new n(o)}finally{m()}try{replayInto(e)}catch(t){p(e);for(let t of childSnapshot(e))t.kind===`element`&&t.attached&&(k(e,t),t.attached=!1);throw releaseWidget(e),t}return e.widget}function replayInto(e){for(let[t,n]of e.listeners)g(e,t,n);e.accessibility&&l(e.widget,d(e.descriptor.gtype,null,e.accessibility));for(let t of siblingsFrom(e.first,e))t.kind===`element`&&attach(e,t);e.textFromChildren&&flushText(e)}function setProp(e,t,l,u){if(h(t))return setEventHandler(e,t,l);if(t===`slot`)return setSlot(e,l);if(t===`accessibility`)return setAccessibility(e,l);if(t===`layout`){let t=l,n=e.parent;if(!n||!e.widget){e.layout=t;return}let r=e.layout;replaceAt(e,n,()=>{e.layout=t},()=>{e.layout=r});return}let d=c(t),p=s(a(e.descriptor.ctor(),e.descriptor.gtype),e.descriptor.gtype,d),g=l==null,_=g?o(e.descriptor,p):r(p,l,e.descriptor.gtype);e.widget!==null&&takesAccessorRoute(_)&&!i(p)&&requireAccessor(e,e.widget,d);let v=d in e.props?e.props[d]:void 0;if(g?delete e.props[d]:e.props[d]=l,e.widget){if(i(p))return rebuild(e,d,v);f(e.widget);try{n(e.widget,accessorName(d),_)||writeProperty(e.widget,d,_)}finally{m()}}}function writeProperty(e,t,n){if(!takesAccessorRoute(n)){e.set_property(t,n);return}let r=accessorName(t);e[r]=n}const accessorName=e=>e.replace(/-([a-z0-9])/g,(e,t)=>t.toUpperCase()),takesAccessorRoute=e=>e===null||Array.isArray(e);function requireAccessor(e,n,r){let i=accessorName(r);if(!(i in n))throw t.noAccessor(e.descriptor.gtype,r,i)}function setEventHandler(e,t,n){e.widget?g(e,t,n):n&&assertSignalExists(e,t),n?e.listeners.set(t,n):e.listeners.delete(t)}function assertSignalExists(e,n){let r=_(n,e.descriptor.eventAliases).split(`::`)[0],i=e.descriptor.ctor().$gtype;if(F.signal_lookup(r,i)===0)throw t.unknownSignal(e.descriptor.gtype,n,r)}function setAccessibility(e,n){let r=n??null,i=d(e.descriptor.gtype,e.accessibility,r);if(r!==null&&!u(e.descriptor.ctor()))throw t.notAccessible(e.descriptor.gtype);e.widget&&l(e.widget,i),e.accessibility=r}function setSlot(e,t){if(e.slot===t)return;let n=e.parent;if(!n||!e.widget){e.slot=t;return}let r=e.slot;replaceAt(e,n,()=>{e.slot=t},()=>{e.slot=r})}function replaceAt(e,t,n,r){k(t,e),e.attached=!1,n();try{attach(t,e)}catch(n){r();try{attach(t,e)}catch{}throw n}}function rebuild(e,t,n){let r=e.parent;if(e.widget){p(e);for(let t of childSnapshot(e))t.kind===`element`&&(k(e,t),t.attached=!1);r&&!T(e.descriptor)&&k(r,e)}releaseWidget(e),e.attached=!1;try{materialize(e)}catch(i){t!==void 0&&(n===void 0?delete e.props[t]:e.props[t]=n);try{materialize(e),r&&attach(r,e)}catch{}throw i}r&&attach(r,e)}function setText(e,t){e.data=t,e.kind===`text`&&e.parent&&flushText(e.parent)}function setElementText(e,t){writeTextSink(e,t),e.textFromChildren=!1,destroyChildren(e)}function flushText(e){let t=``,n=!1;for(let r of childNodes(e))r.kind===`text`&&(t+=r.data,n=!0);if(t===``&&!e.textFromChildren)return;let r=e.descriptor.textSink;if(t===``&&r&&holdsElementInSetterSlot(e)){e.textFromChildren=!1,delete e.props[r];return}writeTextSink(e,t),e.textFromChildren=n}function*setterSlotChildren(e){for(let t of siblingsFrom(e.first,e))t.kind===`element`&&t.attached&&!S(t)&&A(e,t)&&(yield t)}const holdsElementInSetterSlot=e=>!setterSlotChildren(e).next().done;function writeTextSink(e,n){let i=e.descriptor.textSink;if(!i)throw t.textNotAccepted(e.descriptor.gtype,n);materialize(e);let o=e.descriptor.children,c=o.kind===`single`?o.set:null;if(c&&!holdsOursInSlot(e,null)&&appOccupant(e.widget,e.descriptor,c))throw t.occupiedSlot(e.descriptor.gtype,`text`,c);let l=s(a(e.descriptor.ctor(),e.descriptor.gtype),e.descriptor.gtype,i);f(e.widget);try{e.widget.set_property(i,r(l,n,e.descriptor.gtype))}finally{m()}e.props[i]=n;for(let t of setterSlotChildren(e))t.attached=!1}function*childNodes(e){yield*siblingsFrom(e.first,e)}function childSnapshot(e){let t=[];for(let n of siblingsFrom(e.first,e))t.push(n);return t}function*siblingsFrom(e,n){let r=0;for(let i=e;i;i=i.next){if(++r>1e5)throw t.siblingCycle(n.descriptor.gtype);yield i}}function link(e,t,n){t.parent=e,n?(t.prev=n.prev,t.next=n,n.prev?n.prev.next=t:e.first=t,n.prev=t):(t.prev=e.last,t.next=null,e.last?e.last.next=t:e.first=t,e.last=t)}function unlink(e){let t=e.parent;t&&(e.prev?e.prev.next=e.next:t.first=e.next,e.next?e.next.prev=e.prev:t.last=e.prev,e.prev=null,e.next=null,e.parent=null)}function attach(e,t){if(!e.widget)return;materialize(t);let n=T(t.descriptor);if(n){t.attached=E(e,t,n);return}O(e,t),D(e,t),ensureWrapper(e,t),refuseOccupiedSlot(e,t);let r=e.foreign.length>0?e.foreign.filter(t=>t.get_parent()===e.widget):e.foreign,i=r.length>0?r[r.length-1]:null,a=r.length;for(let n of siblingsFrom(e.first,e)){if(n===t)break;n.kind!==`element`||!n.attached||S(n)||(i=v(n),a+=1)}let o=[];for(let n of siblingsFrom(t.next,e))n.kind===`element`&&n.attached&&!S(n)&&o.push(n);x({parent:e,child:t,prevWidget:i,index:a,following:o}),t.attached=!0}function refuseOccupiedSlot(e,n){let r=A(e,n);if(r&&!holdsOursInSlot(e,n.slot)&&appOccupant(e.widget,e.descriptor,r))throw t.occupiedSlot(e.descriptor.gtype,n.descriptor.gtype,r)}function holdsOursInSlot(e,t){for(let n of siblingsFrom(e.first,e))if(n.kind===`element`&&n.attached&&n.slot===t&&!S(n))return!0;return!1}function ensureWrapper(n,r){if(r.wrapper)return;let i;try{i=w(n.descriptor,r.widget,r.slot)}catch(i){throw i instanceof e?i:t.rejectedChild(n.descriptor.gtype,r.descriptor.gtype,i.message)}i&&(r.wrapper=i)}function insert(e,t,n=null){assertHostParent(t);let r=e.parent,i=e.next,a=n===e?i:n;e.parent&&remove(e),link(t,e,a);try{e.kind===`element`?attach(t,e):e.kind===`text`&&flushText(t)}catch(t){throw unlink(e),r&&restore(e,r,i),t}}function assertHostParent(e){if(!isHostElement(e))throw t.notAHostParent(describeValue(e))}function isHostElement(e){let t=e;return!!t&&t.kind===`element`&&typeof t.descriptor==`object`}function describeValue(e){if(e==null)return String(e);if(typeof e!=`object`)return`a ${typeof e}`;let t=e.tagName;if(typeof t==`string`)return`a DOM element <${t.toLowerCase()}>`;let n=e.constructor?.$gtype,r=n?F.type_name(n)??`an unnamed GType`:null;if(r!==null&&r!==`JSObject`)return r;let i=e.constructor?.name;return i&&i!==`Object`?`a ${i}`:`a plain object`}function restore(e,t,n){try{link(t,e,n),e.kind===`element`?attach(t,e):e.kind===`text`&&flushText(t)}catch{unlink(e)}}function restoreTextSink(e){let t=e.descriptor.textSink;if(!t||e.destroyed||!e.widget)return;let n=e.descriptor.children;if(n.kind!==`single`||holdsOursInSlot(e,null)||M(e.widget,n.set))return;let i=t.replace(/-([a-z])/g,(e,t)=>t.toUpperCase()),o=e.props[t]??e.props[i];if(typeof o!=`string`||o===``)return;let c=s(a(e.descriptor.ctor(),e.descriptor.gtype),e.descriptor.gtype,t);f(e.widget);try{e.widget.set_property(t,r(c,o,e.descriptor.gtype))}finally{m()}}function remove(e){let t=e.parent;if(!t&&e.kind===`element`){let t=T(e.descriptor);t&&(b(e,t),e.attached=!1)}t&&e.kind===`element`&&(k(t,e),e.attached=!1,e.wrapper&&=(e.wrapper.set_child(null),null),restoreTextSink(t)),unlink(e),t&&e.kind===`text`&&flushText(t)}function destroyChildren(e){for(let t of childSnapshot(e))destroy(t)}function disconnectHandlers(e){p(e),e.listeners.clear()}function destroy(e){e.kind===`element`&&(destroyChildren(e),p(e),e.listeners.clear());let t=e.kind===`element`?T(e.descriptor):null;if(t&&releaseWidget(e),remove(e),e.kind===`element`){let n=e.widget;!t&&n&&typeof n.destroy==`function`&&typeof n.get_parent==`function`&&n.get_parent()===null&&n.destroy(),releaseWidget(e),e.props={},e.layout=null,e.accessibility=null,e.textFromChildren=!1,e.destroyed=!0}}function mountRoot(e,t){materialize(e),insert(e,adopt(t))}function widgetOf(e){if(e.kind!==`element`)throw t.notAnElement(e.kind);if(e.destroyed)throw t.destroyedNode(e.descriptor.gtype);return materialize(e)}const createDetachedContainer=()=>adopt(C());function adopt(e){let n=e.constructor.$gtype,r=P(n);if(!r)throw t.unknownTag(gtypeNameOf(e));return{kind:`element`,descriptor:r,widget:e,wrapper:null,slot:null,parent:null,prev:null,next:null,first:null,last:null,handlers:new Map,listeners:new Map,props:{},layout:null,accessibility:null,textFromChildren:!1,attached:!0,destroyed:!1,foreign:adoptedChildren(e,r),portalWatch:null}}function adoptedChildren(e,t){let n=j(t.children);if(n.length===0)return directChildren(e);let r=[];for(let i of n){let n=appOccupant(e,t,i);n&&r.push(n)}return r}function appOccupant(e,t,n){let r=M(e,n);if(!r)return null;let i=t.textSink;if(!i)return r;let a=e[i.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())];return typeof a==`string`&&a!==``?null:r}function directChildren(e){let t=[],n=e;if(typeof n.get_first_child!=`function`)return t;for(let e=n.get_first_child();e;e=e.get_next_sibling())t.push(e);return t}const gtypeNameOf=e=>F.type_name(e.constructor.$gtype),parentNode=e=>e.parent,firstChild=e=>e.first,nextSibling=e=>e.next,prevSibling=e=>e.prev;export{adopt,createAnchor,createDetachedContainer,createElement,createText,describeValue,destroy,destroyChildren,disconnectHandlers,firstChild,insert,isHostElement,isText,materialize,mountRoot,nextSibling,parentNode,prevSibling,remove,setAccessibility,setElementText,setEventHandler,setProp,setSlot,setText,widgetOf};
1
+ import"./_virtual/_rolldown/runtime.js";import{GtkHostError as e,err as t}from"./errors.js";import{reconcileStringList as n}from"./list-model.js";import{lookupWidget as r,nearestRegistered as i,requireClass as a}from"./registry.js";import{coerce as o,isConstructOnly as s,paramSpecs as c,removedValue as l,requireSpec as u,toPropertyName as d}from"./props.js";import{applyAccessibilityPlan as f,isAccessibleClass as p,planAccessibility as m}from"./accessibility.js";import{beginHostWrite as h,clearHandlers as g,endHostWrite as _,isEventProp as v,setHandler as y,toSignalName as b}from"./signals.js";import{addressOf as x,closeOutsideParent as S,detachOutsideParent as C,insertChild as w,isUnparented as T,makeDetachedContainer as E,makeWrapper as D,outsideParentOf as O,placeOutsideParent as k,refuseUnknownSlot as A,refuseUnparentable as j,removeChild as M,setterSlotOf as N,setterSlots as P,slotOccupant as F}from"./policies.js";import I from"gi://GObject?version=2.0";function createElement(e,t){let n={kind:`element`,descriptor:r(e),widget:null,wrapper:null,slot:null,parent:null,prev:null,next:null,first:null,last:null,handlers:new Map,listeners:new Map,props:{},layout:null,accessibility:null,textFromChildren:!1,attached:!1,destroyed:!1,foreign:[],portalWatch:null};if(t)for(let[e,r]of Object.entries(t))setProp(n,e,r);return n}const createText=e=>({kind:`text`,data:e,parent:null,prev:null,next:null}),createAnchor=(e=``)=>({kind:`anchor`,data:e,parent:null,prev:null,next:null}),isText=e=>e.kind===`text`;function releaseWidget(e){let t=e.widget?O(e.descriptor):null;t&&S(e,t),e.widget=null,e.wrapper=null}function materialize(e){if(e.widget)return e.widget;for(let n of e.descriptor.requiresProps??[])if(!(n in e.props))throw t.missingConstructProp(e.descriptor.gtype,n);let n=a(e.descriptor),r=c(n,e.descriptor.gtype),i={};for(let[t,n]of Object.entries(e.props))i[t]=o(u(r,e.descriptor.gtype,t),n,e.descriptor.gtype);h(null);try{e.widget=new n(i)}finally{_()}try{replayInto(e)}catch(t){g(e);for(let t of childSnapshot(e))t.kind===`element`&&t.attached&&(M(e,t),t.attached=!1);throw releaseWidget(e),t}return e.widget}function replayInto(e){for(let[t,n]of e.listeners)y(e,t,n);e.accessibility&&f(e.widget,m(e.descriptor.gtype,null,e.accessibility));for(let t of siblingsFrom(e.first,e))t.kind===`element`&&attach(e,t);e.textFromChildren&&flushText(e)}function setProp(e,t,r,i){if(v(t))return setEventHandler(e,t,r);if(t===`slot`)return setSlot(e,r);if(t===`accessibility`)return setAccessibility(e,r);if(t===`layout`){let t=r,n=e.parent;if(!n||!e.widget){e.layout=t;return}let i=e.layout;replaceAt(e,n,()=>{e.layout=t},()=>{e.layout=i});return}let f=d(t),p=u(c(a(e.descriptor),e.descriptor.gtype),e.descriptor.gtype,f),m=r==null,g=m?l(e.descriptor,p):o(p,r,e.descriptor.gtype);e.widget!==null&&takesAccessorRoute(g)&&!s(p)&&requireAccessor(e,e.widget,f);let y=f in e.props?e.props[f]:void 0;if(m?delete e.props[f]:e.props[f]=r,e.widget){if(s(p))return rebuild(e,f,y);h(e.widget);try{n(e.widget,accessorName(f),g)||writeProperty(e.widget,f,g)}finally{_()}}}function writeProperty(e,t,n){if(!takesAccessorRoute(n)){e.set_property(t,n);return}let r=accessorName(t);e[r]=n}const accessorName=e=>e.replace(/-([a-z0-9])/g,(e,t)=>t.toUpperCase()),takesAccessorRoute=e=>e===null||Array.isArray(e);function requireAccessor(e,n,r){let i=accessorName(r);if(!(i in n))throw t.noAccessor(e.descriptor.gtype,r,i)}function setEventHandler(e,t,n){e.widget?y(e,t,n):n&&assertSignalExists(e,t),n?e.listeners.set(t,n):e.listeners.delete(t)}function assertSignalExists(e,n){let r=b(n,e.descriptor.eventAliases).split(`::`)[0],i=a(e.descriptor).$gtype;if(I.signal_lookup(r,i)===0)throw t.unknownSignal(e.descriptor.gtype,n,r)}function setAccessibility(e,n){let r=n??null,i=m(e.descriptor.gtype,e.accessibility,r);if(r!==null&&!p(a(e.descriptor)))throw t.notAccessible(e.descriptor.gtype);e.widget&&f(e.widget,i),e.accessibility=r}function setSlot(e,t){if(e.slot===t)return;let n=e.parent;if(!n||!e.widget){e.slot=t;return}let r=e.slot;replaceAt(e,n,()=>{e.slot=t},()=>{e.slot=r})}function replaceAt(e,t,n,r){M(t,e),e.attached=!1,n();try{attach(t,e)}catch(n){r();try{attach(t,e)}catch{}throw n}}function rebuild(e,t,n){let r=e.parent;if(e.widget){g(e);for(let t of childSnapshot(e))t.kind===`element`&&(M(e,t),t.attached=!1);r&&!O(e.descriptor)&&M(r,e)}releaseWidget(e),e.attached=!1;try{materialize(e)}catch(i){t!==void 0&&(n===void 0?delete e.props[t]:e.props[t]=n);try{materialize(e),r&&attach(r,e)}catch{}throw i}r&&attach(r,e)}function setText(e,t){e.data=t,e.kind===`text`&&e.parent&&flushText(e.parent)}function setElementText(e,t){writeTextSink(e,t),e.textFromChildren=!1,destroyChildren(e)}function flushText(e){let t=``,n=!1;for(let r of childNodes(e))r.kind===`text`&&(t+=r.data,n=!0);if(t===``&&!e.textFromChildren)return;let r=e.descriptor.textSink;if(t===``&&r&&holdsElementInSetterSlot(e)){e.textFromChildren=!1,delete e.props[r];return}writeTextSink(e,t),e.textFromChildren=n}function*setterSlotChildren(e){for(let t of siblingsFrom(e.first,e))t.kind===`element`&&t.attached&&!T(t)&&N(e,t)&&(yield t)}const holdsElementInSetterSlot=e=>!setterSlotChildren(e).next().done;function writeTextSink(e,n){let r=e.descriptor.textSink;if(!r)throw t.textNotAccepted(e.descriptor.gtype,n);materialize(e);let i=e.descriptor.children,s=i.kind===`single`?i.set:null;if(s&&!holdsOursInSlot(e,null)&&appOccupant(e.widget,e.descriptor,s))throw t.occupiedSlot(e.descriptor.gtype,`text`,s);let l=u(c(a(e.descriptor),e.descriptor.gtype),e.descriptor.gtype,r);h(e.widget);try{e.widget.set_property(r,o(l,n,e.descriptor.gtype))}finally{_()}e.props[r]=n;for(let t of setterSlotChildren(e))t.attached=!1}function*childNodes(e){yield*siblingsFrom(e.first,e)}function childSnapshot(e){let t=[];for(let n of siblingsFrom(e.first,e))t.push(n);return t}function*siblingsFrom(e,n){let r=0;for(let i=e;i;i=i.next){if(++r>1e5)throw t.siblingCycle(n.descriptor.gtype);yield i}}function link(e,t,n){t.parent=e,n?(t.prev=n.prev,t.next=n,n.prev?n.prev.next=t:e.first=t,n.prev=t):(t.prev=e.last,t.next=null,e.last?e.last.next=t:e.first=t,e.last=t)}function unlink(e){let t=e.parent;t&&(e.prev?e.prev.next=e.next:t.first=e.next,e.next?e.next.prev=e.prev:t.last=e.prev,e.prev=null,e.next=null,e.parent=null)}function attach(e,t){if(!e.widget)return;materialize(t);let n=O(t.descriptor);if(n){t.attached=k(e,t,n);return}j(e,t),A(e,t),ensureWrapper(e,t),refuseOccupiedSlot(e,t);let r=e.foreign.length>0?e.foreign.filter(t=>t.get_parent()===e.widget):e.foreign,i=r.length>0?r[r.length-1]:null,a=r.length;for(let n of siblingsFrom(e.first,e)){if(n===t)break;n.kind!==`element`||!n.attached||T(n)||(i=x(n),a+=1)}let o=[];for(let n of siblingsFrom(t.next,e))n.kind===`element`&&n.attached&&!T(n)&&o.push(n);w({parent:e,child:t,prevWidget:i,index:a,following:o}),t.attached=!0}function refuseOccupiedSlot(e,n){let r=N(e,n);if(r&&!holdsOursInSlot(e,n.slot)&&appOccupant(e.widget,e.descriptor,r))throw t.occupiedSlot(e.descriptor.gtype,n.descriptor.gtype,r)}function holdsOursInSlot(e,t){for(let n of siblingsFrom(e.first,e))if(n.kind===`element`&&n.attached&&n.slot===t&&!T(n))return!0;return!1}function ensureWrapper(n,r){if(r.wrapper)return;let i;try{i=D(n.descriptor,r.widget,r.slot)}catch(i){throw i instanceof e?i:t.rejectedChild(n.descriptor.gtype,r.descriptor.gtype,i.message)}i&&(r.wrapper=i)}function insert(e,t,n=null){assertHostParent(t);let r=e.parent,i=e.next,a=n===e?i:n;e.parent&&remove(e),link(t,e,a);try{e.kind===`element`?attach(t,e):e.kind===`text`&&flushText(t)}catch(t){throw unlink(e),r&&restore(e,r,i),t}}function assertHostParent(e){if(!isHostElement(e))throw t.notAHostParent(describeValue(e))}function isHostElement(e){let t=e;return!!t&&t.kind===`element`&&typeof t.descriptor==`object`}function describeValue(e){if(e==null)return String(e);if(typeof e!=`object`)return`a ${typeof e}`;let t=e.tagName;if(typeof t==`string`)return`a DOM element <${t.toLowerCase()}>`;let n=e.constructor?.$gtype,r=n?I.type_name(n)??`an unnamed GType`:null;if(r!==null&&r!==`JSObject`)return r;let i=e.constructor?.name;return i&&i!==`Object`?`a ${i}`:`a plain object`}function restore(e,t,n){try{link(t,e,n),e.kind===`element`?attach(t,e):e.kind===`text`&&flushText(t)}catch{unlink(e)}}function restoreTextSink(e){let t=e.descriptor.textSink;if(!t||e.destroyed||!e.widget)return;let n=e.descriptor.children;if(n.kind!==`single`||holdsOursInSlot(e,null)||F(e.widget,n.set))return;let r=t.replace(/-([a-z])/g,(e,t)=>t.toUpperCase()),i=e.props[t]??e.props[r];if(typeof i!=`string`||i===``)return;let s=u(c(a(e.descriptor),e.descriptor.gtype),e.descriptor.gtype,t);h(e.widget);try{e.widget.set_property(t,o(s,i,e.descriptor.gtype))}finally{_()}}function remove(e){let t=e.parent;if(!t&&e.kind===`element`){let t=O(e.descriptor);t&&(C(e,t),e.attached=!1)}t&&e.kind===`element`&&(M(t,e),e.attached=!1,e.wrapper&&=(e.wrapper.set_child(null),null),restoreTextSink(t)),unlink(e),t&&e.kind===`text`&&flushText(t)}function destroyChildren(e){for(let t of childSnapshot(e))destroy(t)}function disconnectHandlers(e){g(e),e.listeners.clear()}function destroy(e){e.kind===`element`&&(destroyChildren(e),g(e),e.listeners.clear());let t=e.kind===`element`?O(e.descriptor):null;if(t&&releaseWidget(e),remove(e),e.kind===`element`){let n=e.widget;!t&&n&&typeof n.destroy==`function`&&typeof n.get_parent==`function`&&n.get_parent()===null&&n.destroy(),releaseWidget(e),e.props={},e.layout=null,e.accessibility=null,e.textFromChildren=!1,e.destroyed=!0}}function mountRoot(e,t){materialize(e),insert(e,adopt(t))}function widgetOf(e){if(e.kind!==`element`)throw t.notAnElement(e.kind);if(e.destroyed)throw t.destroyedNode(e.descriptor.gtype);return materialize(e)}const createDetachedContainer=()=>adopt(E());function adopt(e){let n=e.constructor.$gtype,r=i(n);if(!r)throw t.unknownTag(gtypeNameOf(e));return{kind:`element`,descriptor:r,widget:e,wrapper:null,slot:null,parent:null,prev:null,next:null,first:null,last:null,handlers:new Map,listeners:new Map,props:{},layout:null,accessibility:null,textFromChildren:!1,attached:!0,destroyed:!1,foreign:adoptedChildren(e,r),portalWatch:null}}function adoptedChildren(e,t){let n=P(t.children);if(n.length===0)return directChildren(e);let r=[];for(let i of n){let n=appOccupant(e,t,i);n&&r.push(n)}return r}function appOccupant(e,t,n){let r=F(e,n);if(!r)return null;let i=t.textSink;if(!i)return r;let a=e[i.replace(/-([a-z])/g,(e,t)=>t.toUpperCase())];return typeof a==`string`&&a!==``?null:r}function directChildren(e){let t=[],n=e;if(typeof n.get_first_child!=`function`)return t;for(let e=n.get_first_child();e;e=e.get_next_sibling())t.push(e);return t}const gtypeNameOf=e=>I.type_name(e.constructor.$gtype),parentNode=e=>e.parent,firstChild=e=>e.first,nextSibling=e=>e.next,prevSibling=e=>e.prev;export{adopt,createAnchor,createDetachedContainer,createElement,createText,describeValue,destroy,destroyChildren,disconnectHandlers,firstChild,insert,isHostElement,isText,materialize,mountRoot,nextSibling,parentNode,prevSibling,remove,setAccessibility,setElementText,setEventHandler,setProp,setSlot,setText,widgetOf};
package/lib/esm/index.js CHANGED
@@ -1 +1 @@
1
- import{GtkHostError as e}from"./errors.js";import{constructOnlyNames as t,isConstructOnly as n,isWritable as r,lookupEnumNick as i,paramSpecs as a,toPropertyName as o}from"./props.js";import{isEventProp as s,toSignalName as c}from"./signals.js";import{addressOf as l,isPortal as u,placementOf as d,portalOf as f,reorderMode as p}from"./policies.js";import{assertInjective as m,tagOf as h}from"./tags.js";import{clearRegistry as g,hasWidget as _,lookupWidget as v,nearestRegistered as y,registerWidget as b,registerWidgets as x,registeredTags as S}from"./registry.js";import{adopt as C,createAnchor as w,createDetachedContainer as T,createElement as E,createText as D,destroy as O,destroyChildren as k,disconnectHandlers as A,firstChild as j,insert as M,isHostElement as N,isText as P,materialize as F,mountRoot as I,nextSibling as L,parentNode as R,prevSibling as z,remove as B,setElementText as V,setEventHandler as H,setProp as U,setSlot as W,setText as G,widgetOf as K}from"./host.js";import{GENERATED_PROVENANCE as q,GENERATED_WIDGETS as J}from"./generated/widgets.js";import{GTK_DESCRIPTORS as Y}from"./descriptors/gtk.js";import{ADW_DESCRIPTORS as X}from"./descriptors/adw.js";import{BUILTIN_DESCRIPTORS as Z,CURATED_DESCRIPTORS as Q,mergeGenerated as $,registerBuiltinWidgets as ee,tableProvenance as te}from"./descriptors/index.js";import"./types.js";import{blankReason as ne,checkRendered as re,probeEnabled as ie,runHostProbe as ae,runHostProbeApp as oe,shotEvidence as se}from"./probe.js";export{X as ADW_DESCRIPTORS,Z as BUILTIN_DESCRIPTORS,Q as CURATED_DESCRIPTORS,q as GENERATED_PROVENANCE,J as GENERATED_WIDGETS,Y as GTK_DESCRIPTORS,e as GtkHostError,l as addressOf,C as adopt,m as assertInjective,ne as blankReason,re as checkRendered,g as clearRegistry,t as constructOnlyNames,w as createAnchor,T as createDetachedContainer,E as createElement,D as createText,O as destroy,k as destroyChildren,A as disconnectHandlers,j as firstChild,_ as hasWidget,M as insert,n as isConstructOnly,s as isEventProp,N as isHostElement,u as isPortal,P as isText,r as isWritable,i as lookupEnumNick,v as lookupWidget,F as materialize,$ as mergeGenerated,I as mountRoot,y as nearestRegistered,L as nextSibling,a as paramSpecs,R as parentNode,d as placementOf,f as portalOf,z as prevSibling,ie as probeEnabled,ee as registerBuiltinWidgets,b as registerWidget,x as registerWidgets,S as registeredTags,B as remove,p as reorderMode,ae as runHostProbe,oe as runHostProbeApp,V as setElementText,H as setEventHandler,U as setProp,W as setSlot,G as setText,se as shotEvidence,te as tableProvenance,h as tagOf,o as toPropertyName,c as toSignalName,K as widgetOf};
1
+ import{GtkHostError as e}from"./errors.js";import{assertInjective as t,tagOf as n}from"./tags.js";import{classOf as r,clearRegistry as i,hasClass as a,hasWidget as o,lookupWidget as s,nearestRegistered as c,registerWidget as l,registerWidgets as u,registeredTags as d,requireClass as f}from"./registry.js";import{constructOnlyNames as p,gtypeOfName as m,isConstructOnly as h,isWritable as g,lookupEnumNick as _,paramSpecs as v,toPropertyName as y}from"./props.js";import{isEventProp as b,toSignalName as x}from"./signals.js";import{addressOf as S,isPortal as C,placementOf as w,portalOf as T,reorderMode as E}from"./policies.js";import{adopt as D,createAnchor as O,createDetachedContainer as k,createElement as A,createText as j,destroy as M,destroyChildren as N,disconnectHandlers as P,firstChild as F,insert as I,isHostElement as L,isText as R,materialize as z,mountRoot as B,nextSibling as V,parentNode as H,prevSibling as U,remove as W,setElementText as G,setEventHandler as K,setProp as q,setSlot as J,setText as Y,widgetOf as X}from"./host.js";import{GENERATED_PROVENANCE as Z,GENERATED_WIDGETS as Q}from"./generated/widgets.js";import{GTK_DESCRIPTORS as $}from"./descriptors/gtk.js";import{ADW_DESCRIPTORS as ee}from"./descriptors/adw.js";import{BUILTIN_DESCRIPTORS as te,CURATED_DESCRIPTORS as ne,mergeGenerated as re,registerBuiltinWidgets as ie,tableProvenance as ae}from"./descriptors/index.js";import"./types.js";import{blankReason as oe,checkRendered as se,probeEnabled as ce,runHostProbe as le,runHostProbeApp as ue,shotEvidence as de}from"./probe.js";export{ee as ADW_DESCRIPTORS,te as BUILTIN_DESCRIPTORS,ne as CURATED_DESCRIPTORS,Z as GENERATED_PROVENANCE,Q as GENERATED_WIDGETS,$ as GTK_DESCRIPTORS,e as GtkHostError,S as addressOf,D as adopt,t as assertInjective,oe as blankReason,se as checkRendered,r as classOf,i as clearRegistry,p as constructOnlyNames,O as createAnchor,k as createDetachedContainer,A as createElement,j as createText,M as destroy,N as destroyChildren,P as disconnectHandlers,F as firstChild,m as gtypeOfName,a as hasClass,o as hasWidget,I as insert,h as isConstructOnly,b as isEventProp,L as isHostElement,C as isPortal,R as isText,g as isWritable,_ as lookupEnumNick,s as lookupWidget,z as materialize,re as mergeGenerated,B as mountRoot,c as nearestRegistered,V as nextSibling,v as paramSpecs,H as parentNode,w as placementOf,T as portalOf,U as prevSibling,ce as probeEnabled,ie as registerBuiltinWidgets,l as registerWidget,u as registerWidgets,d as registeredTags,W as remove,E as reorderMode,f as requireClass,le as runHostProbe,ue as runHostProbeApp,G as setElementText,K as setEventHandler,q as setProp,J as setSlot,Y as setText,de as shotEvidence,ae as tableProvenance,n as tagOf,y as toPropertyName,x as toSignalName,X as widgetOf};
package/lib/esm/props.js CHANGED
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{err as e}from"./errors.js";import{buildAdjustment as t,isPortableAdjustment as n}from"./adjustment.js";import{buildStringList as r,isPortableListModel as i}from"./list-model.js";import{buildGioMenu as a,isPortableMenu as o}from"./menu.js";import s from"gi://GObject?version=2.0";import c from"gi://Gtk?version=4.0";import l from"gi://Adw?version=1";import u from"gi://Gdk?version=4.0";import d from"gi://Gio?version=2.0";import f from"gi://Pango?version=1.0";const p=[[`Gtk`,c],[`Adw`,l],[`Gdk`,u],[`Pango`,f],[`G`,d],[`G`,s]];function toPropertyName(e){return e.includes(`-`)?e:e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase()}function withoutKeys(e,t){if(!e)return;let n;for(let r of Object.keys(e))t.has(r)||((n??={})[r]=e[r]);return n}const m=new Map;function paramSpecs(e,t){let n=m.get(t);if(n)return n;n=new Map;for(let t of e.list_properties())n.set(t.get_name(),t);return m.set(t,n),n}const isFlag=(e,t)=>(e&t)!==0,isWritable=e=>isFlag(e.flags,s.ParamFlags.WRITABLE),isConstructOnly=e=>isFlag(e.flags,s.ParamFlags.CONSTRUCT_ONLY);function constructOnlyNames(e,t){let n=[];for(let[r,i]of paramSpecs(e,t))isConstructOnly(i)&&isWritable(i)&&n.push(r);return n}function giTypeObject(e){for(let[t,n]of p){if(!e.startsWith(t))continue;let r=n[e.slice(t.length)];if(!r||typeof r!=`object`)continue;let i=r.$gtype;if(!(!i||s.type_name(i)!==e))return r}}function gtypeOfName(e){return s.type_from_name(e)||giTypeObject(e)?.$gtype}let h;const isWholeNumber=e=>/^[+-]?(?:0[xX][0-9a-fA-F]+|[0-9]+)$/.test(e.trim()),startsNumeric=e=>/^[+-]?[0-9]/.test(e.trim());function memberNickValue(e,t){let n=giTypeObject(s.type_name(e))?.[t.trim().toUpperCase().replace(/-/g,`_`)];return typeof n==`number`?n:void 0}function parseNickText(e,t){if(!isWholeNumber(t)){let n=t.split(`|`);if(n.some(startsNumeric))return n.length===1?memberNickValue(e,t):void 0}h??=new c.Builder;try{let[n,r]=h.value_from_string_type(e,t);return n&&typeof r==`number`?r:void 0}catch{return}}const hasBlankMember=e=>e.split(`|`).some(e=>e.trim().length===0),lookupEnumNick=(e,t)=>{let n=gtypeOfName(e);return n===void 0?void 0:parseNickText(n,t)};function enumMembers(e){let t=giTypeObject(e);if(t)return Object.keys(t).filter(e=>e!==`$gtype`&&typeof t[e]==`number`)}const kindOf=e=>Array.isArray(e)?`an array`:`a ${typeof e}`;function coerce(l,u,f){if(u==null)return u;let p=l.value_type;if(s.type_is_a(p,d.MenuModel.$gtype)&&o(u))return a(u);if(s.type_is_a(p,d.ListModel.$gtype)&&!(u instanceof s.Object)){if(!i(u))throw e.badListModel(f,l.get_name(),kindOf(u));if(!s.type_is_a(c.StringList.$gtype,p))throw e.listModelMismatch(f,l.get_name(),s.type_name(p));return r(u)}if(s.type_is_a(p,c.Adjustment.$gtype)&&!(u instanceof s.Object)){if(!n(u))throw e.badAdjustment(f,l.get_name(),kindOf(u));return t(u)}if(s.type_is_a(p,s.TYPE_ENUM)&&typeof u==`string`){let t=parseNickText(p,u);if(t!==void 0)return t;throw e.badEnum(f,l.get_name(),u,s.type_name(p))}if(s.type_is_a(p,s.TYPE_FLAGS)&&typeof u==`string`){let t=s.type_name(p);if(hasBlankMember(u))throw e.blankFlags(f,l.get_name(),u,t);let n=parseNickText(p,u);if(n!==void 0)return n;throw e.badFlags(f,l.get_name(),u,t)}if(s.type_is_a(p,s.TYPE_BOOLEAN)){if(typeof u==`boolean`)return u;if(u===`true`)return!0;if(u===`false`)return!1;if(typeof u==`string`)throw e.badBoolean(f,l.get_name(),u);return!!u}if(s.type_is_a(p,s.TYPE_STRING)){if(typeof u==`string`)return u;if(typeof u==`number`||typeof u==`boolean`)return String(u);throw e.badString(f,l.get_name(),typeof u)}return(s.type_is_a(p,s.TYPE_INT)||s.type_is_a(p,s.TYPE_UINT)||s.type_is_a(p,s.TYPE_INT64)||s.type_is_a(p,s.TYPE_UINT64))&&typeof u==`number`?Math.trunc(u):u}const g=[s.TYPE_BOOLEAN,s.TYPE_STRING,s.TYPE_INT,s.TYPE_UINT,s.TYPE_INT64,s.TYPE_UINT64,s.TYPE_DOUBLE,s.TYPE_FLOAT],isScalarSpec=e=>s.type_is_a(e.value_type,s.TYPE_ENUM)||g.some(t=>s.type_is_a(e.value_type,t)),toAccessorName=e=>e.replace(/-([a-z0-9])/g,(e,t)=>t.toUpperCase()),_=new Map;function constructedDefaults(e){let t=_.get(e.gtype);if(t)return t;let n=new Map;_.set(e.gtype,n);let r=e.ctor(),i;try{let t={};for(let n of e.requiresProps??[])t[n]=``;i=new r(t)}catch{return n}for(let[t,a]of paramSpecs(r,e.gtype)){if(!isWritable(a)||isConstructOnly(a)||!isFlag(a.flags,s.ParamFlags.READABLE)||isFlag(a.flags,s.ParamFlags.DEPRECATED)||!isScalarSpec(a))continue;let e=toAccessorName(t);e in i&&n.set(t,i[e])}return i instanceof c.Window&&i.destroy(),n}function removedValue(e,t){let n=constructedDefaults(e),r=t.get_name();return n.has(r)?n.get(r):t.get_default_value()}function requireSpec(t,n,r){let i=t.get(r);if(!i)throw e.unknownProp(n,r);if(!isWritable(i))throw e.readOnlyProp(n,r);return i}export{coerce,constructOnlyNames,enumMembers,isConstructOnly,isWritable,lookupEnumNick,paramSpecs,removedValue,requireSpec,toPropertyName,withoutKeys};
1
+ import"./_virtual/_rolldown/runtime.js";import{err as e}from"./errors.js";import{buildAdjustment as t,isPortableAdjustment as n}from"./adjustment.js";import{buildStringList as r,isPortableListModel as i}from"./list-model.js";import{buildGioMenu as a,isPortableMenu as o}from"./menu.js";import{requireClass as s}from"./registry.js";import c from"gi://GObject?version=2.0";import l from"gi://Gtk?version=4.0";import u from"gi://Adw?version=1";import d from"gi://Gdk?version=4.0";import f from"gi://Gio?version=2.0";import p from"gi://Pango?version=1.0";const m=[[`Gtk`,l],[`Adw`,u],[`Gdk`,d],[`Pango`,p],[`G`,f],[`G`,c]];function toPropertyName(e){return e.includes(`-`)?e:e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase()}function withoutKeys(e,t){if(!e)return;let n;for(let r of Object.keys(e))t.has(r)||((n??={})[r]=e[r]);return n}const h=new Map;function paramSpecs(e,t){let n=h.get(t);if(n)return n;n=new Map;for(let t of e.list_properties())n.set(t.get_name(),t);return h.set(t,n),n}const isFlag=(e,t)=>(e&t)!==0,isWritable=e=>isFlag(e.flags,c.ParamFlags.WRITABLE),isConstructOnly=e=>isFlag(e.flags,c.ParamFlags.CONSTRUCT_ONLY);function constructOnlyNames(e,t){let n=[];for(let[r,i]of paramSpecs(e,t))isConstructOnly(i)&&isWritable(i)&&n.push(r);return n}function giTypeObject(e){for(let[t,n]of m){if(!e.startsWith(t))continue;let r=n[e.slice(t.length)],i=r?.$gtype;if(!(!i||c.type_name(i)!==e))return r}}function gtypeOfName(e){return c.type_from_name(e)||giTypeObject(e)?.$gtype}let g;const isWholeNumber=e=>/^[+-]?(?:0[xX][0-9a-fA-F]+|[0-9]+)$/.test(e.trim()),startsNumeric=e=>/^[+-]?[0-9]/.test(e.trim());function memberNickValue(e,t){let n=giTypeObject(c.type_name(e))?.[t.trim().toUpperCase().replace(/-/g,`_`)];return typeof n==`number`?n:void 0}function parseNickText(e,t){if(!isWholeNumber(t)){let n=t.split(`|`);if(n.some(startsNumeric))return n.length===1?memberNickValue(e,t):void 0}g??=new l.Builder;try{let[n,r]=g.value_from_string_type(e,t);return n&&typeof r==`number`?r:void 0}catch{return}}const hasBlankMember=e=>e.split(`|`).some(e=>e.trim().length===0),lookupEnumNick=(e,t)=>{let n=gtypeOfName(e);return n===void 0?void 0:parseNickText(n,t)},isEnumish=e=>c.type_is_a(e,c.TYPE_ENUM)||c.type_is_a(e,c.TYPE_FLAGS);function enumMembers(e){let t=giTypeObject(e),n=t?.$gtype;if(!(!n||!isEnumish(n)))return Object.keys(t).filter(e=>e!==`$gtype`&&typeof t[e]==`number`)}const kindOf=e=>Array.isArray(e)?`an array`:`a ${typeof e}`;function coerce(s,u,d){if(u==null)return u;let p=s.value_type;if(c.type_is_a(p,f.MenuModel.$gtype)&&o(u))return a(u);if(c.type_is_a(p,f.ListModel.$gtype)&&!(u instanceof c.Object)){if(!i(u))throw e.badListModel(d,s.get_name(),kindOf(u));if(!c.type_is_a(l.StringList.$gtype,p))throw e.listModelMismatch(d,s.get_name(),c.type_name(p));return r(u)}if(c.type_is_a(p,l.Adjustment.$gtype)&&!(u instanceof c.Object)){if(!n(u))throw e.badAdjustment(d,s.get_name(),kindOf(u));return t(u)}if(c.type_is_a(p,c.TYPE_ENUM)&&typeof u==`string`){let t=parseNickText(p,u);if(t!==void 0)return t;throw e.badEnum(d,s.get_name(),u,c.type_name(p))}if(c.type_is_a(p,c.TYPE_FLAGS)&&typeof u==`string`){let t=c.type_name(p);if(hasBlankMember(u))throw e.blankFlags(d,s.get_name(),u,t);let n=parseNickText(p,u);if(n!==void 0)return n;throw e.badFlags(d,s.get_name(),u,t)}if(c.type_is_a(p,c.TYPE_BOOLEAN)){if(typeof u==`boolean`)return u;if(u===`true`)return!0;if(u===`false`)return!1;if(typeof u==`string`)throw e.badBoolean(d,s.get_name(),u);return!!u}if(c.type_is_a(p,c.TYPE_STRING)){if(typeof u==`string`)return u;if(typeof u==`number`||typeof u==`boolean`)return String(u);throw e.badString(d,s.get_name(),typeof u)}return(c.type_is_a(p,c.TYPE_INT)||c.type_is_a(p,c.TYPE_UINT)||c.type_is_a(p,c.TYPE_INT64)||c.type_is_a(p,c.TYPE_UINT64))&&typeof u==`number`?Math.trunc(u):u}const _=[c.TYPE_BOOLEAN,c.TYPE_STRING,c.TYPE_INT,c.TYPE_UINT,c.TYPE_INT64,c.TYPE_UINT64,c.TYPE_DOUBLE,c.TYPE_FLOAT],isScalarSpec=e=>c.type_is_a(e.value_type,c.TYPE_ENUM)||_.some(t=>c.type_is_a(e.value_type,t)),toAccessorName=e=>e.replace(/-([a-z0-9])/g,(e,t)=>t.toUpperCase()),v=new Map;function constructedDefaults(e){let t=v.get(e.gtype);if(t)return t;let n=new Map;v.set(e.gtype,n);let r=s(e),i;try{let t={};for(let n of e.requiresProps??[])t[n]=``;i=new r(t)}catch{return n}for(let[t,a]of paramSpecs(r,e.gtype)){if(!isWritable(a)||isConstructOnly(a)||!isFlag(a.flags,c.ParamFlags.READABLE)||isFlag(a.flags,c.ParamFlags.DEPRECATED)||!isScalarSpec(a))continue;let e=toAccessorName(t);e in i&&n.set(t,i[e])}return i instanceof l.Window&&i.destroy(),n}function removedValue(e,t){let n=constructedDefaults(e),r=t.get_name();return n.has(r)?n.get(r):t.get_default_value()}function requireSpec(t,n,r){let i=t.get(r);if(!i)throw e.unknownProp(n,r);if(!isWritable(i))throw e.readOnlyProp(n,r);return i}export{coerce,constructOnlyNames,enumMembers,gtypeOfName,isConstructOnly,isWritable,lookupEnumNick,paramSpecs,removedValue,requireSpec,toPropertyName,withoutKeys};
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{err as e}from"./errors.js";import{tagOf as t}from"./tags.js";import n from"gi://GObject?version=2.0";const r=new Map,i=new Map;function registerWidget(e){r.set(e.gtype,e);let n=t(e.gtype);n!==e.gtype&&i.set(n,e)}function registerWidgets(e){for(let t of e)registerWidget(t)}function lookupWidget(t){let n=r.get(t)??i.get(t);if(!n)throw e.unknownTag(t);return n}const hasWidget=e=>r.has(e)||i.has(e),registeredTags=()=>[...r.keys()].sort();function nearestRegistered(e){for(let t=e;t;t=n.type_parent(t)){let e=n.type_name(t);if(!e)break;let i=r.get(e);if(i)return i}}function clearRegistry(){r.clear(),i.clear()}export{clearRegistry,hasWidget,lookupWidget,nearestRegistered,registerWidget,registerWidgets,registeredTags};
1
+ import"./_virtual/_rolldown/runtime.js";import{err as e}from"./errors.js";import{tagOf as t}from"./tags.js";import n from"gi://GObject?version=2.0";const r=new Map,i=new Map;function registerWidget(e){r.set(e.gtype,e);let n=t(e.gtype);n!==e.gtype&&i.set(n,e)}function registerWidgets(e){for(let t of e)registerWidget(t)}function lookupWidget(t){let n=r.get(t)??i.get(t);if(!n)throw e.unknownTag(t);return n}const hasWidget=e=>r.has(e)||i.has(e);function classOf(e){return e.ctor()??null}const hasClass=e=>classOf(e)!==null;function requireClass(t){let n=classOf(t);if(!n)throw e.absentClass(t.gtype);return n}const registeredTags=()=>[...r.keys()].sort();function nearestRegistered(e){for(let t=e;t;t=n.type_parent(t)){let e=n.type_name(t);if(!e)break;let i=r.get(e);if(i)return i}}function clearRegistry(){r.clear(),i.clear()}export{classOf,clearRegistry,hasClass,hasWidget,lookupWidget,nearestRegistered,registerWidget,registerWidgets,registeredTags,requireClass};
@@ -7,12 +7,10 @@ export type ReactProps = Record<string, unknown>;
7
7
  /**
8
8
  * The HostConfig, exported because it IS the contract.
9
9
  *
10
- * `react.spec.ts` builds a second reconciler over a Proxy of this object to read
11
- * the member set the INSTALLED `react-reconciler` asks for, so a version that
12
- * starts asking for something new fails a test instead of returning `undefined`
13
- * in a commit. It is also the seam for a consumer who needs a differently
14
- * configured reconciler (a `LegacyRoot`, a different event priority) without
15
- * restating the mapping.
10
+ * `react.spec.ts` builds a second reconciler over a Proxy of this object to read the member set the
11
+ * INSTALLED `react-reconciler` asks for, so a version that starts asking for something new fails a
12
+ * test instead of returning `undefined` in a commit. It is also the seam for a consumer who needs
13
+ * a differently configured reconciler (a `LegacyRoot`, a different event priority).
16
14
  */
17
15
  export declare const gtkHostConfig: {
18
16
  supportsMutation: boolean;
@@ -31,15 +29,14 @@ export declare const gtkHostConfig: {
31
29
  /**
32
30
  * `false`, always — one text path instead of two.
33
31
  *
34
- * `true` would tell React to skip text instances for this element and leave
35
- * the string in `props.children` for the adapter to write. The host already
36
- * owns that translation: a text NODE is concatenated into the descriptor's
37
- * `textSink`, and a widget without one refuses text BY TAG NAME. Answering
38
- * `true` would move that decision into the adapter, where it would be a
32
+ * `true` would tell React to skip text instances for this element and leave the string in
33
+ * `props.children` for the adapter to write. The host already owns that translation: a text NODE
34
+ * is concatenated into the descriptor's `textSink`, and a widget without one refuses text BY
35
+ * TAG NAME. Answering `true` would move that decision into the adapter, where it would be a
39
36
  * widget-knowledge test — the one thing ADR 0027 § 7 forbids an adapter.
40
37
  *
41
- * It also keeps `resetTextContent` unreachable: React sets the `ContentReset`
42
- * flag only when `shouldSetTextContent` was true for the PREVIOUS props.
38
+ * It also keeps `resetTextContent` unreachable: React sets the `ContentReset` flag only when
39
+ * `shouldSetTextContent` was true for the PREVIOUS props.
43
40
  */
44
41
  shouldSetTextContent: () => boolean;
45
42
  getRootHostContext: () => object;
@@ -60,14 +57,11 @@ export declare const gtkHostConfig: {
60
57
  /**
61
58
  * The priority an update gets when React is not already inside a lane.
62
59
  *
63
- * React DOM derives this from the DOM event being handled (a click is
64
- * discrete, a scroll continuous). A GTK signal handler is not a DOM event and
65
- * there is no ambient event to read, so every update is a default-lane one —
66
- * the same answer `react-art` and `react-nil` give. Consequence, stated
67
- * because it is load-bearing: a `setState` from a GTK handler is CONCURRENT,
68
- * so it lands when `scheduler` next runs, i.e. on the next GLib main-loop
69
- * iteration. `flushSync` is the escape hatch, and the spec pumps the main
70
- * context to prove the scheduled path works at all under GJS.
60
+ * React DOM derives this from the DOM event being handled (a click is discrete, a scroll
61
+ * continuous). A GTK signal handler is not a DOM event and there is no ambient event to read, so
62
+ * every update is a default-lane one — the same answer `react-art` and `react-nil` give.
63
+ * Consequence, stated because it is load-bearing: a `setState` from a GTK handler is CONCURRENT,
64
+ * so it lands when `scheduler` next runs, i.e. on the next GLib main-loop iteration.
71
65
  */
72
66
  resolveUpdatePriority: () => number;
73
67
  shouldAttemptEagerTransition: () => boolean;
@@ -81,30 +75,21 @@ export declare const gtkHostConfig: {
81
75
  removeChild: (_parent: HostElement, child: HostNode) => void;
82
76
  removeChildFromContainer: (_container: HostElement, child: HostNode) => void;
83
77
  /**
84
- * React clears the root before its FIRST commit — and the application's own
85
- * chrome must survive it.
78
+ * React clears the root before its FIRST commit, and the application's own chrome must survive it.
79
+ * In the DOM that discards leftover markup. Here the container is a widget the application
80
+ * built and filled, so this clears what the HOST put there (the shadow children) and never
81
+ * `el.foreign`, which `adopt` recorded precisely so placement can offset past it.
86
82
  *
87
- * `updateHostRoot` sets the `Snapshot` flag whenever the previous render
88
- * produced no child, and `commitBeforeMutationEffects` then calls this on the
89
- * container. In the DOM that discards leftover markup. Here the container is a
90
- * widget the application built and filled, so this clears what the HOST put
91
- * there (the shadow children) and never `el.foreign`, which `adopt` recorded
92
- * precisely so placement can offset past it.
93
- *
94
- * `destroy` rather than `remove`, for the same reason `removeChild` uses it:
95
- * GJS blocks JS callbacks during GC, so a detached node keeps its handlers
96
- * for the life of the process.
83
+ * `destroy` rather than `remove`, for the same reason `removeChild` uses it: GJS blocks JS
84
+ * callbacks during GC, so a detached node keeps its handlers for the life of the process.
97
85
  */
98
86
  clearContainer: (container: HostElement) => void;
99
87
  /**
100
88
  * Diff AND apply — one phase, because React 19 deleted the other one.
101
89
  *
102
- * The argument list is the change with teeth: React 18 passed
103
- * `(instance, updatePayload, type, prevProps, nextProps, handle)` and 19 passes
104
- * `(instance, type, prevProps, nextProps, handle)`. The payload slot was
105
- * removed from the FRONT, so an adapter that kept the old signature would read
106
- * the type string as its payload and iterate a string — which is why this is
107
- * spelled out rather than left to positional luck.
90
+ * The argument list is the change with teeth: React 19 removed the `updatePayload` slot from the
91
+ * FRONT, so an adapter that kept the old signature would read the type string as its payload
92
+ * and iterate a string.
108
93
  */
109
94
  commitUpdate: (instance: HostElement, _type: string, prevProps: ReactProps, nextProps: ReactProps) => void;
110
95
  commitTextUpdate: (textInstance: HostText, _oldText: string, newText: string) => void;
@@ -7,31 +7,28 @@ import type { HostNode } from './types.js';
7
7
  /**
8
8
  * A `notify::` handler.
9
9
  *
10
- * The host strips the emitting object (`next(...args.slice(1))` in `signals.ts`),
11
- * so what reaches the callback is the ParamSpec alone. Declared HERE rather than in
12
- * the generated file because it is the same for every property in GTK — and because
13
- * a generator that emitted it would have to import GObject for a type that has
14
- * nothing to do with the GIR it read.
10
+ * The host strips the emitting object, so what reaches the callback is the ParamSpec alone. Declared
11
+ * HERE rather than in the generated file because it is the same for every property in GTK — and a
12
+ * generator that emitted it would have to import GObject for a type that has nothing to do with
13
+ * the GIR it read.
15
14
  */
16
15
  export type NotifyHandler = (pspec: GObject.ParamSpec) => void;
17
16
  declare const outParam: unique symbol;
18
17
  /**
19
18
  * A signal parameter GIR declares `out`/`inout` with `caller-allocates="0"`.
20
19
  *
21
- * GJS still passes an argument in that position, and what it holds is whatever
22
- * was in the memory the marshaller allocated: measured on gjs 1.88.1 / GTK
23
- * 4.22.4, a handler on `Gtk.SpinButton::input` receives `new_value` as
24
- * `6.9526682391035e-310`, and one on `Gtk.Editable::insert-text` receives
25
- * `position` as `1711500784`. Both arrive as ordinary numbers. Nothing warns.
20
+ * GJS still passes an argument in that position, and what it holds is whatever was in the memory
21
+ * the marshaller allocated: measured on gjs 1.88.1 / GTK 4.22.4, a handler on
22
+ * `Gtk.SpinButton::input` receives `new_value` as `6.9526682391035e-310`, and one on
23
+ * `Gtk.Editable::insert-text` receives `position` as `1711500784`. Both arrive as ordinary numbers.
24
+ * Nothing warns.
26
25
  *
27
- * So the slot is DECLARED — dropping it would silently shift every parameter
28
- * after it — and given a type nothing can be read out of, and nothing but
29
- * itself assigns to. Annotating the parameter `number` is then a compile error
30
- * naming the position, which is the only place a reader would have looked.
26
+ * So the slot is DECLARED — dropping it would silently shift every parameter after it — and given
27
+ * a type nothing can be read out of, and nothing but itself assigns to. Annotating the parameter
28
+ * `number` is then a compile error naming the position.
31
29
  *
32
- * `caller-allocates="1"` is a different thing and keeps its real type: there the
33
- * callee is handed a live object to FILL, as `Gtk.Overlay::get-child-position`
34
- * is handed a `Gdk.Rectangle`.
30
+ * `caller-allocates="1"` is a different thing and keeps its real type: there the callee is handed
31
+ * a live object to FILL, as `Gtk.Overlay::get-child-position` is handed a `Gdk.Rectangle`.
35
32
  */
36
33
  export type OutParam = {
37
34
  readonly [outParam]: never;
@@ -39,10 +36,9 @@ export type OutParam = {
39
36
  /**
40
37
  * What may appear as a child, mirroring Solid's own `JSX.Element`.
41
38
  *
42
- * The shape is copied from `solid-js/types/jsx.d.ts` because a renderer's element
43
- * union is not a free choice: a string, a number and a boolean are all legal
44
- * children there, an array of children is legal recursively, and a FUNCTION is
45
- * not. Substituting our host node for the DOM's `Node` is the only change.
39
+ * The shape is copied from `solid-js/types/jsx.d.ts` because a renderer's element union is not a free
40
+ * choice: a string, a number and a boolean are all legal children there, an array of children is
41
+ * legal recursively, and a FUNCTION is not.
46
42
  */
47
43
  export type ElementChild = HostNode | ElementChildren | string | number | boolean | null | undefined;
48
44
  export interface ElementChildren extends Array<ElementChild> {
@@ -50,10 +46,9 @@ export interface ElementChildren extends Array<ElementChild> {
50
46
  /**
51
47
  * Add the `.once` spelling of every event prop, without generating 2× the members.
52
48
  *
53
- * `signals.ts` accepts `onClickedOnce` for every `onClicked`, including every
54
- * `onNotifyFooOnce`, which would be another ~1000 generated members. A mapped type
55
- * derives them from the interface instead — including the ones a consumer adds by
56
- * declaration merging.
49
+ * `signals.ts` accepts `onClickedOnce` for every `onClicked`, including every `onNotifyFooOnce`,
50
+ * which would be another ~1000 generated members. A mapped type derives them from the interface
51
+ * instead — including the ones a consumer adds by declaration merging.
57
52
  */
58
53
  export type WithOnce<T> = T & {
59
54
  [K in keyof T & string as K extends `on${string}` ? `${K}Once` : never]?: T[K];
@@ -65,11 +60,11 @@ export interface SlotAttribute {
65
60
  /**
66
61
  * GTK's ARIA surface, on every element of every dialect. Read by `setAccessibility()`.
67
62
  *
68
- * ONE OBJECT, not 53 flat `aria*` props, and the four reasons are in `setAccessibility`'s
69
- * own header — the load-bearing one being that TypeScript exempts a hyphenated JSX
70
- * attribute from excess-property checking while a key in a fresh object literal is
71
- * checked. `AccessibilityAttributes` is GENERATED, because the names and their value
72
- * types are GTK's and are stated nowhere a ParamSpec can be read from.
63
+ * ONE OBJECT, not 53 flat `aria*` props, and the four reasons are in `setAccessibility`'s own
64
+ * header — the load-bearing one being that TypeScript exempts a hyphenated JSX attribute from
65
+ * excess-property checking while a key in a fresh object literal is checked.
66
+ * `AccessibilityAttributes` is GENERATED, because the names and their value types are GTK's and are
67
+ * stated nowhere a ParamSpec can be read from.
73
68
  */
74
69
  export interface AccessibilityAttribute {
75
70
  accessibility?: AccessibilityAttributes | null;
@@ -77,12 +72,10 @@ export interface AccessibilityAttribute {
77
72
  /**
78
73
  * The `on:<raw-signal-name>` escape hatch, typed.
79
74
  *
80
- * `parseEventProp` takes `on:` + a signal name verbatim, which is how a signal
81
- * whose name resists the camelCase derivation gets bound at all. The handler type
82
- * is deliberately the widest one that is not `any`: parameters of `never` accept
83
- * a handler declared with any parameters, so nothing a consumer writes is refused.
84
- * An inline arrow's parameter arrives as `never` here, which is the price of an
85
- * escape hatch that carries no signal-specific knowledge.
75
+ * `parseEventProp` takes `on:` + a signal name verbatim, which is how a signal whose name resists
76
+ * the camelCase derivation gets bound at all. The handler type is deliberately the widest one that
77
+ * is not `any`: parameters of `never` accept a handler declared with any parameters, so nothing a
78
+ * consumer writes is refused.
86
79
  */
87
80
  export interface RawSignalAttributes {
88
81
  [key: `on:${string}`]: ((...args: never[]) => unknown) | undefined;
@@ -107,25 +100,20 @@ export interface JsxAttributes<T> extends AccessibilityAttribute, SlotAttribute,
107
100
  /**
108
101
  * Per-element attributes for Vue.
109
102
  *
110
- * Deliberately NOT `JsxAttributes`: Vue supplies `ref` and `key` itself through
111
- * `VNodeProps`, which every registered component's props are intersected with.
112
- * Declaring our own `ref` would intersect two different `ref` types and could
113
- * leave the property unusable, so the Vue surface adds only what Vue does not —
114
- * and `children` is a SLOT in Vue, never a prop.
103
+ * Deliberately NOT `JsxAttributes`: Vue supplies `ref` and `key` itself through `VNodeProps`, which
104
+ * every registered component's props are intersected with. Declaring our own `ref` would intersect
105
+ * two different `ref` types and could leave the property unusable.
115
106
  */
116
107
  export interface VueAttributes extends AccessibilityAttribute, SlotAttribute, RawSignalAttributes {
117
108
  }
118
109
  /**
119
110
  * The properties whose GObject type is a `GMenuModel`, in both spellings.
120
111
  *
121
- * A NAME LIST, not a type test, and the reason is measured rather than stylistic: the
122
- * obvious `Gio.MenuModel extends NonNullable<T[K]> ? …` also matches every property
123
- * typed as a wider GObject — `Gio.MenuModel extends GObject.Object` is TRUE — so the
124
- * widening would leak onto properties that take an entirely different object. The three
125
- * names below are the whole set on the shipped table (`menu-model` on the two menu
126
- * buttons, the popover menu and the menu bar; `extra-menu` on the text widgets;
127
- * `secondary-menu` on `AdwToolbarView`'s header bar), and `type-tests/` holds the
128
- * widening against real markup in both dialects.
112
+ * A NAME LIST, not a type test, and the reason is measured: the obvious `Gio.MenuModel extends
113
+ * NonNullable<T[K]> ? …` also matches every property typed as a wider GObject — `Gio.MenuModel
114
+ * extends GObject.Object` is TRUE — so the widening would leak onto properties that take an
115
+ * entirely different object. The names below are the whole set on the shipped table, and
116
+ * `type-tests/` holds the widening against real markup in both dialects.
129
117
  */
130
118
  type MenuModelProp = 'menuModel' | 'menu-model' | 'extraMenu' | 'extra-menu' | 'secondaryMenu' | 'secondary-menu';
131
119
  /**
@@ -16,6 +16,25 @@ export declare class GtkHostError extends Error {
16
16
  }
17
17
  export declare const err: {
18
18
  unknownTag: (tag: string) => GtkHostError;
19
+ /**
20
+ * A row of the table naming a class the RUNNING typelib does not carry.
21
+ *
22
+ * The one absence a version cannot explain. The table is generated from one
23
+ * platform's GIR, and a platform does not BUILD every class GTK describes:
24
+ * the Unix print stack is `#ifdef`-ed out on Windows, so its two dialogs are
25
+ * in the GIR and in no `Gtk-4.0.typelib` that a Windows build produces. The
26
+ * generated half is a claim about a library release, not about this host, so
27
+ * the row is right and the class is not here — and `GtkPageSetupUnixDialog`
28
+ * is NOT the whole shape of the failure, because the next absent class is not
29
+ * spelled "Unix" either.
30
+ *
31
+ * So nothing in this host dereferences a row's class before asking: the
32
+ * refusal names the tag instead of letting `undefined.list_properties()` or
33
+ * `undefined.$gtype` report a defect against whatever row the caller happened
34
+ * to be walking. Same shape as `unknownTag` — a tag this process cannot
35
+ * honour is refused BY NAME, because GTK's own failure mode here is silence.
36
+ */
37
+ absentClass: (gtype: string) => GtkHostError;
19
38
  missingConstructProp: (tag: string, prop: string) => GtkHostError;
20
39
  unknownProp: (tag: string, prop: string) => GtkHostError;
21
40
  readOnlyProp: (tag: string, prop: string) => GtkHostError;