@gjsify/gtk-host 0.41.0 → 0.43.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 +454 -6
- package/lib/esm/adapters/react.js +1 -0
- package/lib/esm/adapters/solid.js +1 -0
- package/lib/esm/adapters/vue.js +1 -0
- package/lib/esm/attrs.js +0 -0
- package/lib/esm/conformance/diagnostics.js +2 -2
- package/lib/esm/conformance/index.js +2 -2
- package/lib/esm/descriptors/index.js +1 -1
- package/lib/esm/errors.js +1 -1
- package/lib/esm/generated/props.js +0 -0
- package/lib/esm/generated/widgets.js +1 -0
- package/lib/esm/host.js +1 -1
- package/lib/esm/index.js +1 -1
- package/lib/esm/jsx-runtime.js +1 -0
- package/lib/esm/policies.js +1 -1
- package/lib/esm/probe.js +1 -0
- package/lib/esm/props.js +1 -1
- package/lib/esm/react-jsx-runtime.js +1 -0
- package/lib/esm/registry.js +1 -1
- package/lib/esm/signals.js +1 -1
- package/lib/esm/tags.js +2 -0
- package/lib/esm/vue-components.js +0 -0
- package/lib/types/adapters/react.d.ts +175 -0
- package/lib/types/adapters/react.spec.d.ts +2 -0
- package/lib/types/adapters/solid.d.ts +78 -0
- package/lib/types/adapters/solid.spec.d.ts +2 -0
- package/lib/types/adapters/vue.d.ts +24 -0
- package/lib/types/adapters/vue.spec.d.ts +2 -0
- package/lib/types/attrs.d.ts +102 -0
- package/lib/types/buildable.spec.d.ts +2 -0
- package/lib/types/conformance/diagnostics.d.ts +14 -0
- package/lib/types/conformance/index.d.ts +24 -1
- package/lib/types/conformance/vectors.d.mts +34 -0
- package/lib/types/descriptors/index.d.ts +52 -1
- package/lib/types/errors.d.ts +21 -0
- package/lib/types/generated/props.d.ts +5505 -0
- package/lib/types/generated/surface-data.d.mts +22 -0
- package/lib/types/generated/widgets.d.ts +3 -0
- package/lib/types/generated.spec.d.ts +4 -0
- package/lib/types/generator/emit-types.d.mts +54 -0
- package/lib/types/generator/emit.d.mts +50 -0
- package/lib/types/generator/gir.d.mts +156 -0
- package/lib/types/generator/main.d.mts +23 -0
- package/lib/types/generator/mini.fixture.d.mts +30 -0
- package/lib/types/generator/surface.d.mts +62 -0
- package/lib/types/generator/tsmap.d.mts +73 -0
- package/lib/types/generator.spec.d.ts +2 -0
- package/lib/types/host.d.ts +102 -1
- package/lib/types/index.d.ts +6 -3
- package/lib/types/jsx-runtime.d.ts +70 -0
- package/lib/types/policies.d.ts +58 -0
- package/lib/types/probe.d.ts +58 -0
- package/lib/types/props.d.ts +49 -2
- package/lib/types/react-jsx-runtime.d.ts +108 -0
- package/lib/types/registry.d.ts +1 -1
- package/lib/types/signals.d.ts +16 -1
- package/lib/types/tags.d.ts +25 -0
- package/lib/types/testing/gate.d.mts +2 -0
- package/lib/types/types.d.ts +56 -3
- package/lib/types/vue-components.d.ts +46 -0
- package/package.json +77 -7
package/README.md
CHANGED
|
@@ -28,7 +28,9 @@ NativeScript carries five framework flavours over one host, and the adapters are
|
|
|
28
28
|
small because the host exists: its Solid adapter is **91 lines**, its React
|
|
29
29
|
adapter **505** — and both hold *zero* lines of widget knowledge. Under GTK4 the
|
|
30
30
|
shared share is larger still: GTK4 deleted `GtkContainer`, so there is no generic
|
|
31
|
-
`add
|
|
31
|
+
`add`. `Gtk.Buildable.add_child` is introspected as a vfunc only — the `vfunc_`
|
|
32
|
+
form is callable and correct, so it is an escape hatch, just not a safe default
|
|
33
|
+
(a childless widget accepts a child in silence). Every
|
|
32
34
|
container's adoption rule has to be written down somewhere. Written once, it is a
|
|
33
35
|
table; written per adapter, it is the same table three times — which is what
|
|
34
36
|
stalled `react-gtk`, `react-native-gtk4` and `svelte-gjs`.
|
|
@@ -125,6 +127,17 @@ Construct-only properties cannot be patched; GObject accepts the write and keeps
|
|
|
125
127
|
the old value. Changing one **rebuilds** the widget in place, preserving position,
|
|
126
128
|
properties and listeners.
|
|
127
129
|
|
|
130
|
+
**`undefined` and `null` both mean REMOVED**, and the value that lands is what
|
|
131
|
+
CONSTRUCTION leaves behind rather than the ParamSpec default — the two disagree in
|
|
132
|
+
104 places. `null` counts because every other op already read it that way
|
|
133
|
+
(`slot: null` is no slot, `layout: null` is no position, `onClicked: null`
|
|
134
|
+
unbinds), and because the alternative was three adapters each translating DOM's
|
|
135
|
+
`null` into the host's `undefined`: Vue did, React did it only for a key that
|
|
136
|
+
vanished and not for an authored `label={null}`, and Solid did not at all, so
|
|
137
|
+
`null` reached `set_property` verbatim — a throw for a `gint`, and a `null`
|
|
138
|
+
recorded for the next rebuild to replay. Nothing is lost by folding them: every
|
|
139
|
+
GObject type that CAN hold NULL has NULL as its construction default anyway.
|
|
140
|
+
|
|
128
141
|
## Conformance
|
|
129
142
|
|
|
130
143
|
`@gjsify/gtk-host/conformance` exports the checks that keep the table honest and
|
|
@@ -132,9 +145,444 @@ the readers every vector asserts through:
|
|
|
132
145
|
|
|
133
146
|
- `descriptorProblems()` — every method and text sink a descriptor names must
|
|
134
147
|
exist on that GType in the *installed* GTK.
|
|
135
|
-
- `gtkChildren()` / `gtkChildTypes()` / `dumpTree()`
|
|
136
|
-
tree. A renderer that asserts against
|
|
137
|
-
while the window is wrong.
|
|
148
|
+
- `gtkChildren()` / `gtkChildTypes()` / `dumpTree()` / `findDescendant()` /
|
|
149
|
+
`descendants()` — read the **real** widget tree. A renderer that asserts against
|
|
150
|
+
its own bookkeeping agrees with itself while the window is wrong.
|
|
151
|
+
- `installDiagnosticsGate()` — GTK's failure mode is exit 0, so every vector counts
|
|
152
|
+
GLib warnings-or-worse and fails the test that produced one.
|
|
153
|
+
|
|
154
|
+
**One vector table runs through all three adapters.** `conformance/vectors.mts`
|
|
155
|
+
(a `.mts` file, so it never reaches the published bundle: it imports
|
|
156
|
+
`@gjsify/unit`, a devDependency) exports `runAdapterVectors(harness, gate)`, and
|
|
157
|
+
each adapter's spec supplies a `mount`/`patch`/`unmount` harness over its own
|
|
158
|
+
framework. It exists because a per-framework spec agrees with the framework it was
|
|
159
|
+
written against: measured over the three specs, `slot` and `layout` had ZERO hits
|
|
160
|
+
in any of them, and only React's ever created a text node — so `createText`,
|
|
161
|
+
`setText`, `replaceText`, `isTextNode`, `flushText` and the `text-not-accepted`
|
|
162
|
+
refusal went unexercised through two of the three adapters. Deleting `flushText`
|
|
163
|
+
from `host.ts` now reds twelve vectors across all three, where before it reds two,
|
|
164
|
+
in React alone.
|
|
165
|
+
|
|
166
|
+
**Self-verification for a showcase**, from the main barrel rather than from here:
|
|
167
|
+
`runHostProbeApp({ applicationId, build, assert, present })` owns the
|
|
168
|
+
`GJSIFY_HOST_PROBE`-vs-`activate` split, the diagnostics gate, the `check()`
|
|
169
|
+
recorder and the `PROBE: PASS|FAIL <json>` line, so a showcase writes only its own
|
|
170
|
+
assertions. The recorder checks ITSELF first — every assertion speaks through one
|
|
171
|
+
closure, so a `check` that drops its findings would turn the whole probe green with
|
|
172
|
+
nothing to say, and no showcase assertion could notice.
|
|
173
|
+
|
|
174
|
+
## Adapters
|
|
175
|
+
|
|
176
|
+
Three of them today — `/solid`, `/vue`, `/react` — over one table.
|
|
177
|
+
`scripts/check-adapter-import-direction.mjs` holds all three to that mechanically:
|
|
178
|
+
an adapter fails the check if it reaches for `descriptors`, `policies` or
|
|
179
|
+
`registry`, names a widget in a string, uses one as a VALUE (`new Gtk.Box()`,
|
|
180
|
+
`instanceof`, `$gtype`, a call — a type annotation is fine and is what every
|
|
181
|
+
adapter writes), imports a typelib at runtime (`gi://…`), or names a placement
|
|
182
|
+
method. The last two landed with the violation they describe: the Vue adapter held
|
|
183
|
+
the one runtime `gi://` import and the one concrete widget class in the whole
|
|
184
|
+
adapter set, for `<KeepAlive>`'s off-screen storage. That is `createDetachedContainer()`
|
|
185
|
+
now — a host op, so the adapter has nothing left to know.
|
|
186
|
+
|
|
187
|
+
Everything an adapter needs beyond the fourteen ops is exported from the host, once:
|
|
188
|
+
`widgetOf(node)` (the `ref` seam — Solid and React each carried their own copy and
|
|
189
|
+
Vue carried none, so a Vue app's only route to a widget was `materialize()`, the
|
|
190
|
+
call `widgetOf`'s destroyed-node refusal exists to intercept), `isHostElement(value)`,
|
|
191
|
+
`describeValue(value)` for naming what arrived instead of a node, and
|
|
192
|
+
`withoutKeys(props, reserved)` for the reserved-prop filter whose SET is
|
|
193
|
+
per-framework and whose loop is not.
|
|
194
|
+
|
|
195
|
+
`@gjsify/gtk-host/solid` is the first, and it is the thesis made checkable: Solid
|
|
196
|
+
publishes a ten-method renderer contract, every one of them is a host op, and the
|
|
197
|
+
adapter is the mapping — no widget name, no insertion rule, no GTK knowledge.
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
import { For, createComponent, createElement, insert, mount, setProp } from '@gjsify/gtk-host/solid';
|
|
201
|
+
|
|
202
|
+
const dispose = mount(() => {
|
|
203
|
+
const box = createElement('GtkBox');
|
|
204
|
+
insert(box, createComponent(For, { get each() { return items(); }, children: renderRow }));
|
|
205
|
+
return box;
|
|
206
|
+
}, myWindow);
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
`adopt(container)` is the mount seam every adapter needs: it wraps a widget the
|
|
210
|
+
application owns as a host element, resolving its descriptor through the same
|
|
211
|
+
table as every other parent, and **records the children the container already
|
|
212
|
+
had** so placement offsets past them. Without that record the first insertion
|
|
213
|
+
resolves to GTK's "make first" and the rendered tree lands above the app's own
|
|
214
|
+
chrome.
|
|
215
|
+
|
|
216
|
+
Three things the adapter has to know that the contract does not say:
|
|
217
|
+
|
|
218
|
+
- **`removeNode` is a detach, never a teardown.** Solid uses one op for a
|
|
219
|
+
reconciliation move and for an unmount, and `<For>` moves the same nodes across a
|
|
220
|
+
reorder (measured: 3 of 3 widget objects reused). Destroying there would recreate
|
|
221
|
+
every row on every reorder.
|
|
222
|
+
- **The unmount signal is Solid's per-node scope, not `removeNode`** — but it may
|
|
223
|
+
only disconnect HANDLERS, never unlink. A node dropped by reconciliation is
|
|
224
|
+
unreachable from the root, so no later teardown can find its handlers, and GJS
|
|
225
|
+
blocks JS callbacks during GC. `onCleanup` fires exactly when a node is gone for
|
|
226
|
+
good and survives a reorder. Unlinking there breaks ordering, though: Solid
|
|
227
|
+
disposes these scopes BEFORE `insertExpression` runs, and `reconcileArrays` opens
|
|
228
|
+
with `getNextSibling(last)` — on an unlinked node that reads null, and every
|
|
229
|
+
trailing insertion appends at the end of the parent instead of before the marker.
|
|
230
|
+
A dynamic list with a static sibling after it rendered `head | foot | c`.
|
|
231
|
+
- **`solid-js/universal`'s `render` returns the disposer and nothing else** — the
|
|
232
|
+
DOM renderer additionally clears its container, the universal one has no
|
|
233
|
+
equivalent, so disposing tears down the reactive scopes and leaves the widgets
|
|
234
|
+
mounted (measured: a button kept firing). Tearing the subtree down is `mount`'s job.
|
|
235
|
+
|
|
236
|
+
Solid's control-flow components (`For`, `Index`, `Show`) are re-exported re-typed:
|
|
237
|
+
their runtime is renderer-agnostic, their types are pinned to the DOM's `Element`.
|
|
238
|
+
|
|
239
|
+
**`Dynamic` is the exception and is implemented here, not re-exported.** `For`,
|
|
240
|
+
`Index` and `Show` live in `solid-js`; `Dynamic` lives in `solid-js/web`, and that
|
|
241
|
+
package *is* the DOM renderer — its string branch is
|
|
242
|
+
`document.createElement(component)` followed by the DOM's own `spread`, so under a
|
|
243
|
+
universal renderer nothing arrives through the host ops at all. Measured with
|
|
244
|
+
`<Dynamic component="GtkLabel">` imported from `solid-js/web` into a GJS bundle:
|
|
245
|
+
container `["GtkBox"]`, the box's children just the static sibling, **no throw, no
|
|
246
|
+
GTK diagnostic, exit 0**. (Importing it also makes `--globals auto` inject
|
|
247
|
+
`document`, `HTMLCanvasElement` and `Path2D` and pull `gi://Gdk`, `GdkPixbuf`,
|
|
248
|
+
`Pango` and `PangoCairo`.) Import `Dynamic` from `@gjsify/gtk-host/solid`; the
|
|
249
|
+
adapter's version takes the same `component` — a registered tag name or a
|
|
250
|
+
component function — and **refuses anything else by name**, where Solid's own
|
|
251
|
+
`switch` falls through to `undefined`: `component={registry[key]}` with a key that
|
|
252
|
+
missed is indistinguishable from an empty branch, and rendering nothing on purpose
|
|
253
|
+
is `<Show>`'s job.
|
|
254
|
+
|
|
255
|
+
That silence had a second, more general cause, now closed at the seam:
|
|
256
|
+
`insertExpression`'s last branch is `insertNode(parent, value)` for **any**
|
|
257
|
+
non-array object, and the host wrote its `parent`/`prev`/`next` links onto it and
|
|
258
|
+
returned — the kind was neither `element` nor `text`, so nothing else happened. A
|
|
259
|
+
phantom in the shadow tree that never reaches GTK. `insertNode` now refuses a
|
|
260
|
+
value that is not one of the three node kinds, naming what it got and which
|
|
261
|
+
`solid-js/web` exports (`Dynamic`, `Portal`, `template`) are DOM-bound.
|
|
262
|
+
|
|
263
|
+
`@gjsify/gtk-host/vue` is the second, and it is what makes "framework-agnostic"
|
|
264
|
+
a measured claim rather than an ADR sentence: the same descriptor table and the
|
|
265
|
+
same placement engine satisfy Vue's `RendererOptions` (10 required + 4 optional)
|
|
266
|
+
and Solid's universal renderer (10) without either knowing about the other.
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
import { mount } from '@gjsify/gtk-host/vue';
|
|
270
|
+
mount(defineComponent({ render: () => h('GtkBox', null, [h('GtkLabel', { label: 'hi' })]) }), myWindow);
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Where Vue differs from Solid, and it is all in what Vue asks for:
|
|
274
|
+
|
|
275
|
+
- **`createComment`.** Vue marks every `v-if` branch and fragment boundary with
|
|
276
|
+
one. That is why the host has anchors: they never enter the GTK tree, so an
|
|
277
|
+
empty branch cannot shift a sibling's index.
|
|
278
|
+
- **`createElement` receives the vnode props**, so construct-only values arrive at
|
|
279
|
+
construction instead of forcing a rebuild. Solid's `createElement(tag)` cannot.
|
|
280
|
+
The props are RAW though — `key`, `ref` and the `onVnode*` hooks are Vue's own
|
|
281
|
+
and are filtered out; passing them through produced
|
|
282
|
+
`<GtkLabel> has no property "key"` on the first keyed list.
|
|
283
|
+
- **`remove` is a TEARDOWN here, not a detach** — the opposite of the Solid
|
|
284
|
+
adapter, and measured both ways. Vue moves a node with `insert` alone, so
|
|
285
|
+
`remove` is only ever a real unmount: with it mapped to `destroy`, a keyed
|
|
286
|
+
reorder still reuses 3 of 3 widget objects and the handlers are gone after
|
|
287
|
+
`app.unmount()`. Solid uses one op for both and must therefore detach.
|
|
288
|
+
- **`<KeepAlive>` and `<Suspense>` get a detached scratch container.**
|
|
289
|
+
`KeepAliveImpl.setup` opens with `createElement("div")` for its off-screen
|
|
290
|
+
storage and `SuspenseImpl` does the same for its `hiddenContainer`. Forwarded as
|
|
291
|
+
a tag, `"div"` threw `unknown-tag` *inside `setup`* — and Vue routes that through
|
|
292
|
+
`callWithErrorHandling`, whose production arm is `console.error(err)` with no
|
|
293
|
+
rethrow. Measured under the defines below: `mount()` returned normally, the
|
|
294
|
+
container had **zero** children, GTK emitted no diagnostic, exit 0, and the only
|
|
295
|
+
trace was one line of `{"code":"unknown-tag","name":"GtkHostError"}`.
|
|
296
|
+
|
|
297
|
+
The adapter hands those calls an unparented box through `adopt`, which is the
|
|
298
|
+
faithful analogue of the DOM's detached `<div>`: deactivating really unparents
|
|
299
|
+
the subtree and really keeps it alive, so reactivating moves the *same* widgets
|
|
300
|
+
back. Measured end to end — a `<KeepAlive>`d component's widget object and its
|
|
301
|
+
own `ref` state both survive a toggle away and back.
|
|
302
|
+
|
|
303
|
+
**The discriminator is ARITY, and it had to be measured.** `mountElement` calls
|
|
304
|
+
`hostCreateElement(vnode.type, namespace, props && props.is, props)` — four
|
|
305
|
+
arguments, always; the two built-ins call `createElement("div")` with one.
|
|
306
|
+
Testing the later parameters for `undefined` cannot separate them, because
|
|
307
|
+
`ElementNamespace` *is* `'svg' | 'mathml' | undefined` and a plain GTK element
|
|
308
|
+
gets `undefined` there too. So a user's own `<div>` still arrives with four
|
|
309
|
+
arguments and is still refused by name — the scratch container is never a
|
|
310
|
+
silent yes for something a user wrote.
|
|
311
|
+
- **`cloneNode` and `insertStaticContent` throw.** They back Vue's static hoisting,
|
|
312
|
+
and the second one takes an HTML *string*. Compile with `hoistStatic: false` and
|
|
313
|
+
`transformHoist: null`; if that is ever lost, these throw at the first static
|
|
314
|
+
subtree instead of rendering something wrong.
|
|
315
|
+
- **`<Teleport :to="el">` takes a widget the application owns**, and the adapter
|
|
316
|
+
adopts it — once per widget, so every teleported child and both of Vue's own text
|
|
317
|
+
anchors see the same shadow tree. Adopting per `insert` call re-snapshots the
|
|
318
|
+
container's existing children each time and reorders the teleport: measured,
|
|
319
|
+
`['one','two','three']` landed as `['one','three','two']`. `adopt` is re-exported
|
|
320
|
+
from `@gjsify/gtk-host/vue` for the explicit spelling, `:to="adopt(el)"`.
|
|
321
|
+
|
|
322
|
+
The coercion is what makes that sentence TRUE. Vue returns a non-string target
|
|
323
|
+
verbatim (`resolveTarget`'s non-string branch is `return targetSelector`), so
|
|
324
|
+
"pass the target widget instead" — which this adapter's own error message and
|
|
325
|
+
this README used to say — handed the host a raw `Gtk.Box` as a parent: nothing
|
|
326
|
+
rendered, nothing threw, no diagnostic. The host now refuses a raw widget by
|
|
327
|
+
name (`not-a-host-parent`) as the backstop for every other route in.
|
|
328
|
+
- **A *string* teleport target throws.** Answering null looks gentler and is worse:
|
|
329
|
+
`TeleportImpl` mounts nothing for a falsy target and the warning is `__DEV__`-only,
|
|
330
|
+
which the production defines below strip — so it would render nothing, silently,
|
|
331
|
+
in exactly the configuration this adapter prescribes. Resolving a name would need
|
|
332
|
+
a registry of mounted roots; when a consumer needs it, that is the work.
|
|
333
|
+
- **A prop that disappears is reset, not nulled.** Vue signals removal with `null`;
|
|
334
|
+
the host's contract is `undefined` → the ParamSpec default. Forwarding the `null`
|
|
335
|
+
reached `set_property` verbatim, which throws for an int property — and
|
|
336
|
+
`el.props` had already recorded it for the next rebuild to replay.
|
|
337
|
+
|
|
338
|
+
**Build recipe.** `@vue/runtime-core` is DOM-free in fact — every `document`,
|
|
339
|
+
`navigator`, `location` and `HTMLElement` reference sits in a dev/HMR/devtools
|
|
340
|
+
path behind `typeof window !== 'undefined'` or `__DEV__`. But `--globals auto` is a
|
|
341
|
+
static analysis and injects a polyfill for each identifier it sees, which made the
|
|
342
|
+
bundle require `gi://Gdk`, `GdkPixbuf`, `Pango` and `PangoCairo` at load. Define
|
|
343
|
+
Vue's flags so dead-code elimination removes those branches:
|
|
344
|
+
|
|
345
|
+
```
|
|
346
|
+
--define '__VUE_OPTIONS_API__=false'
|
|
347
|
+
--define '__VUE_PROD_DEVTOOLS__=false'
|
|
348
|
+
--define '__VUE_PROD_HYDRATION_MISMATCH_DETAILS__=false'
|
|
349
|
+
--define 'process.env.NODE_ENV="production"'
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
A vector asserts `globalThis.document` is `undefined`, so losing the recipe fails
|
|
353
|
+
the suite rather than silently growing four typelib dependencies.
|
|
354
|
+
|
|
355
|
+
**`Suspense` is the one import the recipe cannot save**, so measure the bundle if
|
|
356
|
+
you use it. `SuspenseImpl` carries `hydrate: hydrateSuspense`, and that function
|
|
357
|
+
contains a literal `document.createElement("div")` which no define eliminates —
|
|
358
|
+
hydration is not dead code, it is simply never called here. Measured, same entry
|
|
359
|
+
plus one named import, `--app gjs` with the four defines above:
|
|
360
|
+
|
|
361
|
+
| import | bytes | typelibs | DOM |
|
|
362
|
+
|---|---|---|---|
|
|
363
|
+
| baseline (`createRenderer`) | 191 032 | `gi://GLib` | — |
|
|
364
|
+
| `+ Teleport` | 194 907 | `gi://GLib` | — |
|
|
365
|
+
| `+ KeepAlive` | 197 561 | `gi://GLib` | — |
|
|
366
|
+
| `+ Suspense` | 274 177 | `+ Gdk, GdkPixbuf, Gio, Pango, PangoCairo` | `HTMLCanvasElement`, `Path2D` |
|
|
367
|
+
| `+ Suspense`, `--exclude-globals document` | 196 614 | `gi://GLib` | — |
|
|
368
|
+
|
|
369
|
+
`--exclude-globals document` is the escape: `--globals auto` is a static scan, so
|
|
370
|
+
the identifier is what it reacts to, not whether the branch can run. Three more
|
|
371
|
+
built-ins measured clean alongside `Teleport` and `KeepAlive` — `BaseTransition`
|
|
372
|
+
(192–197 KB, `gi://GLib` only), `defineAsyncComponent` and `Fragment`. `Transition`
|
|
373
|
+
is not in this table because `@vue/runtime-core` does not export it at all
|
|
374
|
+
(`MISSING_EXPORT` from rolldown); it belongs to `runtime-dom`.
|
|
375
|
+
|
|
376
|
+
`@gjsify/gtk-host/react` is the third, and it is the one whose contract can be
|
|
377
|
+
READ instead of restated. `react-reconciler` is `module.exports = function
|
|
378
|
+
$$$reconciler($$$hostConfig) { … }` and its body opens by destructuring the whole
|
|
379
|
+
config, so a recording `Proxy` over the config reports exactly which members the
|
|
380
|
+
installed version asks for. Measured on **0.29.2**, production bundle: **76**
|
|
381
|
+
members read, **37** answered here, **39** switched off by three flags the config
|
|
382
|
+
does declare (`supportsPersistence: false`, `supportsHydration: false`,
|
|
383
|
+
`supportsTestSelectors` absent) plus `supportsMicrotasks`, and 4 more declared for
|
|
384
|
+
the development bundle, which reads 94. `react.spec.ts` asserts all three
|
|
385
|
+
directions, so a version bump that starts asking for something new fails a test
|
|
386
|
+
instead of reading `undefined` inside a commit.
|
|
387
|
+
|
|
388
|
+
```ts
|
|
389
|
+
import { createRoot, flushSync } from '@gjsify/gtk-host/react';
|
|
390
|
+
|
|
391
|
+
const root = createRoot(myWindow);
|
|
392
|
+
root.render(createElement('GtkBox', null, createElement('GtkLabel', { label: 'hi' })));
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
- **`render()` is synchronous, and that is a choice with a reason.** A
|
|
396
|
+
`ConcurrentRoot`'s updates are DEFAULT-lane, so they are handed to `scheduler`,
|
|
397
|
+
which under GJS is a GLib timer source — with no main loop running yet, an
|
|
398
|
+
unflushed first render leaves the container empty and says nothing. `render()`
|
|
399
|
+
therefore wraps `updateContainer` in `flushSync`, which sets the current update
|
|
400
|
+
priority to `DiscreteEventPriority` and makes everything scheduled inside it a
|
|
401
|
+
sync lane the same call then flushes.
|
|
402
|
+
- **A `setState` from a GTK signal handler is concurrent** and lands on the next
|
|
403
|
+
main-loop iteration, because `getCurrentEventPriority` returns the default lane
|
|
404
|
+
(there is no ambient DOM event to derive a priority from). `flushSync` is the
|
|
405
|
+
escape hatch. A vector pumps `GLib.MainContext.default()` and proves the
|
|
406
|
+
scheduled path works at all under GJS — it does, on gjs 1.88.1, with no
|
|
407
|
+
polyfill: `scheduler` feature-detects `performance`, `setImmediate`,
|
|
408
|
+
`MessageChannel` and `navigator` and falls back to `setTimeout`, which the GJS
|
|
409
|
+
prologue already provides.
|
|
410
|
+
- **React CLEARS the container before its first commit.** `updateHostRoot` sets
|
|
411
|
+
the `Snapshot` flag whenever the previous render produced no child — in the DOM
|
|
412
|
+
to discard leftover markup. Here the container is a widget the application built
|
|
413
|
+
and filled, so `clearContainer` destroys only the SHADOW children and never
|
|
414
|
+
`el.foreign`. A vector records the call, because surviving chrome alone would
|
|
415
|
+
also be explained by React never making it.
|
|
416
|
+
- **`removeChild` is a TEARDOWN, like Vue's `remove` and unlike Solid's
|
|
417
|
+
`removeNode`.** React moves a node with `insertBefore`/`appendChild` alone, so
|
|
418
|
+
`removeChild` is only ever a real unmount. The reorder vector holds both halves:
|
|
419
|
+
the same widget objects survive, and `removeChild` was never reached.
|
|
420
|
+
- **`getPublicInstance` IS `ref`,** and it returns the author's widget — never the
|
|
421
|
+
`GtkListBoxRow` the host wrapped it in.
|
|
422
|
+
- **`shouldSetTextContent` answers `false`, always.** `true` would leave the string
|
|
423
|
+
in `props.children` for the adapter to write, which is a widget-knowledge test in
|
|
424
|
+
an adapter; the host already routes a text node to the descriptor's `textSink` and
|
|
425
|
+
refuses text by tag name where there is none.
|
|
426
|
+
- **`<Suspense>`'s `hideTextInstance` empties the run's contribution** to its
|
|
427
|
+
parent's sink — a text run owns no widget — and nothing has to be remembered,
|
|
428
|
+
because `unhideTextInstance` is handed the text back.
|
|
429
|
+
|
|
430
|
+
**Build recipe**, and it is not optional:
|
|
431
|
+
|
|
432
|
+
```
|
|
433
|
+
--define 'process.env.NODE_ENV="production"'
|
|
434
|
+
--exclude-globals navigator
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
`react-reconciler/index.js` picks its bundle from `process.env.NODE_ENV`, and the
|
|
438
|
+
development one reaches for `document`, `HTMLCanvasElement` and `Path2D`, which
|
|
439
|
+
makes `--globals auto` inject the GTK-backed DOM registers and pull `gi://Gdk`,
|
|
440
|
+
`GdkPixbuf`, `Pango` and `PangoCairo` into a bundle that needs none of them. Even
|
|
441
|
+
the production `scheduler` carries `typeof navigator !== 'undefined' &&
|
|
442
|
+
navigator.scheduling`, dead code under GJS but still a free identifier the
|
|
443
|
+
detector answers with the same register. With both flags the bundle loads with no
|
|
444
|
+
`document` and no `navigator`, and a vector asserts exactly that.
|
|
445
|
+
|
|
446
|
+
`react` and `react-reconciler` are OPTIONAL peer dependencies, like `solid-js` and
|
|
447
|
+
`@vue/runtime-core`.
|
|
448
|
+
|
|
449
|
+
## What ships
|
|
450
|
+
|
|
451
|
+
`files` negates two shapes the library build already excludes:
|
|
452
|
+
`!lib/types/**/*.d.mts` and `!lib/types/**/*.spec.d.ts`. `build:gjsify` globs
|
|
453
|
+
`src/**/*.{ts,js}` minus the specs, so a `.mts` file is this package's marker for
|
|
454
|
+
"test-only, never in the bundle" — but `build:types` compiles all of `src`, and the
|
|
455
|
+
tarball therefore carried 17 type declarations for runtime modules that are not in
|
|
456
|
+
it, `lib/types/testing/gate.d.mts` among them. Nothing could import one (the exports
|
|
457
|
+
map gates every subpath), so the cost was a package describing modules it does not
|
|
458
|
+
contain, and a reader who concludes `@gjsify/gtk-host/testing` exists.
|
|
459
|
+
|
|
460
|
+
## The widget table, and the type surfaces
|
|
461
|
+
|
|
462
|
+
The table is **generated from the GIR** and committed. 164 concrete GtkWidget
|
|
463
|
+
descendants (Gtk 102, Adw 62), each with its GType name, its kebab tag and a lazy
|
|
464
|
+
`ctor`; 26 of them also carry a **curated** placement rule, and the generator may
|
|
465
|
+
only ever ADD a tag, never contradict one. A tag with no curated rule gets
|
|
466
|
+
`children: { kind: 'uncurated' }` — the widget can be created, given properties and
|
|
467
|
+
given handlers, while inserting a child raises an error naming the tag that needs a
|
|
468
|
+
policy. Guessing is not on offer: `add`, `append` and `set_child` all exist
|
|
469
|
+
somewhere in GTK, and calling the wrong one is a warning at exit 0.
|
|
470
|
+
|
|
471
|
+
Regenerating is a maintainer step, because the GIR files are not in this repo:
|
|
472
|
+
|
|
473
|
+
```sh
|
|
474
|
+
GJSIFY_GIR_DIR=/path/to/girs npm run generate # then look at git diff
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
A fresh clone needs no GIR to build, check, pack or test. What travels instead is
|
|
478
|
+
`generated.spec.ts`, which asks the *installed* GTK whether every generated name is
|
|
479
|
+
real: every offered property present as a writable ParamSpec, every offered signal
|
|
480
|
+
resolvable by `GObject.signal_lookup`, every enum nick resolvable through the
|
|
481
|
+
host's own `coerce()` path. A member the installed library lacks is accepted only
|
|
482
|
+
if the GIR says it arrived in a newer release — `GtkApplicationWindow::save-state`
|
|
483
|
+
is GTK 4.24 and the check runs on 4.22.4.
|
|
484
|
+
|
|
485
|
+
### Solid / JSX
|
|
486
|
+
|
|
487
|
+
```jsonc
|
|
488
|
+
{
|
|
489
|
+
"jsx": "preserve", // babel-preset-solid does the transform
|
|
490
|
+
"jsxImportSource": "@gjsify/gtk-host", // TypeScript appends /jsx-runtime
|
|
491
|
+
"noImplicitAny": true // load-bearing, see below
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
```tsx
|
|
496
|
+
<gtk-box orientation="vertical" spacing={8}>
|
|
497
|
+
<gtk-label label="Hello" />
|
|
498
|
+
<gtk-button label="Go" onClicked={() => count(count() + 1)} />
|
|
499
|
+
</gtk-box>
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
Tags are kebab because a capitalised `JSX.IntrinsicElements` key is never
|
|
503
|
+
consulted — `<GtkBox/>` is `TS2304: Cannot find name 'GtkBox'`. This package ships
|
|
504
|
+
its **own** jsx-runtime rather than augmenting `solid-js`, which would leave all
|
|
505
|
+
208 tags Solid pre-declares (HTML, SVG, MathML) type-checking clean on a GTK
|
|
506
|
+
renderer and rendering nothing.
|
|
507
|
+
|
|
508
|
+
Two things worth knowing:
|
|
509
|
+
|
|
510
|
+
- **`noImplicitAny: true` is not optional.** With `jsx: "preserve"`, no
|
|
511
|
+
`jsxImportSource` and `noImplicitAny` off, every JSX element is implicitly `any`
|
|
512
|
+
and `tsc` exits 0 having checked nothing.
|
|
513
|
+
- **An unknown *hyphenated* prop cannot be refused.** TypeScript exempts every
|
|
514
|
+
hyphen-containing JSX attribute from excess-property checking, so
|
|
515
|
+
`<gtk-box no-such={1}/>` is accepted. Both spellings are generated, so a declared
|
|
516
|
+
`can-focus={'yes'}` still fails on its VALUE — but prefer `canFocus`, which is
|
|
517
|
+
checked both ways.
|
|
518
|
+
|
|
519
|
+
### Vue
|
|
520
|
+
|
|
521
|
+
```ts
|
|
522
|
+
import '@gjsify/gtk-host/vue-components';
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
```jsonc
|
|
526
|
+
{ "vueCompilerOptions": { "strictTemplates": true } }
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
```vue
|
|
530
|
+
<GtkBox orientation="vertical" :spacing="8">
|
|
531
|
+
<GtkButton label="Go" @clicked="go" />
|
|
532
|
+
</GtkBox>
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
Keys are GType names, because Volar camelizes and capitalises a template tag before
|
|
536
|
+
looking it up — so one `GtkBox` key answers both `<GtkBox>` and `<gtk-box>`.
|
|
537
|
+
`strictTemplates: true` is **required**: without it an unknown prop, an unknown
|
|
538
|
+
event and an entirely unresolved tag are all silently accepted while wrong VALUE
|
|
539
|
+
types still error, so the surface looks alive and checks the wrong half.
|
|
540
|
+
|
|
541
|
+
**Set it in the BASE of your `extends` chain.** Measured on `vue-tsc@3.3.11`, all
|
|
542
|
+
four cells: the base tsconfig's value wins and the child's is ignored outright — a
|
|
543
|
+
strict base stays strict under a child that sets `false`, and a lax base stays lax
|
|
544
|
+
under a child that sets `true`. In a monorepo the shared base config therefore
|
|
545
|
+
decides this for every package and a per-package override does nothing. Confirm
|
|
546
|
+
with `vue-tsc --showConfig` rather than by reading the nearest tsconfig.
|
|
547
|
+
|
|
548
|
+
That camelize has no acronym knowledge (`gtk-gl-area` → `GtkGlArea`), so widgets
|
|
549
|
+
with two adjacent capitals get an extra kebab key. The generator finds them by
|
|
550
|
+
rule; today there is exactly one, `GtkGLArea`.
|
|
551
|
+
|
|
552
|
+
### React / JSX
|
|
553
|
+
|
|
554
|
+
```jsonc
|
|
555
|
+
{
|
|
556
|
+
"jsx": "react-jsx",
|
|
557
|
+
"jsxImportSource": "@gjsify/gtk-host/react", // TypeScript appends /jsx-runtime
|
|
558
|
+
"noImplicitAny": true
|
|
559
|
+
}
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
A **separate subpath**, and the split is structural rather than stylistic.
|
|
563
|
+
`@gjsify/gtk-host/jsx-runtime` deliberately throws from `jsx()`/`jsxs()`, which is
|
|
564
|
+
right for the dialects it serves: Solid's reactivity lives in what
|
|
565
|
+
`babel-preset-solid` emits and Vue's in its SFC compiler, so an automatic runtime
|
|
566
|
+
reaching those functions means the pipeline was misconfigured and nothing would
|
|
567
|
+
render. React is the opposite case — its `jsx()` builds a plain, renderer-agnostic
|
|
568
|
+
element record and the host mapping happens later, in `react-reconciler` — so
|
|
569
|
+
`@gjsify/gtk-host/react/jsx-runtime` re-exports React's OWN factories and declares
|
|
570
|
+
its own `JSX` namespace over the same generated tag list. One module cannot both
|
|
571
|
+
refuse the automatic runtime and provide it; `jsxImportSource` picks.
|
|
572
|
+
|
|
573
|
+
Pointing `jsxImportSource` at `"react"` instead is the 208-tag trap: the element
|
|
574
|
+
list then comes from `@types/react`, and every HTML, SVG and MathML tag
|
|
575
|
+
type-checks clean on a GTK renderer and renders nothing.
|
|
576
|
+
|
|
577
|
+
Tags are kebab here too, for the same measured reason as the Solid surface. `ref`
|
|
578
|
+
takes React's `Ref<T>` (a callback *or* a `useRef` object), which is why it is not
|
|
579
|
+
the Solid surface's `ref` type.
|
|
138
580
|
|
|
139
|
-
|
|
140
|
-
|
|
581
|
+
**The export names are the framework's contract, not a style choice** — the same
|
|
582
|
+
lesson the Solid adapter paid for when its `setProp` was exported as
|
|
583
|
+
`setSolidProp` and `babel-plugin-jsx-dom-expressions` emitted
|
|
584
|
+
`import { setProp }` literally. TypeScript's automatic runtime emits `jsx`, `jsxs`
|
|
585
|
+
and `Fragment` from `<jsxImportSource>/jsx-runtime`, and `jsxDEV` from
|
|
586
|
+
`<jsxImportSource>/jsx-dev-runtime`; those four are exactly what this module
|
|
587
|
+
exports, so a rename here is a `MISSING_EXPORT` in a consumer's build rather than
|
|
588
|
+
a matter of taste.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{withoutKeys as e}from"../props.js";import{adopt as t,createElement as n,createText as r,destroy as i,destroyChildren as a,insert as o,materialize as s,setElementText as c,setProp as l,setText as u,widgetOf as d}from"../host.js";import f from"react-reconciler";import{ConcurrentRoot as p,DefaultEventPriority as m}from"react-reconciler/constants.js";const h=new Set([`children`]),ownProps=t=>e(t,h);function diffProps(e,t){let n=null;for(let r of Object.keys(t))h.has(r)||t[r]!==e[r]&&(n??=[]).push([r,t[r],e[r]]);for(let r of Object.keys(e))h.has(r)||r in t||(n??=[]).push([r,void 0,e[r]]);return n}const visibilityTargetOf=e=>{let t=s(e);return e.wrapper??t},g={supportsMutation:!0,supportsPersistence:!1,supportsHydration:!1,isPrimaryRenderer:!0,noTimeout:-1,scheduleTimeout:setTimeout,cancelTimeout:clearTimeout,createInstance:(e,t)=>n(e,ownProps(t)),createTextInstance:e=>r(e),appendInitialChild:(e,t)=>{o(t,e,null)},finalizeInitialChildren:()=>!1,shouldSetTextContent:()=>!1,getRootHostContext:()=>null,getChildHostContext:e=>e,getPublicInstance:e=>s(e),prepareForCommit:()=>null,resetAfterCommit:()=>{},preparePortalMount:()=>{},getCurrentEventPriority:()=>m,appendChild:(e,t)=>{o(t,e,null)},appendChildToContainer:(e,t)=>{o(t,e,null)},insertBefore:(e,t,n)=>{o(t,e,n)},insertInContainerBefore:(e,t,n)=>{o(t,e,n)},removeChild:(e,t)=>{i(t)},removeChildFromContainer:(e,t)=>{i(t)},clearContainer:e=>{a(e)},prepareUpdate:(e,t,n,r)=>diffProps(n,r),commitUpdate:(e,t)=>{for(let[n,r,i]of t)l(e,n,r,i)},commitTextUpdate:(e,t,n)=>{u(e,n)},commitMount:()=>{throw Error(`@gjsify/gtk-host/react: commitMount was called, which means finalizeInitialChildren returned true. Nothing in this adapter asks for a post-mount callback yet.`)},resetTextContent:e=>{c(e,``)},hideInstance:e=>{visibilityTargetOf(e).set_visible(!1)},unhideInstance:e=>{visibilityTargetOf(e).set_visible(!0)},hideTextInstance:e=>{u(e,``)},unhideTextInstance:(e,t)=>{u(e,t)},getInstanceFromNode:()=>null,getInstanceFromScope:()=>null,prepareScopeUpdate:()=>{},beforeActiveInstanceBlur:()=>{},afterActiveInstanceBlur:()=>{},detachDeletedInstance:()=>{}},_=f(g),flushSync=e=>_.flushSync(e);function createRoot(e,n={}){let r=t(e),i=n.onRecoverableError??(e=>{console.error(`@gjsify/gtk-host/react: React recovered from an error`,e)}),a=_.createContainer(r,p,null,!1,null,``,i,null);return{container:r,render(e){_.flushSync(()=>{_.updateContainer(e,a,null,null)})},unmount(){_.flushSync(()=>{_.updateContainer(null,a,null,null)})}}}function mount(e,t,n={}){let r=createRoot(t,n);return r.render(e),r}export{t as adopt,createRoot,flushSync,g as gtkHostConfig,mount,d as widgetOf};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{adopt as e,createElement as t,createText as n,describeValue as r,destroyChildren as i,disconnectHandlers as a,firstChild as o,insert as s,isText as c,nextSibling as l,parentNode as u,remove as d,setProp as f,setText as p,widgetOf as m}from"../host.js";import{For as h,Index as g,Show as _,onCleanup as v,splitProps as y,untrack as b}from"solid-js";import{createRenderer as x}from"solid-js/universal";const S=new Set([`element`,`text`,`anchor`]);function assertHostNode(e){let t=e?.kind;if(!(typeof t==`string`&&S.has(t)))throw Error(`@gjsify/gtk-host/solid: insertNode got ${r(e)}, which is not a node of this renderer. Almost always this is a component from solid-js/web — the DOM renderer — reaching a universal one: its <Dynamic>, <Portal> and template() build DOM elements with document.createElement and spread onto them with the DOM's own spread, so nothing arrives through these host ops and the subtree renders NOTHING, silently. Import Dynamic, For, Index and Show from @gjsify/gtk-host/solid instead; solid-js's own control flow (For/Index/Show) is renderer-agnostic, everything under solid-js/web is not.`)}const{render:C,effect:w,memo:T,createComponent:E,createElement:D,createTextNode:O,insertNode:k,insert:A,spread:j,setProp:M,mergeProps:N,use:P}=x({createElement:e=>{let n=t(e);return v(()=>a(n)),n},createTextNode:e=>n(e),replaceText:(e,t)=>{p(e,t)},isTextNode:e=>c(e),setProperty:(e,t,n,r)=>{f(e,t,n,r)},insertNode:(e,t,n)=>{assertHostNode(t),s(t,e,n??null)},removeNode:(e,t)=>{d(t)},getParentNode:e=>u(e)??void 0,getFirstChild:e=>e.kind===`element`?o(e)??void 0:void 0,getNextSibling:e=>l(e)??void 0});function mount(t,n){let r=e(n),a=C(t,r);return()=>{a(),i(r)}}const F=h,I=g,L=_;function Dynamic(e){let[,t]=y(e,[`component`]);return T(()=>{let n=e.component;if(typeof n==`function`)return b(()=>n(t));if(typeof n==`string`){let e=D(n);return j(e,t,!1),e}throw Error(`@gjsify/gtk-host/solid: <Dynamic component={…}> needs a registered tag name or a component function, and got ${r(n)}. Solid's own DOM version returns undefined here and renders nothing at all — a lookup that missed is indistinguishable from an empty branch. Use <Show when={…}> to render nothing on purpose.`)},!1)}export{Dynamic,F as For,I as Index,L as Show,E as createComponent,D as createElement,O as createTextNode,w as effect,A as insert,k as insertNode,T as memo,N as mergeProps,mount,C as render,M as setProp,j as spread,P as use,m as widgetOf};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{withoutKeys as e}from"../props.js";import{adopt as t,createAnchor as n,createDetachedContainer as r,createElement as i,createText as a,destroy as o,insert as s,isHostElement as c,materialize as l,nextSibling as u,parentNode as d,setElementText as f,setProp as p,setText as m,widgetOf as h}from"../host.js";import{createRenderer as g}from"@vue/runtime-core";const _=new Set([`key`,`ref`,`ref_for`,`ref_key`,`onVnodeBeforeMount`,`onVnodeMounted`,`onVnodeBeforeUpdate`,`onVnodeUpdated`,`onVnodeBeforeUnmount`,`onVnodeUnmounted`]),withoutReservedProps=t=>e(t,_),v=new WeakMap;function asHostParent(e){if(c(e))return e;let n=e;if(typeof n!=`object`||!n)return e;let r=v.get(n);if(r)return r;let i=t(e);return v.set(n,i),i}const createElementOp=((...e)=>e.length===1?r():i(e[0],withoutReservedProps(e[3]))),{render:y,createApp:b}=g({createElement:createElementOp,createText:e=>a(e),createComment:e=>n(e),setText:(e,t)=>m(e,t),setElementText:(e,t)=>f(e,t),patchProp:(e,t,n,r)=>{_.has(t)||p(e,t,r,n)},insert:(e,t,n)=>s(e,asHostParent(t),n??null),remove:e=>o(e),parentNode:e=>d(e),nextSibling:e=>u(e),querySelector:e=>{throw Error(`@gjsify/gtk-host/vue: <Teleport to="${e}"> needs a string target resolved against a widget tree, which this adapter does not implement yet. Pass the target WIDGET instead (<Teleport :to="el">, el being a Gtk.Widget the application owns — this adapter adopts it for you), or pass adopt(el) if you want the host element yourself. A string target would render nothing at all under the production defines this adapter requires.`)},setScopeId:(e,t)=>{l(e).add_css_class?.(t)},cloneNode:e=>{throw Error(`@gjsify/gtk-host/vue: cloneNode is not available on GTK — a GObject does not clone. This is Vue's static-hoisting path: compile with hoistStatic: false and transformHoist: null. (node kind: ${e.kind})`)},insertStaticContent:()=>{throw Error(`@gjsify/gtk-host/vue: insertStaticContent takes an HTML string and GTK parses no HTML. This is Vue's stringifyStatic transform: compile with hoistStatic: false and transformHoist: null.`)}});function mount(e,n){let r=b(e);return r.mount(t(n)),r}export{t as adopt,b as createApp,mount,y as render,h as widgetOf};
|
package/lib/esm/attrs.js
ADDED
|
File without changes
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";import e from"gi://GLib";let t=null;function installDiagnosticsGate(){if(t)return t;let n=[],r=new TextDecoder,i=e.getenv(`G_MESSAGES_DEBUG`)!==null;return e.log_set_writer_func((t,a)=>{try{let o=a
|
|
2
|
-
`);throw n.length=0,Error(`${e?e+`: `:``}GTK reported ${t} diagnostic(s) that would have passed at exit 0:\n ${r}`)}},t}export{installDiagnosticsGate};
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import e from"gi://GLib";let t=null;function describeLogRecord(e,t=new TextDecoder){let text=e=>e instanceof Uint8Array?t.decode(e):String(e),n=e,r=n?.MESSAGE;if(r!=null){let e=text(r);if(e!==``)return e}let i=n?Object.keys(n).filter(e=>e!==`MESSAGE`&&n[e]!==void 0&&n[e]!==null).map(e=>`${e}=${text(n[e])}`):[];return i.length>0?`<no MESSAGE field> ${i.join(` `)}`:`<a log record with no MESSAGE and no other field>`}function installDiagnosticsGate(){if(t)return t;let n=[],r=new TextDecoder,i=e.getenv(`G_MESSAGES_DEBUG`)!==null;return e.log_set_writer_func((t,a)=>{try{let o=describeLogRecord(a,r),s=t&e.LogLevelFlags.LEVEL_MASK;s<=e.LogLevelFlags.LEVEL_WARNING&&n.push(o),(i||s<=e.LogLevelFlags.LEVEL_MESSAGE)&&printerr(o)}catch{printerr(`<gtk-host: a log message could not be decoded>`)}return e.LogWriterOutput.HANDLED}),t={seen:n,reset(){n.length=0},assertQuiet(e){if(n.length===0)return;let t=n.length,r=n.join(`
|
|
2
|
+
`);throw n.length=0,Error(`${e?e+`: `:``}GTK reported ${t} diagnostic(s) that would have passed at exit 0:\n ${r}`)}},t}export{describeLogRecord,installDiagnosticsGate};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";import{
|
|
2
|
-
`)}export{addressesOf,descriptorProblems,dumpTree,gtkChildTypes,gtkChildren,
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{addressOf as e,unhandledPolicy as t}from"../policies.js";import{describeLogRecord as n,installDiagnosticsGate as r}from"./diagnostics.js";import{BUILTIN_DESCRIPTORS as i}from"../descriptors/index.js";import a from"gi://GObject";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[...Object.values(e.slots),e.remove];case`keyed`:return[e.add,e.remove];case`coords`:return[e.attach,e.remove];default:return t(e)}}function descriptorProblems(e=i){let t=[];for(let n of e){let e;try{e=n.ctor()}catch(e){t.push({gtype:n.gtype,problem:`ctor() threw: ${e.message}`});continue}let r=a.type_name(e.$gtype);r!==n.gtype&&t.push({gtype:n.gtype,problem:`ctor() is ${r}, not ${n.gtype}`});for(let i of methodsOf(n.children))typeof e.prototype[i]!=`function`&&t.push({gtype:n.gtype,problem:`declares children.${i}(), which ${r} does not have`});if(n.textSink){let i=e.list_properties().find(e=>e.get_name()===n.textSink);i?(i.flags&a.ParamFlags.WRITABLE)===0?t.push({gtype:n.gtype,problem:`declares a READ-ONLY textSink "${n.textSink}"`}):a.type_is_a(i.value_type,a.TYPE_STRING)||t.push({gtype:n.gtype,problem:`declares textSink "${n.textSink}", which is ${a.type_name(i.value_type)}, not a string`}):t.push({gtype:n.gtype,problem:`declares textSink "${n.textSink}", which ${r} does not have`})}t.push(...policyProblems(n,e,r))}return t}function policyProblems(e,t,n){let r=[],i=t.prototype,a=e.children,requireGetter=(t,a)=>{let o=t.replace(/^set_/,`get_`);typeof i[o]!=`function`&&r.push({gtype:e.gtype,problem:`${a} uses ${t}() but ${n} has no ${o}(), so removal cannot check whether this child is still the one in place`})};if(a.kind===`single`&&requireGetter(a.set,`children.set`),a.kind===`slotted`){for(let[e,t]of Object.entries(a.slots))t.startsWith(`set_`)&&requireGetter(t,`slot "${e}"`);a.defaultSlot in a.slots||r.push({gtype:e.gtype,problem:`defaultSlot "${a.defaultSlot}" is not one of ${Object.keys(a.slots).join(`, `)}`})}if(a.kind===`ordered`&&a.reorder===`native`&&!a.after&&r.push({gtype:e.gtype,problem:`claims reorder: 'native' with no "after" method — reorderMode() would tell an adapter the wrong thing`}),a.kind===`keyed`){let t=i[a.add],o=a.titled?3:1;typeof t==`function`&&t.length!==o&&r.push({gtype:e.gtype,problem:`titled: ${a.titled} implies ${a.add}() takes ${o} argument(s), but ${n}'s takes ${t.length}`})}return r}function gtkChildren(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 gtkChildTypes=e=>gtkChildren(e).map(e=>a.type_name(e.constructor.$gtype));function addressesOf(t){let n=[];for(let r=t.first;r;r=r.next)r.kind===`element`&&r.widget&&n.push(e(r));return n}function findDescendant(e,t){let n=[e];for(;n.length>0;){let r=n.shift();if(r!==e&&t(r))return r;n.push(...gtkChildren(r))}return null}function descendants(e){let t=[e];for(let n of gtkChildren(e))t.push(...descendants(n));return t}function dumpTree(e,t=0){let n=a.type_name(e.constructor.$gtype),r=[`${` `.repeat(t)}${n}`];for(let n of gtkChildren(e))r.push(dumpTree(n,t+1));return r.join(`
|
|
2
|
+
`)}export{addressesOf,descendants,n as describeLogRecord,descriptorProblems,dumpTree,findDescendant,gtkChildTypes,gtkChildren,r as installDiagnosticsGate,methodsOf};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"../_virtual/_rolldown/runtime.js";import{registerWidgets as e}from"../registry.js";import{
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import{registerWidgets as e}from"../registry.js";import{GENERATED_PROVENANCE as t,GENERATED_WIDGETS as n}from"../generated/widgets.js";import{ADW_DESCRIPTORS as r}from"./adw.js";import{GTK_DESCRIPTORS as i}from"./gtk.js";const a=[...i,...r],o={AdwLayoutSlot:[`id`]};function mergeGenerated(e,t){let n=[...e],r=new Set(e.map(e=>e.gtype));for(let e of t){if(r.has(e.gtype))continue;let t=o[e.gtype];n.push({gtype:e.gtype,ctor:e.ctor,children:{kind:`uncurated`},...t?{requiresProps:t}:{}})}return n}const s=mergeGenerated(a,n);function registerBuiltinWidgets(){e(s)}const tableProvenance=()=>({gir:t,curated:a.length,generated:n.length,total:s.length});export{r as ADW_DESCRIPTORS,s as BUILTIN_DESCRIPTORS,a as CURATED_DESCRIPTORS,t as GENERATED_PROVENANCE,n as GENERATED_WIDGETS,i as GTK_DESCRIPTORS,o as REQUIRED_CONSTRUCT_PROPS,mergeGenerated,registerBuiltinWidgets,tableProvenance};
|
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}', … })
|
|
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.`),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} expects the flags type ${r}, and a string ("${n}") cannot be resolved to one. Pass the numeric value (bitwise-or the members). GObject would have dropped the string silently.`),unresolvableEnum:e=>new GtkHostError(`unresolvable-enum`,`Cannot resolve the enum type ${e} to a GI namespace. Pass the numeric value instead, or extend ENUM_NAMESPACES in props.ts.`),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.join(`, `)}.`),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.`),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};
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"../_virtual/_rolldown/runtime.js";import e from"gi://Gtk?version=4.0";import t from"gi://Adw?version=1";const n=`Gtk-4.0 Adw-1`,r=[{gtype:`AdwAboutDialog`,tag:`adw-about-dialog`,ctor:()=>t.AboutDialog},{gtype:`AdwAboutWindow`,tag:`adw-about-window`,ctor:()=>t.AboutWindow},{gtype:`AdwActionRow`,tag:`adw-action-row`,ctor:()=>t.ActionRow},{gtype:`AdwAlertDialog`,tag:`adw-alert-dialog`,ctor:()=>t.AlertDialog},{gtype:`AdwApplicationWindow`,tag:`adw-application-window`,ctor:()=>t.ApplicationWindow},{gtype:`AdwAvatar`,tag:`adw-avatar`,ctor:()=>t.Avatar},{gtype:`AdwBanner`,tag:`adw-banner`,ctor:()=>t.Banner},{gtype:`AdwBin`,tag:`adw-bin`,ctor:()=>t.Bin},{gtype:`AdwBottomSheet`,tag:`adw-bottom-sheet`,ctor:()=>t.BottomSheet},{gtype:`AdwBreakpointBin`,tag:`adw-breakpoint-bin`,ctor:()=>t.BreakpointBin},{gtype:`AdwButtonContent`,tag:`adw-button-content`,ctor:()=>t.ButtonContent},{gtype:`AdwButtonRow`,tag:`adw-button-row`,ctor:()=>t.ButtonRow},{gtype:`AdwCarousel`,tag:`adw-carousel`,ctor:()=>t.Carousel},{gtype:`AdwCarouselIndicatorDots`,tag:`adw-carousel-indicator-dots`,ctor:()=>t.CarouselIndicatorDots},{gtype:`AdwCarouselIndicatorLines`,tag:`adw-carousel-indicator-lines`,ctor:()=>t.CarouselIndicatorLines},{gtype:`AdwClamp`,tag:`adw-clamp`,ctor:()=>t.Clamp},{gtype:`AdwClampScrollable`,tag:`adw-clamp-scrollable`,ctor:()=>t.ClampScrollable},{gtype:`AdwComboRow`,tag:`adw-combo-row`,ctor:()=>t.ComboRow},{gtype:`AdwDialog`,tag:`adw-dialog`,ctor:()=>t.Dialog},{gtype:`AdwEntryRow`,tag:`adw-entry-row`,ctor:()=>t.EntryRow},{gtype:`AdwExpanderRow`,tag:`adw-expander-row`,ctor:()=>t.ExpanderRow},{gtype:`AdwFlap`,tag:`adw-flap`,ctor:()=>t.Flap},{gtype:`AdwHeaderBar`,tag:`adw-header-bar`,ctor:()=>t.HeaderBar},{gtype:`AdwInlineViewSwitcher`,tag:`adw-inline-view-switcher`,ctor:()=>t.InlineViewSwitcher},{gtype:`AdwLayoutSlot`,tag:`adw-layout-slot`,ctor:()=>t.LayoutSlot},{gtype:`AdwLeaflet`,tag:`adw-leaflet`,ctor:()=>t.Leaflet},{gtype:`AdwMessageDialog`,tag:`adw-message-dialog`,ctor:()=>t.MessageDialog},{gtype:`AdwMultiLayoutView`,tag:`adw-multi-layout-view`,ctor:()=>t.MultiLayoutView},{gtype:`AdwNavigationPage`,tag:`adw-navigation-page`,ctor:()=>t.NavigationPage},{gtype:`AdwNavigationSplitView`,tag:`adw-navigation-split-view`,ctor:()=>t.NavigationSplitView},{gtype:`AdwNavigationView`,tag:`adw-navigation-view`,ctor:()=>t.NavigationView},{gtype:`AdwOverlaySplitView`,tag:`adw-overlay-split-view`,ctor:()=>t.OverlaySplitView},{gtype:`AdwPasswordEntryRow`,tag:`adw-password-entry-row`,ctor:()=>t.PasswordEntryRow},{gtype:`AdwPreferencesDialog`,tag:`adw-preferences-dialog`,ctor:()=>t.PreferencesDialog},{gtype:`AdwPreferencesGroup`,tag:`adw-preferences-group`,ctor:()=>t.PreferencesGroup},{gtype:`AdwPreferencesPage`,tag:`adw-preferences-page`,ctor:()=>t.PreferencesPage},{gtype:`AdwPreferencesRow`,tag:`adw-preferences-row`,ctor:()=>t.PreferencesRow},{gtype:`AdwPreferencesWindow`,tag:`adw-preferences-window`,ctor:()=>t.PreferencesWindow},{gtype:`AdwShortcutLabel`,tag:`adw-shortcut-label`,ctor:()=>t.ShortcutLabel},{gtype:`AdwShortcutsDialog`,tag:`adw-shortcuts-dialog`,ctor:()=>t.ShortcutsDialog},{gtype:`AdwSidebar`,tag:`adw-sidebar`,ctor:()=>t.Sidebar},{gtype:`AdwSpinRow`,tag:`adw-spin-row`,ctor:()=>t.SpinRow},{gtype:`AdwSpinner`,tag:`adw-spinner`,ctor:()=>t.Spinner},{gtype:`AdwSplitButton`,tag:`adw-split-button`,ctor:()=>t.SplitButton},{gtype:`AdwSqueezer`,tag:`adw-squeezer`,ctor:()=>t.Squeezer},{gtype:`AdwStatusPage`,tag:`adw-status-page`,ctor:()=>t.StatusPage},{gtype:`AdwSwitchRow`,tag:`adw-switch-row`,ctor:()=>t.SwitchRow},{gtype:`AdwTabBar`,tag:`adw-tab-bar`,ctor:()=>t.TabBar},{gtype:`AdwTabButton`,tag:`adw-tab-button`,ctor:()=>t.TabButton},{gtype:`AdwTabOverview`,tag:`adw-tab-overview`,ctor:()=>t.TabOverview},{gtype:`AdwTabView`,tag:`adw-tab-view`,ctor:()=>t.TabView},{gtype:`AdwToastOverlay`,tag:`adw-toast-overlay`,ctor:()=>t.ToastOverlay},{gtype:`AdwToggleGroup`,tag:`adw-toggle-group`,ctor:()=>t.ToggleGroup},{gtype:`AdwToolbarView`,tag:`adw-toolbar-view`,ctor:()=>t.ToolbarView},{gtype:`AdwViewStack`,tag:`adw-view-stack`,ctor:()=>t.ViewStack},{gtype:`AdwViewSwitcher`,tag:`adw-view-switcher`,ctor:()=>t.ViewSwitcher},{gtype:`AdwViewSwitcherBar`,tag:`adw-view-switcher-bar`,ctor:()=>t.ViewSwitcherBar},{gtype:`AdwViewSwitcherSidebar`,tag:`adw-view-switcher-sidebar`,ctor:()=>t.ViewSwitcherSidebar},{gtype:`AdwViewSwitcherTitle`,tag:`adw-view-switcher-title`,ctor:()=>t.ViewSwitcherTitle},{gtype:`AdwWindow`,tag:`adw-window`,ctor:()=>t.Window},{gtype:`AdwWindowTitle`,tag:`adw-window-title`,ctor:()=>t.WindowTitle},{gtype:`AdwWrapBox`,tag:`adw-wrap-box`,ctor:()=>t.WrapBox},{gtype:`GtkAboutDialog`,tag:`gtk-about-dialog`,ctor:()=>e.AboutDialog},{gtype:`GtkActionBar`,tag:`gtk-action-bar`,ctor:()=>e.ActionBar},{gtype:`GtkAppChooserButton`,tag:`gtk-app-chooser-button`,ctor:()=>e.AppChooserButton},{gtype:`GtkAppChooserDialog`,tag:`gtk-app-chooser-dialog`,ctor:()=>e.AppChooserDialog},{gtype:`GtkAppChooserWidget`,tag:`gtk-app-chooser-widget`,ctor:()=>e.AppChooserWidget},{gtype:`GtkApplicationWindow`,tag:`gtk-application-window`,ctor:()=>e.ApplicationWindow},{gtype:`GtkAspectFrame`,tag:`gtk-aspect-frame`,ctor:()=>e.AspectFrame},{gtype:`GtkAssistant`,tag:`gtk-assistant`,ctor:()=>e.Assistant},{gtype:`GtkBox`,tag:`gtk-box`,ctor:()=>e.Box},{gtype:`GtkButton`,tag:`gtk-button`,ctor:()=>e.Button},{gtype:`GtkCalendar`,tag:`gtk-calendar`,ctor:()=>e.Calendar},{gtype:`GtkCellView`,tag:`gtk-cell-view`,ctor:()=>e.CellView},{gtype:`GtkCenterBox`,tag:`gtk-center-box`,ctor:()=>e.CenterBox},{gtype:`GtkCheckButton`,tag:`gtk-check-button`,ctor:()=>e.CheckButton},{gtype:`GtkColorButton`,tag:`gtk-color-button`,ctor:()=>e.ColorButton},{gtype:`GtkColorChooserDialog`,tag:`gtk-color-chooser-dialog`,ctor:()=>e.ColorChooserDialog},{gtype:`GtkColorChooserWidget`,tag:`gtk-color-chooser-widget`,ctor:()=>e.ColorChooserWidget},{gtype:`GtkColorDialogButton`,tag:`gtk-color-dialog-button`,ctor:()=>e.ColorDialogButton},{gtype:`GtkColumnView`,tag:`gtk-column-view`,ctor:()=>e.ColumnView},{gtype:`GtkComboBox`,tag:`gtk-combo-box`,ctor:()=>e.ComboBox},{gtype:`GtkComboBoxText`,tag:`gtk-combo-box-text`,ctor:()=>e.ComboBoxText},{gtype:`GtkDialog`,tag:`gtk-dialog`,ctor:()=>e.Dialog},{gtype:`GtkDragIcon`,tag:`gtk-drag-icon`,ctor:()=>e.DragIcon},{gtype:`GtkDrawingArea`,tag:`gtk-drawing-area`,ctor:()=>e.DrawingArea},{gtype:`GtkDropDown`,tag:`gtk-drop-down`,ctor:()=>e.DropDown},{gtype:`GtkEditableLabel`,tag:`gtk-editable-label`,ctor:()=>e.EditableLabel},{gtype:`GtkEmojiChooser`,tag:`gtk-emoji-chooser`,ctor:()=>e.EmojiChooser},{gtype:`GtkEntry`,tag:`gtk-entry`,ctor:()=>e.Entry},{gtype:`GtkExpander`,tag:`gtk-expander`,ctor:()=>e.Expander},{gtype:`GtkFileChooserDialog`,tag:`gtk-file-chooser-dialog`,ctor:()=>e.FileChooserDialog},{gtype:`GtkFileChooserWidget`,tag:`gtk-file-chooser-widget`,ctor:()=>e.FileChooserWidget},{gtype:`GtkFixed`,tag:`gtk-fixed`,ctor:()=>e.Fixed},{gtype:`GtkFlowBox`,tag:`gtk-flow-box`,ctor:()=>e.FlowBox},{gtype:`GtkFlowBoxChild`,tag:`gtk-flow-box-child`,ctor:()=>e.FlowBoxChild},{gtype:`GtkFontButton`,tag:`gtk-font-button`,ctor:()=>e.FontButton},{gtype:`GtkFontChooserDialog`,tag:`gtk-font-chooser-dialog`,ctor:()=>e.FontChooserDialog},{gtype:`GtkFontChooserWidget`,tag:`gtk-font-chooser-widget`,ctor:()=>e.FontChooserWidget},{gtype:`GtkFontDialogButton`,tag:`gtk-font-dialog-button`,ctor:()=>e.FontDialogButton},{gtype:`GtkFrame`,tag:`gtk-frame`,ctor:()=>e.Frame},{gtype:`GtkGLArea`,tag:`gtk-gl-area`,ctor:()=>e.GLArea},{gtype:`GtkGraphicsOffload`,tag:`gtk-graphics-offload`,ctor:()=>e.GraphicsOffload},{gtype:`GtkGrid`,tag:`gtk-grid`,ctor:()=>e.Grid},{gtype:`GtkGridView`,tag:`gtk-grid-view`,ctor:()=>e.GridView},{gtype:`GtkHeaderBar`,tag:`gtk-header-bar`,ctor:()=>e.HeaderBar},{gtype:`GtkIconView`,tag:`gtk-icon-view`,ctor:()=>e.IconView},{gtype:`GtkImage`,tag:`gtk-image`,ctor:()=>e.Image},{gtype:`GtkInfoBar`,tag:`gtk-info-bar`,ctor:()=>e.InfoBar},{gtype:`GtkInscription`,tag:`gtk-inscription`,ctor:()=>e.Inscription},{gtype:`GtkLabel`,tag:`gtk-label`,ctor:()=>e.Label},{gtype:`GtkLevelBar`,tag:`gtk-level-bar`,ctor:()=>e.LevelBar},{gtype:`GtkLinkButton`,tag:`gtk-link-button`,ctor:()=>e.LinkButton},{gtype:`GtkListBox`,tag:`gtk-list-box`,ctor:()=>e.ListBox},{gtype:`GtkListBoxRow`,tag:`gtk-list-box-row`,ctor:()=>e.ListBoxRow},{gtype:`GtkListView`,tag:`gtk-list-view`,ctor:()=>e.ListView},{gtype:`GtkLockButton`,tag:`gtk-lock-button`,ctor:()=>e.LockButton},{gtype:`GtkMediaControls`,tag:`gtk-media-controls`,ctor:()=>e.MediaControls},{gtype:`GtkMenuButton`,tag:`gtk-menu-button`,ctor:()=>e.MenuButton},{gtype:`GtkMessageDialog`,tag:`gtk-message-dialog`,ctor:()=>e.MessageDialog},{gtype:`GtkNotebook`,tag:`gtk-notebook`,ctor:()=>e.Notebook},{gtype:`GtkOverlay`,tag:`gtk-overlay`,ctor:()=>e.Overlay},{gtype:`GtkPageSetupUnixDialog`,tag:`gtk-page-setup-unix-dialog`,ctor:()=>e.PageSetupUnixDialog},{gtype:`GtkPaned`,tag:`gtk-paned`,ctor:()=>e.Paned},{gtype:`GtkPasswordEntry`,tag:`gtk-password-entry`,ctor:()=>e.PasswordEntry},{gtype:`GtkPicture`,tag:`gtk-picture`,ctor:()=>e.Picture},{gtype:`GtkPopover`,tag:`gtk-popover`,ctor:()=>e.Popover},{gtype:`GtkPopoverBin`,tag:`gtk-popover-bin`,ctor:()=>e.PopoverBin},{gtype:`GtkPopoverMenu`,tag:`gtk-popover-menu`,ctor:()=>e.PopoverMenu},{gtype:`GtkPopoverMenuBar`,tag:`gtk-popover-menu-bar`,ctor:()=>e.PopoverMenuBar},{gtype:`GtkPrintUnixDialog`,tag:`gtk-print-unix-dialog`,ctor:()=>e.PrintUnixDialog},{gtype:`GtkProgressBar`,tag:`gtk-progress-bar`,ctor:()=>e.ProgressBar},{gtype:`GtkRange`,tag:`gtk-range`,ctor:()=>e.Range},{gtype:`GtkRevealer`,tag:`gtk-revealer`,ctor:()=>e.Revealer},{gtype:`GtkScale`,tag:`gtk-scale`,ctor:()=>e.Scale},{gtype:`GtkScaleButton`,tag:`gtk-scale-button`,ctor:()=>e.ScaleButton},{gtype:`GtkScrollbar`,tag:`gtk-scrollbar`,ctor:()=>e.Scrollbar},{gtype:`GtkScrolledWindow`,tag:`gtk-scrolled-window`,ctor:()=>e.ScrolledWindow},{gtype:`GtkSearchBar`,tag:`gtk-search-bar`,ctor:()=>e.SearchBar},{gtype:`GtkSearchEntry`,tag:`gtk-search-entry`,ctor:()=>e.SearchEntry},{gtype:`GtkSeparator`,tag:`gtk-separator`,ctor:()=>e.Separator},{gtype:`GtkShortcutLabel`,tag:`gtk-shortcut-label`,ctor:()=>e.ShortcutLabel},{gtype:`GtkShortcutsGroup`,tag:`gtk-shortcuts-group`,ctor:()=>e.ShortcutsGroup},{gtype:`GtkShortcutsSection`,tag:`gtk-shortcuts-section`,ctor:()=>e.ShortcutsSection},{gtype:`GtkShortcutsShortcut`,tag:`gtk-shortcuts-shortcut`,ctor:()=>e.ShortcutsShortcut},{gtype:`GtkShortcutsWindow`,tag:`gtk-shortcuts-window`,ctor:()=>e.ShortcutsWindow},{gtype:`GtkSpinButton`,tag:`gtk-spin-button`,ctor:()=>e.SpinButton},{gtype:`GtkSpinner`,tag:`gtk-spinner`,ctor:()=>e.Spinner},{gtype:`GtkStack`,tag:`gtk-stack`,ctor:()=>e.Stack},{gtype:`GtkStackSidebar`,tag:`gtk-stack-sidebar`,ctor:()=>e.StackSidebar},{gtype:`GtkStackSwitcher`,tag:`gtk-stack-switcher`,ctor:()=>e.StackSwitcher},{gtype:`GtkStatusbar`,tag:`gtk-statusbar`,ctor:()=>e.Statusbar},{gtype:`GtkSwitch`,tag:`gtk-switch`,ctor:()=>e.Switch},{gtype:`GtkText`,tag:`gtk-text`,ctor:()=>e.Text},{gtype:`GtkTextView`,tag:`gtk-text-view`,ctor:()=>e.TextView},{gtype:`GtkToggleButton`,tag:`gtk-toggle-button`,ctor:()=>e.ToggleButton},{gtype:`GtkTreeExpander`,tag:`gtk-tree-expander`,ctor:()=>e.TreeExpander},{gtype:`GtkTreeView`,tag:`gtk-tree-view`,ctor:()=>e.TreeView},{gtype:`GtkVideo`,tag:`gtk-video`,ctor:()=>e.Video},{gtype:`GtkViewport`,tag:`gtk-viewport`,ctor:()=>e.Viewport},{gtype:`GtkVolumeButton`,tag:`gtk-volume-button`,ctor:()=>e.VolumeButton},{gtype:`GtkWindow`,tag:`gtk-window`,ctor:()=>e.Window},{gtype:`GtkWindowControls`,tag:`gtk-window-controls`,ctor:()=>e.WindowControls},{gtype:`GtkWindowHandle`,tag:`gtk-window-handle`,ctor:()=>e.WindowHandle}];export{n as GENERATED_PROVENANCE,r as GENERATED_WIDGETS};
|