@gjsify/react-native 0.53.0 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/types/app-registry.d.ts +25 -34
- package/lib/types/primitives/table.d.ts +26 -31
- package/lib/types/router/tabs.d.ts +21 -30
- package/package.json +6 -6
|
@@ -8,17 +8,15 @@ export type ComponentProvider = () => ComponentType<Record<string, unknown>>;
|
|
|
8
8
|
* `runApplication`'s parameters: React Native's `initialProps` plus the window
|
|
9
9
|
* shape, over the WHOLE option set of the application shell this layer runs on.
|
|
10
10
|
*
|
|
11
|
-
* `Omit<AdwaitaAppOptions, 'createWindow'>` rather than a hand-copied list of the
|
|
12
|
-
*
|
|
13
|
-
* `
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* on this layer could not be driven from outside (#1455). `createWindow` is the one
|
|
21
|
-
* option this layer answers itself — it renders the registered component.
|
|
11
|
+
* `Omit<AdwaitaAppOptions, 'createWindow'>` rather than a hand-copied list of the fields worth
|
|
12
|
+
* forwarding, and that is the load-bearing part. The shell owns `devtools`, `about`, `onStartup`,
|
|
13
|
+
* `quitAction`, `flags` and `css`, each wired at the lifecycle moment only the shell knows —
|
|
14
|
+
* `installDevtools` in particular MUST run in `startup`, because the bus connection and object path
|
|
15
|
+
* exist only after the application has registered, which is inside `runAdwaitaApp` and unreachable
|
|
16
|
+
* from a consumer's entry file. A forwarding list would have to grow every time the shell gains an
|
|
17
|
+
* option, and the field nobody remembered to add is exactly the one a consumer needs: `devtools`
|
|
18
|
+
* was that field, and its absence is why an application on this layer could not be driven from
|
|
19
|
+
* outside (#1455). `createWindow` is the one option this layer answers itself.
|
|
22
20
|
*/
|
|
23
21
|
export interface RunApplicationOptions extends Omit<AdwaitaAppOptions, 'createWindow'> {
|
|
24
22
|
/**
|
|
@@ -45,36 +43,29 @@ export declare const windowChromeChecks: () => number;
|
|
|
45
43
|
/**
|
|
46
44
|
* Everything `runApplication` hands the application shell, as a VALUE.
|
|
47
45
|
*
|
|
48
|
-
* A named function with a spec rather than an object literal inline, because the
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* drive their own application at all (#1455). `app-registry.spec.ts` asserts that
|
|
53
|
-
* NOTHING is dropped, whatever it is, so re-introducing a field list fails for any
|
|
54
|
-
* option rather than only for the ones a test happened to name.
|
|
46
|
+
* A named function with a spec rather than an object literal inline, because the defect it
|
|
47
|
+
* prevents is invisible at the call site: an inline shape that listed `applicationId` and `css` and
|
|
48
|
+
* dropped every other field reads as complete and silently swallowed `devtools` (#1455).
|
|
49
|
+
* `app-registry.spec.ts` asserts that NOTHING is dropped, whatever it is.
|
|
55
50
|
*
|
|
56
|
-
* `createWindow` last: it is the one option this layer answers itself, and a
|
|
57
|
-
*
|
|
51
|
+
* `createWindow` last: it is the one option this layer answers itself, and a consumer's
|
|
52
|
+
* `createWindow` must not be able to replace the React root.
|
|
58
53
|
*/
|
|
59
54
|
export declare function toShellOptions(options: RunApplicationOptions, createWindow: (app: Adw.Application) => Gtk.Window): AdwaitaAppOptions;
|
|
60
55
|
/**
|
|
61
56
|
* Build the window, mount the registered component into it, publish the chrome.
|
|
62
57
|
*
|
|
63
|
-
* A NAMED FUNCTION AND NOT THE CLOSURE IT WAS, for the reason `window-chrome.ts` gives
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* two mapped `AdwHeaderBar`s: two sets of window controls, one dead close button
|
|
70
|
-
* (#1460).
|
|
58
|
+
* A NAMED FUNCTION AND NOT THE CLOSURE IT WAS, for the reason `window-chrome.ts` gives one
|
|
59
|
+
* function earlier: the vectors have to measure THIS composition, and a spec that rebuilt it by hand
|
|
60
|
+
* passes while the shipping shell drifts. That is #1549 as measured — deleting
|
|
61
|
+
* `provideWindowChrome(chrome, …)` from the render call below left `oxfmt` clean, `oxlint` at 0,
|
|
62
|
+
* `tsc` at 0 and the whole `@gjsify/react-native` suite green, ten hand-written window-chrome
|
|
63
|
+
* vectors included, while the running application drew two mapped `AdwHeaderBar`s (#1460).
|
|
71
64
|
*
|
|
72
|
-
* The seam is HERE and not one call further out because `runApplication` cannot be
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* timed-out case. Everything past this function is the shell's, and `toShellOptions`
|
|
77
|
-
* already holds the hand-over to it.
|
|
65
|
+
* The seam is HERE and not one call further out because `runApplication` cannot be entered from a
|
|
66
|
+
* spec at all: it runs a `Gio.Application`, and a nested `g_application_run` inside the test
|
|
67
|
+
* runner's own main loop never returns — measured, `g_application_run: assertion
|
|
68
|
+
* '!application->priv->must_quit_now' failed` and a timed-out case.
|
|
78
69
|
*/
|
|
79
70
|
export declare function mountApplicationRoot(app: Adw.Application, appKey: string, options: RunApplicationOptions, provider: ComponentProvider): Gtk.Window;
|
|
80
71
|
/**
|
|
@@ -73,24 +73,21 @@ export interface RefusedRoute {
|
|
|
73
73
|
/**
|
|
74
74
|
* A prop the LAYER answers by calling a method when a signal fires.
|
|
75
75
|
*
|
|
76
|
-
* `accessibilityLiveRegion` is the whole of it, and the shape is forced by the
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
* is an IMPERATIVE call: the caller supplies both the moment and the message.
|
|
76
|
+
* `accessibilityLiveRegion` is the whole of it, and the shape is forced by the mismatch between
|
|
77
|
+
* the two platforms' models. React Native's prop is a DECLARATION — "when this element's
|
|
78
|
+
* content changes, tell the user" — and the platform's accessibility layer watches for the
|
|
79
|
+
* change. GTK has no such declaration: since 4.14 it has `gtk_accessible_announce(self,
|
|
80
|
+
* message, priority)` (MEASURED on gtk 4.22.4 — on the `Gtk.Accessible` interface, so every
|
|
81
|
+
* widget has it), which is an IMPERATIVE call: the caller supplies both the moment and the
|
|
82
|
+
* message.
|
|
84
83
|
*
|
|
85
|
-
* So a live region can only be built where this layer knows both. It knows both on
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* common route refuses the prop by name rather than this route answering it.
|
|
84
|
+
* So a live region can only be built where this layer knows both. It knows both on exactly one
|
|
85
|
+
* primitive — `Text`, whose content IS one widget property, so `notify::label` is the moment
|
|
86
|
+
* and `label` is the message. Everywhere else the content is a SUBTREE and GTK emits nothing
|
|
87
|
+
* when one changes, which is why the common route refuses the prop by name.
|
|
90
88
|
*
|
|
91
|
-
* Like {@link FileRoute} and {@link GestureRoute}, the table holds the whole of the
|
|
92
|
-
*
|
|
93
|
-
* nothing under `primitives/` imports `gi://`.
|
|
89
|
+
* Like {@link FileRoute} and {@link GestureRoute}, the table holds the whole of the DECISION
|
|
90
|
+
* and none of the call: nothing under `primitives/` imports `gi://`.
|
|
94
91
|
*/
|
|
95
92
|
export interface AnnounceRoute {
|
|
96
93
|
readonly to: 'announce';
|
|
@@ -124,14 +121,13 @@ export interface IgnoredRoute {
|
|
|
124
121
|
/**
|
|
125
122
|
* A prop whose value becomes a `Gio.File` — and the reason it is its own kind.
|
|
126
123
|
*
|
|
127
|
-
* `Gtk.Picture:file` takes a `Gio.File`, an OBJECT, and building one needs
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* call: `Gio.File.new_for_path` or `Gio.File.new_for_uri`.
|
|
124
|
+
* `Gtk.Picture:file` takes a `Gio.File`, an OBJECT, and building one needs `gi://Gio`.
|
|
125
|
+
* Nothing under `primitives/` imports `gi://` (that is what makes L2 testable without a display
|
|
126
|
+
* and reusable by a binding that never loads GTK), so the table cannot produce the value —
|
|
127
|
+
* only the DECISION about it. So L2 does the whole of the decision, which is where every
|
|
128
|
+
* refusal lives (`http:` has no synchronous loader, a `require()` id has no asset registry, an
|
|
129
|
+
* array is a device-scale picker), and hands the framework layer a `{ kind, value }` pair it
|
|
130
|
+
* turns into one call.
|
|
135
131
|
*/
|
|
136
132
|
export interface FileRoute {
|
|
137
133
|
readonly to: 'file';
|
|
@@ -143,13 +139,12 @@ export interface FileRoute {
|
|
|
143
139
|
/**
|
|
144
140
|
* A prop bound through a gesture CONTROLLER rather than a signal on the widget.
|
|
145
141
|
*
|
|
146
|
-
* `TouchableWithoutFeedback` is the one primitive that needs it: it has no button
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
* applies: the table names the signal, the framework layer builds the controller.
|
|
142
|
+
* `TouchableWithoutFeedback` is the one primitive that needs it: it has no button chrome, so
|
|
143
|
+
* its widget is a `Gtk.Box`, and a box emits no `clicked` (measured — `Gtk.Button`'s two
|
|
144
|
+
* signals are `activate` and `clicked`, and a box has neither). The desktop answer is a
|
|
145
|
+
* `Gtk.GestureClick` added to the widget, whose `released` signal is the press completing. A
|
|
146
|
+
* controller is a constructed OBJECT, so the same rule as {@link FileRoute} applies: the table
|
|
147
|
+
* names the signal, the framework layer builds the controller.
|
|
153
148
|
*/
|
|
154
149
|
export interface GestureRoute {
|
|
155
150
|
readonly to: 'gesture';
|
|
@@ -8,12 +8,11 @@ export interface TabScreenOptions {
|
|
|
8
8
|
/**
|
|
9
9
|
* The switcher button's icon, as an icon-theme name (`go-home-symbolic`).
|
|
10
10
|
*
|
|
11
|
-
* NOT OPTIONAL DECORATION, which is why it is here rather than left to the
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* broken one".
|
|
11
|
+
* NOT OPTIONAL DECORATION, which is why it is here rather than left to the application.
|
|
12
|
+
* `Adw.ViewSwitcher` reserves the icon whether or not one is set — MEASURED, the same five
|
|
13
|
+
* tabs measure 317/647 px with icons and without — and a page with no `icon-name` draws the
|
|
14
|
+
* icon theme's missing-image glyph in the space it reserved. So the choice was never "icons or
|
|
15
|
+
* no icons"; it was "your icon or a broken one".
|
|
17
16
|
*
|
|
18
17
|
* A name the theme does not carry draws that same glyph, and nothing says so.
|
|
19
18
|
* `Gtk.IconTheme.has_icon()` is the check worth running when picking one.
|
|
@@ -23,33 +22,25 @@ export interface TabScreenOptions {
|
|
|
23
22
|
/**
|
|
24
23
|
* Put the stack on the focused page, or leave it alone because that page is not there yet.
|
|
25
24
|
*
|
|
26
|
-
* THE PRESENCE CHECK IS THE TERMINATING CONDITION, and the
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* if (stack.get_visible_child_name() !== focused) stack.set_visible_child_name(focused);
|
|
30
|
-
*
|
|
31
|
-
* reads as "set it unless it is already set", and it terminates only when the set TAKES.
|
|
25
|
+
* THE PRESENCE CHECK IS THE TERMINATING CONDITION, and the obvious guard is a bet rather than a
|
|
26
|
+
* test. Writing `if (stack.get_visible_child_name() !== focused) stack.set_visible_child_name(
|
|
27
|
+
* focused)` reads as "set it unless it is already set", and it terminates only when the set TAKES.
|
|
32
28
|
* MEASURED on libadwaita 1.9.3: `set_visible_child_name` with a name the stack does not hold
|
|
33
|
-
* changes nothing, emits NO `notify::visible-child-name`, and prints
|
|
34
|
-
*
|
|
35
|
-
* still
|
|
36
|
-
*
|
|
37
|
-
*
|
|
29
|
+
* changes nothing, emits NO `notify::visible-child-name`, and prints `Adwaita-WARNING: Child name
|
|
30
|
+
* '…' not found in AdwViewStack`. So the getter still answers the old page, the comparison is
|
|
31
|
+
* still unequal, and the effect — which has no dependency array on purpose, because a page can
|
|
32
|
+
* materialise on a render where `focused` did not change — repeats the failing call on every
|
|
33
|
+
* render for as long as the mismatch lasts.
|
|
38
34
|
*
|
|
39
|
-
* A focused route whose page React has not committed yet is an ORDINARY intermediate state,
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* which is what "not there yet" deserves — and one warning per render for a normal state is
|
|
43
|
-
* how a log stops being read.
|
|
35
|
+
* A focused route whose page React has not committed yet is an ORDINARY intermediate state, not a
|
|
36
|
+
* fault, so the answer is to do nothing and let the next render try — one warning per render for a
|
|
37
|
+
* normal state is how a log stops being read.
|
|
44
38
|
*
|
|
45
|
-
* AND THE SET HAS A SECOND WAY TO DO NOTHING, which is why presence alone is not the whole
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* caller would be told the stack shows `focused` while it shows the other page, and no log
|
|
51
|
-
* anywhere would disagree. Both no-op paths are therefore asked about BEFORE the write, which
|
|
52
|
-
* is also what keeps each one attributable to its own failing assertion.
|
|
39
|
+
* AND THE SET HAS A SECOND WAY TO DO NOTHING, which is why presence alone is not the whole gate.
|
|
40
|
+
* `adw_view_stack_set_visible_child_name` ends on `if (gtk_widget_get_visible (page->widget))
|
|
41
|
+
* set_visible_child (...)`, so a page that is there but HIDDEN changes nothing, emits no notify and
|
|
42
|
+
* — unlike the missing name — prints NOTHING AT ALL (measured). That is the same non-terminating
|
|
43
|
+
* state by the quieter road. Both no-op paths are therefore asked about BEFORE the write.
|
|
53
44
|
*
|
|
54
45
|
* @returns whether the stack now shows `focused`.
|
|
55
46
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.54.0",
|
|
4
4
|
"description": "The React Native view vocabulary rendered onto GTK4/Adwaita, over @gjsify/gtk-host",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "lib/esm/index.js",
|
|
@@ -120,8 +120,8 @@
|
|
|
120
120
|
"react-native"
|
|
121
121
|
],
|
|
122
122
|
"dependencies": {
|
|
123
|
-
"@gjsify/adwaita-app": "^0.
|
|
124
|
-
"@gjsify/gtk-host": "^0.
|
|
123
|
+
"@gjsify/adwaita-app": "^0.54.0",
|
|
124
|
+
"@gjsify/gtk-host": "^0.54.0"
|
|
125
125
|
},
|
|
126
126
|
"peerDependencies": {
|
|
127
127
|
"@react-navigation/core": "^7.21.13",
|
|
@@ -152,9 +152,9 @@
|
|
|
152
152
|
"@girs/gdk-4.0": "5.4.0",
|
|
153
153
|
"@girs/gjs": "5.4.0",
|
|
154
154
|
"@girs/gtk-4.0": "5.4.0",
|
|
155
|
-
"@gjsify/cli": "^0.
|
|
156
|
-
"@gjsify/rolldown-plugin-gjsify": "^0.
|
|
157
|
-
"@gjsify/unit": "^0.
|
|
155
|
+
"@gjsify/cli": "^0.54.0",
|
|
156
|
+
"@gjsify/rolldown-plugin-gjsify": "^0.54.0",
|
|
157
|
+
"@gjsify/unit": "^0.54.0",
|
|
158
158
|
"@react-navigation/core": "^7.21.13",
|
|
159
159
|
"@react-navigation/routers": "^7.6.4",
|
|
160
160
|
"@types/node": "^25.9.2",
|