@gjsify/adwaita-core 0.64.13-next.283 → 0.64.14

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.
@@ -1,8 +1,8 @@
1
- import type { AdwMenuActions, AdwMenuInput, AdwMenuItem, AdwMenuItemState, AdwMenuModel, AdwMenuPath } from '../menu.js';
1
+ import type { AdwMenuActions, AdwMenuInput, AdwMenuItem, AdwMenuItemState, AdwMenuTree, AdwMenuPath } from '../menu.js';
2
2
  /** One {@link normalizeMenuModel} expectation. */
3
3
  export interface MenuNormalizeVector {
4
4
  input: AdwMenuInput;
5
- model: AdwMenuModel;
5
+ tree: AdwMenuTree;
6
6
  rule: string;
7
7
  }
8
8
  /**
@@ -17,7 +17,7 @@ export declare const MENU_NORMALIZE_VECTORS: ReadonlyArray<MenuNormalizeVector>;
17
17
  export interface MenuParseVector {
18
18
  /** The raw attribute (or `null` when absent). */
19
19
  json: string | null;
20
- model: AdwMenuModel;
20
+ tree: AdwMenuTree;
21
21
  rule: string;
22
22
  }
23
23
  /**
@@ -34,7 +34,7 @@ export interface MenuFlatRowVector {
34
34
  }
35
35
  /** One {@link flattenMenu} expectation. */
36
36
  export interface MenuFlattenVector {
37
- model: AdwMenuModel;
37
+ tree: AdwMenuTree;
38
38
  rows: readonly MenuFlatRowVector[];
39
39
  rule: string;
40
40
  }
