Skip to content

v1.4.0

Latest

Choose a tag to compare

@eugeniodepalo eugeniodepalo released this 25 Aug 20:06

Read the announcement: GTKX 1.4: Introducing @gtkx/navigation.

New Features

  • @gtkx/navigation brings React Navigation to native Adwaita widgets — The new, separately installed package builds on React Navigation 7's core and routers without a React Native dependency. createStackNavigator renders an AdwNavigationView, createTabNavigator renders an AdwViewStack with native switchers, createDrawerNavigator renders an AdwOverlaySplitView, and createSplitViewNavigator renders an adaptive AdwNavigationSplitView. It includes NavigationContainer, typed params and routes, dynamic and static configuration, nested navigators, native headers and back controls, lazy screens, transition/tab/drawer events, guarded native pops, refs, actions, hooks, and live Adwaita dark/high-contrast theme state. Add Adw-1 to libraries before codegen. (#557)
  • Opt-in v2 resource importsfuture.v2ResourceImports replaces the #data/* import map with relative, query-suffixed imports. ?resource bundles an asset and returns its GResource path, with ?resource=/exact/path for an explicit path; ?icon bundles an SVG, PNG, or XPM into the application's private icon theme and returns its icon name; ?url is available when an API needs a file; and relative .gschema.xml imports remain typed without a query. Assets and icons from dependencies work too, including lazy and side-effect-only imports. Development refreshes changed, added, and deleted resources, while production emits an automatically registered gtkx.gresource. The resource prefix derives from applicationId, is exported as resourceBasePath by virtual:gtkx-config, and becomes the default application element resourceBasePath. New scaffolds enable the flag. (#575)
  • Application icons become a project-wide build input — The new top-level applicationIcon setting accepts one SVG, PNG, or XPM file or a complete icon-theme tree. When it is omitted, GTKX uses a matching <applicationId>.svg, .png, or .xpm from the project root if exactly one exists; multiple matches require an explicit choice, and no match leaves the icon unset. Development, builds, and every deployment target now use the same source; theme sizes and variants survive packaging, and AppImage selects the best application-context icon. (#575)
  • Controlled GtkListBox selectionGtkListBox gains a selectedIndex prop. -1 or null clears the selection, a row that has not mounted yet is selected when it appears, and GTKX suppresses the row-selected caused by its own write. If GTK changes a controlled selection, GTKX restores the requested row on the next microtask without requiring a React render. A fractional index throws. (#560, #566)
  • Explicit minimum native-library versions in packagesdeploy.minimumLibraryVersions adds Debian and RPM constraints for the generated GTK and libadwaita dependencies. For example, { "Gtk-4.0": "4.14" } produces libgtk-4-1 (>= 4.14) and gtk4 >= 4.14; versions may include a patch segment. Codegen records the expanded library inventory, so deploy still identifies the libraries an app bound when the config uses libraries: "*" or the deployment skips its build. (#561, #566)
  • Pre-bound native struct fieldst.field and t.fieldAt compile a struct-field descriptor once and expose reusable fixed-offset and strided accessors. Generated/runtime consumers no longer reparse the descriptor on every read and write, and Cairo uses the new path for its buffer and record access. (#558)

Breaking Changes

  • deploy.icons moves to top-level applicationIcon — Move the same file or icon-theme path beside applicationId. Config validation now rejects deploy.icons; the top-level setting lets development, builds, and deployment consume one source. Projects that relied on 1.3's implicit data/icons directory must now set applicationIcon: "data/icons" or place exactly one application-ID-named image in the project root. Deploying without an icon still fails. (#575)
  • Non-GTK package dependencies become explicit — Automatic Debian and RPM mappings remain for Gtk-4.0 and Adw-1. GtkSourceView, WebKitGTK, and every other GIR library must now be named under deploy.depends, avoiding an incorrect guess about a distribution's package name. (#566)
  • Opting into v2 resource imports requires a source migration — Remove the package imports entry for #data/*; replace asset imports with relative ?resource, ?icon, or ?url imports; import schemas relatively without a query; and prepend resource:// only where an API requires a URI, because ?resource returns a path. A bare relative asset import deliberately fails while the flag is on. Legacy #data/* imports continue to work while the flag is off. (#575)
  • Application resource paths follow the configured application IDGtkApplication and AdwApplication now default resourceBasePath to the path derived from gtkx.config.ts's applicationId. If an application element overrides applicationId, also pass resourceBasePath when it should use a different resource tree. (#575)
  • Deploy build metadata is unified and versioneddist/gtkx-packages.json is replaced by dist/gtkx-schemas.json, which records both schemas and package metadata under a versioned format. A gtkx deploy --skip-build against a build made by GTKX 1.3 must be rebuilt once with 1.4. (#575)
  • Registered signal declarations use GLib spellingsregisterClass({ signals }) now rejects uppercase letters in signal keys. Rename a declaration such as dataChanged to data-changed or data_changed; JavaScript default-handler methods remain camel-cased, such as onDataChanged. (#566)
  • Borrowed callback structs expire with the native call — A boxed or plain struct lent by C now aliases the caller's memory, so writes made during the callback reach the caller and reads or writes after the callback returns throw. Code that retained a callback-owned record must copy the data it needs while the callback is active. (#558)
  • Unsafe Cairo ownership APIs are removedScaledFont.textToGlyphs, FontFace.createForFtFace, FontFace.createForPattern, Surface.mapToImage, and Surface.unmapImage are omitted because their allocation or borrow contracts cannot be represented safely by independently owned wrappers. Use PangoCairo for shaping and rich text layout, and modify a surface by drawing through its Context rather than mapping it.

Bug Fixes

  • Fixed popped navigation pages remaining retained, stack animation flags settling incorrectly, a closed drawer's goBack ignoring route history, split views revealing an empty pane, and a closing stack page rendering stale params. Navigator factory return types now distinguish dynamic and static configurations correctly. (#566)
  • Fixed controlled selection and route props trying to restore GTK state inside the same event that changed it. Drift is now corrected after the event, avoiding reentrant disagreement between GTK and React state. (#566)
  • Fixed prop, property, notify-detail, signal, and handler resolution for names escaped by codegen and names with digit boundaries such as enable-2d-canvas-acceleration. Signals declared on registered classes now work as JSX onX props, while an unknown handler prop fails deterministically. (#557, #566)
  • Fixed commit-time signal suppression hiding every notify emitted during a prop write. GTKX now suppresses only the property it writes, so a secondary property that the widget changes in reaction still reaches its onNotifyX handler. (#557, #566)
  • Fixed boxed native outputs whose registered GType is represented as a plain pointer, such as Gsk.RenderReplay, failing to use the GIR-declared release function on every decoding path. (#566)
  • Fixed lent boxed and plain-struct callback parameters being copied or left usable after their native lifetime. Mutations now reach the native caller while the callback is active and stale wrappers are rejected afterwards. (#558)
  • Fixed map and accessibility watchers remaining connected after their element was destroyed. (#566)

Full changelog: v1.3.0...v1.4.0