@gjsify/gtk-host 0.53.0 → 0.55.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.
@@ -0,0 +1 @@
1
+ const e={layout:{refused:`gtk-host's host has no door for a layout-manager child object (ADR 0092); load the .blp through Gtk.Builder instead`},strings:{refused:`gtk-host's host builds widgets and a Gtk.StringList is not one (ADR 0072); load the .blp through Gtk.Builder instead`},responses:{refused:`gtk-host's host builds widgets and a dialog's responses have no door in it (ADR 0072); load the .blp through Gtk.Builder instead`},page:`implemented`,extern:{refused:`gtk-host's host resolves a tag against its built-in widget descriptors and has no registry for an application class; load the .blp through Gtk.Builder instead`},signal:{refused:`gtk-host's tree builder resolves no handler names; a GTK app connects signals in code, or loads the .blp through Gtk.Builder with a scope`},bind:{refused:`gtk-host's tree builder resolves no bindings between objects; a GTK app binds properties in code, or loads the .blp through Gtk.Builder`},breakpoint:{refused:`gtk-host's tree builder resolves no setters between objects and has no Adw.Breakpoint; a GTK app loads the .blp through Gtk.Builder, or builds an Adw.Breakpoint in code`}};export{e as capabilities};
@@ -1 +1 @@
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};
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];case`paged`:return[e.append,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};
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";import{createElement as e,insert as t,materialize as n,setProp as r}from"../host.js";function buildSharedTree(i,a=[]){if(i.extensions!==void 0)throw Error(`gtk-host's shared-tree builder has no door for \`${i.tag}\`'s ${Object.keys(i.extensions).join(` and `)} (ADR 0072); load the .blp through Gtk.Builder instead.`);let o=e(i.tag,i.props);a.push(o),n(o),i.slot!==void 0&&r(o,`slot`,i.slot);for(let e of i.children??[])t(buildSharedTree(e,a),o);return o}export{buildSharedTree};
1
+ import"../_virtual/_rolldown/runtime.js";import{createElement as e,insert as t,materialize as n,setProp as r}from"../host.js";import{capabilities as i}from"../capabilities.js";import{assertTreeConstructs as a}from"@gjsify/adwaita-core/conformance";function buildSharedTree(e,t=[]){return a(`gtk-host`,i,e),buildNode(e,t)}function buildNode(i,a){let o=e(i.tag,i.props);a.push(o),n(o),i.slot!==void 0&&r(o,`slot`,i.slot);for(let e of i.children??[]){let n=buildNode(e,a);e.page!==void 0&&setPageLayout(o,n,e),t(n,o)}return o}function setPageLayout(e,t,n){let{page:i}=n,a=e.descriptor.gtype;if(a===`GtkNotebook`)r(t,`layout`,i?.label===void 0?{}:{tabLabel:i.label});else if(a===`GtkStack`)r(t,`layout`,{...i?.name===void 0?{}:{name:i.name},...i?.label===void 0?{}:{title:i.label}});else throw Error(`gtk-host's shared-tree builder: \`${n.tag}\` has a page, and ${a} has no pages.`)}export{buildSharedTree};
@@ -1 +1 @@
1
- import"../_virtual/_rolldown/runtime.js";import e from"gi://Gtk?version=4.0";const t={kind:`toplevel`,present:`present`,close:`destroy`},n=[{gtype:`GtkBox`,ctor:()=>e.Box,children:{kind:`ordered`,append:`append`,after:`insert_child_after`,remove:`remove`,reorder:`native`}},{gtype:`GtkWindow`,ctor:()=>e.Window,children:{kind:`single`,set:`set_child`},placement:t},{gtype:`GtkApplicationWindow`,ctor:()=>e.ApplicationWindow,children:{kind:`single`,set:`set_child`},placement:t},{gtype:`GtkDialog`,ctor:()=>e.Dialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkAboutDialog`,ctor:()=>e.AboutDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkMessageDialog`,ctor:()=>e.MessageDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkAssistant`,ctor:()=>e.Assistant,children:{kind:`uncurated`},placement:t},{gtype:`GtkAppChooserDialog`,ctor:()=>e.AppChooserDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkColorChooserDialog`,ctor:()=>e.ColorChooserDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkFileChooserDialog`,ctor:()=>e.FileChooserDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkFontChooserDialog`,ctor:()=>e.FontChooserDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkShortcutsWindow`,ctor:()=>e.ShortcutsWindow,children:{kind:`uncurated`},placement:t},{gtype:`GtkPageSetupUnixDialog`,ctor:()=>e.PageSetupUnixDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkPrintUnixDialog`,ctor:()=>e.PrintUnixDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkAspectFrame`,ctor:()=>e.AspectFrame,children:{kind:`single`,set:`set_child`}},{gtype:`GtkScrolledWindow`,ctor:()=>e.ScrolledWindow,children:{kind:`single`,set:`set_child`}},{gtype:`GtkFrame`,ctor:()=>e.Frame,children:{kind:`single`,set:`set_child`}},{gtype:`GtkOverlay`,ctor:()=>e.Overlay,children:{kind:`slotted`,slots:{child:`set_child`,overlay:`add_overlay`},defaultSlot:`child`,remove:`remove_overlay`}},{gtype:`GtkLabel`,ctor:()=>e.Label,children:{kind:`none`},textSink:`label`},{gtype:`GtkButton`,ctor:()=>e.Button,children:{kind:`single`,set:`set_child`},textSink:`label`},{gtype:`GtkToggleButton`,ctor:()=>e.ToggleButton,children:{kind:`single`,set:`set_child`},textSink:`label`},{gtype:`GtkImage`,ctor:()=>e.Image,children:{kind:`none`}},{gtype:`GtkSwitch`,ctor:()=>e.Switch,children:{kind:`none`}},{gtype:`GtkEntry`,ctor:()=>e.Entry,children:{kind:`none`},textSink:`text`},{gtype:`GtkListBox`,ctor:()=>e.ListBox,children:{kind:`indexed`,insert:`insert`,remove:`remove`,wrap:`list-box-row`}},{gtype:`GtkFlowBox`,ctor:()=>e.FlowBox,children:{kind:`indexed`,insert:`insert`,remove:`remove`,wrap:`flow-box-child`,perLineCap:`max-children-per-line`}},{gtype:`GtkListBoxRow`,ctor:()=>e.ListBoxRow,children:{kind:`single`,set:`set_child`}},{gtype:`GtkListItem`,ctor:()=>e.ListItem,children:{kind:`single`,set:`set_child`}},{gtype:`GtkListHeader`,ctor:()=>e.ListHeader,children:{kind:`single`,set:`set_child`}},{gtype:`GtkColumnViewCell`,ctor:()=>e.ColumnViewCell,children:{kind:`single`,set:`set_child`}},{gtype:`GtkStack`,ctor:()=>e.Stack,children:{kind:`keyed`,add:`add_titled`,remove:`remove`,nameFrom:`name`,titled:!0}},{gtype:`GtkGrid`,ctor:()=>e.Grid,children:{kind:`coords`,attach:`attach`,remove:`remove`}},{gtype:`GtkHeaderBar`,ctor:()=>e.HeaderBar,children:{kind:`slotted`,slots:{start:`pack_start`,end:`pack_end`,title:`set_title_widget`},defaultSlot:`start`,remove:`remove`}}];export{n as GTK_DESCRIPTORS,t as TOPLEVEL};
1
+ import"../_virtual/_rolldown/runtime.js";import e from"gi://Gtk?version=4.0";const t={kind:`toplevel`,present:`present`,close:`destroy`},n=[{gtype:`GtkBox`,ctor:()=>e.Box,children:{kind:`ordered`,append:`append`,after:`insert_child_after`,remove:`remove`,reorder:`native`}},{gtype:`GtkWindow`,ctor:()=>e.Window,children:{kind:`single`,set:`set_child`},placement:t},{gtype:`GtkApplicationWindow`,ctor:()=>e.ApplicationWindow,children:{kind:`single`,set:`set_child`},placement:t},{gtype:`GtkDialog`,ctor:()=>e.Dialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkAboutDialog`,ctor:()=>e.AboutDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkMessageDialog`,ctor:()=>e.MessageDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkAssistant`,ctor:()=>e.Assistant,children:{kind:`uncurated`},placement:t},{gtype:`GtkAppChooserDialog`,ctor:()=>e.AppChooserDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkColorChooserDialog`,ctor:()=>e.ColorChooserDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkFileChooserDialog`,ctor:()=>e.FileChooserDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkFontChooserDialog`,ctor:()=>e.FontChooserDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkShortcutsWindow`,ctor:()=>e.ShortcutsWindow,children:{kind:`uncurated`},placement:t},{gtype:`GtkPageSetupUnixDialog`,ctor:()=>e.PageSetupUnixDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkPrintUnixDialog`,ctor:()=>e.PrintUnixDialog,children:{kind:`uncurated`},placement:t},{gtype:`GtkAspectFrame`,ctor:()=>e.AspectFrame,children:{kind:`single`,set:`set_child`}},{gtype:`GtkScrolledWindow`,ctor:()=>e.ScrolledWindow,children:{kind:`single`,set:`set_child`}},{gtype:`GtkViewport`,ctor:()=>e.Viewport,children:{kind:`single`,set:`set_child`}},{gtype:`GtkWindowHandle`,ctor:()=>e.WindowHandle,children:{kind:`single`,set:`set_child`}},{gtype:`GtkScrollbar`,ctor:()=>e.Scrollbar,children:{kind:`none`}},{gtype:`GtkFrame`,ctor:()=>e.Frame,children:{kind:`single`,set:`set_child`}},{gtype:`GtkGraphicsOffload`,ctor:()=>e.GraphicsOffload,children:{kind:`single`,set:`set_child`}},{gtype:`GtkOverlay`,ctor:()=>e.Overlay,children:{kind:`slotted`,slots:{child:`set_child`,overlay:`add_overlay`},defaultSlot:`child`,remove:`remove_overlay`}},{gtype:`GtkLabel`,ctor:()=>e.Label,children:{kind:`none`},textSink:`label`},{gtype:`GtkButton`,ctor:()=>e.Button,children:{kind:`single`,set:`set_child`},textSink:`label`},{gtype:`GtkToggleButton`,ctor:()=>e.ToggleButton,children:{kind:`single`,set:`set_child`},textSink:`label`},{gtype:`GtkImage`,ctor:()=>e.Image,children:{kind:`none`}},{gtype:`GtkSwitch`,ctor:()=>e.Switch,children:{kind:`none`}},{gtype:`GtkEntry`,ctor:()=>e.Entry,children:{kind:`none`},textSink:`text`},{gtype:`GtkListBox`,ctor:()=>e.ListBox,children:{kind:`indexed`,insert:`insert`,remove:`remove`,wrap:`list-box-row`}},{gtype:`GtkFlowBox`,ctor:()=>e.FlowBox,children:{kind:`indexed`,insert:`insert`,remove:`remove`,wrap:`flow-box-child`,perLineCap:`max-children-per-line`}},{gtype:`GtkListBoxRow`,ctor:()=>e.ListBoxRow,children:{kind:`single`,set:`set_child`}},{gtype:`GtkFlowBoxChild`,ctor:()=>e.FlowBoxChild,children:{kind:`single`,set:`set_child`}},{gtype:`GtkListItem`,ctor:()=>e.ListItem,children:{kind:`single`,set:`set_child`}},{gtype:`GtkListHeader`,ctor:()=>e.ListHeader,children:{kind:`single`,set:`set_child`}},{gtype:`GtkColumnViewCell`,ctor:()=>e.ColumnViewCell,children:{kind:`single`,set:`set_child`}},{gtype:`GtkRevealer`,ctor:()=>e.Revealer,children:{kind:`single`,set:`set_child`}},{gtype:`GtkExpander`,ctor:()=>e.Expander,children:{kind:`slotted`,slots:{child:`set_child`,label:`set_label_widget`},defaultSlot:`child`}},{gtype:`GtkPaned`,ctor:()=>e.Paned,children:{kind:`slotted`,slots:{start:`set_start_child`,end:`set_end_child`},defaultSlot:`start`}},{gtype:`GtkCenterBox`,ctor:()=>e.CenterBox,children:{kind:`slotted`,slots:{start:`set_start_widget`,center:`set_center_widget`,end:`set_end_widget`},defaultSlot:`center`}},{gtype:`GtkStack`,ctor:()=>e.Stack,children:{kind:`keyed`,add:`add_titled`,remove:`remove`,nameFrom:`name`,titled:!0}},{gtype:`GtkNotebook`,ctor:()=>e.Notebook,children:{kind:`paged`,append:`append_page`,remove:`detach_tab`,labelFrom:`tabLabel`}},{gtype:`GtkGrid`,ctor:()=>e.Grid,children:{kind:`coords`,attach:`attach`,remove:`remove`}},{gtype:`GtkHeaderBar`,ctor:()=>e.HeaderBar,children:{kind:`slotted`,slots:{start:`pack_start`,end:`pack_end`,title:`set_title_widget`},defaultSlot:`start`,remove:`remove`}}];export{n as GTK_DESCRIPTORS,t as TOPLEVEL};
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)}const m=1;function adoptFontconfigMap(e,t){if(t.length===0||f.getenv(`PANGOCAIRO_BACKEND`)!==null)return;let n=p.FontMap.new_for_font_type(1);if(n===null)return;let r=familyNames(n);if(r.length===0)return;let i=new Map;for(let e of t)try{n.add_font_file(e)}catch(t){i.set(e,messageOf(t))}if(!familyNames(n).filter(e=>!r.includes(e)).every(t=>e.get_family(t)!==null))return n.set_default(),{map:n,before:r,failed:i}}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:[],fontconfigFallback:!1};let m=p.FontMap.get_default(),h=i.length===0?[]:familyNames(m),g=i.map(e=>({source:e,registered:[],declined:[],failed:[]}));for(let e of g){let t=[];collectFaces(d.File.new_for_path(e.source.dir),t,e.failed);for(let n of t.sort())try{m.add_font_file(n),e.registered.push(n)}catch(t){if(isUnsupportedByFontMap(t)){e.declined.push(n);continue}e.failed.push({path:n,message:messageOf(t)})}}let _=adoptFontconfigMap(m,g.flatMap(e=>e.declined));if(_!==void 0){m=_.map,h=_.before;for(let e of g){let t=e.declined;e.declined=[];for(let n of t){let t=_.failed.get(n);t===void 0?e.registered.push(n):e.failed.push({path:n,message:t})}}}for(let e of g)s.push(...e.registered),c.push(...e.declined),l.push(...e.failed),o.push({...e.source,registered:e.registered,declined:e.declined,failed:e.failed});let v=familyNames(m),y=i.length===0?[]:v.filter(e=>!h.includes(e)).sort(),b=r(u,v);captureUiFontBaseline();let x=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 b)e.kind!==`exact`&&console.warn(`initFonts: ${n(e)}`);return{dir:a,sources:o,uiFont:x,registered:s,declined:c,failed:l,families:y,matches:b,fontconfigFallback:_!==void 0}}let h=!1,g;function captureUiFontBaseline(){if(h)return g;let e=u.Settings.get_default();if(e!==null)return g=e.gtk_font_name??void 0,h=!0,g}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,m as CAIRO_FONT_TYPE_FT,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};
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import{GtkHostError as e,err as t}from"./errors.js";import{beginHostWrite as n,endHostWrite as r}from"./signals.js";import i from"gi://GObject?version=2.0";import a from"gi://Gtk?version=4.0";function addressOf(e){let n=e.wrapper??e.widget;if(!n)throw t.notAWidget(e.descriptor.gtype);return n}function slotPropertyOf(e){return e.startsWith(`set_`)?e.slice(4).replace(/_/g,`-`):null}function slotNames(e){if(e.kind===`single`){let t=slotPropertyOf(e.set);return t===null?[]:[t]}if(e.kind!==`slotted`)return[];let t=[];for(let[n,r]of Object.entries(e.slots)){t.push(n);let e=slotPropertyOf(r);e!==null&&e!==n&&t.push(e)}return t}function slottedSlot(e,n,r){if(n==null){if(e.defaultSlot in e.slots)return e.defaultSlot;throw t.unknownSlot(r,e.defaultSlot,slotNames(e))}if(n in e.slots)return n;for(let[t,r]of Object.entries(e.slots))if(slotPropertyOf(r)===n)return t;throw t.unknownSlot(r,n,slotNames(e))}function refuseUnknownSlot(e,n){let r=n.slot;if(r==null)return;let i=e.descriptor.children;if(i.kind===`slotted`){slottedSlot(i,r,e.descriptor.gtype);return}if(i.kind!==`keyed`&&!(i.kind===`single`&&slotPropertyOf(i.set)===r))throw t.unknownSlot(e.descriptor.gtype,r,slotNames(i))}function makeWrapper(e,t,n){let r=e.children,i=r.kind===`indexed`?r.wrap:r.kind===`slotted`?r.wrapSlots?.[slottedSlot(r,n,e.gtype)]??null:null;if(!i)return null;if(i===`list-box-row`){if(t instanceof a.ListBoxRow)return null;let e=new a.ListBoxRow;return e.set_child(t),e}if(t instanceof a.FlowBoxChild)return null;let o=new a.FlowBoxChild;return o.set_child(t),o}const makeDetachedContainer=()=>new a.Box;function unhandledPolicy(e){throw Error(`unhandled child policy: ${JSON.stringify(e)}`)}function setterSlotOf(e,t){let n=e.descriptor.children;if(n.kind===`single`)return n.set;if(n.kind!==`slotted`)return null;let r=n.slots[slottedSlot(n,t.slot,e.descriptor.gtype)];return r?.startsWith(`set_`)===!0?r:null}function adderSlots(e){return e.kind===`slotted`?Object.entries(e.slots).filter(([,e])=>!e.startsWith(`set_`)).map(([e])=>e):[]}function setterSlots(e){return e.kind===`single`?[e.set]:e.kind===`slotted`?Object.values(e.slots).filter(e=>e.startsWith(`set_`)):[]}function slotOccupant(e,t){let n=e,r=t.replace(/^set_/,`get_`);if(typeof n[r]==`function`)return n[r]()??null}const o={kind:`parented`},placementOf=e=>e.placement??o;function outsideParentOf(e){let t=placementOf(e);switch(t.kind){case`parented`:return null;case`portal`:case`toplevel`:return t;default:return unhandledPlacement(t)}}function portalOf(e){let t=outsideParentOf(e);return t?.kind===`portal`?t:null}function unhandledPlacement(e){throw Error(`unhandled node placement: ${JSON.stringify(e)}`)}const isPortal=e=>portalOf(e.descriptor)!==null,isUnparented=e=>outsideParentOf(e.descriptor)!==null;function placementMethod(e,n,r,i){let a=e.widget?.[r];if(typeof a!=`function`)throw t.placementMethodMissing(e.descriptor.gtype,n.kind,r,i);return a}const toplevelOf=e=>{let t=e.get_root();return t instanceof a.Window?t:null};function presentPortal(e,t,n){let r=e.widget;return r?(placementMethod(t,n,n.present,`present`),placementMethod(t,n,n.close,`close`),watchPortalRoot(r,t,n),placeAgainst(r,t,n)):!1}function placeAgainst(e,t,n){let r=t.widget;if(!r)return!1;let i=toplevelOf(e);if(!i)return placementMethod(t,n,n.close,`close`).call(r),!1;if(r.get_parent()){if(toplevelOf(r)===i)return!0;placementMethod(t,n,n.close,`close`).call(r)}return placementMethod(t,n,n.present,`present`).call(r,e),!0}function watchPortalRoot(e,t,n){t.portalWatch?.widget!==e&&(t.portalWatch&&retractPortalWatch(t),t.portalWatch={widget:e,id:e.connect(`notify::root`,()=>{t.attached=placeAgainst(e,t,n)})})}function retractPortalWatch(e){let t=e.portalWatch;t&&(e.portalWatch=null,t.widget.disconnect(t.id))}function retractPortal(e,t){retractPortalWatch(e),e.widget&&placementMethod(e,t,t.close,`close`).call(e.widget)}function presentToplevel(e,t){let n=e.widget;if(!n)return!1;let r=placementMethod(e,t,t.present,`present`);return placementMethod(e,t,t.close,`close`),e.props.visible!==!1&&r.call(n),!0}function closeToplevel(e,t){e.widget&&placementMethod(e,t,t.close,`close`).call(e.widget)}function detachToplevel(e){let t=e.widget;t&&t.set_visible(!1)}function placeOutsideParent(e,t,n){switch(n.kind){case`portal`:return presentPortal(e,t,n);case`toplevel`:return presentToplevel(t,n);default:return unhandledPlacement(n)}}function detachOutsideParent(e,t){switch(t.kind){case`portal`:return retractPortal(e,t);case`toplevel`:return detachToplevel(e);default:return unhandledPlacement(t)}}function closeOutsideParent(e,t){switch(t.kind){case`portal`:return retractPortal(e,t);case`toplevel`:return closeToplevel(e,t);default:return unhandledPlacement(t)}}function classPlacementKind(e,t){return i.type_is_a(e,a.Root.$gtype)?`toplevel`:typeof t==`function`&&t.length===1?`portal`:null}function nodePlacementKind(e){let t=e.constructor?.$gtype;return t?classPlacementKind(t,e.present):null}function refuseUnparentable(e,n){if(n.descriptor.placement!==void 0)return;let r=n.widget;if(!r)return;let i=nodePlacementKind(r);if(i)throw t.unparentableChild(e.descriptor.gtype,n.descriptor.gtype,i,i===`toplevel`?`${n.descriptor.gtype} implements Gtk.Root, so it IS a toplevel and cannot have a parent`:`${n.descriptor.gtype}.present() takes a parent, so it is presented AGAINST one and never placed into one`)}function insertChild(n){try{placeChild(n)}catch(r){throw r instanceof e?r:t.rejectedChild(n.parent.descriptor.gtype,n.child.descriptor.gtype,r.message)}syncPerLineCap(n.parent)}function placeChild(e){let{parent:n,child:r}=e,i=n.descriptor.children,a=n.widget,o=addressOf(r);switch(i.kind){case`none`:throw t.unclaimedChild(n.descriptor.gtype,r.descriptor.gtype);case`uncurated`:throw t.uncuratedPlacement(n.descriptor.gtype,r.descriptor.gtype);case`single`:a[i.set](o);return;case`indexed`:a[i.insert](o,e.index);return;case`coords`:appendChild(n,r,a);return;case`ordered`:if(i.after){a[i.after](o,e.prevWidget??null);return}case`slotted`:case`keyed`:appendChild(n,r,a),rotateTail(n,r,e.following,a);return;default:return unhandledPolicy(i)}}function appendChild(e,n,r){let i=e.descriptor.children,a=addressOf(n);switch(i.kind){case`uncurated`:throw t.uncuratedPlacement(e.descriptor.gtype,n.descriptor.gtype);case`ordered`:r[i.append](a);return;case`slotted`:{let t=slottedSlot(i,n.slot,e.descriptor.gtype);r[i.slots[t]](a);return}case`keyed`:{let e=n.layout?.[i.nameFrom]??n.slot,t=n.layout?.title;i.titled?r[i.add](a,e??null,t??e??``):r[i.add](a);return}case`coords`:{let e=n.layout??{};r[i.attach](a,e.column??0,e.row??0,e.columnSpan??1,e.rowSpan??1);return}default:throw t.unclaimedChild(e.descriptor.gtype,n.descriptor.gtype)}}function rotateTail(e,t,n,r){let i=e.descriptor.children,a=n;if(i.kind===`slotted`){if(setterSlotOf(e,t))return;let slotOf=t=>slottedSlot(i,t.slot,e.descriptor.gtype),r=slotOf(t);a=n.filter(e=>slotOf(e)===r)}for(let t of a)detachChild(e,t,r);for(let t of a)appendChild(e,t,r)}function detachChild(e,n,r){let i=e.descriptor.children,a=n.wrapper??n.widget;if(a)switch(i.kind){case`none`:case`uncurated`:return;case`single`:clearIfCurrent(r,i.set,a);return;case`slotted`:{let o=setterSlotOf(e,n);if(o){clearIfCurrent(r,o,a);return}let s=slottedSlot(i,n.slot,e.descriptor.gtype);if(!i.remove)throw t.slotNeedsRemove(e.descriptor.gtype,s,i.slots[s]??`?`);r[i.remove](a);return}case`keyed`:{let e=i.hideBeforeRemove===!0&&a.get_visible();e&&writeVisible(a,!1),r[i.remove](a),e&&writeVisible(a,!0);return}case`ordered`:case`indexed`:case`coords`:r[i.remove](a);return;default:return unhandledPolicy(i)}}function writeVisible(e,t){n(null);try{e.set_visible(t)}finally{r()}}function clearIfCurrent(e,t,n){let r=slotOccupant(e,t);(r===void 0||r===n)&&e[t](null)}function removeChild(e,t){let n=outsideParentOf(t.descriptor);if(n)return detachOutsideParent(t,n);let r=e.widget;r&&t.attached&&(detachChild(e,t,r),syncPerLineCap(e))}function syncPerLineCap(e){let t=e.descriptor.children;if(t.kind!==`indexed`||t.perLineCap===void 0||e.props[t.perLineCap]!==void 0)return;let i=e.widget;if(!i)return;let a=0;for(let e=i.get_first_child();e!==null;e=e.get_next_sibling())a+=1;n(null);try{i.set_property(t.perLineCap,Math.min(65535,Math.max(1,a)))}finally{r()}}function reorderMode(e){switch(e.kind){case`uncurated`:return`n/a`;case`ordered`:return e.reorder;case`indexed`:return`native`;case`slotted`:return adderSlots(e).length>0?`remove-all`:`n/a`;case`keyed`:return`remove-all`;case`coords`:case`single`:case`none`:return`n/a`;default:return unhandledPolicy(e)}}export{adderSlots,addressOf,classPlacementKind,closeOutsideParent,closeToplevel,detachOutsideParent,detachToplevel,insertChild,isPortal,isUnparented,makeDetachedContainer,makeWrapper,nodePlacementKind,outsideParentOf,placeOutsideParent,placementOf,portalOf,presentPortal,presentToplevel,refuseUnknownSlot,refuseUnparentable,removeChild,reorderMode,retractPortal,setterSlotOf,setterSlots,slotNames,slotOccupant,slotPropertyOf,slottedSlot,unhandledPlacement,unhandledPolicy};
1
+ import"./_virtual/_rolldown/runtime.js";import{GtkHostError as e,err as t}from"./errors.js";import{beginHostWrite as n,endHostWrite as r}from"./signals.js";import i from"gi://GObject?version=2.0";import a from"gi://Gtk?version=4.0";function addressOf(e){let n=e.wrapper??e.widget;if(!n)throw t.notAWidget(e.descriptor.gtype);return n}function slotPropertyOf(e){return e.startsWith(`set_`)?e.slice(4).replace(/_/g,`-`):null}function slotNames(e){if(e.kind===`single`){let t=slotPropertyOf(e.set);return t===null?[]:[t]}if(e.kind!==`slotted`)return[];let t=[];for(let[n,r]of Object.entries(e.slots)){t.push(n);let e=slotPropertyOf(r);e!==null&&e!==n&&t.push(e)}return t}function slottedSlot(e,n,r){if(n==null){if(e.defaultSlot in e.slots)return e.defaultSlot;throw t.unknownSlot(r,e.defaultSlot,slotNames(e))}if(n in e.slots)return n;for(let[t,r]of Object.entries(e.slots))if(slotPropertyOf(r)===n)return t;throw t.unknownSlot(r,n,slotNames(e))}function refuseUnknownSlot(e,n){let r=n.slot;if(r==null)return;let i=e.descriptor.children;if(i.kind===`slotted`){slottedSlot(i,r,e.descriptor.gtype);return}if(i.kind!==`keyed`&&!(i.kind===`single`&&slotPropertyOf(i.set)===r))throw t.unknownSlot(e.descriptor.gtype,r,slotNames(i))}function makeWrapper(e,t,n){let r=e.children,i=r.kind===`indexed`?r.wrap:r.kind===`slotted`?r.wrapSlots?.[slottedSlot(r,n,e.gtype)]??null:null;if(!i)return null;if(i===`list-box-row`){if(t instanceof a.ListBoxRow)return null;let e=new a.ListBoxRow;return e.set_child(t),e}if(t instanceof a.FlowBoxChild)return null;let o=new a.FlowBoxChild;return o.set_child(t),o}const makeDetachedContainer=()=>new a.Box;function unhandledPolicy(e){throw Error(`unhandled child policy: ${JSON.stringify(e)}`)}function setterSlotOf(e,t){let n=e.descriptor.children;if(n.kind===`single`)return n.set;if(n.kind!==`slotted`)return null;let r=n.slots[slottedSlot(n,t.slot,e.descriptor.gtype)];return r?.startsWith(`set_`)===!0?r:null}function adderSlots(e){return e.kind===`slotted`?Object.entries(e.slots).filter(([,e])=>!e.startsWith(`set_`)).map(([e])=>e):[]}function setterSlots(e){return e.kind===`single`?[e.set]:e.kind===`slotted`?Object.values(e.slots).filter(e=>e.startsWith(`set_`)):[]}function slotOccupant(e,t){let n=e,r=t.replace(/^set_/,`get_`);if(typeof n[r]==`function`)return n[r]()??null}const o={kind:`parented`},placementOf=e=>e.placement??o;function outsideParentOf(e){let t=placementOf(e);switch(t.kind){case`parented`:return null;case`portal`:case`toplevel`:return t;default:return unhandledPlacement(t)}}function portalOf(e){let t=outsideParentOf(e);return t?.kind===`portal`?t:null}function unhandledPlacement(e){throw Error(`unhandled node placement: ${JSON.stringify(e)}`)}const isPortal=e=>portalOf(e.descriptor)!==null,isUnparented=e=>outsideParentOf(e.descriptor)!==null;function placementMethod(e,n,r,i){let a=e.widget?.[r];if(typeof a!=`function`)throw t.placementMethodMissing(e.descriptor.gtype,n.kind,r,i);return a}const toplevelOf=e=>{let t=e.get_root();return t instanceof a.Window?t:null};function presentPortal(e,t,n){let r=e.widget;return r?(placementMethod(t,n,n.present,`present`),placementMethod(t,n,n.close,`close`),watchPortalRoot(r,t,n),placeAgainst(r,t,n)):!1}function placeAgainst(e,t,n){let r=t.widget;if(!r)return!1;let i=toplevelOf(e);if(!i)return placementMethod(t,n,n.close,`close`).call(r),!1;if(r.get_parent()){if(toplevelOf(r)===i)return!0;placementMethod(t,n,n.close,`close`).call(r)}return placementMethod(t,n,n.present,`present`).call(r,e),!0}function watchPortalRoot(e,t,n){t.portalWatch?.widget!==e&&(t.portalWatch&&retractPortalWatch(t),t.portalWatch={widget:e,id:e.connect(`notify::root`,()=>{t.attached=placeAgainst(e,t,n)})})}function retractPortalWatch(e){let t=e.portalWatch;t&&(e.portalWatch=null,t.widget.disconnect(t.id))}function retractPortal(e,t){retractPortalWatch(e),e.widget&&placementMethod(e,t,t.close,`close`).call(e.widget)}function presentToplevel(e,t){let n=e.widget;if(!n)return!1;let r=placementMethod(e,t,t.present,`present`);return placementMethod(e,t,t.close,`close`),e.props.visible!==!1&&r.call(n),!0}function closeToplevel(e,t){e.widget&&placementMethod(e,t,t.close,`close`).call(e.widget)}function detachToplevel(e){let t=e.widget;t&&t.set_visible(!1)}function placeOutsideParent(e,t,n){switch(n.kind){case`portal`:return presentPortal(e,t,n);case`toplevel`:return presentToplevel(t,n);default:return unhandledPlacement(n)}}function detachOutsideParent(e,t){switch(t.kind){case`portal`:return retractPortal(e,t);case`toplevel`:return detachToplevel(e);default:return unhandledPlacement(t)}}function closeOutsideParent(e,t){switch(t.kind){case`portal`:return retractPortal(e,t);case`toplevel`:return closeToplevel(e,t);default:return unhandledPlacement(t)}}function classPlacementKind(e,t){return i.type_is_a(e,a.Root.$gtype)?`toplevel`:typeof t==`function`&&t.length===1?`portal`:null}function nodePlacementKind(e){let t=e.constructor?.$gtype;return t?classPlacementKind(t,e.present):null}function refuseUnparentable(e,n){if(n.descriptor.placement!==void 0)return;let r=n.widget;if(!r)return;let i=nodePlacementKind(r);if(i)throw t.unparentableChild(e.descriptor.gtype,n.descriptor.gtype,i,i===`toplevel`?`${n.descriptor.gtype} implements Gtk.Root, so it IS a toplevel and cannot have a parent`:`${n.descriptor.gtype}.present() takes a parent, so it is presented AGAINST one and never placed into one`)}function insertChild(n){try{placeChild(n)}catch(r){throw r instanceof e?r:t.rejectedChild(n.parent.descriptor.gtype,n.child.descriptor.gtype,r.message)}syncPerLineCap(n.parent)}function placeChild(e){let{parent:n,child:r}=e,i=n.descriptor.children,a=n.widget,o=addressOf(r);switch(i.kind){case`none`:throw t.unclaimedChild(n.descriptor.gtype,r.descriptor.gtype);case`uncurated`:throw t.uncuratedPlacement(n.descriptor.gtype,r.descriptor.gtype);case`single`:a[i.set](o);return;case`indexed`:a[i.insert](o,e.index);return;case`coords`:appendChild(n,r,a);return;case`ordered`:if(i.after){a[i.after](o,e.prevWidget??null);return}case`slotted`:case`keyed`:case`paged`:appendChild(n,r,a),rotateTail(n,r,e.following,a);return;default:return unhandledPolicy(i)}}function appendChild(e,n,r){let i=e.descriptor.children,o=addressOf(n);switch(i.kind){case`uncurated`:throw t.uncuratedPlacement(e.descriptor.gtype,n.descriptor.gtype);case`ordered`:r[i.append](o);return;case`slotted`:{let t=slottedSlot(i,n.slot,e.descriptor.gtype);r[i.slots[t]](o);return}case`keyed`:{let e=n.layout?.[i.nameFrom]??n.slot,t=n.layout?.title;i.titled?r[i.add](o,e??null,t??e??``):r[i.add](o);return}case`paged`:{let e=n.layout?.[i.labelFrom];r[i.append](o,e===void 0?null:new a.Label({label:e}));return}case`coords`:{let e=n.layout??{};r[i.attach](o,e.column??0,e.row??0,e.columnSpan??1,e.rowSpan??1);return}default:throw t.unclaimedChild(e.descriptor.gtype,n.descriptor.gtype)}}function rotateTail(e,t,n,r){let i=e.descriptor.children,a=n;if(i.kind===`slotted`){if(setterSlotOf(e,t))return;let slotOf=t=>slottedSlot(i,t.slot,e.descriptor.gtype),r=slotOf(t);a=n.filter(e=>slotOf(e)===r)}for(let t of a)detachChild(e,t,r);for(let t of a)appendChild(e,t,r)}function detachChild(e,n,r){let i=e.descriptor.children,a=n.wrapper??n.widget;if(a)switch(i.kind){case`none`:case`uncurated`:return;case`single`:clearIfCurrent(r,i.set,a);return;case`slotted`:{let o=setterSlotOf(e,n);if(o){clearIfCurrent(r,o,a);return}let s=slottedSlot(i,n.slot,e.descriptor.gtype);if(!i.remove)throw t.slotNeedsRemove(e.descriptor.gtype,s,i.slots[s]??`?`);r[i.remove](a);return}case`keyed`:{let e=i.hideBeforeRemove===!0&&a.get_visible();e&&writeVisible(a,!1),r[i.remove](a),e&&writeVisible(a,!0);return}case`ordered`:case`indexed`:case`coords`:case`paged`:r[i.remove](a);return;default:return unhandledPolicy(i)}}function writeVisible(e,t){n(null);try{e.set_visible(t)}finally{r()}}function clearIfCurrent(e,t,n){let r=slotOccupant(e,t);(r===void 0||r===n)&&e[t](null)}function removeChild(e,t){let n=outsideParentOf(t.descriptor);if(n)return detachOutsideParent(t,n);let r=e.widget;r&&t.attached&&(detachChild(e,t,r),syncPerLineCap(e))}function syncPerLineCap(e){let t=e.descriptor.children;if(t.kind!==`indexed`||t.perLineCap===void 0||e.props[t.perLineCap]!==void 0)return;let i=e.widget;if(!i)return;let a=0;for(let e=i.get_first_child();e!==null;e=e.get_next_sibling())a+=1;n(null);try{i.set_property(t.perLineCap,Math.min(65535,Math.max(1,a)))}finally{r()}}function reorderMode(e){switch(e.kind){case`uncurated`:return`n/a`;case`ordered`:return e.reorder;case`indexed`:return`native`;case`slotted`:return adderSlots(e).length>0?`remove-all`:`n/a`;case`paged`:case`keyed`:return`remove-all`;case`coords`:case`single`:case`none`:return`n/a`;default:return unhandledPolicy(e)}}export{adderSlots,addressOf,classPlacementKind,closeOutsideParent,closeToplevel,detachOutsideParent,detachToplevel,insertChild,isPortal,isUnparented,makeDetachedContainer,makeWrapper,nodePlacementKind,outsideParentOf,placeOutsideParent,placementOf,portalOf,presentPortal,presentToplevel,refuseUnknownSlot,refuseUnparentable,removeChild,reorderMode,retractPortal,setterSlotOf,setterSlots,slotNames,slotOccupant,slotPropertyOf,slottedSlot,unhandledPlacement,unhandledPolicy};
@@ -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];
@@ -62,14 +57,22 @@ export type WithOnce<T> = T & {
62
57
  export interface SlotAttribute {
63
58
  slot?: string | null;
64
59
  }
60
+ /**
61
+ * What this child tells its parent's layout, read by `setProp()` at placement: a grid cell's
62
+ * `row` and `column`, a stack page's `name` and `title`, a notebook page's `tabLabel`. The keys
63
+ * belong to the PARENT's child policy, so the record is open here.
64
+ */
65
+ export interface LayoutAttribute {
66
+ layout?: Record<string, unknown> | null;
67
+ }
65
68
  /**
66
69
  * GTK's ARIA surface, on every element of every dialect. Read by `setAccessibility()`.
67
70
  *
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.
71
+ * ONE OBJECT, not 53 flat `aria*` props, and the four reasons are in `setAccessibility`'s own
72
+ * header — the load-bearing one being that TypeScript exempts a hyphenated JSX attribute from
73
+ * excess-property checking while a key in a fresh object literal is checked.
74
+ * `AccessibilityAttributes` is GENERATED, because the names and their value types are GTK's and are
75
+ * stated nowhere a ParamSpec can be read from.
73
76
  */
74
77
  export interface AccessibilityAttribute {
75
78
  accessibility?: AccessibilityAttributes | null;
@@ -77,12 +80,10 @@ export interface AccessibilityAttribute {
77
80
  /**
78
81
  * The `on:<raw-signal-name>` escape hatch, typed.
79
82
  *
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.
83
+ * `parseEventProp` takes `on:` + a signal name verbatim, which is how a signal whose name resists
84
+ * the camelCase derivation gets bound at all. The handler type is deliberately the widest one that
85
+ * is not `any`: parameters of `never` accept a handler declared with any parameters, so nothing a
86
+ * consumer writes is refused.
86
87
  */
87
88
  export interface RawSignalAttributes {
88
89
  [key: `on:${string}`]: ((...args: never[]) => unknown) | undefined;
@@ -100,32 +101,27 @@ export interface RawSignalAttributes {
100
101
  * `T` is the widget's own instance type, so `ref={(el) => …}` infers `el` as
101
102
  * `Gtk.Box` rather than the `unknown` a DOM renderer settles for.
102
103
  */
103
- export interface JsxAttributes<T> extends AccessibilityAttribute, SlotAttribute, RawSignalAttributes {
104
+ export interface JsxAttributes<T> extends AccessibilityAttribute, SlotAttribute, LayoutAttribute, RawSignalAttributes {
104
105
  children?: ElementChild;
105
106
  ref?: T | ((el: T) => void) | undefined;
106
107
  }
107
108
  /**
108
109
  * Per-element attributes for Vue.
109
110
  *
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.
111
+ * Deliberately NOT `JsxAttributes`: Vue supplies `ref` and `key` itself through `VNodeProps`, which
112
+ * every registered component's props are intersected with. Declaring our own `ref` would intersect
113
+ * two different `ref` types and could leave the property unusable.
115
114
  */
116
- export interface VueAttributes extends AccessibilityAttribute, SlotAttribute, RawSignalAttributes {
115
+ export interface VueAttributes extends AccessibilityAttribute, SlotAttribute, LayoutAttribute, RawSignalAttributes {
117
116
  }
118
117
  /**
119
118
  * The properties whose GObject type is a `GMenuModel`, in both spellings.
120
119
  *
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.
120
+ * A NAME LIST, not a type test, and the reason is measured: the obvious `Gio.MenuModel extends
121
+ * NonNullable<T[K]> ? …` also matches every property typed as a wider GObject — `Gio.MenuModel
122
+ * extends GObject.Object` is TRUE — so the widening would leak onto properties that take an
123
+ * entirely different object. The names below are the whole set on the shipped table, and
124
+ * `type-tests/` holds the widening against real markup in both dialects.
129
125
  */
130
126
  type MenuModelProp = 'menuModel' | 'menu-model' | 'extraMenu' | 'extra-menu' | 'secondaryMenu' | 'secondary-menu';
131
127
  /**
@@ -0,0 +1,2 @@
1
+ import type { ConstructCapabilities } from '@gjsify/adwaita-core/conformance';
2
+ export declare const capabilities: ConstructCapabilities;
@@ -1,4 +1,4 @@
1
- import type { SharedTreeNode } from '@gjsify/adwaita-core/conformance';
1
+ import { type SharedTreeNode } from '@gjsify/adwaita-core/conformance';
2
2
  import type { HostElement } from '../types.js';
3
3
  /**
4
4
  * A `SharedTreeNode`, realised: a tag, its authored properties, its placement, its children,
@@ -0,0 +1,2 @@
1
+ declare const _default: () => Promise<void>;
2
+ export default _default;
@@ -1,8 +1,11 @@
1
1
  import Gtk from 'gi://Gtk?version=4.0';
2
+ import { type FontFaceFailure } from '@gjsify/utils/font-map';
2
3
  import { type FontFamilyMatch } from './font-families.js';
3
4
  import { type FontSource, type ResolveFontSourcesOptions } from './font-dir.js';
4
5
  import { type PlanUiFontOptions, type UiFontPlan, type UiFontPolicy } from './ui-font.js';
5
6
  export { describeFontFamilyMatch, matchFontFamilies, matchFontFamily, type FontFamilyMatch, type FontFamilyMatchKind, } from './font-families.js';
7
+ export { CAIRO_FONT_TYPE_FT, isUnsupportedByFontMap } from '@gjsify/utils/font-map';
8
+ export type { FontFaceFailure } from '@gjsify/utils/font-map';
6
9
  export { ADWAITA_UI_FONT_FAMILY, GNOME_UI_FONT_POINT_SIZE, UI_FONT_POLICIES, planUiFont, planUiFontPolicy, type PlanUiFontOptions, type PlanUiFontPolicyOptions, type UiFontPlan, type UiFontPlanKind, type UiFontPolicy, } from './ui-font.js';
7
10
  export { resolveFontSources, type FontSource, type ResolveFontSourcesOptions } from './font-dir.js';
8
11
  /**
@@ -36,11 +39,6 @@ export interface InitFontsOptions extends Omit<ResolveFontSourcesOptions, 'env'>
36
39
  */
37
40
  readonly expectedFamilies?: readonly string[];
38
41
  }
39
- /** A face the font map would not take, and why. */
40
- export interface FontFaceFailure {
41
- readonly path: string;
42
- readonly message: string;
43
- }
44
42
  /**
45
43
  * A {@link FontSource} and the faces IT contributed.
46
44
  *
@@ -61,6 +59,14 @@ export interface FontSourceOutcome extends FontSource {
61
59
  readonly registered: readonly string[];
62
60
  /** Faces from THIS directory the font map declined — see {@link isUnsupportedByFontMap}. */
63
61
  readonly declined: readonly string[];
62
+ /**
63
+ * Faces from THIS directory that are on the map and that no layout can be served by — the map had
64
+ * already resolved their family to the fallback and caches that answer. Disjoint from
65
+ * {@link declined} and a subset of {@link registered}; `FontFaceRegistration.unreachable` in
66
+ * `@gjsify/utils/font-map` owns the reading and the fresh-map fallback that normally clears this
67
+ * list, so a non-empty one means that fallback was unavailable and the substitution is real.
68
+ */
69
+ readonly unreachable: readonly string[];
64
70
  /** Faces from THIS directory that failed otherwise, plus the directory itself if unreadable. */
65
71
  readonly failed: readonly FontFaceFailure[];
66
72
  }
@@ -98,6 +104,19 @@ export interface InitFontsResult {
98
104
  * {@link isUnsupportedByFontMap}.
99
105
  */
100
106
  readonly declined: readonly string[];
107
+ /**
108
+ * Faces that are on the map and that no layout can be served by, across every {@link sources}
109
+ * entry: the map resolved their family to the fallback before the face arrived and caches that
110
+ * answer, so registering the face changed `list_families()` and nothing else. A SUBSET of
111
+ * {@link registered} — the face really is on the map and `get_family` answers its family — which
112
+ * is why it is reported beside the flat lists rather than inside them.
113
+ *
114
+ * EMPTY wherever the fontconfig fallback took over, which is the whole point of it: then a fresh
115
+ * map serves the faces and there is nothing left to say. Non-empty means that fallback was
116
+ * unavailable (`PANGOCAIRO_BACKEND` pinned, no fontconfig configuration, no fc backend) and the
117
+ * substitution will happen whatever the application does next.
118
+ */
119
+ readonly unreachable: readonly string[];
101
120
  /**
102
121
  * Faces that failed for any other reason, across every {@link sources} entry. Each was warned
103
122
  * about; none threw.
@@ -135,7 +154,7 @@ export interface InitFontsResult {
135
154
  readonly matches: readonly FontFamilyMatch[];
136
155
  /**
137
156
  * `true` when this call REPLACED the process's default font map with a fontconfig-backed one
138
- * so the faces could be registered at all — see {@link adoptFontconfigMap}.
157
+ * so the faces could be registered at all — see `probeFontconfigMap` in `@gjsify/utils/font-map`.
139
158
  *
140
159
  * Reported because it is a whole-application consequence of one call: every widget created
141
160
  * afterwards renders through FreeType instead of the platform rasteriser. It happens only
@@ -145,42 +164,6 @@ export interface InitFontsResult {
145
164
  */
146
165
  readonly fontconfigFallback: boolean;
147
166
  }
148
- /**
149
- * Did the font map decline runtime registration outright?
150
- *
151
- * `pango_font_map_add_font_file()` is a vfunc, and the CoreText map implements none — so on macOS
152
- * the call falls through to the base implementation, which answers `G_IO_ERROR_NOT_SUPPORTED`.
153
- * That is not a failure to report: macOS is already correct declaratively, because the bundle's
154
- * `ATSApplicationFontsPath` had the OS activate the staged directory before the process started,
155
- * and the ordering makes the runtime call the wrong tool there rather than merely a redundant one
156
- * — `pango_core_text_font_map_changed()` only bumps a serial, there is no
157
- * `kCTFontManagerRegisteredFontsChangedNotification` observer and no re-scan path in
158
- * `pangocoretext-fontmap.c`, so a face registered after the map initialises could not be recovered
159
- * by poking it anyway.
160
- *
161
- * Keyed on the ERROR rather than on `process.platform`, which is the difference between a
162
- * capability test and a guess about who is asking. It costs no `gjsify.os` declaration (this
163
- * package makes no OS decision, and ADR 0018's candidate set is derived from the code that reads
164
- * the host), and it stays right for any other map that declines. The OS name was never the thing
165
- * being asked — which stopped being hypothetical: the backend is whichever one is selected rather
166
- * than one per platform, and `@gjsify/node-gi`'s loader selects `PANGOCAIRO_BACKEND=fc` on the
167
- * bundled windowing runtime (ADR 0038 § Amendment 3), so a darwin process on it reaches this
168
- * arm's other side and REGISTERS the faces. A `process.platform` branch would have had to be
169
- * found and reversed instead.
170
- */
171
- export declare function isUnsupportedByFontMap(error: unknown): boolean;
172
- /**
173
- * `CAIRO_FONT_TYPE_FT` from `cairo.h` — the value `pango_cairo_font_map_new_for_font_type()` maps
174
- * to its fontconfig backend.
175
- *
176
- * A literal rather than `gi://cairo`'s `FontType.FT`: this module runs on both legs (GJS and
177
- * `@gjsify/node-gi`), and the enum is part of cairo's ABI, so importing a fourth namespace to
178
- * spell one stable integer would add a load-time dependency for nothing.
179
- *
180
- * Exported so `fonts.spec.ts`'s independent probe spells the SAME integer rather than a second
181
- * literal that could drift from this one silently — see § duplication instead of a helper.
182
- */
183
- export declare const CAIRO_FONT_TYPE_FT = 1;
184
167
  /**
185
168
  * Register every face in the application's shipped font directory with the default font map.
186
169
  *
@@ -188,8 +171,11 @@ export declare const CAIRO_FONT_TYPE_FT = 1;
188
171
  * fontconfig backend rather than tidiness: it caches the FONTSET resolved for a description and
189
172
  * `add_font_file` does not invalidate it, so a `Pango.Layout` that measured the family first keeps
190
173
  * measuring the fallback for the life of the process even though the family is then in
191
- * `list_families()`. win32 clears its cache instead and recovers, so registering early is free
192
- * there and unrecoverable-if-missed on Linux (measured both ways; `fonts.spec.ts`).
174
+ * `list_families()`. win32 clears its cache instead and recovers, so registering early is free there
175
+ * and unrecoverable-if-missed on Linux (measured both ways; `fonts.spec.ts`). Calling it late is no
176
+ * longer SILENTLY wrong, though: `registerFontFaces` measures what it registered, replaces the default
177
+ * map when a face turned out to be unserved, and reports what it could not rescue in
178
+ * {@link InitFontsResult.unreachable} — see the file header for what that leaves of the rule.
193
179
  *
194
180
  * Nothing here is eager: this
195
181
  * package is the element model renderers bind to and owns no application lifecycle, and a