@@ -103,7 +103,7 @@ export interface MenuItemStateVector {
103
103
  export declare const MENU_ITEM_STATE_VECTORS: ReadonlyArray<MenuItemStateVector>;
104
104
  /** One {@link menuRefusals} expectation. */
105
105
  export interface MenuRefusalVector {
106
- model: AdwMenuModel;
106
+ tree: AdwMenuTree;
107
107
  /** The paths that must be refused, in walk order. */
108
108
  paths: readonly AdwMenuPath[];
109
109
  rule: string;
@@ -131,3 +131,343 @@ export interface MenuLabelTextVector {
131
131
  * marker, which `adw_strip_mnemonic` (the core `stripMnemonic`) drops.
132
132
  */
133
133
  export declare const MENU_LABEL_TEXT_VECTORS: ReadonlyArray<MenuLabelTextVector>;
134
+ /** What a type-surface row asks of the implementation. */
135
+ export type MenuTypeQuery =
136
+ /** `new Gio.MenuModel()` — the abstract base. */
137
+ 'construct-abstract'
138
+ /** `new Gio.Menu().constructor.$gtype.name`. */
139
+ | 'gtype-name'
140
+ /** `GObject.type_parent(Gio.Menu.$gtype).name`. */
141
+ | 'parent-gtype-name'
142
+ /** `new Gio.Menu() instanceof Gio.MenuModel`. */
143
+ | 'instance-of-base'
144
+ /** `GObject.signal_lookup('items-changed', Gio.MenuModel.$gtype) !== 0`. */
145
+ | 'items-changed-on-base'
146
+ /** `new Gio.Menu().get_n_items()`. */
147
+ | 'fresh-n-items'
148
+ /** `new Gio.Menu().is_mutable()`. */
149
+ | 'fresh-is-mutable';
150
+ /** One type-surface fact a `Gio.Menu` twin has to reproduce. */
151
+ export interface MenuModelTypeVector {
152
+ query: MenuTypeQuery;
153
+ /** What the query answered, or `undefined` where it threw. */
154
+ answer?: string | number | boolean;
155
+ /** The message it threw, where it threw. */
156
+ throws?: string;
157
+ rule: string;
158
+ }
159
+ /**
160
+ * CORE-ONLY: a GType surface has no rendered form — a renderer can only observe it
161
+ * through the door that reads it, which is MENU_MODEL_DOOR_VECTORS, and both renderers
162
+ * drive that. Holding the same facts twice would assert the port's registration against
163
+ * itself in a place no widget can see.
164
+ *
165
+ * The GType surface: what a menu IS before anything is in it.
166
+ *
167
+ * The row a reader guesses wrong is the first one. `Gio.MenuModel` is an abstract CLASS,
168
+ * not an interface, so the twin declares it with `registerBaseClass` and has no
169
+ * `Implements` to answer for. ADR 0122's string list had the opposite shape:
170
+ * `Gio.ListModel` IS an interface, and the whole `ACCEPTED_INTERFACES` apparatus exists
171
+ * for it. A port that copied the string list wholesale would have invented an interface
172
+ * GTK does not have.
173
+ */
174
+ export declare const MENU_MODEL_TYPE_VECTORS: ReadonlyArray<MenuModelTypeVector>;
175
+ /** A mutator call, as data, so the table can be driven rather than read. */
176
+ export type MenuMutatorCall = {
177
+ readonly method: 'append' | 'prepend';
178
+ readonly label: string;
179
+ readonly action?: string;
180
+ } | {
181
+ readonly method: 'insert';
182
+ readonly position: number;
183
+ readonly label: string;
184
+ readonly action?: string;
185
+ } | {
186
+ readonly method: 'append_item' | 'prepend_item';
187
+ readonly label: string;
188
+ } | {
189
+ readonly method: 'insert_item';
190
+ readonly position: number;
191
+ readonly label: string;
192
+ } | {
193
+ readonly method: 'append_section' | 'append_submenu' | 'prepend_section' | 'prepend_submenu';
194
+ readonly label: string | null;
195
+ readonly children: readonly string[];
196
+ } | {
197
+ readonly method: 'insert_section' | 'insert_submenu';
198
+ readonly position: number;
199
+ readonly label: string | null;
200
+ readonly children: readonly string[];
201
+ } | {
202
+ readonly method: 'remove';
203
+ readonly position: number;
204
+ } | {
205
+ readonly method: 'remove_all';
206
+ } | {
207
+ readonly method: 'items_changed';
208
+ readonly position: number;
209
+ readonly removed: number;
210
+ readonly added: number;
211
+ };
212
+ /** One measured `Gio.Menu` mutator and the single `items-changed` it emits. */
213
+ export interface MenuMutatorEmissionVector {
214
+ /** How many plain items the menu holds before the call. */
215
+ before: number;
216
+ call: MenuMutatorCall;
217
+ /** `items-changed(position, removed, added)` — exactly ONE emission per call. */
218
+ emission: readonly [number, number, number];
219
+ /** How many items the menu holds after it. */
220
+ after: number;
221
+ rule: string;
222
+ }
223
+ /**
224
+ * CORE-ONLY: the emission is the CONTRACT a renderer consumes, and what a renderer can
225
+ * be held to is the reaction, not the triple — which is
226
+ * MENU_MODEL_NOTIFY_VECTORS and COMBO_ITEMS_CHANGED_VECTORS, both renderer-driven. A
227
+ * renderer suite asserting the triple would be asserting the model it was handed.
228
+ *
229
+ * Every mutator, the triple it emits, and the count it leaves behind.
230
+ *
231
+ * ONE emission per call, always: there is no mutator that batches and none that stays
232
+ * silent. The last two rows are the ones that separate a menu from a list store. A
233
+ * `remove_all()` on an EMPTY menu STILL emits `(0, 0, 0)` — measured — so the no-op skip
234
+ * that is right for `Gtk.StringList` (ADR 0122) is wrong here, and `items_changed` is a
235
+ * PUBLIC emitter that changes nothing, which is how a subclass reports a splice it made
236
+ * itself.
237
+ */
238
+ export declare const MENU_MUTATOR_EMISSION_VECTORS: ReadonlyArray<MenuMutatorEmissionVector>;
239
+ /** A GVariant the table hands to `set_attribute_value`, spelled as type + value. */
240
+ export interface MenuAttributeVariant {
241
+ /** A type string from ADR 0118 § 2's subset — `s`, `i`, `b` or `d`. */
242
+ readonly type: 's' | 'i' | 'b' | 'd';
243
+ readonly value: string | number | boolean;
244
+ }
245
+ /** How the attribute under test got onto the item. */
246
+ export type MenuAttributeSet =
247
+ /** `item.set_detailed_action(detailed)` — writes `action` and maybe `target`. */
248
+ {
249
+ readonly kind: 'detailed-action';
250
+ readonly detailed: string;
251
+ }
252
+ /** `item.set_label(label)`. */
253
+ | {
254
+ readonly kind: 'label';
255
+ readonly label: string;
256
+ }
257
+ /** `item.set_attribute_value(name, variant)`. */
258
+ | {
259
+ readonly kind: 'attribute';
260
+ readonly name: string;
261
+ readonly variant: MenuAttributeVariant;
262
+ }
263
+ /** Nothing was set — the row is about reading what was never written. */
264
+ | {
265
+ readonly kind: 'nothing';
266
+ };
267
+ /** One `get_item_attribute_value` read, and the variant type it answers with. */
268
+ export interface MenuAttributeVariantVector {
269
+ set: MenuAttributeSet;
270
+ /** The attribute name the read asks for. */
271
+ read: string;
272
+ /** `expected_type`, where the row is about passing one. */
273
+ expectedType?: string;
274
+ /** The type string the read answers with, or `null` for an empty read. */
275
+ type: string | null;
276
+ /** `deepUnpack()` of the answer, where the row is about the VALUE and not only the type. */
277
+ value?: string | number | boolean;
278
+ rule: string;
279
+ }
280
+ /**
281
+ * CORE-ONLY: an attribute's variant TYPE never reaches a rendered surface — what a
282
+ * renderer draws from it is held by MENU_NORMALIZE_VECTORS and MENU_ITEM_STATE_VECTORS,
283
+ * which both renderers drive.
284
+ *
285
+ * What type each menu attribute comes back as.
286
+ *
287
+ * `target` is the row that explains the table: its type is the TARGET's own, not a fixed
288
+ * `s`. A radio item written `win.zoom(2)` reads `i` and one written `app.view::list`
289
+ * reads `s`, which is why `resolveMenuItemState` compares the PRINTED target rather than
290
+ * the unpacked one. The two rows at the end are the empty reads, and neither throws — an
291
+ * unknown attribute name and a mismatched `expected_type` both answer `null`, so a
292
+ * surface cannot tell a typo from an absence and must not try.
293
+ */
294
+ export declare const MENU_ATTRIBUTE_VARIANT_VECTORS: ReadonlyArray<MenuAttributeVariantVector>;
295
+ /** What a link row asks of the implementation, against the scene its docblock describes. */
296
+ export type MenuLinkQuery =
297
+ /** `menu.get_item_link(0, 'section')` is the very section that was appended. */
298
+ 'section-identity'
299
+ /** Two reads of the same link are identity-equal. */
300
+ | 'repeat-read-identity'
301
+ /** `get_item_link(0, 'submenu')` on a SECTION item. */
302
+ | 'wrong-link-name'
303
+ /** `get_item_link(0, 'x-no-such-link')`. */
304
+ | 'unknown-link-name'
305
+ /** The link names `iterate_item_links(0)` yields. */
306
+ | 'link-iteration'
307
+ /** The attribute names `iterate_item_attributes(0)` yields. */
308
+ | 'attribute-iteration'
309
+ /** Root emissions counted while the SECTION is appended to. */
310
+ | 'link-emission-does-not-bubble'
311
+ /** The link's own count after that append. */
312
+ | 'link-count-after-append';
313
+ /** One link read, or the emission a link does not send. */
314
+ export interface MenuLinkVector {
315
+ query: MenuLinkQuery;
316
+ /** What it answered: a boolean, a count, or the names an iterator yielded. */
317
+ answer: boolean | number | readonly string[] | null;
318
+ rule: string;
319
+ }
320
+ /**
321
+ * CORE-ONLY: the non-bubbling emission is the reason `watchMenuModel` exists, and what a
322
+ * renderer owes is the REDRAW — held by MENU_TREE_VECTORS, which both renderers drive
323
+ * through their own widgets.
324
+ *
325
+ * Links, their identity, and the emission that stays where it was raised.
326
+ *
327
+ * THE SCENE every row runs against: a menu holding one `append_section('Edit', sec)` at
328
+ * position 0, where `sec` holds a single `append('Cut', 'app.cut')`.
329
+ *
330
+ * The last two rows are the whole reason `watchMenuModel` exists (ADR 0128 § 6). A
331
+ * section's own `items-changed` does NOT bubble to the menu holding it, while the link
332
+ * read reflects the change immediately — so a renderer connected only to the root shows a
333
+ * stale section for ever. That defect was unreachable while the model was an array,
334
+ * because every mutation went through a re-parse of the whole tree; it arrives WITH the
335
+ * real model, which is why the vector arrives with it too.
336
+ */
337
+ export declare const MENU_LINK_VECTORS: ReadonlyArray<MenuLinkVector>;
338
+ /** The widgets whose `menu-model` property was measured. */
339
+ export type MenuModelHolder = 'Adw.SplitButton' | 'Gtk.MenuButton';
340
+ /** One value in a write sequence: the name of a model, or the empty value. */
341
+ export type MenuModelWrite = 'A' | 'B' | null;
342
+ /** One widget `menu-model` write sequence and the `notify::menu-model` count per write. */
343
+ export interface MenuModelNotifyVector {
344
+ widget: MenuModelHolder;
345
+ /** The writes, in order. `A` and `B` are two DISTINCT models; `null` clears. */
346
+ writes: ReadonlyArray<MenuModelWrite>;
347
+ /** How many `notify::menu-model` each write produced, in order. */
348
+ notifies: ReadonlyArray<number>;
349
+ /** Set where the sequence ends by MUTATING the held model rather than writing one. */
350
+ mutateHeldModel?: boolean;
351
+ rule: string;
352
+ }
353
+ /**
354
+ * The identity guard, which the TWO libraries disagree about.
355
+ *
356
+ * Both widgets declare `menu-model` with `value_type=GMenuModel` and both take the same
357
+ * values, but `Adw.SplitButton` compares by POINTER and skips the notify for a repeat,
358
+ * while `Gtk.MenuButton` notifies unconditionally — including `null` over `null`.
359
+ * Measured, both of them, because a port guessing one way is wrong about one widget: a
360
+ * port that guards both is wrong about `Gtk.MenuButton`, and one that guards neither is
361
+ * wrong about `Adw.SplitButton`, whose notify rebuilds the popover.
362
+ *
363
+ * The last row is the one that puts `JSON.stringify` out of the picture for good. Mutating
364
+ * a HELD model is not a property change: the content arrives over `items-changed` and
365
+ * never over `notify`, so a widget keying its popover on a serialisation of the model
366
+ * (which `split-button.ts` did, as `menuKey`) redraws on writes that changed nothing and
367
+ * stays still for mutations that changed everything.
368
+ */
369
+ export declare const MENU_MODEL_NOTIFY_VECTORS: ReadonlyArray<MenuModelNotifyVector>;
370
+ /** One value written to a widget's `menu-model` property, and the door's answer. */
371
+ export interface MenuModelDoorVector {
372
+ /** What was assigned. */
373
+ write: 'menu' | 'null' | 'array' | 'plain-object' | 'wrong-gobject' | 'json-string';
374
+ /** The message the write threw, or `null` where it was accepted. */
375
+ error: string | null;
376
+ /**
377
+ * Where ONE surface answers differently, keyed by `AdwMenuSurface['name']`: `null`
378
+ * means that surface accepts the write, a string is a FRAGMENT of its refusal (the
379
+ * full message names the widget class, which belongs to the caller and not here).
380
+ *
381
+ * One row needs it, and the asymmetry is deliberate rather than a gap. The browser has
382
+ * a real `menu-model` ATTRIBUTE, so a JSON string is what markup actually delivers and
383
+ * the door parses it. NativeScript's XML Builder writes an attribute STRAIGHT onto the
384
+ * property, so the same string would arrive at the same door a code assignment uses —
385
+ * and ADR 0042 kept that door shut rather than open an XML seam no probe can prove.
386
+ * Same write, two answers, each measured against its own platform.
387
+ */
388
+ bySurface?: Readonly<Record<string, string | null>>;
389
+ rule: string;
390
+ }
391
+ /**
392
+ * What the `menu-model` door accepts, and the words it refuses with.
393
+ *
394
+ * The two GJS refusals are reproduced VERBATIM — an array and a plain object are both
395
+ * rejected by the GObject value check before any menu code sees them, which is what makes
396
+ * "assign an array to `menu-model`" a type error rather than a convenience the port could
397
+ * have kept. The `json-string` row is the port's OWN door and not GIO's: an authored
398
+ * `menu="…"` attribute is a string by the time it reaches a widget, and ADR 0128 § 7
399
+ * coerces it at the same seam ADR 0122 § 5 coerces a list at, which is the one place a
400
+ * ParamSpec cannot.
401
+ */
402
+ export declare const MENU_MODEL_DOOR_VECTORS: ReadonlyArray<MenuModelDoorVector>;
403
+ /** A behaviour the twin has to ANSWER for, named so a spec can drive it. */
404
+ export type MenuDivergenceProbe =
405
+ /** `get_item_attribute_value(99, 'label', null)` on a one-item menu. */
406
+ 'attribute-read-out-of-range'
407
+ /** `get_item_link(99, 'section')` on a one-item menu. */
408
+ | 'link-read-out-of-range'
409
+ /** `freeze()`, then `append` — `is_mutable()` and the resulting count. */
410
+ | 'freeze-does-not-lock'
411
+ /** `set_label` on an item ALREADY appended. */
412
+ | 'item-is-a-snapshot'
413
+ /** `set_attribute_value(name, null)`. */
414
+ | 'null-attribute-removes'
415
+ /** `set_attribute_value('x', 'str')` — a bare JS string where a Variant belongs. */
416
+ | 'bare-string-attribute-refused'
417
+ /** The serialised-GIcon `icon` attribute GIO writes and the subset has no type for. */
418
+ | 'icon-is-a-serialised-gicon'
419
+ /** `get_item_attribute` — the varargs form. */
420
+ | 'varargs-attribute-getter-absent'
421
+ /** `get_string` / `get_boolean` / `get_int32` on an attribute Variant. */
422
+ | 'typed-variant-getters-refused'
423
+ /** What `expected_type` is: `get_item_attribute_value(0, 'label', <type>)`. */
424
+ | 'variant-type-is-a-string';
425
+ /** One place the twin cannot copy GIO, with what each side does. */
426
+ export interface MenuModelDivergenceVector {
427
+ probe: MenuDivergenceProbe;
428
+ /** What GIO does, measured. */
429
+ gio: string;
430
+ /** What the twin does — the port's declared answer, which the spec drives. */
431
+ twin: string;
432
+ rule: string;
433
+ }
434
+ /**
435
+ * CORE-ONLY: a divergence is between the port and GIO, so there is no third surface to
436
+ * hold it against — the renderer-visible consequence is the snapshot read, which is
437
+ * MENU_TREE_VECTORS, and both renderers drive that.
438
+ *
439
+ * Where the port cannot copy GIO, and what it does instead.
440
+ *
441
+ * The first row is not a style choice. `get_item_attribute_value` past the end trips a C
442
+ * position assertion and takes the process with it — measured by crashing a probe — so
443
+ * there is no behaviour to reproduce and the twin has to PICK one. It picks the empty
444
+ * read, matching every other out-of-range read in this package. `freeze-does-not-lock` is
445
+ * the opposite of what the name suggests and is measured both ways: the flag flips and the
446
+ * mutators keep working, so a twin that refused mutation after a freeze would break a
447
+ * caller GIO lets through. The last three are the edges of ADR 0118 § 2's variant subset
448
+ * and of GJS's own introspection, and each is a deliberate narrowing rather than a gap
449
+ * someone forgot.
450
+ */
451
+ export declare const MENU_MODEL_DIVERGENCE_VECTORS: ReadonlyArray<MenuModelDivergenceVector>;
452
+ /** One `Gio` menu constant the twin has to export with the measured value. */
453
+ export interface MenuConstantVector {
454
+ /** The name on the `Gio` namespace. */
455
+ name: string;
456
+ /** Its value, measured. */
457
+ value: string | number;
458
+ rule: string;
459
+ }
460
+ /**
461
+ * CORE-ONLY: a constant has no rendered form at all. What a renderer does with the names
462
+ * it stands for is MENU_NORMALIZE_VECTORS, which both renderers drive through their own
463
+ * split button.
464
+ *
465
+ * The constants, because a caller writing `Gio.MENU_ATTRIBUTE_LABEL` instead of `'label'`
466
+ * has to get the same string from the port as from GJS.
467
+ *
468
+ * `MENU_EXPORTER_MAX_SECTION_SIZE` is the odd one out: nothing in the port enforces it and
469
+ * nothing should, since it is a D-Bus exporter limit. It is here so that a caller reading
470
+ * it is handed the real number rather than `undefined` — the failure mode of a port that
471
+ * exports the constants it happens to use.
472
+ */
473
+ export declare const MENU_CONSTANT_VECTORS: ReadonlyArray<MenuConstantVector>;
@@ -1,4 +1,4 @@
1
- import type { AdwMenuItem, AdwMenuModel, AdwMenuPath } from '../menu.js';
1
+ import type { AdwMenuItem, AdwMenuPath, AdwMenuTree } from '../menu.js';
2
2
  import type { AdwArrowIcon, SplitButtonContentMode, SplitButtonDirection, SplitButtonHalfState, SplitButtonProperty, SplitButtonStyleClass } from '../split-button.js';
3
3
  /** One mutation in a {@link SplitButtonContentVector} sequence, with its outcome. */
4
4
  export interface SplitButtonContentStep {
@@ -129,7 +129,7 @@ export interface SplitButtonRootStateVector {
129
129
  export declare const SPLIT_BUTTON_ROOT_STATE_VECTORS: ReadonlyArray<SplitButtonRootStateVector>;
130
130
  /** One activate-by-position expectation. */
131
131
  export interface SplitButtonMenuActivationVector {
132
- model: AdwMenuModel;
132
+ tree: AdwMenuTree;
133
133
  path: AdwMenuPath;
134
134
  /** The item that must be dispatched, or `null`. */
135
135
  activated: AdwMenuItem | null;
@@ -147,8 +147,11 @@ export declare const SPLIT_BUTTON_MENU_ACTIVATION_VECTORS: ReadonlyArray<SplitBu
147
147
  * a row with both also exercises the dissociation.
148
148
  */
149
149
  export interface SplitButtonDropdownVector {
150
- /** The menu model to install (empty = none). */
151
- model: AdwMenuModel;
150
+ /**
151
+ * The tree to BUILD a menu model from and install, or `null` to install no model at
152
+ * all. `[]` is a real but EMPTY menu, which is not the same row as `null` (ADR 0128).
153
+ */
154
+ tree: AdwMenuTree | null;
152
155
  /** Whether a popover is installed before it. */
153
156
  popover: boolean;
154
157
  /** Whether the dropdown half is live. */
@@ -159,7 +162,8 @@ export interface SplitButtonDropdownVector {
159
162
  }
160
163
  /**
161
164
  * "If the menu model is `NULL`, the dropdown is disabled",
162
- * and the same for the popover. An empty entry list is the renderers'
163
- * only spelling of "no menu", so it collapses onto the `NULL` case.
165
+ * and the same for the popover. `NULL` is the ONLY spelling of "no menu": a present but
166
+ * empty model leaves the dropdown live, which is why the port needed a real model to say
167
+ * it at all (ADR 0128).
164
168
  */
165
169
  export declare const SPLIT_BUTTON_DROPDOWN_VECTORS: ReadonlyArray<SplitButtonDropdownVector>;
@@ -12,6 +12,20 @@ export interface ForeignScalarProperty {
12
12
  readonly default?: string | boolean | number | null;
13
13
  readonly nick?: string;
14
14
  readonly blurb?: string;
15
+ /**
16
+ * The property emits `notify` ITSELF, so neither engine emits one for an ordinary write.
17
+ *
18
+ * This is `G_PARAM_EXPLICIT_NOTIFY`, and it is a declaration ABOUT THE REAL WIDGET, not a
19
+ * convenience: `Adw.ComboRow:selected` carries the flag upstream, and a write that moves the
20
+ * index there emits `selected` AND `selected-item` — an order no store-level "it changed, so
21
+ * notify" can produce. The widget that sets this owns both emissions, from `afterNotify` or
22
+ * from whatever state push stands in for the C setter. Measured, GJS 1.88 / libadwaita 1.9.4:
23
+ * `selected = 2` → `["selected", "selected-item"]`; out of range → nothing at all.
24
+ *
25
+ * Leave it off and the engine emits one `notify` per changed property, which is what every
26
+ * other declared property wants.
27
+ */
28
+ readonly explicitNotify?: boolean;
15
29
  }
16
30
  /**
17
31
  * A property holding another GObject, or `null` — `Adw.ComboRow:model` (ADR 0122 § 6).
@@ -33,6 +47,8 @@ export interface ForeignObjectProperty {
33
47
  readonly valueType: GType | GInterface;
34
48
  readonly nick?: string;
35
49
  readonly blurb?: string;
50
+ /** `G_PARAM_EXPLICIT_NOTIFY` — see {@link ForeignScalarProperty.explicitNotify}. */
51
+ readonly explicitNotify?: boolean;
36
52
  }
37
53
  /** One property a widget class declares at its `extends`. */
38
54
  export type ForeignProperty = ForeignScalarProperty | ForeignObjectProperty;