react-native-gtkx 0.4.0-alpha.3 → 0.4.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.
Files changed (47) hide show
  1. package/dist/apis/host.gtkx.js.map +1 -1
  2. package/dist/components/modal.d.ts +1 -1
  3. package/dist/components/modal.js +16 -8
  4. package/dist/components/modal.js.map +1 -1
  5. package/dist/gtkx/bridge/adw.js.map +1 -1
  6. package/dist/gtkx/bridge/core.d.ts +1 -2
  7. package/dist/gtkx/bridge/core.js +2 -5
  8. package/dist/gtkx/bridge/core.js.map +1 -1
  9. package/dist/gtkx/bridge/geometry.js +1 -1
  10. package/dist/gtkx/bridge/geometry.js.map +1 -1
  11. package/dist/gtkx/bridge/layout-manager.js +18 -5
  12. package/dist/gtkx/bridge/layout-manager.js.map +1 -1
  13. package/dist/gtkx/bridge/slot-portal.js.map +1 -1
  14. package/dist/gtkx/bridge/svg-node.js +13 -6
  15. package/dist/gtkx/bridge/svg-node.js.map +1 -1
  16. package/dist/gtkx/bridge/view-box.js +18 -9
  17. package/dist/gtkx/bridge/view-box.js.map +1 -1
  18. package/dist/gtkx/bridge/widgets.generated.adw.js +1 -1
  19. package/dist/gtkx/bridge/widgets.generated.adw.js.map +1 -1
  20. package/dist/mcp/data/generated.d.ts +58 -42
  21. package/dist/mcp/data/generated.js +63 -43
  22. package/dist/mcp/data/generated.js.map +1 -1
  23. package/dist/runner/host-dev.js +5 -0
  24. package/dist/runner/host-dev.js.map +1 -1
  25. package/dist/runner/host.js +15 -0
  26. package/dist/runner/host.js.map +1 -1
  27. package/dist/runner/index.d.ts +27 -0
  28. package/dist/runner/index.js +206 -1
  29. package/dist/runner/index.js.map +1 -1
  30. package/dist/sea/assemble.d.ts +9 -0
  31. package/dist/sea/assemble.js +16 -3
  32. package/dist/sea/assemble.js.map +1 -1
  33. package/dist/sea/bundle.d.ts +37 -2
  34. package/dist/sea/bundle.js +76 -4
  35. package/dist/sea/bundle.js.map +1 -1
  36. package/dist/sea/native-shim.js +1 -1
  37. package/dist/sea/native-shim.js.map +1 -1
  38. package/dist/testing/index.js +28 -0
  39. package/dist/testing/index.js.map +1 -1
  40. package/dist/vite/index.js +3 -3
  41. package/dist/vite/index.js.map +1 -1
  42. package/dist/vitest/index.d.ts +1 -1
  43. package/dist/vitest/index.js.map +1 -1
  44. package/package.json +9 -9
  45. package/dist/gtkx/bridge/use-signal.d.ts +0 -2
  46. package/dist/gtkx/bridge/use-signal.js +0 -41
  47. package/dist/gtkx/bridge/use-signal.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"host.gtkx.js","sourceRoot":"","sources":["../../src/apis/host.gtkx.ts"],"names":[],"mappings":"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","sourcesContent":["// Production host adapter: the ONLY module under src/apis/ allowed to import\n// the gtkx bridge. Everything GTK-specific lives here; the API modules stay\n// pure and receive this object (or a mock in unit tests) via injection.\n\nimport type { SubscriptionHandle } from \"../contracts\"\nimport {\n adwAvailable,\n colorScheme,\n requireAdwGi,\n styleManager,\n} from \"../gtkx/bridge/adw\"\nimport {\n getPlainColorScheme,\n onPlainColorSchemeChange,\n setPlainColorScheme,\n} from \"../gtkx/bridge/color-scheme-portal\"\nimport { Gdk, Gio, Gtk, quit, toNumber } from \"../gtkx/bridge/index\"\nimport type {\n ColorSchemeName,\n Host,\n HostAlertRequest,\n ScaledSize,\n} from \"./host\"\n\nconst FALLBACK_METRICS: ScaledSize = {\n width: 0,\n height: 0,\n scale: 1,\n fontScale: 1,\n}\n\nconst getApplication = (): Gtk.Application | null =>\n Gio.Application.getDefault() as unknown as Gtk.Application | null\n\nconst getActiveAppWindow = (): Gtk.Window | null => {\n const app = getApplication()\n if (!app || typeof app.getActiveWindow !== \"function\") {\n return null\n }\n return app.getActiveWindow() ?? null\n}\n\nconst windowAt = (model: Gio.ListModel, index: number): Gtk.Window | null =>\n model.getItem(index) as unknown as Gtk.Window | null\n\n// The application's active window if any, otherwise the first toplevel. The\n// toplevel fallback covers the test harness, where windows exist without a\n// GtkApplication (`Gio.Application.getDefault()` is null there).\n// RN's Dimensions(\"window\") means the MAIN window: transient toplevels\n// (Modal → modal GtkWindow, dialogs) must never be resolved as \"the window\" —\n// an open modal becomes the active window and would shrink the app viewport\n// to the modal size.\nconst isMainWindow = (window: Gtk.Window): boolean =>\n window.getTransientFor() === null\n\nconst resolveWindow = (): Gtk.Window | null => {\n const active = getActiveAppWindow()\n if (active && isMainWindow(active)) {\n return active\n }\n const toplevels = Gtk.Window.getToplevels()\n const count = toNumber(toplevels.getNItems())\n let first: Gtk.Window | null = null\n for (let index = 0; index < count; index += 1) {\n const window = windowAt(toplevels, index)\n if (!window || !isMainWindow(window)) {\n continue\n }\n if (window.isActive()) {\n return window\n }\n first = first ?? window\n }\n return first\n}\n\nconst isAnyWindowActive = (): boolean => {\n const toplevels = Gtk.Window.getToplevels()\n const count = toNumber(toplevels.getNItems())\n for (let index = 0; index < count; index += 1) {\n if (windowAt(toplevels, index)?.isActive()) {\n return true\n }\n }\n return false\n}\n\nconst windowMetrics = (): ScaledSize => {\n const window = resolveWindow()\n if (!window) {\n return FALLBACK_METRICS\n }\n // RN's Dimensions(\"window\") is the app viewport: the window CHILD's\n // allocation (the content area under the headerbar), not the window widget\n // size. Falls back to the window size before the first allocation.\n const child = window.getChild()\n const childAllocation = child?.getAllocation()\n const allocatedWidth =\n childAllocation && childAllocation.width > 0\n ? toNumber(childAllocation.width)\n : toNumber(window.getWidth())\n const allocatedHeight =\n childAllocation && childAllocation.height > 0\n ? toNumber(childAllocation.height)\n : toNumber(window.getHeight())\n // Before the first allocation everything reports 0 — fall back to\n // the requested default size (which GTK4 also keeps updated on resize).\n const width =\n allocatedWidth > 0\n ? allocatedWidth\n : Math.max(toNumber(window.defaultWidth ?? 0), 0)\n const height =\n allocatedHeight > 0\n ? allocatedHeight\n : Math.max(toNumber(window.defaultHeight ?? 0), 0)\n return {\n width,\n height,\n scale: toNumber(window.getScaleFactor()),\n fontScale: 1,\n }\n}\n\nconst screenMetrics = (): ScaledSize => {\n const display = Gdk.Display.getDefault()\n if (!display) {\n return windowMetrics()\n }\n const monitors = display.getMonitors()\n if (toNumber(monitors.getNItems()) === 0) {\n return windowMetrics()\n }\n const monitor = monitors.getItem(0) as unknown as Gdk.Monitor | null\n if (!monitor) {\n return windowMetrics()\n }\n const geometry = monitor.getGeometry()\n return {\n width: toNumber(geometry.width),\n height: toNumber(geometry.height),\n scale: toNumber(monitor.getScaleFactor()),\n fontScale: 1,\n }\n}\n\n// GtkNative.getSurface is an interface method merged onto Gtk.Window at\n// runtime via mixins; accessed defensively to stay typecheckable either way.\nconst surfaceOf = (window: Gtk.Window): Gdk.Surface | null => {\n const native = window as unknown as { getSurface?: () => Gdk.Surface | null }\n return typeof native.getSurface === \"function\"\n ? (native.getSurface() ?? null)\n : null\n}\n\n// Tracks the \"current\" window across creation/destruction/focus moves:\n// listens on the given signals of the resolved window (and, when requested,\n// its GdkSurface) plus the toplevel list model, re-resolving and re-attaching\n// whenever the tracked window may have changed. Modules dedupe, so\n// over-notifying is fine.\n//\n// Why the surface: notify::default-width fires when setDefaultSize() is\n// called, i.e. before the compositor actually resizes the surface — the\n// allocated size (what Dimensions reports) only changes when the surface\n// does. And GdkSurface notify::width/height fires at configure time, still\n// before the widget allocation pass, so the \"layout\" signal is also needed:\n// it is emitted during the frame's layout phase and — because GTK's own\n// relayout handler is connected first — our handler observes the updated\n// allocation. The module dedupes, so early/no-op emissions cost nothing.\nconst watchWindow = (\n windowSignals: readonly string[],\n surfaceSignals: readonly string[],\n notify: () => void,\n): SubscriptionHandle => {\n let window: Gtk.Window | null = null\n let surface: Gdk.Surface | null = null\n\n const attachWindow = (): void => {\n if (!window) {\n return\n }\n for (const signal of windowSignals) {\n window.on(signal, onSignal)\n }\n }\n\n const detachWindow = (): void => {\n if (!window) {\n return\n }\n for (const signal of windowSignals) {\n window.off(signal, onSignal)\n }\n }\n\n const attachSurface = (): void => {\n if (!surface) {\n return\n }\n for (const signal of surfaceSignals) {\n surface.on(signal, onSignal)\n }\n }\n\n const detachSurface = (): void => {\n if (!surface) {\n return\n }\n for (const signal of surfaceSignals) {\n surface.off(signal, onSignal)\n }\n }\n\n const syncTargets = (): void => {\n const nextWindow = resolveWindow()\n if (nextWindow !== window) {\n detachWindow()\n window = nextWindow\n attachWindow()\n }\n const nextSurface =\n window && surfaceSignals.length > 0 ? surfaceOf(window) : null\n if (nextSurface !== surface) {\n detachSurface()\n surface = nextSurface\n attachSurface()\n }\n }\n\n const onSignal = (): void => {\n syncTargets()\n notify()\n }\n\n const toplevels = Gtk.Window.getToplevels()\n const onToplevelsChanged = (): void => {\n syncTargets()\n notify()\n }\n toplevels.on(\"items-changed\", onToplevelsChanged)\n syncTargets()\n\n return {\n remove: () => {\n detachWindow()\n detachSurface()\n window = null\n surface = null\n toplevels.off(\"items-changed\", onToplevelsChanged)\n },\n }\n}\n\n// realize/map re-run target resolution so the surface listeners attach as\n// soon as the surface exists.\nconst WINDOW_SIZE_SIGNALS = [\n \"notify::default-width\",\n \"notify::default-height\",\n \"realize\",\n \"map\",\n] as const\n\nconst SURFACE_SIZE_SIGNALS = [\n \"notify::width\",\n \"notify::height\",\n \"layout\",\n] as const\n\nconst WINDOW_ACTIVE_SIGNALS = [\"notify::is-active\"] as const\n\nconst gtkVersion = (): string =>\n `${toNumber(Gtk.getMajorVersion())}.${toNumber(Gtk.getMinorVersion())}.${toNumber(Gtk.getMicroVersion())}`\n\n// AdwStyleManager is the only thing that decides the palette here, and it is\n// enough on its own — appearance.test.tsx asserts that a real widget's\n// computed foreground flips with it. This used to also write the classic\n// GtkSettings:gtk-application-prefer-dark-theme, guarding against Adwaita\n// not restyling a GtkApplication (we do not use AdwApplication). Under\n// libadwaita that write is inert: adw_init() takes the color scheme over,\n// answers the setting with \"unsupported ... use AdwStyleManager:color-scheme\n// instead\" and keeps its own value, so all the duplicate ever produced was a\n// warning per call — seven per test run.\nconst setColorSchemeAdw = (scheme: ColorSchemeName | null): void => {\n const manager = styleManager()\n const { ColorScheme } = requireAdwGi(\"Appearance\")\n if (scheme === \"dark\") {\n manager.setColorScheme(ColorScheme.FORCE_DARK)\n } else if (scheme === \"light\") {\n manager.setColorScheme(ColorScheme.FORCE_LIGHT)\n } else {\n manager.setColorScheme(ColorScheme.DEFAULT)\n }\n}\n\nconst onColorSchemeChangeAdw = (notify: () => void): SubscriptionHandle => {\n const manager = styleManager()\n const listener = (): void => notify()\n manager.on(\"notify::dark\", listener)\n return { remove: () => manager.off(\"notify::dark\", listener) }\n}\n\n// Without Adw-1 (adwAvailable() === false): the org.freedesktop.appearance\n// portal, falling back to Gtk.Settings — see gtkx/bridge/color-scheme-portal.ts\n// for the two-tier mechanism and .claude/epics/adw-optional/004.md for why.\nconst setColorScheme = (scheme: ColorSchemeName | null): void =>\n adwAvailable() ? setColorSchemeAdw(scheme) : setPlainColorScheme(scheme)\n\nconst onColorSchemeChange = (notify: () => void): SubscriptionHandle =>\n adwAvailable()\n ? onColorSchemeChangeAdw(notify)\n : onPlainColorSchemeChange(notify)\n\nconst showAlertAdw = async (\n request: HostAlertRequest,\n): Promise<string | null> => {\n const { AlertDialog, ResponseAppearance } = requireAdwGi(\"Alert\")\n const dialog = new AlertDialog()\n dialog.setHeading(request.title)\n if (request.message !== undefined && request.message.length > 0) {\n dialog.setBody(request.message)\n }\n let closeResponse: string | null = null\n for (const button of request.buttons) {\n dialog.addResponse(button.id, button.label)\n if (button.style === \"destructive\") {\n dialog.setResponseAppearance(button.id, ResponseAppearance.DESTRUCTIVE)\n }\n if (button.isPreferred) {\n dialog.setResponseAppearance(button.id, ResponseAppearance.SUGGESTED)\n dialog.setDefaultResponse(button.id)\n }\n if (button.style === \"cancel\") {\n closeResponse = button.id\n }\n }\n if (closeResponse !== null) {\n // Esc / close maps onto the cancel button, like RN's cancel semantics.\n dialog.setCloseResponse(closeResponse)\n } else if (!request.cancelable) {\n // No cancel button and not cancelable: block Esc-dismissal. Responses\n // still close the dialog (they bypass the can-close guard).\n dialog.setCanClose(false)\n }\n const response = await dialog.choose(resolveWindow())\n // Anything that is not one of our buttons (e.g. the built-in \"close\"\n // response) is a dismissal.\n return request.buttons.some((button) => button.id === response)\n ? response\n : null\n}\n\n// Without Adw-1: Gtk.AlertDialog (GTK >= 4.10) — index-based rather than\n// Adw's string response ids, so the button's position in request.buttons IS\n// its Gtk.AlertDialog index; no id bookkeeping needed. What is LOST: Adw's\n// ResponseAppearance (DESTRUCTIVE/SUGGESTED) has no Gtk.AlertDialog\n// equivalent at all — every button renders the same, undocumented-away in\n// docs/api.md's Alert row rather than silently dropped. Default/cancel\n// mapping is preserved via defaultButton/cancelButton, same idea as Adw's\n// defaultResponse/closeResponse above.\nconst showAlertPlain = async (\n request: HostAlertRequest,\n): Promise<string | null> => {\n const dialog = new Gtk.AlertDialog({\n message: request.title,\n detail: request.message ?? \"\",\n buttons: request.buttons.map((button) => button.label),\n modal: true,\n })\n const preferredIndex = request.buttons.findIndex(\n (button) => button.isPreferred,\n )\n if (preferredIndex >= 0) {\n dialog.setDefaultButton(preferredIndex)\n }\n const cancelIndex = request.buttons.findIndex(\n (button) => button.style === \"cancel\",\n )\n if (cancelIndex >= 0) {\n // Esc maps onto the cancel button, same as the Adw path's closeResponse.\n dialog.setCancelButton(cancelIndex)\n } else if (!request.cancelable && process.env.NODE_ENV !== \"production\") {\n // Unlike Adw.AlertDialog.setCanClose(false), Gtk.AlertDialog has no way\n // to block Esc/window-close dismissal outright — with no cancel button\n // set, GTK closes the dialog anyway and rejects choose() with\n // Gtk.DialogError.DISMISSED (caught below, mapped to the same null\n // dismissal cancelable: true would produce). Documented in docs/api.md;\n // an app that truly needs to block dismissal should add a cancel\n // button on both profiles rather than relying on cancelable: false alone.\n console.warn(\n '[react-native-gtkx] Alert.alert was called with cancelable: false and no \"cancel\" ' +\n \"style button. The plain-GTK profile's Gtk.AlertDialog fallback cannot block \" +\n \"Esc/window-close dismissal the way Adw.AlertDialog does — the dialog stays \" +\n \"dismissable. Add a cancel-style button for identical behavior on both profiles.\",\n )\n }\n try {\n const index = await dialog.choose(resolveWindow())\n return request.buttons[index]?.id ?? null\n } catch {\n // Dismissed (Esc / window-close) with no valid cancel button — the\n // plain-profile equivalent of the Adw path's unmatched \"close\" response.\n return null\n }\n}\n\nconst showAlert = async (request: HostAlertRequest): Promise<string | null> =>\n adwAvailable() ? showAlertAdw(request) : showAlertPlain(request)\n\nconst launchUri = async (uri: string): Promise<void> => {\n const launcher = new Gtk.UriLauncher({ uri })\n // Promisified by the gi codegen; rejects with the GError on failure.\n await launcher.launch(resolveWindow())\n}\n\n// The default widget direction is GTK's read of the locale text direction.\nconst isRTL = (): boolean => {\n try {\n return Gtk.Widget.getDefaultDirection() === Gtk.TextDirection.RTL\n } catch {\n return false\n }\n}\n\nexport const gtkxHost: Host = {\n gtkVersion,\n getWindowMetrics: windowMetrics,\n getScreenMetrics: screenMetrics,\n onMetricsChange: (notify) =>\n watchWindow(WINDOW_SIZE_SIGNALS, SURFACE_SIZE_SIGNALS, notify),\n getColorScheme: () =>\n adwAvailable() ? colorScheme() : getPlainColorScheme(),\n setColorScheme,\n onColorSchemeChange,\n isActive: isAnyWindowActive,\n onActiveChange: (notify) => watchWindow(WINDOW_ACTIVE_SIGNALS, [], notify),\n showAlert,\n launchUri,\n isRTL,\n exitApp: () => quit(),\n}\n"]}
