Skip to content

fix(field): scissors right-click no longer destroys the trace when the layer is hidden#81

Merged
dustenhubbard merged 1 commit into
mainfrom
fix/scissors-rightclick-delete
Jul 18, 2026
Merged

fix(field): scissors right-click no longer destroys the trace when the layer is hidden#81
dustenhubbard merged 1 commit into
mainfrom
fix/scissors-rightclick-delete

Conversation

@dustenhubbard

Copy link
Copy Markdown
Owner

Upstream issue SynapseWeb#51, fixed fork-first.

Root cause: scissorsPress picks up a trace by DELETING it (raw section.deleteTraces, unguarded), relying on lineRelease -> newTrace to recreate it. newTrace is wrapped by @field_interaction, which returns early when hide_trace_layer is set, so with the trace layer hidden the pickup deleted and the recreate silently no-oped: permanent trace loss. (Verified across all 8 hidden-state combos: per-trace 'hide others' does NOT trigger it; only the layer-hidden mode does.)

Fix: lineRelease detects whether newTrace actually added a replacement (added_traces delta) and restores the original trace if not; autoMerge and the modify log gate on the same signal. Knife and merge delete-and-recreate atomically inside one guarded method and were confirmed immune.

Port outlook: affected files are byte-identical to upstream main; clean cherry-pick when we contribute it.

Repro test: 4 layer-hidden parametrizations fail before, all 8 pass after. Suite: 1198 passed, 5 pre-existing xfails.

🤖 Generated with Claude Code

…ayer hidden

The scissors tool picks a trace up by DELETING it up front in scissorsPress
(a raw section.deleteTraces call, not guarded by @field_interaction) and relies
on the right-click completion in lineRelease to recreate it via newTrace. But
newTrace is wrapped by @field_interaction, which is a no-op while the trace
layer is hidden. So a scissors pickup followed by a right-click completion with
the trace layer hidden deleted the trace with nothing put back, silently
destroying the user's work (upstream issue #51).

lineRelease now detects whether newTrace actually added the replacement (via the
section.added_traces delta, since the return value carries log_event which is
forced False while scissoring) and, when it did not, restores the original
picked-up trace instead of leaving it deleted. Also gates autoMerge and the
scissors "Modify trace(s)" log on that same signal so neither fires when no
trace was created.

Sibling tools were checked: knife (cutTrace) and mergeTraces delete and recreate
inside a single @field_interaction method, so they skip atomically when hidden
and never lose data. Only the scissors tool split its delete from its guarded
recreate across two event handlers.

Regression test drives the real scissorsPress + lineRelease + newTrace headless.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dustenhubbard
dustenhubbard enabled auto-merge (squash) July 18, 2026 22:46
@dustenhubbard
dustenhubbard merged commit dbc7cc7 into main Jul 18, 2026
1 check passed
@dustenhubbard
dustenhubbard deleted the fix/scissors-rightclick-delete branch July 18, 2026 22:47
dustenhubbard added a commit that referenced this pull request Jul 23, 2026
…ayer hidden (#81)

The scissors tool picks a trace up by DELETING it up front in scissorsPress
(a raw section.deleteTraces call, not guarded by @field_interaction) and relies
on the right-click completion in lineRelease to recreate it via newTrace. But
newTrace is wrapped by @field_interaction, which is a no-op while the trace
layer is hidden. So a scissors pickup followed by a right-click completion with
the trace layer hidden deleted the trace with nothing put back, silently
destroying the user's work (upstream issue #51).

lineRelease now detects whether newTrace actually added the replacement (via the
section.added_traces delta, since the return value carries log_event which is
forced False while scissoring) and, when it did not, restores the original
picked-up trace instead of leaving it deleted. Also gates autoMerge and the
scissors "Modify trace(s)" log on that same signal so neither fires when no
trace was created.

Sibling tools were checked: knife (cutTrace) and mergeTraces delete and recreate
inside a single @field_interaction method, so they skip atomically when hidden
and never lose data. Only the scissors tool split its delete from its guarded
recreate across two event handlers.

Regression test drives the real scissorsPress + lineRelease + newTrace headless.
Sign up for free to 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.

1 participant