Skip to content

Patches for Observable Drag Detection / Updates - #12

Open
joshpar wants to merge 1 commit into
codelynx:developfrom
joshpar:develop
Open

Patches for Observable Drag Detection / Updates#12
joshpar wants to merge 1 commit into
codelynx:developfrom
joshpar:develop

Conversation

@joshpar

Copy link
Copy Markdown

Summary
On the GTK4 backend, a drag whose onChanged handler writes to @observable state fires only once per press — the motion after the first drag-update is lost — so a "drag to set a value" control (knob, slider, XY pad) backed by an @observable model can't track the drag.

Root cause
GTKViewHost.rebuild() has a narrow mutation path that applies text / color / canvas changes in place (gtkCanApplyTextColorHostMutation accepts .canvasContent), preserving the widget tree — and with it any in-flight GtkGestureDrag. But that path is guarded by !fromObservation: an @Observable-driven change always falls through to a full rebuild, which tears down and recreates the subtree, cancelling the active gesture. The guard exists because the narrow path did not re-run body under withObservationTracking, which would leave the one-shot subscription dead after the first change.

Fix
Let @Observable-driven changes use the narrow path too, and re-register the subscription there: when fromObservation, run the narrow path's describe pass under withObservationTracking, so re-reading the observed properties re-subscribes — the same re-registration the full rebuild gets from buildBodyWithTracking, without the teardown. Non-narrow-applicable changes still fall through to the full rebuild. @State behaviour is unchanged.

Validation
Ubuntu 24.04 (arm64), GTK4, Swift 6.3.3. An @Observable-backed Canvas knob with .onDrag: before — one step per press; after — tracks continuously, and subsequent @observable changes still redraw (subscription stays live). A @State knob worked before and still does.

Scope
One function, GTKViewHost.rebuild(). No API change. The narrow-path guard drops !fromObservation, and the describe call is wrapped in withObservationTracking on the fromObservation branch, mirroring buildBodyWithTracking.

CopilotAI lite review requested due to automatic review settings August 22, 2026 15:49
@joshparjoshpar changed the title Patches for Lyrebird UI Linux workPatches for Observable Drag Detection / UpdatesAug 22, 2026
@joshpar

Copy link
Copy Markdown
Author

Thanks for your consideration! This is supporting part of a Linux port for Lyrebird ( https://realizedsound.mooo.com/josh/Lyrebird ), a synthesis and music composition environment written for Swift.

CopilotAI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The change is narrowly scoped to GTKViewHost.rebuild() and correctly re-establishes Observation tracking on the narrow path to avoid widget-tree teardown during active gestures.

Pull request overview

This PR fixes a GTK4 backend interaction bug where @Observable-driven updates during an in-flight drag caused GTKViewHost.rebuild() to fall back to a full widget-tree rebuild, canceling the active GtkGestureDrag and making drag updates appear to fire only once.

Changes:

  • Expands the narrow in-place mutation path in GTKViewHost.rebuild() to run for @Observable-triggered rebuilds as well (instead of forcing a full rebuild).
  • When the rebuild was triggered by Observation, wraps the narrow-path describeBody pass in withObservationTracking so the one-shot observation subscription is re-registered without tearing down the widget subtree.
File summaries
FileDescription
Sources/Backend/GTK4/Rendering/GTKViewHost.swiftAllows Observation-triggered rebuilds to use the in-place mutation path while re-subscribing to withObservationTracking to keep updates flowing during gestures.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@joshpar