1
+ {"version":3,"file":"host.gtkx.js","sourceRoot":"","sources":["../../src/apis/host.gtkx.ts"],"names":[],"mappings":"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","sourcesContent":["// Production host adapter: the ONLY module under src/apis/ allowed to import\n// the gtkx bridge. Everything GTK-specific lives here; the API modules stay\n// pure and receive this object (or a mock in unit tests) via injection.\n\nimport type { SubscriptionHandle } from \"../contracts\"\nimport {\n adwAvailable,\n colorScheme,\n requireAdwGi,\n styleManager,\n} from \"../gtkx/bridge/adw\"\nimport {\n getPlainColorScheme,\n onPlainColorSchemeChange,\n setPlainColorScheme,\n} from \"../gtkx/bridge/color-scheme-portal\"\nimport { Gdk, Gio, Gtk, quit, toNumber } from \"../gtkx/bridge/index\"\nimport type {\n ColorSchemeName,\n Host,\n HostAlertRequest,\n ScaledSize,\n} from \"./host\"\n\nconst FALLBACK_METRICS: ScaledSize = {\n width: 0,\n height: 0,\n scale: 1,\n fontScale: 1,\n}\n\nconst getApplication = (): Gtk.Application | null =>\n Gio.Application.getDefault() as unknown as Gtk.Application | null\n\nconst getActiveAppWindow = (): Gtk.Window | null => {\n const app = getApplication()\n if (!app || typeof app.getActiveWindow !== \"function\") {\n return null\n }\n return app.getActiveWindow() ?? null\n}\n\nconst windowAt = (model: Gio.ListModel, index: number): Gtk.Window | null =>\n model.getItem(index) as unknown as Gtk.Window | null\n\n// The application's active window if any, otherwise the first toplevel. The\n// toplevel fallback covers the test harness, where windows exist without a\n// GtkApplication (`Gio.Application.getDefault()` is null there).\n// RN's Dimensions(\"window\") means the MAIN window: transient toplevels\n// (Modal → modal GtkWindow, dialogs) must never be resolved as \"the window\" —\n// an open modal becomes the active window and would shrink the app viewport\n// to the modal size.\nconst isMainWindow = (window: Gtk.Window): boolean =>\n window.getTransientFor() === null\n\nconst resolveWindow = (): Gtk.Window | null => {\n const active = getActiveAppWindow()\n if (active && isMainWindow(active)) {\n return active\n }\n const toplevels = Gtk.Window.getToplevels()\n const count = toNumber(toplevels.getNItems())\n let first: Gtk.Window | null = null\n for (let index = 0; index < count; index += 1) {\n const window = windowAt(toplevels, index)\n if (!window || !isMainWindow(window)) {\n continue\n }\n if (window.isActive()) {\n return window\n }\n first = first ?? window\n }\n return first\n}\n\nconst isAnyWindowActive = (): boolean => {\n const toplevels = Gtk.Window.getToplevels()\n const count = toNumber(toplevels.getNItems())\n for (let index = 0; index < count; index += 1) {\n if (windowAt(toplevels, index)?.isActive()) {\n return true\n }\n }\n return false\n}\n\nconst windowMetrics = (): ScaledSize => {\n const window = resolveWindow()\n if (!window) {\n return FALLBACK_METRICS\n }\n // RN's Dimensions(\"window\") is the app viewport: the window CHILD's\n // allocation (the content area under the headerbar), not the window widget\n // size. Falls back to the window size before the first allocation.\n const child = window.getChild()\n const childAllocation = child?.getAllocation()\n const allocatedWidth =\n childAllocation && childAllocation.width > 0\n ? toNumber(childAllocation.width)\n : toNumber(window.getWidth())\n const allocatedHeight =\n childAllocation && childAllocation.height > 0\n ? toNumber(childAllocation.height)\n : toNumber(window.getHeight())\n // Before the first allocation everything reports 0 — fall back to\n // the requested default size (which GTK4 also keeps updated on resize).\n const width =\n allocatedWidth > 0\n ? allocatedWidth\n : Math.max(toNumber(window.defaultWidth ?? 0), 0)\n const height =\n allocatedHeight > 0\n ? allocatedHeight\n : Math.max(toNumber(window.defaultHeight ?? 0), 0)\n return {\n width,\n height,\n scale: toNumber(window.getScaleFactor()),\n fontScale: 1,\n }\n}\n\nconst screenMetrics = (): ScaledSize => {\n const display = Gdk.Display.getDefault()\n if (!display) {\n return windowMetrics()\n }\n const monitors = display.getMonitors()\n if (toNumber(monitors.getNItems()) === 0) {\n return windowMetrics()\n }\n const monitor = monitors.getItem(0) as unknown as Gdk.Monitor | null\n if (!monitor) {\n return windowMetrics()\n }\n const geometry = monitor.getGeometry()\n return {\n width: toNumber(geometry.width),\n height: toNumber(geometry.height),\n scale: toNumber(monitor.getScaleFactor()),\n fontScale: 1,\n }\n}\n\n// GtkNative.getSurface is an interface method merged onto Gtk.Window at\n// runtime via mixins; accessed defensively to stay typecheckable either way.\nconst surfaceOf = (window: Gtk.Window): Gdk.Surface | null => {\n const native = window as unknown as { getSurface?: () => Gdk.Surface | null }\n return typeof native.getSurface === \"function\"\n ? (native.getSurface() ?? null)\n : null\n}\n\n// Tracks the \"current\" window across creation/destruction/focus moves:\n// listens on the given signals of the resolved window (and, when requested,\n// its GdkSurface) plus the toplevel list model, re-resolving and re-attaching\n// whenever the tracked window may have changed. Modules dedupe, so\n// over-notifying is fine.\n//\n// Why the surface: notify::default-width fires when setDefaultSize() is\n// called, i.e. before the compositor actually resizes the surface — the\n// allocated size (what Dimensions reports) only changes when the surface\n// does. And GdkSurface notify::width/height fires at configure time, still\n// before the widget allocation pass, so the \"layout\" signal is also needed:\n// it is emitted during the frame's layout phase and — because GTK's own\n// relayout handler is connected first — our handler observes the updated\n// allocation. The module dedupes, so early/no-op emissions cost nothing.\nconst watchWindow = (\n windowSignals: readonly (keyof Gtk.WindowSignals)[],\n surfaceSignals: readonly (keyof Gdk.SurfaceSignals)[],\n notify: () => void,\n): SubscriptionHandle => {\n let window: Gtk.Window | null = null\n let surface: Gdk.Surface | null = null\n\n const attachWindow = (): void => {\n if (!window) {\n return\n }\n for (const signal of windowSignals) {\n window.on(signal, onSignal)\n }\n }\n\n const detachWindow = (): void => {\n if (!window) {\n return\n }\n for (const signal of windowSignals) {\n window.off(signal, onSignal)\n }\n }\n\n const attachSurface = (): void => {\n if (!surface) {\n return\n }\n for (const signal of surfaceSignals) {\n surface.on(signal, onSignal)\n }\n }\n\n const detachSurface = (): void => {\n if (!surface) {\n return\n }\n for (const signal of surfaceSignals) {\n surface.off(signal, onSignal)\n }\n }\n\n const syncTargets = (): void => {\n const nextWindow = resolveWindow()\n if (nextWindow !== window) {\n detachWindow()\n window = nextWindow\n attachWindow()\n }\n const nextSurface =\n window && surfaceSignals.length > 0 ? surfaceOf(window) : null\n if (nextSurface !== surface) {\n detachSurface()\n surface = nextSurface\n attachSurface()\n }\n }\n\n const onSignal = (): void => {\n syncTargets()\n notify()\n }\n\n const toplevels = Gtk.Window.getToplevels()\n const onToplevelsChanged = (): void => {\n syncTargets()\n notify()\n }\n toplevels.on(\"items-changed\", onToplevelsChanged)\n syncTargets()\n\n return {\n remove: () => {\n detachWindow()\n detachSurface()\n window = null\n surface = null\n toplevels.off(\"items-changed\", onToplevelsChanged)\n },\n }\n}\n\n// realize/map re-run target resolution so the surface listeners attach as\n// soon as the surface exists.\nconst WINDOW_SIZE_SIGNALS = [\n \"notify::default-width\",\n \"notify::default-height\",\n \"realize\",\n \"map\",\n] as const\n\nconst SURFACE_SIZE_SIGNALS = [\n \"notify::width\",\n \"notify::height\",\n \"layout\",\n] as const\n\nconst WINDOW_ACTIVE_SIGNALS = [\"notify::is-active\"] as const\n\nconst gtkVersion = (): string =>\n `${toNumber(Gtk.getMajorVersion())}.${toNumber(Gtk.getMinorVersion())}.${toNumber(Gtk.getMicroVersion())}`\n\n// AdwStyleManager is the only thing that decides the palette here, and it is\n// enough on its own — appearance.test.tsx asserts that a real widget's\n// computed foreground flips with it. This used to also write the classic\n// GtkSettings:gtk-application-prefer-dark-theme, guarding against Adwaita\n// not restyling a GtkApplication (we do not use AdwApplication). Under\n// libadwaita that write is inert: adw_init() takes the color scheme over,\n// answers the setting with \"unsupported ... use AdwStyleManager:color-scheme\n// instead\" and keeps its own value, so all the duplicate ever produced was a\n// warning per call — seven per test run.\nconst setColorSchemeAdw = (scheme: ColorSchemeName | null): void => {\n const manager = styleManager()\n const { ColorScheme } = requireAdwGi(\"Appearance\")\n if (scheme === \"dark\") {\n manager.setColorScheme(ColorScheme.FORCE_DARK)\n } else if (scheme === \"light\") {\n manager.setColorScheme(ColorScheme.FORCE_LIGHT)\n } else {\n manager.setColorScheme(ColorScheme.DEFAULT)\n }\n}\n\nconst onColorSchemeChangeAdw = (notify: () => void): SubscriptionHandle => {\n const manager = styleManager()\n const listener = (): void => notify()\n manager.on(\"notify::dark\", listener)\n return { remove: () => manager.off(\"notify::dark\", listener) }\n}\n\n// Without Adw-1 (adwAvailable() === false): the org.freedesktop.appearance\n// portal, falling back to Gtk.Settings — see gtkx/bridge/color-scheme-portal.ts\n// for the two-tier mechanism and .claude/epics/adw-optional/004.md for why.\nconst setColorScheme = (scheme: ColorSchemeName | null): void =>\n adwAvailable() ? setColorSchemeAdw(scheme) : setPlainColorScheme(scheme)\n\nconst onColorSchemeChange = (notify: () => void): SubscriptionHandle =>\n adwAvailable()\n ? onColorSchemeChangeAdw(notify)\n : onPlainColorSchemeChange(notify)\n\nconst showAlertAdw = async (\n request: HostAlertRequest,\n): Promise<string | null> => {\n const { AlertDialog, ResponseAppearance } = requireAdwGi(\"Alert\")\n const dialog = new AlertDialog()\n dialog.setHeading(request.title)\n if (request.message !== undefined && request.message.length > 0) {\n dialog.setBody(request.message)\n }\n let closeResponse: string | null = null\n for (const button of request.buttons) {\n dialog.addResponse(button.id, button.label)\n if (button.style === \"destructive\") {\n dialog.setResponseAppearance(button.id, ResponseAppearance.DESTRUCTIVE)\n }\n if (button.isPreferred) {\n dialog.setResponseAppearance(button.id, ResponseAppearance.SUGGESTED)\n dialog.setDefaultResponse(button.id)\n }\n if (button.style === \"cancel\") {\n closeResponse = button.id\n }\n }\n if (closeResponse !== null) {\n // Esc / close maps onto the cancel button, like RN's cancel semantics.\n dialog.setCloseResponse(closeResponse)\n } else if (!request.cancelable) {\n // No cancel button and not cancelable: block Esc-dismissal. Responses\n // still close the dialog (they bypass the can-close guard).\n dialog.setCanClose(false)\n }\n const response = await dialog.choose(resolveWindow())\n // Anything that is not one of our buttons (e.g. the built-in \"close\"\n // response) is a dismissal.\n return request.buttons.some((button) => button.id === response)\n ? response\n : null\n}\n\n// Without Adw-1: Gtk.AlertDialog (GTK >= 4.10) — index-based rather than\n// Adw's string response ids, so the button's position in request.buttons IS\n// its Gtk.AlertDialog index; no id bookkeeping needed. What is LOST: Adw's\n// ResponseAppearance (DESTRUCTIVE/SUGGESTED) has no Gtk.AlertDialog\n// equivalent at all — every button renders the same, undocumented-away in\n// docs/api.md's Alert row rather than silently dropped. Default/cancel\n// mapping is preserved via defaultButton/cancelButton, same idea as Adw's\n// defaultResponse/closeResponse above.\nconst showAlertPlain = async (\n request: HostAlertRequest,\n): Promise<string | null> => {\n const dialog = new Gtk.AlertDialog({\n message: request.title,\n detail: request.message ?? \"\",\n buttons: request.buttons.map((button) => button.label),\n modal: true,\n })\n const preferredIndex = request.buttons.findIndex(\n (button) => button.isPreferred,\n )\n if (preferredIndex >= 0) {\n dialog.setDefaultButton(preferredIndex)\n }\n const cancelIndex = request.buttons.findIndex(\n (button) => button.style === \"cancel\",\n )\n if (cancelIndex >= 0) {\n // Esc maps onto the cancel button, same as the Adw path's closeResponse.\n dialog.setCancelButton(cancelIndex)\n } else if (!request.cancelable && process.env.NODE_ENV !== \"production\") {\n // Unlike Adw.AlertDialog.setCanClose(false), Gtk.AlertDialog has no way\n // to block Esc/window-close dismissal outright — with no cancel button\n // set, GTK closes the dialog anyway and rejects choose() with\n // Gtk.DialogError.DISMISSED (caught below, mapped to the same null\n // dismissal cancelable: true would produce). Documented in docs/api.md;\n // an app that truly needs to block dismissal should add a cancel\n // button on both profiles rather than relying on cancelable: false alone.\n console.warn(\n '[react-native-gtkx] Alert.alert was called with cancelable: false and no \"cancel\" ' +\n \"style button. The plain-GTK profile's Gtk.AlertDialog fallback cannot block \" +\n \"Esc/window-close dismissal the way Adw.AlertDialog does — the dialog stays \" +\n \"dismissable. Add a cancel-style button for identical behavior on both profiles.\",\n )\n }\n try {\n const index = await dialog.choose(resolveWindow())\n return request.buttons[index]?.id ?? null\n } catch {\n // Dismissed (Esc / window-close) with no valid cancel button — the\n // plain-profile equivalent of the Adw path's unmatched \"close\" response.\n return null\n }\n}\n\nconst showAlert = async (request: HostAlertRequest): Promise<string | null> =>\n adwAvailable() ? showAlertAdw(request) : showAlertPlain(request)\n\nconst launchUri = async (uri: string): Promise<void> => {\n const launcher = new Gtk.UriLauncher({ uri })\n // Promisified by the gi codegen; rejects with the GError on failure.\n await launcher.launch(resolveWindow())\n}\n\n// The default widget direction is GTK's read of the locale text direction.\nconst isRTL = (): boolean => {\n try {\n return Gtk.Widget.getDefaultDirection() === Gtk.TextDirection.RTL\n } catch {\n return false\n }\n}\n\nexport const gtkxHost: Host = {\n gtkVersion,\n getWindowMetrics: windowMetrics,\n getScreenMetrics: screenMetrics,\n onMetricsChange: (notify) =>\n watchWindow(WINDOW_SIZE_SIGNALS, SURFACE_SIZE_SIGNALS, notify),\n getColorScheme: () =>\n adwAvailable() ? colorScheme() : getPlainColorScheme(),\n setColorScheme,\n onColorSchemeChange,\n isActive: isAnyWindowActive,\n onActiveChange: (notify) => watchWindow(WINDOW_ACTIVE_SIGNALS, [], notify),\n showAlert,\n launchUri,\n isRTL,\n exitApp: () => quit(),\n}\n"]}
@@ -9,4 +9,4 @@ export type ModalProps = {
9
9
  height?: number;
10
10
  children?: ReactNode;
11
11
  };
