fix(field): scissors right-click no longer destroys the trace when the layer is hidden#81
Merged
Merged
Conversation
…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
enabled auto-merge (squash)
July 18, 2026 22:46
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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