@gjsify/gtk-host 0.47.0 → 0.49.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 +158 -2
- package/lib/esm/adjustment.js +1 -0
- package/lib/esm/conformance/diagnostics.js +1 -1
- package/lib/esm/conformance/index.js +1 -2
- package/lib/esm/conformance/tree.js +2 -0
- package/lib/esm/conformance/window-chrome.js +1 -0
- package/lib/esm/descriptors/adw.js +1 -1
- package/lib/esm/descriptors/gtk.js +1 -1
- package/lib/esm/descriptors/index.js +1 -1
- package/lib/esm/errors.js +1 -1
- package/lib/esm/font-families.js +1 -0
- package/lib/esm/fonts.js +1 -1
- package/lib/esm/host.js +1 -1
- package/lib/esm/index.js +1 -1
- package/lib/esm/list-model.js +1 -0
- package/lib/esm/menu.js +1 -0
- package/lib/esm/policies.js +1 -1
- package/lib/esm/probe.js +1 -1
- package/lib/esm/props.js +1 -1
- package/lib/esm/style/font-family.js +3 -0
- package/lib/esm/style/index.js +1 -1
- package/lib/esm/style/paint.js +1 -1
- package/lib/types/adjustment.d.ts +28 -0
- package/lib/types/adjustment.spec.d.ts +2 -0
- package/lib/types/attrs.d.ts +79 -0
- package/lib/types/conformance/index.d.ts +28 -29
- package/lib/types/conformance/tree.d.ts +30 -0
- package/lib/types/conformance/vectors.d.mts +6 -0
- package/lib/types/conformance/window-chrome.d.ts +29 -0
- package/lib/types/descriptors/gtk.d.ts +32 -1
- package/lib/types/errors.d.ts +43 -0
- package/lib/types/font-families.d.ts +40 -0
- package/lib/types/font-families.spec.d.ts +2 -0
- package/lib/types/fonts.d.ts +45 -1
- package/lib/types/generated/enum-values.d.mts +38 -0
- package/lib/types/generated/methods.d.mts +46 -0
- package/lib/types/index.d.ts +1 -1
- package/lib/types/jsx-runtime.d.ts +2 -2
- package/lib/types/list-model.d.ts +38 -0
- package/lib/types/list-model.spec.d.ts +2 -0
- package/lib/types/menu.d.ts +43 -0
- package/lib/types/menu.spec.d.ts +2 -0
- package/lib/types/placement.spec.d.ts +2 -0
- package/lib/types/policies.d.ts +241 -1
- package/lib/types/react-jsx-runtime.d.ts +2 -2
- package/lib/types/shared-trees.spec.d.ts +2 -0
- package/lib/types/style/font-family.d.ts +64 -0
- package/lib/types/style/index.d.ts +3 -1
- package/lib/types/style/paint.d.ts +37 -0
- package/lib/types/testing/refusal.d.mts +2 -0
- package/lib/types/types.d.ts +177 -1
- package/lib/types/vue-components.d.ts +2 -2
- package/package.json +8 -5
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import Gio from 'gi://Gio?version=2.0';
|
|
2
|
+
import type { AdwMenuInput, AdwMenuModel } from '@gjsify/adwaita-core';
|
|
3
|
+
/**
|
|
4
|
+
* A portable menu model as a live `Gio.Menu`.
|
|
5
|
+
*
|
|
6
|
+
* Accepts the AUTHORED form as well as the normalised one, so a JSX attribute needs no
|
|
7
|
+
* conversion step of its own: `normalizeMenuModel` is idempotent, which is what makes
|
|
8
|
+
* the two safe to take through one door.
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildGioMenu(input: AdwMenuInput | AdwMenuModel): Gio.Menu;
|
|
11
|
+
/**
|
|
12
|
+
* Whether a value is a portable menu model rather than a `GMenuModel`.
|
|
13
|
+
*
|
|
14
|
+
* An ARRAY, and nothing else. `Gio.MenuModel` is a GObject and never an array, so the
|
|
15
|
+
* test cannot confuse the two — and a caller passing a real `Gio.Menu` (the imperative
|
|
16
|
+
* path every existing GJS application uses) keeps passing it straight through.
|
|
17
|
+
*/
|
|
18
|
+
export declare const isPortableMenu: (value: unknown) => value is AdwMenuInput;
|
|
19
|
+
/**
|
|
20
|
+
* A `GMenuModel` back as a portable model — the inverse of {@link buildGioMenu}.
|
|
21
|
+
*
|
|
22
|
+
* IT EXISTS TO MAKE THE LOSSLESS CLAIM MEASURABLE. ADR 0042 says the model maps onto
|
|
23
|
+
* `Gio.Menu` with nothing left over; a builder alone cannot show that, because whatever
|
|
24
|
+
* it drops is dropped in silence. `conformance/menu.ts` drives every vector through
|
|
25
|
+
* `buildGioMenu` and back through this function and compares, so a forgotten attribute
|
|
26
|
+
* fails a test naming it instead of disappearing from a popup nobody re-opened.
|
|
27
|
+
*
|
|
28
|
+
* It reads what GTK reads plus `id`, so an application's OWN extra attributes do not
|
|
29
|
+
* survive the round trip — stated rather than implied: this is not a general
|
|
30
|
+
* `GMenuModel` serialiser, it is the inverse of the builder above.
|
|
31
|
+
*
|
|
32
|
+
* TWO EDGES A HAND-BUILT `Gio.Menu` CAN REACH AND THE MODEL CANNOT, both matching GTK
|
|
33
|
+
* rather than diverging from it:
|
|
34
|
+
*
|
|
35
|
+
* · an item carrying BOTH links reads as a SECTION and its submenu is not walked.
|
|
36
|
+
* `GtkMenuTracker` decides the same way (`gtkmenutracker.c:317-352`): it tests
|
|
37
|
+
* `G_MENU_LINK_SECTION` first and
|
|
38
|
+
* recurses, so the submenu link is unreachable there too.
|
|
39
|
+
* · a non-string `label` reads as `''`. `attr()` asks for type `s`; so does
|
|
40
|
+
* `g_menu_item_get_attribute (item, "label", "&s", …)`, which fails the same way and
|
|
41
|
+
* leaves GTK drawing an unlabelled row.
|
|
42
|
+
*/
|
|
43
|
+
export declare function fromGioMenu(model: Gio.MenuModel): AdwMenuModel;
|
package/lib/types/policies.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import GObject from 'gi://GObject?version=2.0';
|
|
1
2
|
import Gtk from 'gi://Gtk?version=4.0';
|
|
2
|
-
import type { ChildPolicy, HostElement } from './types.js';
|
|
3
|
+
import type { ChildPolicy, HostElement, NodePlacement, WidgetDescriptor } from './types.js';
|
|
3
4
|
/** The object the PARENT addresses: a wrapper row when the policy demands one. */
|
|
4
5
|
export declare function addressOf(el: HostElement): Gtk.Widget;
|
|
5
6
|
/**
|
|
@@ -86,6 +87,245 @@ export declare function setterSlots(policy: ChildPolicy): string[];
|
|
|
86
87
|
* occupant is the widget they handed over.
|
|
87
88
|
*/
|
|
88
89
|
export declare function slotOccupant(widget: Gtk.Widget, setter: string): Gtk.Widget | null | undefined;
|
|
90
|
+
/** A placement that does NOT put the node into its parent's child list. */
|
|
91
|
+
export type OutsideParent = Exclude<NodePlacement, {
|
|
92
|
+
kind: 'parented';
|
|
93
|
+
}>;
|
|
94
|
+
/**
|
|
95
|
+
* The declared placement of a node. The ONE place absence is turned into a value.
|
|
96
|
+
*
|
|
97
|
+
* Everything downstream switches on the union rather than on `descriptor.placement
|
|
98
|
+
* !== undefined`, so the absent case is a member with a name instead of a
|
|
99
|
+
* falsiness test that a third kind would quietly join.
|
|
100
|
+
*/
|
|
101
|
+
export declare const placementOf: (descriptor: WidgetDescriptor) => NodePlacement;
|
|
102
|
+
/**
|
|
103
|
+
* The placement, when it is NOT `parented` — the narrow question every caller asks.
|
|
104
|
+
*
|
|
105
|
+
* Returning the arm rather than a boolean is what keeps the two non-parented kinds
|
|
106
|
+
* ONE question: a caller switches over what it gets and its `never` arm fails to
|
|
107
|
+
* compile the day a fourth kind arrives.
|
|
108
|
+
*/
|
|
109
|
+
export declare function outsideParentOf(descriptor: WidgetDescriptor): OutsideParent | null;
|
|
110
|
+
/** The portal arm specifically, or null. */
|
|
111
|
+
export declare function portalOf(descriptor: WidgetDescriptor): Extract<NodePlacement, {
|
|
112
|
+
kind: 'portal';
|
|
113
|
+
}> | null;
|
|
114
|
+
/** `unhandledPolicy`'s twin for the placement axis, and it exists for the same reason. */
|
|
115
|
+
export declare function unhandledPlacement(placement: never): never;
|
|
116
|
+
/** Is this node placed against its parent rather than into it? */
|
|
117
|
+
export declare const isPortal: (el: HostElement) => boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Does this node take NO position in its parent's child list?
|
|
120
|
+
*
|
|
121
|
+
* The question four sibling walks ask, and it is the placement AXIS rather than
|
|
122
|
+
* the portal arm: a toplevel occupies a parent's child list exactly as little as a
|
|
123
|
+
* portal does. Asking `isPortal` there was correct while `portal` was the only
|
|
124
|
+
* non-parented kind and became a silent hole the moment it was not — counting a
|
|
125
|
+
* toplevel as a sibling shifts every later child by one and hands
|
|
126
|
+
* `insert_child_after` a widget that is not in the container (a critical at exit 0),
|
|
127
|
+
* and rotating one calls the parent's adder on a node that must never enter it.
|
|
128
|
+
*/
|
|
129
|
+
export declare const isUnparented: (el: HostElement) => boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Show a portal node against its parent — or subscribe and wait, if it is too early.
|
|
132
|
+
*
|
|
133
|
+
* Returns whether GTK has actually taken the node, which is what `attached` means.
|
|
134
|
+
*
|
|
135
|
+
* WHY THE WAIT IS THE FEATURE. Every framework builds bottom-up: React creates the
|
|
136
|
+
* whole subtree, appends its children, and inserts the ROOT into the container
|
|
137
|
+
* last, so at the moment a `<Modal>` is inserted its parent is usually not in a
|
|
138
|
+
* window yet. MEASURED on libadwaita 1.9.3 / GTK 4.22.4, presenting against an
|
|
139
|
+
* unrooted box: `adw_dialog_present` finds no `AdwDialogHost` among the parent's
|
|
140
|
+
* ancestors and takes its documented other branch, `present_as_window` — the
|
|
141
|
+
* dialog opens as a SEPARATE `GtkWindow`, `win.visibleDialog` stays false, exit 0,
|
|
142
|
+
* no diagnostic. A modal that floats out of its own application is exactly the
|
|
143
|
+
* green-and-wrong this host exists to refuse, and nothing in the shadow tree can
|
|
144
|
+
* see it.
|
|
145
|
+
*
|
|
146
|
+
* `notify::root` is the instrument. MEASURED: it fires on a GRANDCHILD box when
|
|
147
|
+
* the toplevel takes the subtree (root -> AdwWindow), and again on unroot (root ->
|
|
148
|
+
* null). The subscription STAYS for the life of the attachment rather than being
|
|
149
|
+
* one-shot, because re-rooting is real: measured, unrooting the parent leaves an
|
|
150
|
+
* already-presented dialog in the OLD window's host — `w1.visibleDialog` still
|
|
151
|
+
* true after `w1.set_content(null)` — so a subtree moved to a second window would
|
|
152
|
+
* silently keep showing its modal in the first.
|
|
153
|
+
*
|
|
154
|
+
* SYMMETRIC, and the second direction is not free. GTK does not take the dialog
|
|
155
|
+
* down when the anchor loses its window, so losing a toplevel RETRACTS the node
|
|
156
|
+
* rather than merely failing to present it (see `placeAgainst`). Without that, a
|
|
157
|
+
* subtree that is detached and never re-rooted keeps its sheet on screen in the
|
|
158
|
+
* window it left, and only a re-root — which such a subtree never gets — repairs it.
|
|
159
|
+
*/
|
|
160
|
+
export declare function presentPortal(parent: HostElement, child: HostElement, portal: Extract<NodePlacement, {
|
|
161
|
+
kind: 'portal';
|
|
162
|
+
}>): boolean;
|
|
163
|
+
/**
|
|
164
|
+
* Take a portal node back down, with no probe and no `attached` guard.
|
|
165
|
+
*
|
|
166
|
+
* UNCONDITIONALLY, twice over, and both halves are measured. The method the
|
|
167
|
+
* descriptor names is the FORCED close (`force_close`, not `close`): an unmount is
|
|
168
|
+
* not a user request, and `close()` on a dialog whose `can-close` is FALSE returns
|
|
169
|
+
* FALSE, emits `close-attempt` and leaves it on screen. And `force_close()` on a
|
|
170
|
+
* node that was never presented is silent, where `close()` is
|
|
171
|
+
* `Adwaita-CRITICAL **: Trying to close … that's not presented` at exit 0 — so the
|
|
172
|
+
* host needs no "is it up?" question, which is the one it could not answer without
|
|
173
|
+
* knowing what a dialog is.
|
|
174
|
+
*/
|
|
175
|
+
export declare function retractPortal(child: HostElement, portal: Extract<NodePlacement, {
|
|
176
|
+
kind: 'portal';
|
|
177
|
+
}>): void;
|
|
178
|
+
/**
|
|
179
|
+
* Show a toplevel node — and it needs nothing from its parent, which is the point.
|
|
180
|
+
*
|
|
181
|
+
* NO ANCHOR, NO WAIT, NO SUBSCRIPTION. A portal has two positions in the tree and
|
|
182
|
+
* defers until the parent supplies the second one; a toplevel HAS no second
|
|
183
|
+
* position, so the whole `notify::root` machinery next door has nothing to watch
|
|
184
|
+
* for. Measured: `gtk_window_present` takes 0 arguments where
|
|
185
|
+
* `adw_dialog_present` takes 1, and that arity is exactly the difference.
|
|
186
|
+
*
|
|
187
|
+
* Returns whether GTK has taken the node — always true once there is a widget,
|
|
188
|
+
* because a root is taken by nobody: measured, a presented window answers
|
|
189
|
+
* `get_parent() === null` and `get_root() === itself`. That is not the portal's
|
|
190
|
+
* "claimed but not yet taken" state, it is the finished one.
|
|
191
|
+
*
|
|
192
|
+
* AN AUTHORED `visible: false` IS HONOURED rather than overwritten. `present()`
|
|
193
|
+
* sets the window visible (measured), so presenting unconditionally would make
|
|
194
|
+
* `<gtk-window visible={false}>` a property this host silently reverses — the
|
|
195
|
+
* exact shape it exists to refuse. The node is still `attached`: GTK holds it as
|
|
196
|
+
* its own root whether or not it is on screen, and a later `setProp(el,
|
|
197
|
+
* 'visible', true)` shows it through the ordinary property path.
|
|
198
|
+
*/
|
|
199
|
+
export declare function presentToplevel(child: HostElement, placement: Extract<NodePlacement, {
|
|
200
|
+
kind: 'toplevel';
|
|
201
|
+
}>): boolean;
|
|
202
|
+
/**
|
|
203
|
+
* Take a toplevel back down — the FORCED call, and it is TERMINAL.
|
|
204
|
+
*
|
|
205
|
+
* `destroy` and not `close`, measured on GTK 4.22.4: `gtk_window_close()` emits
|
|
206
|
+
* `close-request`, and an application handler returning TRUE leaves the window
|
|
207
|
+
* mapped and visible. That veto is how an application asks the USER to confirm,
|
|
208
|
+
* and an unmount is not a user request — the same reasoning that makes the portal
|
|
209
|
+
* arm name `force_close`.
|
|
210
|
+
*
|
|
211
|
+
* Unconditional for the same reason too: measured, `destroy()` on a window that
|
|
212
|
+
* was never presented is silent, so no "is it up?" probe is needed. What differs
|
|
213
|
+
* from the portal is that there IS no way back — measured, `present()` after a
|
|
214
|
+
* destroy (or after a `close()`, whose default handler destroys) answers
|
|
215
|
+
* `Gtk-WARNING **: A window is shown after it has been destroyed`.
|
|
216
|
+
*
|
|
217
|
+
* SO THIS IS `destroy`'s CALL AND NOT `remove`'s, which is the whole reason
|
|
218
|
+
* `detachToplevel` exists next door. `remove` documents itself as reversible.
|
|
219
|
+
*/
|
|
220
|
+
export declare function closeToplevel(child: HostElement, placement: Extract<NodePlacement, {
|
|
221
|
+
kind: 'toplevel';
|
|
222
|
+
}>): void;
|
|
223
|
+
/**
|
|
224
|
+
* Take a toplevel OFF SCREEN, reversibly — `remove`'s call.
|
|
225
|
+
*
|
|
226
|
+
* `remove` is documented as a detach that a later `insert` undoes ("Frameworks
|
|
227
|
+
* move nodes; `remove` must not destroy one"), and Solid takes it literally: its
|
|
228
|
+
* `removeNode` calls `remove(node)` for a move and reaches `destroy` only through
|
|
229
|
+
* the root disposer. Running the declared, TERMINAL close there made a move
|
|
230
|
+
* `destroy()` the window and then present the corpse —
|
|
231
|
+
* `Gtk-WARNING **: A window is shown after it has been destroyed`, at exit 0,
|
|
232
|
+
* visible only because `installDiagnosticsGate()` was watching.
|
|
233
|
+
*
|
|
234
|
+
* A PROPERTY WRITE AND NOT A DECLARED METHOD, and that is the honest shape rather
|
|
235
|
+
* than a shortcut: a window's presence on screen IS its `visible` property — which
|
|
236
|
+
* is why `presentToplevel` already reads it — so every toplevel detaches the same
|
|
237
|
+
* way and a per-row name would be the same string once per declared row. The portal
|
|
238
|
+
* arm needs no counterpart at all, because its declared close is ALREADY reversible.
|
|
239
|
+
*
|
|
240
|
+
* MEASURED on GTK 4.22.4, one window, in order: `set_visible(false)` leaves it
|
|
241
|
+
* `visible` false with one `unmap`, emits NO `close-request`, and keeps it in
|
|
242
|
+
* `Gtk.Window.list_toplevels()` — so it is a detach and not a teardown; `present()`
|
|
243
|
+
* afterwards maps it again with no diagnostic at all; a second `set_visible(false)`
|
|
244
|
+
* is a no-op; and `destroy()` on the hidden window adds no `unmap` and DOES drop it
|
|
245
|
+
* from the toplevel list. `set_visible` rather than the deprecated `hide()`, which
|
|
246
|
+
* is the same call one rename older.
|
|
247
|
+
*
|
|
248
|
+
* Unbracketed, unlike `writeVisible`'s host writes: this is not bookkeeping around
|
|
249
|
+
* a libadwaita defect that the consumer's model never mentions — the window really
|
|
250
|
+
* did leave the screen, and a bound `notify::visible` is entitled to hear it.
|
|
251
|
+
*/
|
|
252
|
+
export declare function detachToplevel(child: HostElement): void;
|
|
253
|
+
/**
|
|
254
|
+
* Place a node that does NOT go into its parent's child list, and say whether GTK took it.
|
|
255
|
+
*
|
|
256
|
+
* The ONE dispatch over the non-parented arms. Every caller in `host.ts` reaches
|
|
257
|
+
* the axis through this and its two twins below, so a fourth placement kind is
|
|
258
|
+
* three `never` arms away from compiling rather than a search through the host.
|
|
259
|
+
*/
|
|
260
|
+
export declare function placeOutsideParent(parent: HostElement, child: HostElement, placement: OutsideParent): boolean;
|
|
261
|
+
/**
|
|
262
|
+
* The REVERSIBLE take-down — what `remove` means, per arm.
|
|
263
|
+
*
|
|
264
|
+
* THE TWO ARMS DIFFER HERE AND NOWHERE ELSE, which is why one function could not
|
|
265
|
+
* serve both: measured, `force_close()` followed by `present(parent)` re-hosts a
|
|
266
|
+
* dialog against the SAME parent with no diagnostic, while `destroy()` followed by
|
|
267
|
+
* `present()` is `Gtk-WARNING **: A window is shown after it has been destroyed`.
|
|
268
|
+
* The portal arm therefore never showed this defect and the toplevel arm shipped
|
|
269
|
+
* with it: a single `retractOutsideParent` treated a reversible verb and a terminal
|
|
270
|
+
* one as the same thing.
|
|
271
|
+
*/
|
|
272
|
+
export declare function detachOutsideParent(child: HostElement, placement: OutsideParent): void;
|
|
273
|
+
/**
|
|
274
|
+
* The TERMINAL take-down — what `destroy` means, and what a DISCARD means.
|
|
275
|
+
*
|
|
276
|
+
* Its one caller is `releaseWidget` in `host.ts`, which is every place the host
|
|
277
|
+
* drops `el.widget`: a toplevel is held by GTK's own list rather than by a parent
|
|
278
|
+
* (measured, `list_toplevels()` holds a window from CONSTRUCTION and loses it only
|
|
279
|
+
* on `destroy`), so a discard that merely detached would leak one window each time
|
|
280
|
+
* — per construct-only write, and per half-built element a failed replay rolls back.
|
|
281
|
+
*/
|
|
282
|
+
export declare function closeOutsideParent(child: HostElement, placement: OutsideParent): void;
|
|
283
|
+
/**
|
|
284
|
+
* The placement the installed libraries give this class, or null for an ordinary child.
|
|
285
|
+
*
|
|
286
|
+
* STRUCTURAL, never a name. ADR 0027 rule 1 forbids widget knowledge in the host,
|
|
287
|
+
* and a list of gtypes here would be exactly that — so the class is asked two
|
|
288
|
+
* questions it answers itself. Both were measured over the WHOLE shipped table on
|
|
289
|
+
* GTK 4.22.4 / libadwaita 1.9.3 rather than over a sample, which is what makes the
|
|
290
|
+
* second one a partition and not an observation:
|
|
291
|
+
*
|
|
292
|
+
* - `Gtk.Root` is GTK's OWN word for "this widget is a toplevel", and every class
|
|
293
|
+
* in the table implementing it — `GtkWindow` through `GtkPrintUnixDialog` — is
|
|
294
|
+
* one no parent may legally take.
|
|
295
|
+
* - A `present()` that TAKES AN ARGUMENT is a node presented AGAINST something.
|
|
296
|
+
* In the table that set is EXACTLY the `Adw.Dialog` descendants and nothing
|
|
297
|
+
* else — the ones whose `root` vfunc calls `g_error()`.
|
|
298
|
+
* `Gtk.Popover.present()` is the discriminator that makes the ARITY part of the
|
|
299
|
+
* question rather than the name: it exists, it takes 0 arguments, and a popover
|
|
300
|
+
* is parented with `set_parent()` like any other child.
|
|
301
|
+
*
|
|
302
|
+
* The order matters and is not alphabetical: every `Gtk.Root` in the table that has
|
|
303
|
+
* a `present` at all has a 0-argument one, and `GtkDragIcon` has none — so the root
|
|
304
|
+
* test has to come first and cannot be replaced by an arity test.
|
|
305
|
+
*
|
|
306
|
+
* @param gtype the class's GType — `type_is_a` walks interfaces as well as parents
|
|
307
|
+
* @param present the class's own `present`, or the value found on an instance
|
|
308
|
+
*/
|
|
309
|
+
export declare function classPlacementKind(gtype: GObject.GType, present: unknown): OutsideParent['kind'] | null;
|
|
310
|
+
/** `classPlacementKind` for a live widget, which is what the insert path holds. */
|
|
311
|
+
export declare function nodePlacementKind(node: Gtk.Widget): OutsideParent['kind'] | null;
|
|
312
|
+
/**
|
|
313
|
+
* Refuse a child the installed libraries will not adopt, BEFORE the adder runs.
|
|
314
|
+
*
|
|
315
|
+
* This is the catchable half of the abort class (ADR 0054). `descriptorProblems()`
|
|
316
|
+
* says the same thing about the whole TABLE up front, which is what keeps the
|
|
317
|
+
* shipped rows honest — but `registerWidget` takes descriptors from applications
|
|
318
|
+
* and nothing checks those, and for one of the two families the consequence is not
|
|
319
|
+
* a wrong window: `adw_dialog_root()` is `g_error()`, so the process is gone before
|
|
320
|
+
* any handler runs. A refusal is only possible while there is still a process.
|
|
321
|
+
*
|
|
322
|
+
* ONLY WHERE THE DESCRIPTOR IS SILENT, and that is the escape hatch rather than an
|
|
323
|
+
* oversight. `placement` present — including an explicit `{ kind: 'parented' }` —
|
|
324
|
+
* means the author has answered this question, and the host does not overrule an
|
|
325
|
+
* answer with a heuristic. A consumer widget that trips the `present(parent)` half
|
|
326
|
+
* of the oracle while really being a child says so in one line.
|
|
327
|
+
*/
|
|
328
|
+
export declare function refuseUnparentable(parent: HostElement, child: HostElement): void;
|
|
89
329
|
export interface Placement {
|
|
90
330
|
parent: HostElement;
|
|
91
331
|
child: HostElement;
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
*/
|
|
34
34
|
import type { Key, ReactElement, ReactNode, Ref } from 'react';
|
|
35
35
|
import type { WidgetClassByTag, WidgetPropsByTag } from './generated/props.js';
|
|
36
|
-
import type { RawSignalAttributes, SlotAttribute, WithOnce } from './attrs.js';
|
|
36
|
+
import type { RawSignalAttributes, SlotAttribute, WithOnce, WithPortableValues } from './attrs.js';
|
|
37
37
|
export { Fragment } from 'react/jsx-runtime';
|
|
38
38
|
/**
|
|
39
39
|
* React's own factories, RE-TYPED over this package's element list.
|
|
@@ -74,7 +74,7 @@ export interface ReactWidgetAttributes<T> extends SlotAttribute, RawSignalAttrib
|
|
|
74
74
|
}
|
|
75
75
|
/** Every GTK/Adwaita tag, with its properties, its handlers, its `ref` and its `key`. */
|
|
76
76
|
export type GtkReactIntrinsicElements = {
|
|
77
|
-
[K in keyof WidgetPropsByTag]: WithOnce<WidgetPropsByTag[K]
|
|
77
|
+
[K in keyof WidgetPropsByTag]: WithOnce<WithPortableValues<WidgetPropsByTag[K]>> & ReactWidgetAttributes<WidgetClassByTag[K]>;
|
|
78
78
|
};
|
|
79
79
|
export declare namespace JSX {
|
|
80
80
|
/**
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A `font-family` value → the text that goes into the declaration.
|
|
3
|
+
*
|
|
4
|
+
* Exported because a consumer that has been quoting defensively (see the incident in
|
|
5
|
+
* the header) can call this instead and stop, and because both routes into the
|
|
6
|
+
* partition — a `style={{ fontFamily }}` object and a `font-*` utility resolving
|
|
7
|
+
* against `tokens.fontFamily` — must go through exactly this one function.
|
|
8
|
+
*/
|
|
9
|
+
export declare function serialiseFontFamily(value: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* What GTK does with an authored value that was NOT serialised.
|
|
12
|
+
*
|
|
13
|
+
* Three states rather than a boolean, and the third one is why. `refused` is the
|
|
14
|
+
* loud bug — GTK rejects the declaration, the containment probe rejects the rule,
|
|
15
|
+
* and the screen is gone. `misread` is the QUIET one: GTK accepts the bare text and
|
|
16
|
+
* resolves a DIFFERENT family, so the application renders in a substituted font with
|
|
17
|
+
* no diagnostic anywhere. A boolean column would have merged `misread` into
|
|
18
|
+
* `accepted` and asserted that serialising changes nothing — which is false for
|
|
19
|
+
* exactly the vectors where changing something is the whole point.
|
|
20
|
+
*/
|
|
21
|
+
export type BareReading = 'refused' | 'accepted' | 'misread';
|
|
22
|
+
/** One authored `font-family` value, what it must become, and what GTK does with it unserialised. */
|
|
23
|
+
export interface FontFamilyVector {
|
|
24
|
+
/** What a `tokens.fontFamily` entry or a `style={{ fontFamily }}` carries. */
|
|
25
|
+
readonly authored: string;
|
|
26
|
+
/** What {@link serialiseFontFamily} must emit for it. */
|
|
27
|
+
readonly emitted: string;
|
|
28
|
+
/**
|
|
29
|
+
* What GTK does with `authored` AS IT STANDS.
|
|
30
|
+
*
|
|
31
|
+
* The column that makes this table a test rather than a restatement, and every
|
|
32
|
+
* state of it is RE-MEASURED against the running GTK by `gtk-css.spec.ts`:
|
|
33
|
+
* `refused` must be rejected, `accepted` must parse to the same computed value
|
|
34
|
+
* as `emitted`, and `misread` must parse to a DIFFERENT one. So the state is a
|
|
35
|
+
* finding and not a claim, and a vector cannot quietly stop exercising the rule.
|
|
36
|
+
*/
|
|
37
|
+
readonly bare: BareReading;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The conformance set for `font-family` values.
|
|
41
|
+
*
|
|
42
|
+
* WHY THIS TABLE EXISTS, and it is the whole finding behind #1539. `gtk-css.ts`
|
|
43
|
+
* probed `['font-family', 'Cantarell']` — ONE word, valid as a bare identifier, and
|
|
44
|
+
* therefore the single family for which the missing quoting is invisible. The suite
|
|
45
|
+
* asserted that `font-family` is emitted and never that it is emitted CORRECTLY, so
|
|
46
|
+
* it would have gone green against an implementation that quoted nothing. A vector
|
|
47
|
+
* whose value cannot exercise the rule reads exactly like a vector that passed.
|
|
48
|
+
*
|
|
49
|
+
* So the set carries, deliberately: a family that NEEDS quoting, a family that does
|
|
50
|
+
* not, a bare multi-identifier family GTK already accepted (the case a
|
|
51
|
+
* quote-on-space reading would call broken), a stack mixing a quoted family with a
|
|
52
|
+
* bare keyword, a value already quoted, a `var()` reference, and a value GTK MISREADS
|
|
53
|
+
* rather than refuses. `bare` is re-measured by `gtk-css.spec.ts`, which also refuses
|
|
54
|
+
* a table that has lost its refused or its misread vectors.
|
|
55
|
+
*
|
|
56
|
+
* The three added after the first review are the shapes the SPLIT and the two
|
|
57
|
+
* PASSTHROUGHS have to survive rather than the quoter: a bare name carrying an odd
|
|
58
|
+
* quote character in front of a fallback, a nested `var()`, and an already-quoted
|
|
59
|
+
* member holding a carriage return. Each was emitted as something GTK accepted and
|
|
60
|
+
* was wrong about — so `gtk-css.spec.ts` also holds the three CLASSES directly, by
|
|
61
|
+
* asking GTK where the fallback member ended up, whether the document survived, and
|
|
62
|
+
* whether a declaration appeared that nothing here wrote.
|
|
63
|
+
*/
|
|
64
|
+
export declare const FONT_FAMILY_VECTORS: readonly FontFamilyVector[];
|
|
@@ -3,8 +3,10 @@ export { GTK_WIDGET_PROPERTIES, GTK_WIDGET_PROPERTY_PROBES, NOT_GTK_WIDGET_PROPE
|
|
|
3
3
|
export { MINIMAL_TOKENS, TAILWIND_DEFAULT_TOKENS, lookupToken, mergeTokens, requireToken, tailwindDefaultHint, } from './tokens.js';
|
|
4
4
|
export type { Scale, StyleTokens } from './tokens.js';
|
|
5
5
|
export { UnknownUtilityError } from './errors.js';
|
|
6
|
-
export { PAINT_PROPERTIES, partitionPaint, resolvePaintUtility } from './paint.js';
|
|
6
|
+
export { CSS_VALUE, CSS_VALUE_KIND, PAINT_PROPERTIES, partitionPaint, resolvePaintUtility } from './paint.js';
|
|
7
7
|
export type { PaintProps } from './paint.js';
|
|
8
|
+
export { FONT_FAMILY_VECTORS, serialiseFontFamily } from './font-family.js';
|
|
9
|
+
export type { FontFamilyVector } from './font-family.js';
|
|
8
10
|
export { LAYOUT_PROPERTIES, partitionLayout, resolveLayoutUtility } from './layout.js';
|
|
9
11
|
export type { AlignValue, Edge, JustifyValue, LayoutIntent, LayoutPartition, LayoutProps, OverlayIntent, WrapIntent, } from './layout.js';
|
|
10
12
|
export { partition, resolveUtilities, resolveUtility } from './resolve.js';
|
|
@@ -32,6 +32,38 @@ export interface PaintProps {
|
|
|
32
32
|
* `partition`'s per-call guard, which no input can reach while the table is right.
|
|
33
33
|
*/
|
|
34
34
|
export declare const CSS_NAME: Readonly<Record<keyof PaintProps, string>>;
|
|
35
|
+
/**
|
|
36
|
+
* What KIND of value each property carries — and therefore whether that value can
|
|
37
|
+
* end the declaration early.
|
|
38
|
+
*
|
|
39
|
+
* DECLARED, not derived, because it is a judgement about a vocabulary rather than
|
|
40
|
+
* something the code can compute. It is here so the judgement is machine-held: the
|
|
41
|
+
* key set is `keyof PaintProps`, so a new property cannot skip it, and
|
|
42
|
+
* `paint.spec.ts` asserts that the `name`-valued properties are EXACTLY the ones
|
|
43
|
+
* {@link CSS_VALUE} serialises. A colour, a length, a number and a keyword are all
|
|
44
|
+
* self-delimiting; a `name` is supplied verbatim by the project and is the only kind
|
|
45
|
+
* that can carry a space, a comma or a quote.
|
|
46
|
+
*
|
|
47
|
+
* The measured answer today is that `font-family` is the only one — checked against
|
|
48
|
+
* the layout half too, which emits margins and paddings and nothing else. The next
|
|
49
|
+
* candidate is not hypothetical: `background-image: url(…)` would be the second.
|
|
50
|
+
*/
|
|
51
|
+
export declare const CSS_VALUE_KIND: Readonly<Record<keyof PaintProps, 'colour' | 'length' | 'number' | 'keyword' | 'name'>>;
|
|
52
|
+
/**
|
|
53
|
+
* The properties whose value is SERIALISED rather than interpolated.
|
|
54
|
+
*
|
|
55
|
+
* PER PROPERTY, and that is the design rather than an accident of there being one
|
|
56
|
+
* entry: a global rule would have to decide what a comma or a space means without
|
|
57
|
+
* knowing which property it is in, and it means something different in every one.
|
|
58
|
+
* The table is the seam a second such property joins at, and
|
|
59
|
+
* {@link CSS_VALUE_KIND} is what makes joining it compulsory.
|
|
60
|
+
*
|
|
61
|
+
* Both routes to a `font-family` — a `style={{ fontFamily }}` object and a `font-*`
|
|
62
|
+
* utility resolving against `tokens.fontFamily` — arrive at `partitionPaint`, so
|
|
63
|
+
* one entry here covers both. That is why the serialisation lives at the emitter
|
|
64
|
+
* and not at either front end.
|
|
65
|
+
*/
|
|
66
|
+
export declare const CSS_VALUE: Readonly<Partial<Record<keyof PaintProps, (value: string) => string>>>;
|
|
35
67
|
/**
|
|
36
68
|
* One utility class → the paint properties it sets, or `null` for "not mine".
|
|
37
69
|
*
|
|
@@ -49,5 +81,10 @@ export declare const PAINT_PROPERTIES: ReadonlySet<string>;
|
|
|
49
81
|
* GTK's parser with no diagnostic, which is the exact silence the whole partition
|
|
50
82
|
* exists to avoid. The check is cheap and it has caught the one property that looks
|
|
51
83
|
* like paint and is not.
|
|
84
|
+
*
|
|
85
|
+
* The VALUE gets the same treatment, per property, through {@link CSS_VALUE}. A
|
|
86
|
+
* checked name with an unserialised value is only half the guard: GTK refused the
|
|
87
|
+
* whole rule for `font-family: Source Sans 3` while the property name was right
|
|
88
|
+
* (#1539), and the value is the half a project supplies verbatim.
|
|
52
89
|
*/
|
|
53
90
|
export declare function partitionPaint(props: PaintProps): readonly string[];
|