12
- export declare const Modal: ({ visible, onRequestClose, title, width, height, children, }: ModalProps) => React.ReactPortal | null;
12
+ export declare const Modal: ({ visible, onRequestClose, title, width, height, children, }: ModalProps) => React.JSX.Element | null;
@@ -1,18 +1,26 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { createPortal, GtkWindow, useApplication, useParentWindow, } from "../gtkx/bridge/index";
2
+ import { GtkWindow } from "../gtkx/bridge/index";
3
3
  import { Root } from "./root";
4
- // RN Modal → a modal GtkWindow portaled onto the application, transient for
5
- // the window that rendered it. Visibility is fully controlled by the prop:
6
- // the close request is reported and swallowed.
4
+ // RN Modal → a GtkWindow with a regular RN tree inside. Through gtkx 1.0
5
+ // this used to wrap the window in our own `createPortal(..., application)`
6
+ // and pass an explicit `transientFor` read via `useParentWindow()`. Neither
7
+ // is needed any more: gtkx 1.0's own GtkWindow JSX component is
8
+ // createWindowComponent(createElementComponent("GtkWindow"))
9
+ // (node_modules/.gtkx/jsx/gtk/gtk.js), which already composes
10
+ // createPortaledComponent (self-portals to @gtkx/react's rootElement,
11
+ // unconditionally, regardless of where it is rendered in the tree) and
12
+ // withDefaultTransientFor (defaults transientFor from ParentWindowContext —
13
+ // the exact context useParentWindow() read — whenever the prop is left
14
+ // undefined). Removing our own portal/transientFor was probed both ways
15
+ // (gallery's Modal section, before/after: same position, same blocked
16
+ // parent, same close/reopen behavior) before landing — see 003-notes.md.
7
17
  export const Modal = ({ visible = false, onRequestClose, title = "", width = 480, height = 400, children, }) => {
8
- const application = useApplication();
9
- const parentWindow = useParentWindow();
10
18
  if (!visible) {
11
19
  return null;
12
20
  }
13
- return createPortal(_jsx(GtkWindow, { title: title, modal: true, transientFor: parentWindow ?? undefined, defaultWidth: width, defaultHeight: height, onCloseRequest: () => {
21
+ return (_jsx(GtkWindow, { title: title, modal: true, defaultWidth: width, defaultHeight: height, onCloseRequest: () => {
14
22
  onRequestClose?.();
15
23
  return true;
16
- }, children: _jsx(Root, { width: width, height: height, followAllocation: true, children: children }) }), application);
24
+ }, children: _jsx(Root, { width: width, height: height, followAllocation: true, children: children }) }));
17
25
  };
18
26
  //# sourceMappingURL=modal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"modal.js","sourceRoot":"","sources":["../../src/components/modal.tsx"],"names":[],"mappings":";AACA,OAAO,EACL,YAAY,EACZ,SAAS,EACT,cAAc,EACd,eAAe,GAChB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAe7B,4EAA4E;AAC5E,2EAA2E;AAC3E,+CAA+C;AAC/C,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,EACpB,OAAO,GAAG,KAAK,EACf,cAAc,EACd,KAAK,GAAG,EAAE,EACV,KAAK,GAAG,GAAG,EACX,MAAM,GAAG,GAAG,EACZ,QAAQ,GACG,EAAE,EAAE;IACf,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IACpC,MAAM,YAAY,GAAG,eAAe,EAAE,CAAA;IAEtC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,YAAY,CACjB,KAAC,SAAS,IACR,KAAK,EAAE,KAAK,EACZ,KAAK,QACL,YAAY,EAAE,YAAY,IAAI,SAAS,EACvC,YAAY,EAAE,KAAK,EACnB,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,GAAG,EAAE;YACnB,cAAc,EAAE,EAAE,CAAA;YAClB,OAAO,IAAI,CAAA;QACb,CAAC,YAED,KAAC,IAAI,IACH,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,gBAAgB,kBAEf,QAAQ,GACJ,GACG,EACZ,WAAW,CACZ,CAAA;AACH,CAAC,CAAA","sourcesContent":["import { type ReactNode } from \"react\"\nimport {\n createPortal,\n GtkWindow,\n useApplication,\n useParentWindow,\n} from \"../gtkx/bridge/index\"\nimport { Root } from \"./root\"\n\nexport type ModalProps = {\n visible?: boolean\n onRequestClose?: () => void\n title?: string\n // Desktop mapping: RN modals become modal windows; transparent/animationType\n // have no GTK equivalent and are accepted as no-ops for API parity.\n transparent?: boolean\n animationType?: \"none\" | \"slide\" | \"fade\"\n width?: number\n height?: number\n children?: ReactNode\n}\n\n// RN Modal → a modal GtkWindow portaled onto the application, transient for\n// the window that rendered it. Visibility is fully controlled by the prop:\n// the close request is reported and swallowed.\nexport const Modal = ({\n visible = false,\n onRequestClose,\n title = \"\",\n width = 480,\n height = 400,\n children,\n}: ModalProps) => {\n const application = useApplication()\n const parentWindow = useParentWindow()\n\n if (!visible) {\n return null\n }\n\n return createPortal(\n <GtkWindow\n title={title}\n modal\n transientFor={parentWindow ?? undefined}\n defaultWidth={width}\n defaultHeight={height}\n onCloseRequest={() => {\n onRequestClose?.()\n return true\n }}\n >\n <Root\n width={width}\n height={height}\n followAllocation\n >\n {children}\n </Root>\n </GtkWindow>,\n application,\n )\n}\n"]}
1
+ {"version":3,"file":"modal.js","sourceRoot":"","sources":["../../src/components/modal.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAe7B,yEAAyE;AACzE,2EAA2E;AAC3E,4EAA4E;AAC5E,gEAAgE;AAChE,6DAA6D;AAC7D,8DAA8D;AAC9D,sEAAsE;AACtE,uEAAuE;AACvE,4EAA4E;AAC5E,uEAAuE;AACvE,wEAAwE;AACxE,sEAAsE;AACtE,yEAAyE;AACzE,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,EACpB,OAAO,GAAG,KAAK,EACf,cAAc,EACd,KAAK,GAAG,EAAE,EACV,KAAK,GAAG,GAAG,EACX,MAAM,GAAG,GAAG,EACZ,QAAQ,GACG,EAAE,EAAE;IACf,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,CACL,KAAC,SAAS,IACR,KAAK,EAAE,KAAK,EACZ,KAAK,QACL,YAAY,EAAE,KAAK,EACnB,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,GAAG,EAAE;YACnB,cAAc,EAAE,EAAE,CAAA;YAClB,OAAO,IAAI,CAAA;QACb,CAAC,YAED,KAAC,IAAI,IACH,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,gBAAgB,kBAEf,QAAQ,GACJ,GACG,CACb,CAAA;AACH,CAAC,CAAA","sourcesContent":["import { type ReactNode } from \"react\"\nimport { GtkWindow } from \"../gtkx/bridge/index\"\nimport { Root } from \"./root\"\n\nexport type ModalProps = {\n visible?: boolean\n onRequestClose?: () => void\n title?: string\n // Desktop mapping: RN modals become modal windows; transparent/animationType\n // have no GTK equivalent and are accepted as no-ops for API parity.\n transparent?: boolean\n animationType?: \"none\" | \"slide\" | \"fade\"\n width?: number\n height?: number\n children?: ReactNode\n}\n\n// RN Modal → a GtkWindow with a regular RN tree inside. Through gtkx 1.0\n// this used to wrap the window in our own `createPortal(..., application)`\n// and pass an explicit `transientFor` read via `useParentWindow()`. Neither\n// is needed any more: gtkx 1.0's own GtkWindow JSX component is\n// createWindowComponent(createElementComponent(\"GtkWindow\"))\n// (node_modules/.gtkx/jsx/gtk/gtk.js), which already composes\n// createPortaledComponent (self-portals to @gtkx/react's rootElement,\n// unconditionally, regardless of where it is rendered in the tree) and\n// withDefaultTransientFor (defaults transientFor from ParentWindowContext —\n// the exact context useParentWindow() read — whenever the prop is left\n// undefined). Removing our own portal/transientFor was probed both ways\n// (gallery's Modal section, before/after: same position, same blocked\n// parent, same close/reopen behavior) before landing — see 003-notes.md.\nexport const Modal = ({\n visible = false,\n onRequestClose,\n title = \"\",\n width = 480,\n height = 400,\n children,\n}: ModalProps) => {\n if (!visible) {\n return null\n }\n\n return (\n <GtkWindow\n title={title}\n modal\n defaultWidth={width}\n defaultHeight={height}\n onCloseRequest={() => {\n onRequestClose?.()\n return true\n }}\n >\n <Root\n width={width}\n height={height}\n followAllocation\n >\n {children}\n </Root>\n </GtkWindow>\n )\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"adw.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/adw.ts"],"names":[],"mappings":"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","sourcesContent":["// The ONLY module allowed to import @gtkx/gi/adw and @gtkx/jsx/adw — see\n// .claude/epics/adw-optional/001.md. Everything the RN core needs lives in\n// ./core instead, with zero Adw imports, so an app whose gtkx.config.ts\n// declares `libraries: [\"Gtk-4.0\"]` alone (no \"Adw-1\") never reaches either\n// specifier: a codegen store generated that way has no \"./adw\" entry in\n// either package's `exports` map AT ALL (empirically verified: neither\n// directory even exists on disk), so a STATIC import of either one fails\n// the whole build — `gtkx build`'s own \"gtkx:undeclared-library\" vite\n// plugin throws while resolving it, unconditionally, whether or not the\n// import is ever reached at runtime.\n//\n// __GTKX_ADW_AVAILABLE__ (declared ambient just below) is a build-time\n// constant the vite preset injects (src/vite/index.ts, see its own doc for\n// the full story — .claude/epics/adw-optional/006.md is the regression this\n// exists to fix): true only when THIS app's codegen store actually has an\n// \"adw\" entry. The probe below guards on it and, only inside that guard,\n// imports @gtkx/gi/adw and @gtkx/jsx/adw as LITERAL specifiers —\n// deliberately, unlike a runtime-assembled string. A hidden specifier is\n// invisible to Rollup's build graph, which sounds like the safer choice,\n// but it is ALSO invisible to everything that graph gives every OTHER gtkx\n// import for free: `resolve.dedupe` (RC4-WORKAROUND(runtime-dedupe) in\n// docs/gtkx-rc4-notes.md) and `gtkx build`'s own asset pipeline for the\n// native addon (`@gtkx/cli`'s `gtkx:native` plugin, which rewrites every\n// STATICALLY reachable `@gtkx/native` import onto the single `dist/gtkx.node`\n// it emits) — a hidden specifier resolves a SECOND, independent copy from\n// node_modules at runtime instead, and two distinct native addons\n// double-initialize the gtkx runtime and abort the process\n// (`g_log_set_writer_func() called multiple times`, proven with a core dump\n// showing both `.node` files mapped into one process). A literal specifier\n// gets the exact same static treatment as every other gtkx import; when the\n// build-time constant folds to `false` instead, dead-code elimination\n// removes the whole guarded body — literal specifiers included — before\n// Rollup's graph walk ever starts, so `gtkx:undeclared-library` never\n// throws on the plain-GTK profile either.\n//\n// No module-scope await, anywhere — the one thing that actually changed\n// here (.claude/epics/adw-optional/007-sea-tla.md): this file used to\n// resolve Adw with a TOP-LEVEL AWAIT (both the #132 guarded literal imports\n// and the fallback probe), so every call site below could stay synchronous\n// without an explicit wait of its own. That broke `react-native\n// build-linux` outright — reproduced empirically in the VM, WITH OR\n// WITHOUT --sea/--standalone (all three share the same Metro `bundle()`\n// call, `--dev false`): Metro's own minifier (metro-minify-terser, i.e.\n// terser) parses each module's compiled factory as a plain SCRIPT, not an\n// ES module — `await` is just an ordinary identifier there, not a keyword,\n// so \"await probeViaDynamicImport()\" is a hard syntax error (\"Unexpected\n// token: name (probeViaDynamicImport)\"), independent of the SEA/rolldown\n// CJS-format restriction the task file also names (CJS has no TLA either —\n// the same file would have failed a second time even past Metro).\n//\n// Tried and reverted: resolving gi through a synchronous `require()` (via\n// `createRequire(import.meta.url)`) instead of a dynamic import — it does\n// answer synchronously under vite build/dev and vitest, but\n// `import.meta.url` is ITSELF ESM-only syntax, exactly like top-level\n// await: Metro's minifier happened not to reject it at minify time (unlike\n// `await`), but Node's own parser does, the moment the Metro/SEA host\n// actually executes the bundle via `vm.runInThisContext` (which runs the\n// whole bundle as a plain SCRIPT, not a module) — \"SyntaxError: Cannot use\n// 'import.meta' outside a module\", reproduced building and running\n// examples/hn-app's SEA artifact. Same class of bug as the TLA one this\n// file exists to fix, so back to a dynamic import for both gi and jsx —\n// their own literal specifiers, unlike ours, are genuinely fine either way\n// since Metro/the SEA host never reach this branch at all (see\n// fromHostModules below) and every other toolchain is real ESM.\n//\n// So: a single, ordinary (non-async, non-top-level-await) function starts\n// BOTH imports together — Promise.all, exactly like the old probe — the\n// moment this module itself finishes evaluating, fire-and-forget (no\n// module-scope await to block on this time). No formal ordering guarantee\n// versus the old TLA probe's, but starting it as early as this module can\n// (not lazily, on the first actual `requireAdwJsx()`/`requireAdwGi()` call)\n// gives it a real, if informal, chance to have already settled — verified\n// against this package's own gtk test suite, including the one caller with\n// the least slack of all: react-native-gtkx/adw's own `adw/index.ts` calls\n// `requireAdwJsx()` eagerly, at ITS OWN module scope, the moment it is\n// imported (immediately after this file). Under Vite's SSR module runner\n// (dev and vitest both), every static import a transformed module has is\n// itself an awaited call in that runner, cached or not — so `adw/index.ts`\n// evaluating is always at least one module-boundary await after this\n// file's own module body, including the Promise.all it starts, finished\n// running. tests/gtk/bridge/auxiliary-elements.gtk.test.tsx (imports\n// react-native-gtkx/adw) and tests/gtk/adw/* are all green under this.\n//\n// The Metro/SEA host fast path (fromHostModules, below) takes priority over\n// all of this and never touches import() at all: `global.__hostModules` is\n// already populated — both gi and jsx together, when present — before the\n// run-linux host or the SEA entry's own async wrapper (src/sea/bundle.ts's\n// `buildEntrySource`, itself already just an ordinary async FUNCTION, never\n// a module-scope await) ever executes the bundle that reaches this file.\nimport type * as AdwGi from \"@gtkx/gi/adw\"\nimport type * as AdwJsx from \"@gtkx/jsx/adw\"\n\n// Assembled rather than written as one literal: used only as a lookup key\n// into global.__hostModules (an object property read, not an import), which\n// the run-linux host populates keyed by these exact strings\n// (HOST_MODULE_EXTERNALS in src/metro/index.ts). Kept opaque to a plain text\n// search for consistency with the rest of this file, not because anything\n// would fail resolving it — fromHostModules never imports.\nconst GI_ADW = [\"@gtkx\", \"gi\", \"adw\"].join(\"/\")\nconst JSX_ADW = [\"@gtkx\", \"jsx\", \"adw\"].join(\"/\")\n\ntype AdwModules = {\n gi: typeof AdwGi\n jsx: typeof AdwJsx\n}\n\ntype HostModulesGlobal = typeof globalThis & {\n __hostModules?: Record<string, unknown>\n}\n\n// The run-linux (Metro) host already resolved every external — including\n// these two, when the app declared \"Adw-1\" — into global.__hostModules\n// BEFORE the bundle ever runs (see src/runner/host.ts) — synchronously, as\n// far as this module is concerned, and the authoritative answer on that\n// toolchain: reading it directly is both correct and avoids a second,\n// redundant resolution attempt Metro's bundler cannot serve anyway (no\n// \"virtual:gtkx-config\" loader hook outside Vite's own pipeline or the\n// host's own module.registerHooks).\n// Returns undefined (not false) when there is no host indirection in play\n// at all — the vite dev/build toolchain, where every spike and example in\n// this repo runs — so the caller knows to fall through to the real probe.\nconst fromHostModules = (): AdwModules | null | undefined => {\n const hostModules = (globalThis as HostModulesGlobal).__hostModules\n if (!hostModules) {\n return undefined\n }\n const gi = hostModules[GI_ADW]\n const jsx = hostModules[JSX_ADW]\n return gi && jsx\n ? { gi: gi as typeof AdwGi, jsx: jsx as typeof AdwJsx }\n : null\n}\n\nconst hostModulesResult = fromHostModules()\n\n// Skips the probe outright when the vite preset has POSITIVELY told us Adw\n// is not in this app's codegen store (see the module doc above for why a\n// literal specifier below needs this guard to exist at all). `typeof`, not\n// a direct reference: safe on any toolchain that never defines the constant\n// (a bare `vitest` \"unit\" project, or a consumer not using our preset) —\n// reads as \"undefined\", so the guard is skipped and the probe runs for\n// real. Only an explicit `false` short-circuits.\ndeclare const __GTKX_ADW_AVAILABLE__: boolean | undefined\n\nlet cached: AdwModules | null | undefined\n\nif (hostModulesResult !== undefined) {\n cached = hostModulesResult\n} else if (\n typeof __GTKX_ADW_AVAILABLE__ !== \"undefined\" &&\n !__GTKX_ADW_AVAILABLE__\n) {\n cached = null\n} else {\n // Fire-and-forget — see the module doc above for why this can no longer\n // be a module-scope `await` and why starting it here, unconditionally,\n // still settles in time for every real caller.\n Promise.all([import(\"@gtkx/gi/adw\"), import(\"@gtkx/jsx/adw\")])\n .then(([gi, jsx]) => {\n cached = { gi: gi as typeof AdwGi, jsx: jsx as typeof AdwJsx }\n })\n .catch(() => {\n cached = null\n })\n}\n\n/**\n * True when this app's codegen store actually generated Adwaita bindings —\n * i.e. `\"Adw-1\"` is in this app's gtkx.config.ts `libraries`. Synchronous\n * from every caller's point of view on the Metro/SEA host and the\n * plain-GTK profile (both resolved above with nothing to await); on vite\n * build/dev and vitest this reads whatever the fire-and-forget probe above\n * has settled to by the time it is called — see the module doc for why\n * that is reliably \"already settled\" for every real call site in this\n * package, not a formal guarantee.\n */\nexport const adwAvailable = (): boolean =>\n cached !== null && cached !== undefined\n\nconst NOT_AVAILABLE =\n ' requires \"Adw-1\" in this app\\'s gtkx.config.ts `libraries` — see ' +\n \"docs/guide/plain-gtk.md for what needs Adw unconditionally \" +\n \"and what falls back without it.\"\n\n/** The repo's loud named throw for a feature that reached for Adw and found\n * none. Every Adw-dependent call site in the seam funnels through this, but\n * most no longer reach it in practice: Alert, Appearance and chrome:\n * \"content\" all check `adwAvailable()` themselves first and take a\n * plain-GTK fallback instead (see .claude/epics/adw-optional/002.md,\n * 003.md, 004.md) — this throw is what is left for the features with no\n * fallback at all (NavigationStack, react-native-gtkx/adw's own\n * AdwBreakpoint family). */\nconst requireAdw = (feature: string): AdwModules => {\n if (!cached) {\n throw new Error(`[react-native-gtkx] ${feature}${NOT_AVAILABLE}`)\n }\n return cached\n}\n\n/** The real `@gtkx/gi/adw` namespace (enums, GObject classes — `Adw.StyleManager`,\n * `Adw.ColorScheme`, `Adw.ResponseAppearance`, ...), or the loud throw above. */\nexport const requireAdwGi = (feature: string): typeof AdwGi =>\n requireAdw(feature).gi\n\n/** The real `@gtkx/jsx/adw` namespace (raw JSX elements — `AdwApplicationWindow`,\n * `AdwNavigationView`, `AdwNavigationPage`, ...), or the loud throw above. */\nexport const requireAdwJsx = (feature: string): typeof AdwJsx =>\n requireAdw(feature).jsx\n\n// Type-only (erased at build — no runtime import, so this costs nothing on\n// the plain profile): re-exported so a consumer like common/navigation-stack.tsx\n// can spell `Ref<Adw.NavigationView | null>` without importing @gtkx/gi/adw\n// itself, which the eslint fence (no @gtkx/* outside src/gtkx/bridge/**)\n// would refuse anyway.\nexport type { AdwGi as Adw }\n\nexport type ColorScheme = \"light\" | \"dark\"\n\n// Folded in from the pre-seam ./theme.ts: both are pure Adw, both were only\n// ever called from apis/host.gtkx.ts, and keeping them as their own\n// (formerly eagerly-imported) file would just move the eager `import * as\n// Adw` problem one hop over instead of removing it.\nexport const styleManager = (): AdwGi.StyleManager =>\n requireAdwGi(\"Appearance\").StyleManager.getDefault()\n\n// The Appearance API subscribes to notify::dark on the style manager.\nexport const colorScheme = (): ColorScheme =>\n styleManager().getDark() ? \"dark\" : \"light\"\n"]}
1
+ {"version":3,"file":"adw.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/adw.ts"],"names":[],"mappings":"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","sourcesContent":["// The ONLY module allowed to import @gtkx/gi/adw and @gtkx/jsx/adw — see\n// .claude/epics/adw-optional/001.md. Everything the RN core needs lives in\n// ./core instead, with zero Adw imports, so an app whose gtkx.config.ts\n// declares `libraries: [\"Gtk-4.0\"]` alone (no \"Adw-1\") never reaches either\n// specifier: a codegen store generated that way has no \"./adw\" entry in\n// either package's `exports` map AT ALL (empirically verified: neither\n// directory even exists on disk), so a STATIC import of either one fails\n// the whole build — `gtkx build`'s own \"gtkx:undeclared-library\" vite\n// plugin throws while resolving it, unconditionally, whether or not the\n// import is ever reached at runtime.\n//\n// __GTKX_ADW_AVAILABLE__ (declared ambient just below) is a build-time\n// constant the vite preset injects (src/vite/index.ts, see its own doc for\n// the full story — .claude/epics/adw-optional/006.md is the regression this\n// exists to fix): true only when THIS app's codegen store actually has an\n// \"adw\" entry. The probe below guards on it and, only inside that guard,\n// imports @gtkx/gi/adw and @gtkx/jsx/adw as LITERAL specifiers —\n// deliberately, unlike a runtime-assembled string. A hidden specifier is\n// invisible to Rollup's build graph, which sounds like the safer choice,\n// but it is ALSO invisible to everything that graph gives every OTHER gtkx\n// import for free: `resolve.dedupe` (1.2-WORKAROUND(runtime-dedupe) in\n// docs/gtkx-1.2-notes.md) and `gtkx build`'s own asset pipeline for the\n// native addon (`@gtkx/cli`'s `gtkx:native` plugin, which rewrites every\n// STATICALLY reachable `@gtkx/native` import onto the single `dist/gtkx.node`\n// it emits) — a hidden specifier resolves a SECOND, independent copy from\n// node_modules at runtime instead, and two distinct native addons\n// double-initialize the gtkx runtime and abort the process\n// (`g_log_set_writer_func() called multiple times`, proven with a core dump\n// showing both `.node` files mapped into one process). A literal specifier\n// gets the exact same static treatment as every other gtkx import; when the\n// build-time constant folds to `false` instead, dead-code elimination\n// removes the whole guarded body — literal specifiers included — before\n// Rollup's graph walk ever starts, so `gtkx:undeclared-library` never\n// throws on the plain-GTK profile either.\n//\n// No module-scope await, anywhere — the one thing that actually changed\n// here (.claude/epics/adw-optional/007-sea-tla.md): this file used to\n// resolve Adw with a TOP-LEVEL AWAIT (both the #132 guarded literal imports\n// and the fallback probe), so every call site below could stay synchronous\n// without an explicit wait of its own. That broke `react-native\n// build-linux` outright — reproduced empirically in the VM, WITH OR\n// WITHOUT --sea/--standalone (all three share the same Metro `bundle()`\n// call, `--dev false`): Metro's own minifier (metro-minify-terser, i.e.\n// terser) parses each module's compiled factory as a plain SCRIPT, not an\n// ES module — `await` is just an ordinary identifier there, not a keyword,\n// so \"await probeViaDynamicImport()\" is a hard syntax error (\"Unexpected\n// token: name (probeViaDynamicImport)\"), independent of the SEA/rolldown\n// CJS-format restriction the task file also names (CJS has no TLA either —\n// the same file would have failed a second time even past Metro).\n//\n// Tried and reverted: resolving gi through a synchronous `require()` (via\n// `createRequire(import.meta.url)`) instead of a dynamic import — it does\n// answer synchronously under vite build/dev and vitest, but\n// `import.meta.url` is ITSELF ESM-only syntax, exactly like top-level\n// await: Metro's minifier happened not to reject it at minify time (unlike\n// `await`), but Node's own parser does, the moment the Metro/SEA host\n// actually executes the bundle via `vm.runInThisContext` (which runs the\n// whole bundle as a plain SCRIPT, not a module) — \"SyntaxError: Cannot use\n// 'import.meta' outside a module\", reproduced building and running\n// examples/hn-app's SEA artifact. Same class of bug as the TLA one this\n// file exists to fix, so back to a dynamic import for both gi and jsx —\n// their own literal specifiers, unlike ours, are genuinely fine either way\n// since Metro/the SEA host never reach this branch at all (see\n// fromHostModules below) and every other toolchain is real ESM.\n//\n// So: a single, ordinary (non-async, non-top-level-await) function starts\n// BOTH imports together — Promise.all, exactly like the old probe — the\n// moment this module itself finishes evaluating, fire-and-forget (no\n// module-scope await to block on this time). No formal ordering guarantee\n// versus the old TLA probe's, but starting it as early as this module can\n// (not lazily, on the first actual `requireAdwJsx()`/`requireAdwGi()` call)\n// gives it a real, if informal, chance to have already settled — verified\n// against this package's own gtk test suite, including the one caller with\n// the least slack of all: react-native-gtkx/adw's own `adw/index.ts` calls\n// `requireAdwJsx()` eagerly, at ITS OWN module scope, the moment it is\n// imported (immediately after this file). Under Vite's SSR module runner\n// (dev and vitest both), every static import a transformed module has is\n// itself an awaited call in that runner, cached or not — so `adw/index.ts`\n// evaluating is always at least one module-boundary await after this\n// file's own module body, including the Promise.all it starts, finished\n// running. tests/gtk/bridge/auxiliary-elements.gtk.test.tsx (imports\n// react-native-gtkx/adw) and tests/gtk/adw/* are all green under this.\n//\n// The Metro/SEA host fast path (fromHostModules, below) takes priority over\n// all of this and never touches import() at all: `global.__hostModules` is\n// already populated — both gi and jsx together, when present — before the\n// run-linux host or the SEA entry's own async wrapper (src/sea/bundle.ts's\n// `buildEntrySource`, itself already just an ordinary async FUNCTION, never\n// a module-scope await) ever executes the bundle that reaches this file.\nimport type * as AdwGi from \"@gtkx/gi/adw\"\nimport type * as AdwJsx from \"@gtkx/jsx/adw\"\n\n// Assembled rather than written as one literal: used only as a lookup key\n// into global.__hostModules (an object property read, not an import), which\n// the run-linux host populates keyed by these exact strings\n// (HOST_MODULE_EXTERNALS in src/metro/index.ts). Kept opaque to a plain text\n// search for consistency with the rest of this file, not because anything\n// would fail resolving it — fromHostModules never imports.\nconst GI_ADW = [\"@gtkx\", \"gi\", \"adw\"].join(\"/\")\nconst JSX_ADW = [\"@gtkx\", \"jsx\", \"adw\"].join(\"/\")\n\ntype AdwModules = {\n gi: typeof AdwGi\n jsx: typeof AdwJsx\n}\n\ntype HostModulesGlobal = typeof globalThis & {\n __hostModules?: Record<string, unknown>\n}\n\n// The run-linux (Metro) host already resolved every external — including\n// these two, when the app declared \"Adw-1\" — into global.__hostModules\n// BEFORE the bundle ever runs (see src/runner/host.ts) — synchronously, as\n// far as this module is concerned, and the authoritative answer on that\n// toolchain: reading it directly is both correct and avoids a second,\n// redundant resolution attempt Metro's bundler cannot serve anyway (no\n// \"virtual:gtkx-config\" loader hook outside Vite's own pipeline or the\n// host's own module.registerHooks).\n// Returns undefined (not false) when there is no host indirection in play\n// at all — the vite dev/build toolchain, where every spike and example in\n// this repo runs — so the caller knows to fall through to the real probe.\nconst fromHostModules = (): AdwModules | null | undefined => {\n const hostModules = (globalThis as HostModulesGlobal).__hostModules\n if (!hostModules) {\n return undefined\n }\n const gi = hostModules[GI_ADW]\n const jsx = hostModules[JSX_ADW]\n return gi && jsx\n ? { gi: gi as typeof AdwGi, jsx: jsx as typeof AdwJsx }\n : null\n}\n\nconst hostModulesResult = fromHostModules()\n\n// Skips the probe outright when the vite preset has POSITIVELY told us Adw\n// is not in this app's codegen store (see the module doc above for why a\n// literal specifier below needs this guard to exist at all). `typeof`, not\n// a direct reference: safe on any toolchain that never defines the constant\n// (a bare `vitest` \"unit\" project, or a consumer not using our preset) —\n// reads as \"undefined\", so the guard is skipped and the probe runs for\n// real. Only an explicit `false` short-circuits.\ndeclare const __GTKX_ADW_AVAILABLE__: boolean | undefined\n\nlet cached: AdwModules | null | undefined\n\nif (hostModulesResult !== undefined) {\n cached = hostModulesResult\n} else if (\n typeof __GTKX_ADW_AVAILABLE__ !== \"undefined\" &&\n !__GTKX_ADW_AVAILABLE__\n) {\n cached = null\n} else {\n // Fire-and-forget — see the module doc above for why this can no longer\n // be a module-scope `await` and why starting it here, unconditionally,\n // still settles in time for every real caller.\n Promise.all([import(\"@gtkx/gi/adw\"), import(\"@gtkx/jsx/adw\")])\n .then(([gi, jsx]) => {\n cached = { gi: gi as typeof AdwGi, jsx: jsx as typeof AdwJsx }\n })\n .catch(() => {\n cached = null\n })\n}\n\n/**\n * True when this app's codegen store actually generated Adwaita bindings —\n * i.e. `\"Adw-1\"` is in this app's gtkx.config.ts `libraries`. Synchronous\n * from every caller's point of view on the Metro/SEA host and the\n * plain-GTK profile (both resolved above with nothing to await); on vite\n * build/dev and vitest this reads whatever the fire-and-forget probe above\n * has settled to by the time it is called — see the module doc for why\n * that is reliably \"already settled\" for every real call site in this\n * package, not a formal guarantee.\n */\nexport const adwAvailable = (): boolean =>\n cached !== null && cached !== undefined\n\nconst NOT_AVAILABLE =\n ' requires \"Adw-1\" in this app\\'s gtkx.config.ts `libraries` — see ' +\n \"docs/guide/plain-gtk.md for what needs Adw unconditionally \" +\n \"and what falls back without it.\"\n\n/** The repo's loud named throw for a feature that reached for Adw and found\n * none. Every Adw-dependent call site in the seam funnels through this, but\n * most no longer reach it in practice: Alert, Appearance and chrome:\n * \"content\" all check `adwAvailable()` themselves first and take a\n * plain-GTK fallback instead (see .claude/epics/adw-optional/002.md,\n * 003.md, 004.md) — this throw is what is left for the features with no\n * fallback at all (NavigationStack, react-native-gtkx/adw's own\n * AdwBreakpoint family). */\nconst requireAdw = (feature: string): AdwModules => {\n if (!cached) {\n throw new Error(`[react-native-gtkx] ${feature}${NOT_AVAILABLE}`)\n }\n return cached\n}\n\n/** The real `@gtkx/gi/adw` namespace (enums, GObject classes — `Adw.StyleManager`,\n * `Adw.ColorScheme`, `Adw.ResponseAppearance`, ...), or the loud throw above. */\nexport const requireAdwGi = (feature: string): typeof AdwGi =>\n requireAdw(feature).gi\n\n/** The real `@gtkx/jsx/adw` namespace (raw JSX elements — `AdwApplicationWindow`,\n * `AdwNavigationView`, `AdwNavigationPage`, ...), or the loud throw above. */\nexport const requireAdwJsx = (feature: string): typeof AdwJsx =>\n requireAdw(feature).jsx\n\n// Type-only (erased at build — no runtime import, so this costs nothing on\n// the plain profile): re-exported so a consumer like common/navigation-stack.tsx\n// can spell `Ref<Adw.NavigationView | null>` without importing @gtkx/gi/adw\n// itself, which the eslint fence (no @gtkx/* outside src/gtkx/bridge/**)\n// would refuse anyway.\nexport type { AdwGi as Adw }\n\nexport type ColorScheme = \"light\" | \"dark\"\n\n// Folded in from the pre-seam ./theme.ts: both are pure Adw, both were only\n// ever called from apis/host.gtkx.ts, and keeping them as their own\n// (formerly eagerly-imported) file would just move the eager `import * as\n// Adw` problem one hop over instead of removing it.\nexport const styleManager = (): AdwGi.StyleManager =>\n requireAdwGi(\"Appearance\").StyleManager.getDefault()\n\n// The Appearance API subscribes to notify::dark on the style manager.\nexport const colorScheme = (): ColorScheme =>\n styleManager().getDark() ? \"dark\" : \"light\"\n"]}
@@ -11,9 +11,8 @@ export { GtkApplication, GtkGestureClick } from "@gtkx/jsx/gtk";
11
11
  export { GMenu, GSimpleAction } from "@gtkx/jsx/gio";
12
12
  export { GtkAdjustment, GtkDragSource, GtkDropControllerMotion, GtkDropTarget, GtkShortcut, GtkShortcutController, GtkTextBuffer, } from "@gtkx/jsx/gtk";
13
13
  export * from "./widgets.generated";
14
- export { createPortal, createRoot, quit, rootElement, useApplication, useBindSetting, useParentWindow, useProperty, useSetting, type Root, type RootElement, } from "@gtkx/react";
14
+ export { createPortal, createRoot, quit, rootElement, useApplication, useBindSetting, useParentWindow, useProperty, useSetting, useSignal, type Root, type RootElement, } from "@gtkx/react";
15
15
  export type { SettingsSchema, SettingsSchemaKeys, SettingValue, } from "@gtkx/react/internal";
16
- export { useSignal } from "./use-signal";
17
16
  export { css, cx, injectGlobal } from "@gtkx/css";
18
17
  export { createWidgetCss, type WidgetCss } from "./widget-css";
19
18
  export { createTextProbe, measureWidget, toNumber } from "./measure";
@@ -8,7 +8,7 @@
8
8
  // still reaches for them, behind a probe (adwAvailable()); its absence
9
9
  // surfaces as a named throw, not a build failure.
10
10
  //
11
- // Caveats baked into this surface (catalogued in docs/gtkx-rc4-notes.md):
11
+ // Caveats baked into this surface (catalogued in docs/gtkx-1.2-notes.md):
12
12
  // - 64-bit FFI values arrive as BigInt → normalize with toNumber() at this boundary
13
13
  // import-then-export (not `export * as`): the latter is the one syntax the
14
14
  // stock @react-native/babel-preset cannot transform — this form keeps
@@ -48,10 +48,7 @@ export { GtkAdjustment, GtkDragSource, GtkDropControllerMotion, GtkDropTarget, G
48
48
  // exported only from ./adw — see that file's header for why the two cannot
49
49
  // share one module.
50
50
  export * from "./widgets.generated";
51
- export { createPortal, createRoot, quit, rootElement, useApplication, useBindSetting, useParentWindow, useProperty, useSetting, } from "@gtkx/react";
52
- // useSignal comes from ./use-signal, not @gtkx/react — see the workaround note
53
- // there (rc.3 delivers a stale handler).
54
- export { useSignal } from "./use-signal";
51
+ export { createPortal, createRoot, quit, rootElement, useApplication, useBindSetting, useParentWindow, useProperty, useSetting, useSignal, } from "@gtkx/react";
55
52
  export { css, cx, injectGlobal } from "@gtkx/css";
56
53
  // The imperative counterpart of `css`: a private provider on one widget,
57
54
  // for values that change per frame and must not enter the shared stylesheet.
@@ -1 +1 @@
1
- {"version":3,"file":"core.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/core.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,4EAA4E;AAC5E,4EAA4E;AAC5E,uEAAuE;AACvE,4EAA4E;AAC5E,0EAA0E;AAC1E,wEAAwE;AACxE,uEAAuE;AACvE,kDAAkD;AAClD,EAAE;AACF,0EAA0E;AAC1E,oFAAoF;AAEpF,2EAA2E;AAC3E,sEAAsE;AACtE,qDAAqD;AACrD,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,KAAK,IAAI,MAAM,eAAe,CAAA;AACrC,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAA;AAEvC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;AAE7D,uEAAuE;AACvE,2EAA2E;AAC3E,2EAA2E;AAC3E,WAAW;AACX,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAE/D,yEAAyE;AACzE,0EAA0E;AAC1E,sEAAsE;AACtE,gEAAgE;AAChE,2EAA2E;AAC3E,2EAA2E;AAC3E,0EAA0E;AAC1E,uEAAuE;AACvE,kEAAkE;AAClE,oDAAoD;AACpD,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,EACL,aAAa,EACb,aAAa,EACb,uBAAuB,EACvB,aAAa,EACb,WAAW,EACX,qBAAqB,EACrB,aAAa,GACd,MAAM,eAAe,CAAA;AAEtB,wEAAwE;AACxE,qEAAqE;AACrE,uEAAuE;AACvE,6EAA6E;AAC7E,qEAAqE;AACrE,kFAAkF;AAClF,2EAA2E;AAC3E,oBAAoB;AACpB,cAAc,qBAAqB,CAAA;AAEnC,OAAO,EACL,YAAY,EACZ,UAAU,EACV,IAAI,EACJ,WAAW,EACX,cAAc,EACd,cAAc,EACd,eAAe,EACf,WAAW,EACX,UAAU,GAGX,MAAM,aAAa,CAAA;AAcpB,+EAA+E;AAC/E,yCAAyC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAExC,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAEjD,yEAAyE;AACzE,6EAA6E;AAC7E,OAAO,EAAE,eAAe,EAAkB,MAAM,cAAc,CAAA;AAE9D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpE,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAc,MAAM,YAAY,CAAA;AAC7E,OAAO,EAAE,cAAc,EAAwB,MAAM,cAAc,CAAA;AACnE,0EAA0E;AAC1E,0EAA0E;AAC1E,4DAA4D;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,SAAS,GAEV,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,eAAe,EACf,oBAAoB,GAWrB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,aAAa,EACb,cAAc,EACd,cAAc,EACd,aAAa,EACb,WAAW,GAGZ,MAAM,kBAAkB,CAAA","sourcesContent":["// The core door onto gtkx: everything the RN core (components, APIs,\n// gesture-handler, reanimated, dnd) needs, and NOTHING from @gtkx/gi/adw or\n// @gtkx/jsx/adw — see .claude/epics/adw-optional/001.md. This is what makes\n// `libraries: [\"Gtk-4.0\"]` alone buildable: an app that never declares\n// \"Adw-1\" has no \"./adw\" entry in either package's codegen store at all, so\n// a static import of either specifier fails the whole build regardless of\n// whether it is ever reached at runtime. ./adw.ts is the one place that\n// still reaches for them, behind a probe (adwAvailable()); its absence\n// surfaces as a named throw, not a build failure.\n//\n// Caveats baked into this surface (catalogued in docs/gtkx-rc4-notes.md):\n// - 64-bit FFI values arrive as BigInt → normalize with toNumber() at this boundary\n\n// import-then-export (not `export * as`): the latter is the one syntax the\n// stock @react-native/babel-preset cannot transform — this form keeps\n// consumer apps on their unmodified RN Babel config.\nimport * as Gdk from \"@gtkx/gi/gdk\"\nimport * as Gio from \"@gtkx/gi/gio\"\nimport * as GLib from \"@gtkx/gi/glib\"\nimport * as GObject from \"@gtkx/gi/gobject\"\nimport * as Graphene from \"@gtkx/gi/graphene\"\nimport * as Gsk from \"@gtkx/gi/gsk\"\nimport * as Gtk from \"@gtkx/gi/gtk\"\nimport * as Pango from \"@gtkx/gi/pango\"\n\nexport { Gdk, Gio, GLib, GObject, Graphene, Gsk, Gtk, Pango }\n\n// GtkApplication and GtkGestureClick are not Gtk.Widget subclasses (an\n// application object and an event controller, respectively), so the widget\n// surface generator never sees them — kept here by hand, same as before it\n// existed.\nexport { GtkApplication, GtkGestureClick } from \"@gtkx/jsx/gtk\"\n\n// Auxiliary gtkx JSX elements that are not Gtk.Widget subclasses either,\n// same reason as the pair above — scripts/generate-widget-surface.ts only\n// classifies widgets, so these fall into its \"notAWidget\" bucket (see\n// scripts/widget-surface/classification.json) and are otherwise\n// unreachable through react-native-gtkx/gtk. Every one of these is a real,\n// necessary building block for a real app: actions and menus (Gio), a text\n// buffer and an adjustment (the model objects GtkTextView/GtkSpinRow etc.\n// bind to), keyboard shortcuts, and the two drag-and-drop controllers.\n// Adwaita's own auxiliary elements (AdwBreakpoint, AdwToggle, the\n// AdwShortcutsDialog leaves) live in ./adw instead.\nexport { GMenu, GSimpleAction } from \"@gtkx/jsx/gio\"\nexport {\n GtkAdjustment,\n GtkDragSource,\n GtkDropControllerMotion,\n GtkDropTarget,\n GtkShortcut,\n GtkShortcutController,\n GtkTextBuffer,\n} from \"@gtkx/jsx/gtk\"\n\n// The full GTK widget surface — every GTK class gtkx binds that derives\n// Gtk.Widget, raw. src/gtk/widgets.generated wraps most of them with\n// wrapReactNative; this file is where @gtkx/jsx is still allowed to be\n// imported directly (see the eslint carve-out for src/gtkx/bridge/**), so it\n// pulls the raw widgets from here rather than from @gtkx/jsx itself.\n// Adwaita's raw widgets are the sibling generated file, widgets.generated.adw.ts,\n// exported only from ./adw — see that file's header for why the two cannot\n// share one module.\nexport * from \"./widgets.generated\"\n\nexport {\n createPortal,\n createRoot,\n quit,\n rootElement,\n useApplication,\n useBindSetting,\n useParentWindow,\n useProperty,\n useSetting,\n type Root,\n type RootElement,\n} from \"@gtkx/react\"\n\n// rc.4 moved the settings-schema types off the public entry point into\n// /internal, with no replacement on `@gtkx/react` — `useSetting`/\n// `useBindSetting` are still public and still typed by them, so a consumer\n// that wants to name the type of a setting has no supported import for it.\n// We re-export them from here, which is the whole point of the bridge; the\n// ask to put them back is filed in docs/upstream-gtkx.md.\nexport type {\n SettingsSchema,\n SettingsSchemaKeys,\n SettingValue,\n} from \"@gtkx/react/internal\"\n\n// useSignal comes from ./use-signal, not @gtkx/react — see the workaround note\n// there (rc.3 delivers a stale handler).\nexport { useSignal } from \"./use-signal\"\n\nexport { css, cx, injectGlobal } from \"@gtkx/css\"\n\n// The imperative counterpart of `css`: a private provider on one widget,\n// for values that change per frame and must not enter the shared stylesheet.\nexport { createWidgetCss, type WidgetCss } from \"./widget-css\"\n\nexport { createTextProbe, measureWidget, toNumber } from \"./measure\"\nexport { computePointIn, computePointInWindow, type Point } from \"./geometry\"\nexport { beginDragLayer, type DragLayerHandle } from \"./drag-layer\"\n// A portal into a NAMED slot of a remote object (the window's action map,\n// its controllers) rather than into its default child slot — see the file\n// for why gtkx's own createPortal is not enough on its own.\nexport { createSlotPortal } from \"./slot-portal\"\nexport {\n cacheChildOrder,\n getViewBoxComponent,\n invalidateZOrder,\n setBoxOnly,\n setBoxPassthrough,\n setHitSlop,\n setPaintOnlyLeaf,\n setPointerTarget,\n setZIndex,\n type HitSlop,\n} from \"./view-box\"\nexport {\n getSvgNodeComponent,\n getSvgNodeDescriptor,\n queueSvgRedraw,\n resolveSvgColor,\n resolveSvgPaint,\n setSvgNodeDescriptor,\n type SvgDefsDescriptor,\n type SvgGradientUnits,\n type SvgGroupDescriptor,\n type SvgLinearGradientDescriptor,\n type SvgNodeDescriptor,\n type SvgPaintSpec,\n type SvgRadialGradientDescriptor,\n type SvgShapeDescriptor,\n type SvgStopDescriptor,\n type SvgSvgDescriptor,\n} from \"./svg-node\"\nexport {\n allocateChild,\n attachRnLayout,\n detachRnLayout,\n queueAllocate,\n queueResize,\n type RnLayoutHooks,\n type RnLayoutOrientation,\n} from \"./layout-manager\"\n"]}
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/core.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,4EAA4E;AAC5E,4EAA4E;AAC5E,uEAAuE;AACvE,4EAA4E;AAC5E,0EAA0E;AAC1E,wEAAwE;AACxE,uEAAuE;AACvE,kDAAkD;AAClD,EAAE;AACF,0EAA0E;AAC1E,oFAAoF;AAEpF,2EAA2E;AAC3E,sEAAsE;AACtE,qDAAqD;AACrD,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,KAAK,IAAI,MAAM,eAAe,CAAA;AACrC,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAA;AAC3C,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAC7C,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,KAAK,GAAG,MAAM,cAAc,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAA;AAEvC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;AAE7D,uEAAuE;AACvE,2EAA2E;AAC3E,2EAA2E;AAC3E,WAAW;AACX,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAE/D,yEAAyE;AACzE,0EAA0E;AAC1E,sEAAsE;AACtE,gEAAgE;AAChE,2EAA2E;AAC3E,2EAA2E;AAC3E,0EAA0E;AAC1E,uEAAuE;AACvE,kEAAkE;AAClE,oDAAoD;AACpD,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,EACL,aAAa,EACb,aAAa,EACb,uBAAuB,EACvB,aAAa,EACb,WAAW,EACX,qBAAqB,EACrB,aAAa,GACd,MAAM,eAAe,CAAA;AAEtB,wEAAwE;AACxE,qEAAqE;AACrE,uEAAuE;AACvE,6EAA6E;AAC7E,qEAAqE;AACrE,kFAAkF;AAClF,2EAA2E;AAC3E,oBAAoB;AACpB,cAAc,qBAAqB,CAAA;AAEnC,OAAO,EACL,YAAY,EACZ,UAAU,EACV,IAAI,EACJ,WAAW,EACX,cAAc,EACd,cAAc,EACd,eAAe,EACf,WAAW,EACX,UAAU,EACV,SAAS,GAGV,MAAM,aAAa,CAAA;AAcpB,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAEjD,yEAAyE;AACzE,6EAA6E;AAC7E,OAAO,EAAE,eAAe,EAAkB,MAAM,cAAc,CAAA;AAE9D,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpE,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAc,MAAM,YAAY,CAAA;AAC7E,OAAO,EAAE,cAAc,EAAwB,MAAM,cAAc,CAAA;AACnE,0EAA0E;AAC1E,0EAA0E;AAC1E,4DAA4D;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,SAAS,GAEV,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,eAAe,EACf,oBAAoB,GAWrB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,aAAa,EACb,cAAc,EACd,cAAc,EACd,aAAa,EACb,WAAW,GAGZ,MAAM,kBAAkB,CAAA","sourcesContent":["// The core door onto gtkx: everything the RN core (components, APIs,\n// gesture-handler, reanimated, dnd) needs, and NOTHING from @gtkx/gi/adw or\n// @gtkx/jsx/adw — see .claude/epics/adw-optional/001.md. This is what makes\n// `libraries: [\"Gtk-4.0\"]` alone buildable: an app that never declares\n// \"Adw-1\" has no \"./adw\" entry in either package's codegen store at all, so\n// a static import of either specifier fails the whole build regardless of\n// whether it is ever reached at runtime. ./adw.ts is the one place that\n// still reaches for them, behind a probe (adwAvailable()); its absence\n// surfaces as a named throw, not a build failure.\n//\n// Caveats baked into this surface (catalogued in docs/gtkx-1.2-notes.md):\n// - 64-bit FFI values arrive as BigInt → normalize with toNumber() at this boundary\n\n// import-then-export (not `export * as`): the latter is the one syntax the\n// stock @react-native/babel-preset cannot transform — this form keeps\n// consumer apps on their unmodified RN Babel config.\nimport * as Gdk from \"@gtkx/gi/gdk\"\nimport * as Gio from \"@gtkx/gi/gio\"\nimport * as GLib from \"@gtkx/gi/glib\"\nimport * as GObject from \"@gtkx/gi/gobject\"\nimport * as Graphene from \"@gtkx/gi/graphene\"\nimport * as Gsk from \"@gtkx/gi/gsk\"\nimport * as Gtk from \"@gtkx/gi/gtk\"\nimport * as Pango from \"@gtkx/gi/pango\"\n\nexport { Gdk, Gio, GLib, GObject, Graphene, Gsk, Gtk, Pango }\n\n// GtkApplication and GtkGestureClick are not Gtk.Widget subclasses (an\n// application object and an event controller, respectively), so the widget\n// surface generator never sees them — kept here by hand, same as before it\n// existed.\nexport { GtkApplication, GtkGestureClick } from \"@gtkx/jsx/gtk\"\n\n// Auxiliary gtkx JSX elements that are not Gtk.Widget subclasses either,\n// same reason as the pair above — scripts/generate-widget-surface.ts only\n// classifies widgets, so these fall into its \"notAWidget\" bucket (see\n// scripts/widget-surface/classification.json) and are otherwise\n// unreachable through react-native-gtkx/gtk. Every one of these is a real,\n// necessary building block for a real app: actions and menus (Gio), a text\n// buffer and an adjustment (the model objects GtkTextView/GtkSpinRow etc.\n// bind to), keyboard shortcuts, and the two drag-and-drop controllers.\n// Adwaita's own auxiliary elements (AdwBreakpoint, AdwToggle, the\n// AdwShortcutsDialog leaves) live in ./adw instead.\nexport { GMenu, GSimpleAction } from \"@gtkx/jsx/gio\"\nexport {\n GtkAdjustment,\n GtkDragSource,\n GtkDropControllerMotion,\n GtkDropTarget,\n GtkShortcut,\n GtkShortcutController,\n GtkTextBuffer,\n} from \"@gtkx/jsx/gtk\"\n\n// The full GTK widget surface — every GTK class gtkx binds that derives\n// Gtk.Widget, raw. src/gtk/widgets.generated wraps most of them with\n// wrapReactNative; this file is where @gtkx/jsx is still allowed to be\n// imported directly (see the eslint carve-out for src/gtkx/bridge/**), so it\n// pulls the raw widgets from here rather than from @gtkx/jsx itself.\n// Adwaita's raw widgets are the sibling generated file, widgets.generated.adw.ts,\n// exported only from ./adw — see that file's header for why the two cannot\n// share one module.\nexport * from \"./widgets.generated\"\n\nexport {\n createPortal,\n createRoot,\n quit,\n rootElement,\n useApplication,\n useBindSetting,\n useParentWindow,\n useProperty,\n useSetting,\n useSignal,\n type Root,\n type RootElement,\n} from \"@gtkx/react\"\n\n// rc.4 moved the settings-schema types off the public entry point into\n// /internal, with no replacement on `@gtkx/react` — `useSetting`/\n// `useBindSetting` are still public and still typed by them, so a consumer\n// that wants to name the type of a setting has no supported import for it.\n// We re-export them from here, which is the whole point of the bridge; the\n// ask to put them back is filed in docs/upstream-gtkx.md.\nexport type {\n SettingsSchema,\n SettingsSchemaKeys,\n SettingValue,\n} from \"@gtkx/react/internal\"\n\nexport { css, cx, injectGlobal } from \"@gtkx/css\"\n\n// The imperative counterpart of `css`: a private provider on one widget,\n// for values that change per frame and must not enter the shared stylesheet.\nexport { createWidgetCss, type WidgetCss } from \"./widget-css\"\n\nexport { createTextProbe, measureWidget, toNumber } from \"./measure\"\nexport { computePointIn, computePointInWindow, type Point } from \"./geometry\"\nexport { beginDragLayer, type DragLayerHandle } from \"./drag-layer\"\n// A portal into a NAMED slot of a remote object (the window's action map,\n// its controllers) rather than into its default child slot — see the file\n// for why gtkx's own createPortal is not enough on its own.\nexport { createSlotPortal } from \"./slot-portal\"\nexport {\n cacheChildOrder,\n getViewBoxComponent,\n invalidateZOrder,\n setBoxOnly,\n setBoxPassthrough,\n setHitSlop,\n setPaintOnlyLeaf,\n setPointerTarget,\n setZIndex,\n type HitSlop,\n} from \"./view-box\"\nexport {\n getSvgNodeComponent,\n getSvgNodeDescriptor,\n queueSvgRedraw,\n resolveSvgColor,\n resolveSvgPaint,\n setSvgNodeDescriptor,\n type SvgDefsDescriptor,\n type SvgGradientUnits,\n type SvgGroupDescriptor,\n type SvgLinearGradientDescriptor,\n type SvgNodeDescriptor,\n type SvgPaintSpec,\n type SvgRadialGradientDescriptor,\n type SvgShapeDescriptor,\n type SvgStopDescriptor,\n type SvgSvgDescriptor,\n} from \"./svg-node\"\nexport {\n allocateChild,\n attachRnLayout,\n detachRnLayout,\n queueAllocate,\n queueResize,\n type RnLayoutHooks,\n type RnLayoutOrientation,\n} from \"./layout-manager\"\n"]}
@@ -17,7 +17,7 @@ import * as Graphene from "@gtkx/gi/graphene";
17
17
  // Graphene.Point's constructor takes plain scalars, so it never hit the
18
18
  // nested-boxed-struct crash Graphene.Rect's did (the retired
19
19
  // graphene-rect-nested-boxed-props workaround, fixed upstream in rc.3 by our
20
- // gtkx-org/gtkx#473 — see "Fixed in rc.3" in docs/gtkx-rc4-notes.md).
20
+ // gtkx-org/gtkx#473 — see "Fixed in rc.3" in docs/gtkx-1.2-notes.md).
21
21
  // alloc+init stays because it is the cheaper of the two here, not because
22
22
  // the constructor is unsafe.
23
23
  const point = (x, y) => Graphene.Point.alloc().init(x, y);
@@ -1 +1 @@
1
- {"version":3,"file":"geometry.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/geometry.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,qEAAqE;AACrE,EAAE;AACF,0EAA0E;AAC1E,2EAA2E;AAC3E,oEAAoE;AACpE,2EAA2E;AAC3E,4EAA4E;AAC5E,6EAA6E;AAC7E,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,2EAA2E;AAC3E,4EAA4E;AAC5E,wCAAwC;AACxC,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAK7C,wEAAwE;AACxE,6DAA6D;AAC7D,6EAA6E;AAC7E,sEAAsE;AACtE,0EAA0E;AAC1E,6BAA6B;AAC7B,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,CAAS,EAAkB,EAAE,CACrD,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAEnC;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,MAAkB,EAClB,MAAkB,EAClB,CAAS,EACT,CAAS,EACK,EAAE;IAChB,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IACjE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AACzD,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,MAAkB,EAClB,CAAS,EACT,CAAS,EACK,EAAE;IAChB,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAA;IAC7B,OAAO,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACzD,CAAC,CAAA","sourcesContent":["// Widget geometry in foreign coordinate spaces — what RN's measure()/\n// measureInWindow()/measureLayout() and an event's pageX/pageY need.\n//\n// GTK4 folds a widget's allocated position into its transform relative to\n// its parent, so there is no globally meaningful x/y to read off a widget:\n// the position only exists as an answer to \"in whose coordinates?\".\n// gtk_widget_compute_point() walks that transform chain, which is also why\n// it comes out right inside a scrolled viewport — GtkViewport allocates its\n// child at -adjustment.value, so the scroll offset IS the child's transform.\n//\n// gtk_widget_translate_coordinates() and gtk_widget_get_allocation() do the\n// same job and are deprecated since GTK 4.12; compute_point/compute_bounds\n// are the replacements. Both can legitimately fail (no common ancestor, an\n// unrealized widget, a singular transform) — every helper here returns null\n// rather than a plausible-looking zero.\nimport * as Graphene from \"@gtkx/gi/graphene\"\nimport type * as Gtk from \"@gtkx/gi/gtk\"\n\nexport type Point = { x: number; y: number }\n\n// Graphene.Point's constructor takes plain scalars, so it never hit the\n// nested-boxed-struct crash Graphene.Rect's did (the retired\n// graphene-rect-nested-boxed-props workaround, fixed upstream in rc.3 by our\n// gtkx-org/gtkx#473 — see \"Fixed in rc.3\" in docs/gtkx-rc4-notes.md).\n// alloc+init stays because it is the cheaper of the two here, not because\n// the constructor is unsafe.\nconst point = (x: number, y: number): Graphene.Point =>\n Graphene.Point.alloc().init(x, y)\n\n/**\n * Translates a point from `widget`'s coordinates into `target`'s.\n * Returns null when the two are not in the same widget hierarchy.\n */\nexport const computePointIn = (\n widget: Gtk.Widget,\n target: Gtk.Widget,\n x: number,\n y: number,\n): Point | null => {\n const [ok, translated] = widget.computePoint(target, point(x, y))\n return ok ? { x: translated.x, y: translated.y } : null\n}\n\n/**\n * Translates a point from `widget`'s coordinates into its toplevel's — RN's\n * \"page\" space. Returns null for a widget that is not in a window yet.\n */\nexport const computePointInWindow = (\n widget: Gtk.Widget,\n x: number,\n y: number,\n): Point | null => {\n const root = widget.getRoot()\n return root ? computePointIn(widget, root, x, y) : null\n}\n"]}
1
+ {"version":3,"file":"geometry.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/geometry.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,qEAAqE;AACrE,EAAE;AACF,0EAA0E;AAC1E,2EAA2E;AAC3E,oEAAoE;AACpE,2EAA2E;AAC3E,4EAA4E;AAC5E,6EAA6E;AAC7E,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,2EAA2E;AAC3E,4EAA4E;AAC5E,wCAAwC;AACxC,OAAO,KAAK,QAAQ,MAAM,mBAAmB,CAAA;AAK7C,wEAAwE;AACxE,6DAA6D;AAC7D,6EAA6E;AAC7E,sEAAsE;AACtE,0EAA0E;AAC1E,6BAA6B;AAC7B,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,CAAS,EAAkB,EAAE,CACrD,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAEnC;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,MAAkB,EAClB,MAAkB,EAClB,CAAS,EACT,CAAS,EACK,EAAE;IAChB,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IACjE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AACzD,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,MAAkB,EAClB,CAAS,EACT,CAAS,EACK,EAAE;IAChB,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAA;IAC7B,OAAO,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACzD,CAAC,CAAA","sourcesContent":["// Widget geometry in foreign coordinate spaces — what RN's measure()/\n// measureInWindow()/measureLayout() and an event's pageX/pageY need.\n//\n// GTK4 folds a widget's allocated position into its transform relative to\n// its parent, so there is no globally meaningful x/y to read off a widget:\n// the position only exists as an answer to \"in whose coordinates?\".\n// gtk_widget_compute_point() walks that transform chain, which is also why\n// it comes out right inside a scrolled viewport — GtkViewport allocates its\n// child at -adjustment.value, so the scroll offset IS the child's transform.\n//\n// gtk_widget_translate_coordinates() and gtk_widget_get_allocation() do the\n// same job and are deprecated since GTK 4.12; compute_point/compute_bounds\n// are the replacements. Both can legitimately fail (no common ancestor, an\n// unrealized widget, a singular transform) — every helper here returns null\n// rather than a plausible-looking zero.\nimport * as Graphene from \"@gtkx/gi/graphene\"\nimport type * as Gtk from \"@gtkx/gi/gtk\"\n\nexport type Point = { x: number; y: number }\n\n// Graphene.Point's constructor takes plain scalars, so it never hit the\n// nested-boxed-struct crash Graphene.Rect's did (the retired\n// graphene-rect-nested-boxed-props workaround, fixed upstream in rc.3 by our\n// gtkx-org/gtkx#473 — see \"Fixed in rc.3\" in docs/gtkx-1.2-notes.md).\n// alloc+init stays because it is the cheaper of the two here, not because\n// the constructor is unsafe.\nconst point = (x: number, y: number): Graphene.Point =>\n Graphene.Point.alloc().init(x, y)\n\n/**\n * Translates a point from `widget`'s coordinates into `target`'s.\n * Returns null when the two are not in the same widget hierarchy.\n */\nexport const computePointIn = (\n widget: Gtk.Widget,\n target: Gtk.Widget,\n x: number,\n y: number,\n): Point | null => {\n const [ok, translated] = widget.computePoint(target, point(x, y))\n return ok ? { x: translated.x, y: translated.y } : null\n}\n\n/**\n * Translates a point from `widget`'s coordinates into its toplevel's — RN's\n * \"page\" space. Returns null for a widget that is not in a window yet.\n */\nexport const computePointInWindow = (\n widget: Gtk.Widget,\n x: number,\n y: number,\n): Point | null => {\n const root = widget.getRoot()\n return root ? computePointIn(widget, root, x, y) : null\n}\n"]}
@@ -20,8 +20,21 @@ const ensureRegistered = () => {
20
20
  if (RnGtkxLayoutClass) {
21
21
  return RnGtkxLayoutClass;
22
22
  }
23
+ // gtkx 1.0 renamed every vtable override slot to a `vfunc`-prefixed method
24
+ // (vfuncMeasure/vfuncAllocate/vfuncGetRequestMode here — was measure/
25
+ // allocate/getRequestMode on rc.4). This is not a workaround to tag: it is
26
+ // the sanctioned 1.0 spelling, verified against
27
+ // node_modules/@gtkx/gi/gtk/gtk.js's registerWrapperClass(LayoutManager,
28
+ // ...) registry and gtk.d.ts. Left as a signpost because the failure mode
29
+ // is silent and easy to reintroduce: registerClass() discovers overrides by
30
+ // exact method-name match against that registry
31
+ // (@gtkx/runtime/register-class.js discoverClassVfuncs) — a name that
32
+ // doesn't match is neither wired nor rejected, it just never reaches the
33
+ // vtable. That silent drop was the blank-content-pane root cause: with
34
+ // allocate() never called, every View's children went unallocated while
35
+ // native chrome (not driven by this layout manager) rendered fine.
23
36
  class RnGtkxLayout extends Gtk.LayoutManager {
24
- measure(_widget, orientation, forSize) {
37
+ vfuncMeasure(_widget, orientation, forSize) {
25
38
  const hooks = hooksByManager.get(this);
26
39
  if (!hooks) {
27
40
  return [0, 0, -1, -1];
@@ -29,12 +42,12 @@ const ensureRegistered = () => {
29
42
  const size = hooks.measure(orientation === Gtk.Orientation.HORIZONTAL ? "horizontal" : "vertical", forSize);
30
43
  return [size, size, -1, -1];
31
44
  }
32
- // Trailing vfunc params (baseline; widget) are dropped — JS tolerates the
33
- // arity mismatch and the linter rejects unused trailing args.
34
- allocate(_widget, width, height) {
45
+ // Trailing vfunc params (baseline) are dropped — JS tolerates the arity
46
+ // mismatch and the linter rejects unused trailing args.
47
+ vfuncAllocate(_widget, width, height) {
35
48
  hooksByManager.get(this)?.allocate(width, height);
36
49
  }
37
- getRequestMode() {
50
+ vfuncGetRequestMode() {
38
51
  return Gtk.SizeRequestMode.CONSTANT_SIZE;
39
52
  }
40
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"layout-manager.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/layout-manager.ts"],"names":[],"mappings":"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","sourcesContent":["// RnGtkxLayout — a GObject subclass of GtkLayoutManager registered entirely\n// from JS (docs/research/layout-manager.md, \"B0\"). The manager obeys ONLY the\n// layout engine: measure() reports the engine-provided size (minimum ==\n// natural, children are never queried) and allocate() delegates to the engine,\n// which places every child at exactly its computed rect via allocateChild().\n// This is what removes the GTK-vs-RN layout conflicts at the root: window\n// minimum ratchet, overflow children inflating ancestors, and widget minimums\n// pushing rects.\nimport * as Gdk from \"@gtkx/gi/gdk\"\nimport * as Gsk from \"@gtkx/gi/gsk\"\nimport * as Gtk from \"@gtkx/gi/gtk\"\nimport { registerClass } from \"@gtkx/runtime\"\nimport type { Transform2D } from \"../../contracts\"\n\nexport type RnLayoutOrientation = \"horizontal\" | \"vertical\"\n\nexport type RnLayoutHooks = {\n // Engine-provided size for the given axis; minimum == natural == this value.\n measure(orientation: RnLayoutOrientation, forSize: number): number\n // Called during GTK's allocation phase with the container's final size.\n // The engine must size-allocate every child (allocateChild) synchronously.\n allocate(width: number, height: number): void\n}\n\n// The class must exist before any instance is created, but registration needs\n// GObject to be initialized — both hold after the bridge is imported, so the\n// class is registered lazily on first attach (also keeps the module safe to\n// import in environments without a display).\nlet RnGtkxLayoutClass: (new () => Gtk.LayoutManager) | null = null\n\nconst hooksByManager = new WeakMap<Gtk.LayoutManager, RnLayoutHooks>()\n\nconst ensureRegistered = (): new () => Gtk.LayoutManager => {\n if (RnGtkxLayoutClass) {\n return RnGtkxLayoutClass\n }\n\n class RnGtkxLayout extends Gtk.LayoutManager {\n override measure(\n _widget: Gtk.Widget,\n orientation: Gtk.Orientation,\n forSize: number,\n ): [number, number, number, number] {\n const hooks = hooksByManager.get(this)\n if (!hooks) {\n return [0, 0, -1, -1]\n }\n const size = hooks.measure(\n orientation === Gtk.Orientation.HORIZONTAL ? \"horizontal\" : \"vertical\",\n forSize,\n )\n return [size, size, -1, -1]\n }\n\n // Trailing vfunc params (baseline; widget) are dropped — JS tolerates the\n // arity mismatch and the linter rejects unused trailing args.\n override allocate(\n _widget: Gtk.Widget,\n width: number,\n height: number,\n ): void {\n hooksByManager.get(this)?.allocate(width, height)\n }\n\n override getRequestMode(): Gtk.SizeRequestMode {\n return Gtk.SizeRequestMode.CONSTANT_SIZE\n }\n }\n\n // Explicit typeName: bundlers minify class names and registerClass derives\n // the GType name from klass.name by default (FINDINGS §1).\n registerClass(RnGtkxLayout, { typeName: \"RnGtkxLayout\" })\n RnGtkxLayoutClass = RnGtkxLayout\n return RnGtkxLayout\n}\n\n// Replaces the widget's layout manager with an RnGtkxLayout driven by `hooks`.\n// The container must attach its children in a layout-child-free way (GtkBox\n// append / set_parent) — GtkFixed.put demands a GtkFixedLayoutChild from the\n// current manager and is incompatible (FINDINGS §2).\nexport const attachRnLayout = (\n widget: Gtk.Widget,\n hooks: RnLayoutHooks,\n): void => {\n const Klass = ensureRegistered()\n if (hooksByManager.has(widget.getLayoutManager() as Gtk.LayoutManager)) {\n throw new Error(\"attachRnLayout: widget already has an RnGtkxLayout\")\n }\n const manager = new Klass()\n hooksByManager.set(manager, hooks)\n widget.setLayoutManager(manager)\n}\n\n// Drops the hooks and hands layout back to a fresh manager of the widget's\n// own class default. Safe to call on widgets that were never attached.\nexport const detachRnLayout = (widget: Gtk.Widget): void => {\n const manager = widget.getLayoutManager() as Gtk.LayoutManager | null\n if (!manager || !hooksByManager.has(manager)) {\n return\n }\n hooksByManager.delete(manager)\n widget.setLayoutManager(null as unknown as Gtk.LayoutManager)\n}\n\n// Places one child at an exact rect, optionally under a visual transform.\n// Only meaningful from inside an allocate() hook — GTK forbids\n// size-allocating outside the layout phase.\n//\n// The transform path is gtk_widget_allocate(), which is what\n// gtk_widget_size_allocate() itself calls with a plain translate — the child\n// keeps the width/height Yoga gave it and only its placement matrix changes,\n// which is exactly RN's \"transforms are visual only\". GTK4 inverts that\n// matrix in gtk_widget_pick(), so input follows the rotated/scaled shape for\n// free (measured: docs/research/transforms.md).\nexport const allocateChild = (\n child: Gtk.Widget,\n x: number,\n y: number,\n width: number,\n height: number,\n matrix: Transform2D | null = null,\n): void => {\n const left = Math.round(x)\n const top = Math.round(y)\n const w = Math.max(0, Math.round(width))\n const h = Math.max(0, Math.round(height))\n\n if (!matrix) {\n child.sizeAllocate(\n new Gdk.Rectangle({ x: left, y: top, width: w, height: h }),\n -1,\n )\n return\n }\n\n // RN's transform origin is the centre of the view, so the matrix GTK gets\n // is T(left + cx, top + cy) · matrix · T(-cx, -cy) — folded into the six\n // components here rather than chained through GskTransform, which would\n // cost five FFI hops instead of one.\n const cx = w / 2\n const cy = h / 2\n const transform = Gsk.Transform.new().matrix2d(\n matrix.xx,\n matrix.yx,\n matrix.xy,\n matrix.yy,\n left + cx - (matrix.xx * cx + matrix.xy * cy) + matrix.dx,\n top + cy - (matrix.yx * cx + matrix.yy * cy) + matrix.dy,\n )\n // gtk_widget_allocate consumes the transform (transfer full) and gtkx\n // hands ownership over with it — never unref it here (that aborts on\n // GLib's rc-box magic assertion).\n child.allocate(w, h, -1, transform)\n}\n\n// Engine flush → new rects for the same container size: schedule allocation\n// only. A measure-affecting change must use queueResize instead.\nexport const queueAllocate = (widget: Gtk.Widget): void => {\n widget.queueAllocate()\n}\n\nexport const queueResize = (widget: Gtk.Widget): void => {\n widget.queueResize()\n}\n"]}
1
+ {"version":3,"file":"layout-manager.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/layout-manager.ts"],"names":[],"mappings":"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","sourcesContent":["// RnGtkxLayout — a GObject subclass of GtkLayoutManager registered entirely\n// from JS (docs/research/layout-manager.md, \"B0\"). The manager obeys ONLY the\n// layout engine: measure() reports the engine-provided size (minimum ==\n// natural, children are never queried) and allocate() delegates to the engine,\n// which places every child at exactly its computed rect via allocateChild().\n// This is what removes the GTK-vs-RN layout conflicts at the root: window\n// minimum ratchet, overflow children inflating ancestors, and widget minimums\n// pushing rects.\nimport * as Gdk from \"@gtkx/gi/gdk\"\nimport * as Gsk from \"@gtkx/gi/gsk\"\nimport * as Gtk from \"@gtkx/gi/gtk\"\nimport { registerClass } from \"@gtkx/runtime\"\nimport type { Transform2D } from \"../../contracts\"\n\nexport type RnLayoutOrientation = \"horizontal\" | \"vertical\"\n\nexport type RnLayoutHooks = {\n // Engine-provided size for the given axis; minimum == natural == this value.\n measure(orientation: RnLayoutOrientation, forSize: number): number\n // Called during GTK's allocation phase with the container's final size.\n // The engine must size-allocate every child (allocateChild) synchronously.\n allocate(width: number, height: number): void\n}\n\n// The class must exist before any instance is created, but registration needs\n// GObject to be initialized — both hold after the bridge is imported, so the\n// class is registered lazily on first attach (also keeps the module safe to\n// import in environments without a display).\nlet RnGtkxLayoutClass: (new () => Gtk.LayoutManager) | null = null\n\nconst hooksByManager = new WeakMap<Gtk.LayoutManager, RnLayoutHooks>()\n\nconst ensureRegistered = (): new () => Gtk.LayoutManager => {\n if (RnGtkxLayoutClass) {\n return RnGtkxLayoutClass\n }\n\n // gtkx 1.0 renamed every vtable override slot to a `vfunc`-prefixed method\n // (vfuncMeasure/vfuncAllocate/vfuncGetRequestMode here — was measure/\n // allocate/getRequestMode on rc.4). This is not a workaround to tag: it is\n // the sanctioned 1.0 spelling, verified against\n // node_modules/@gtkx/gi/gtk/gtk.js's registerWrapperClass(LayoutManager,\n // ...) registry and gtk.d.ts. Left as a signpost because the failure mode\n // is silent and easy to reintroduce: registerClass() discovers overrides by\n // exact method-name match against that registry\n // (@gtkx/runtime/register-class.js discoverClassVfuncs) — a name that\n // doesn't match is neither wired nor rejected, it just never reaches the\n // vtable. That silent drop was the blank-content-pane root cause: with\n // allocate() never called, every View's children went unallocated while\n // native chrome (not driven by this layout manager) rendered fine.\n class RnGtkxLayout extends Gtk.LayoutManager {\n override vfuncMeasure(\n _widget: Gtk.Widget,\n orientation: Gtk.Orientation,\n forSize: number,\n ): [number, number, number, number] {\n const hooks = hooksByManager.get(this)\n if (!hooks) {\n return [0, 0, -1, -1]\n }\n const size = hooks.measure(\n orientation === Gtk.Orientation.HORIZONTAL ? \"horizontal\" : \"vertical\",\n forSize,\n )\n return [size, size, -1, -1]\n }\n\n // Trailing vfunc params (baseline) are dropped — JS tolerates the arity\n // mismatch and the linter rejects unused trailing args.\n override vfuncAllocate(\n _widget: Gtk.Widget,\n width: number,\n height: number,\n ): void {\n hooksByManager.get(this)?.allocate(width, height)\n }\n\n override vfuncGetRequestMode(): Gtk.SizeRequestMode {\n return Gtk.SizeRequestMode.CONSTANT_SIZE\n }\n }\n\n // Explicit typeName: bundlers minify class names and registerClass derives\n // the GType name from klass.name by default (FINDINGS §1).\n registerClass(RnGtkxLayout, { typeName: \"RnGtkxLayout\" })\n RnGtkxLayoutClass = RnGtkxLayout\n return RnGtkxLayout\n}\n\n// Replaces the widget's layout manager with an RnGtkxLayout driven by `hooks`.\n// The container must attach its children in a layout-child-free way (GtkBox\n// append / set_parent) — GtkFixed.put demands a GtkFixedLayoutChild from the\n// current manager and is incompatible (FINDINGS §2).\nexport const attachRnLayout = (\n widget: Gtk.Widget,\n hooks: RnLayoutHooks,\n): void => {\n const Klass = ensureRegistered()\n if (hooksByManager.has(widget.getLayoutManager() as Gtk.LayoutManager)) {\n throw new Error(\"attachRnLayout: widget already has an RnGtkxLayout\")\n }\n const manager = new Klass()\n hooksByManager.set(manager, hooks)\n widget.setLayoutManager(manager)\n}\n\n// Drops the hooks and hands layout back to a fresh manager of the widget's\n// own class default. Safe to call on widgets that were never attached.\nexport const detachRnLayout = (widget: Gtk.Widget): void => {\n const manager = widget.getLayoutManager() as Gtk.LayoutManager | null\n if (!manager || !hooksByManager.has(manager)) {\n return\n }\n hooksByManager.delete(manager)\n widget.setLayoutManager(null as unknown as Gtk.LayoutManager)\n}\n\n// Places one child at an exact rect, optionally under a visual transform.\n// Only meaningful from inside an allocate() hook — GTK forbids\n// size-allocating outside the layout phase.\n//\n// The transform path is gtk_widget_allocate(), which is what\n// gtk_widget_size_allocate() itself calls with a plain translate — the child\n// keeps the width/height Yoga gave it and only its placement matrix changes,\n// which is exactly RN's \"transforms are visual only\". GTK4 inverts that\n// matrix in gtk_widget_pick(), so input follows the rotated/scaled shape for\n// free (measured: docs/research/transforms.md).\nexport const allocateChild = (\n child: Gtk.Widget,\n x: number,\n y: number,\n width: number,\n height: number,\n matrix: Transform2D | null = null,\n): void => {\n const left = Math.round(x)\n const top = Math.round(y)\n const w = Math.max(0, Math.round(width))\n const h = Math.max(0, Math.round(height))\n\n if (!matrix) {\n child.sizeAllocate(\n new Gdk.Rectangle({ x: left, y: top, width: w, height: h }),\n -1,\n )\n return\n }\n\n // RN's transform origin is the centre of the view, so the matrix GTK gets\n // is T(left + cx, top + cy) · matrix · T(-cx, -cy) — folded into the six\n // components here rather than chained through GskTransform, which would\n // cost five FFI hops instead of one.\n const cx = w / 2\n const cy = h / 2\n const transform = Gsk.Transform.new().matrix2d(\n matrix.xx,\n matrix.yx,\n matrix.xy,\n matrix.yy,\n left + cx - (matrix.xx * cx + matrix.xy * cy) + matrix.dx,\n top + cy - (matrix.yx * cx + matrix.yy * cy) + matrix.dy,\n )\n // gtk_widget_allocate consumes the transform (transfer full) and gtkx\n // hands ownership over with it — never unref it here (that aborts on\n // GLib's rc-box magic assertion).\n child.allocate(w, h, -1, transform)\n}\n\n// Engine flush → new rects for the same container size: schedule allocation\n// only. A measure-affecting change must use queueResize instead.\nexport const queueAllocate = (widget: Gtk.Widget): void => {\n widget.queueAllocate()\n}\n\nexport const queueResize = (widget: Gtk.Widget): void => {\n widget.queueResize()\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"slot-portal.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/slot-portal.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,aAAa,EAA0C,MAAM,OAAO,CAAA;AAE7E,2EAA2E;AAC3E,yEAAyE;AACzE,8CAA8C;AAC9C,MAAM,YAAY,GAAG,WAGnB,CAAA;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,QAAmB,EACnB,MAAsB,EACtB,IAAY,EACZ,GAAY,EACD,EAAE,CACb,YAAY,CACV,aAAa,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,EACzD,MAAM,EACN,GAAG,CACJ,CAAA","sourcesContent":["// Rendering children into a NAMED SLOT of an object that is not their parent.\n//\n// gtkx's own `createPortal(children, container)` targets the container's\n// DEFAULT slot — \"children\", the one a widget takes another widget through.\n// Everything else an object can be given declaratively is a named slot\n// reached in JSX by an element-valued PROP: a window's `Gio.ActionMap`\n// (`actions`), the event controllers on a widget (`controllers`), an\n// `AdwApplicationWindow`'s `breakpoints`. Those slots are what the\n// reconciler routes an element-valued prop into — it wraps the prop's value\n// in an internal element that carries the slot name, and that element is\n// what actually places children into the named slot.\n//\n// So a portal whose single child is that internal element lands its children\n// in a named slot of a remote object, which is what `WindowActions` and\n// `WindowControllers` need: declare in the app tree, attach to the window.\n//\n// RC4-WORKAROUND(prop-portal): the internal element's name is spelled out\n// here because @gtkx/react exports it from neither its public entry point\n// nor its `/internal` subpath — only from a deep module path, which this\n// package does not reach into. The bridge is the one module allowed to know\n// a gtkx internal, so the knowledge is confined to this file: if the name\n// ever changes, exactly one line moves. See docs/gtkx-rc4-notes.md.\nimport type * as GObject from \"@gtkx/gi/gobject\"\nimport { createPortal } from \"@gtkx/react\"\nimport { createElement, type FunctionComponent, type ReactNode } from \"react\"\n\n// Typed as a component rather than an intrinsic tag: \"gtkx:prop\" is not in\n// the generated JSX.IntrinsicElements map (it is not a GObject type), so\n// createElement would reject the bare string.\nconst PROP_ELEMENT = \"gtkx:prop\" as unknown as FunctionComponent<{\n propName: string\n children?: ReactNode\n}>\n\n/**\n * A React portal that renders `children` into `target`'s named `slot`\n * instead of into the tree position where it is written — the declarative\n * equivalent of passing `<Target slot={children} />`, for a target the\n * declaring component does not render.\n *\n * The children stay part of the React tree where the portal element sits,\n * so context, state and effects behave exactly as they would in place.\n */\nexport const createSlotPortal = (\n children: ReactNode,\n target: GObject.Object,\n slot: string,\n key?: string,\n): ReactNode =>\n createPortal(\n createElement(PROP_ELEMENT, { propName: slot }, children),\n target,\n key,\n )\n"]}
1
+ {"version":3,"file":"slot-portal.js","sourceRoot":"","sources":["../../../src/gtkx/bridge/slot-portal.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,aAAa,EAA0C,MAAM,OAAO,CAAA;AAE7E,2EAA2E;AAC3E,yEAAyE;AACzE,8CAA8C;AAC9C,MAAM,YAAY,GAAG,WAGnB,CAAA;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,QAAmB,EACnB,MAAsB,EACtB,IAAY,EACZ,GAAY,EACD,EAAE,CACb,YAAY,CACV,aAAa,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,EACzD,MAAM,EACN,GAAG,CACJ,CAAA","sourcesContent":["// Rendering children into a NAMED SLOT of an object that is not their parent.\n//\n// gtkx's own `createPortal(children, container)` targets the container's\n// DEFAULT slot — \"children\", the one a widget takes another widget through.\n// Everything else an object can be given declaratively is a named slot\n// reached in JSX by an element-valued PROP: a window's `Gio.ActionMap`\n// (`actions`), the event controllers on a widget (`controllers`), an\n// `AdwApplicationWindow`'s `breakpoints`. Those slots are what the\n// reconciler routes an element-valued prop into — it wraps the prop's value\n// in an internal element that carries the slot name, and that element is\n// what actually places children into the named slot.\n//\n// So a portal whose single child is that internal element lands its children\n// in a named slot of a remote object, which is what `WindowActions` and\n// `WindowControllers` need: declare in the app tree, attach to the window.\n//\n// 1.2-WORKAROUND(prop-portal): the internal element's name is spelled out\n// here because @gtkx/react exports it from neither its public entry point\n// nor its `/internal` subpath — only from a deep module path, which this\n// package does not reach into. The bridge is the one module allowed to know\n// a gtkx internal, so the knowledge is confined to this file: if the name\n// ever changes, exactly one line moves. See docs/gtkx-1.2-notes.md.\nimport type * as GObject from \"@gtkx/gi/gobject\"\nimport { createPortal } from \"@gtkx/react\"\nimport { createElement, type FunctionComponent, type ReactNode } from \"react\"\n\n// Typed as a component rather than an intrinsic tag: \"gtkx:prop\" is not in\n// the generated JSX.IntrinsicElements map (it is not a GObject type), so\n// createElement would reject the bare string.\nconst PROP_ELEMENT = \"gtkx:prop\" as unknown as FunctionComponent<{\n propName: string\n children?: ReactNode\n}>\n\n/**\n * A React portal that renders `children` into `target`'s named `slot`\n * instead of into the tree position where it is written — the declarative\n * equivalent of passing `<Target slot={children} />`, for a target the\n * declaring component does not render.\n *\n * The children stay part of the React tree where the portal element sits,\n * so context, state and effects behave exactly as they would in place.\n */\nexport const createSlotPortal = (\n children: ReactNode,\n target: GObject.Object,\n slot: string,\n key?: string,\n): ReactNode =>\n createPortal(\n createElement(PROP_ELEMENT, { propName: slot }, children),\n target,\n key,\n )\n"]}
@@ -10,12 +10,14 @@
10
10
  // state cannot live on `this` — same reasoning as hooksByManager in
11
11
  // layout-manager.ts).
12
12
  //
13
- // `Gtk.Widget.snapshot()` is a real, working vfunc in gtkx's codegen
13
+ // `Gtk.Widget`'s snapshot slot is a real, working vfunc in gtkx's codegen
14
14
  // (node_modules/@gtkx/gi/gtk/gtk.js, registerWrapperClass(Widget, ...) lists
15
- // it with byteOffset 320) even though it is missing from the shipped
16
- // `gtk.d.ts` the type generator drops it, the codegen that actually wires
17
- // vfuncs does not. Verified by reading the generated registry before writing
18
- // any of this; see epic.md.
15
+ // it, keyed `vfuncSnapshot` since gtkx 1.0 see the override below for why
16
+ // the method name matters). On rc.4 it was missing from the shipped
17
+ // `gtk.d.ts` even though the registry always had it (the type generator
18
+ // dropped it, the codegen that actually wires vfuncs did not); 1.0 ships the
19
+ // type too. Verified by reading the generated registry before writing any of
20
+ // this; see epic.md.
19
21
  import * as Gdk from "@gtkx/gi/gdk";
20
22
  import * as Graphene from "@gtkx/gi/graphene";
21
23
  import * as Gsk from "@gtkx/gi/gsk";
@@ -266,11 +268,16 @@ const ensureRegistered = () => {
266
268
  // style, no content) and their own snapshot() no-ops for anything that
267
269
  // is not the mounted <Svg> root (see below), so nothing is ever
268
270
  // double-painted through GTK's normal child-snapshot path.
271
+ // gtkx 1.0 renamed Widget's vtable override slot from `snapshot` to
272
+ // `vfuncSnapshot` (verified against node_modules/@gtkx/gi/gtk/gtk.d.ts and
273
+ // gtk.js's registerWrapperClass(Widget, ...) registry — see
274
+ // layout-manager.ts's RnGtkxLayout for the full mechanism writeup: a plain
275
+ // `snapshot` override here would silently never reach the vtable).
269
276
  class RnGtkxSvgNode extends Gtk.Box {
270
277
  // Only ever invoked by GTK on the mounted <Svg> root (nothing calls
271
278
  // snapshotChild() on the inert descendant instances). Defensive no-op
272
279
  // otherwise, so a stray direct call never throws.
273
- snapshot(snapshot) {
280
+ vfuncSnapshot(snapshot) {
274
281
  const descriptor = nodeDescriptors.get(this);
275
282
  if (!descriptor || descriptor.kind !== "svg") {
276
283
  return;