Skip to content

fix(editor): Tracks-pane faders can be dragged again - #323

Merged
ChrisBeWithYou merged 3 commits into
mainfrom
fix/editor-track-fader-row-drag
Jul 19, 2026
Merged

fix(editor): Tracks-pane faders can be dragged again#323
ChrisBeWithYou merged 3 commits into
mainfrom
fix/editor-track-fader-row-drag

Conversation

@ChrisBeWithYou

@ChrisBeWithYou ChrisBeWithYou commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Reported twice by testers:

I cant seem to click and drag the sliders on the left hand side track pane left and right, i can only click and send their slider to a new location on their path

yeah you have like a split second to move before it goes into "drag the track" mode

Cause

Track rows carry draggable="true" for reorder, so a native HTML5 drag beginning anywhere inside one steals the gesture. A plain click looked fine only because it never moved far enough to pass the browser's drag threshold — the "split second" is exactly that threshold.

Why the obvious fix doesn't work

The guard cannot live in dragstart. The drag source is the row, so dragstart.target is the row, not the control under the pointer — they're indistinguishable there. I confirmed this in Chromium against a minimal repro before settling on the approach:

dragstart.target on a row containing a range input:
    "guard | closestInput=false"

guard at dragstart : value 53.0 -> 55.0    dragover=24   <- drag stole it
draggable toggle   : value 53.0 -> 101.0   dragover=0    <- fader kept it

draggable="false" on the input is inert for the same reason: the drag source resolves to the nearest draggable ancestor regardless of the child's own attribute.

I mention this because I wrote the dragstart version first and it passed a unit test — the test constructed the event with target set to the fader, which is not what the browser does. The browser check is what caught it.

The fix

The row drops out of the drag on pointerdown when the gesture starts on a form control, and rejoins on pointerup/pointercancel. Reorder from the row body is untouched.

Note for a follow-up

This leaves the existing rename-input branch in the dragstart handler as dead code — it tests the same target that can never match, so it has presumably never fired. I left it alone to keep this diff scoped to the reported bug, but it's worth removing on its own.

Tests

tests/track_session_fader_row_drag.test.mjs — the row leaves the drag on a fader press (fails on main), comes back on release, comes back on cancel, is untouched by a press on the row body, and doesn't leak a pointerup listener per gesture.

Distinct from tests/track_session_fader_drag.test.mjs, which covers the innerHTML rebuild destroying the slider mid-drag. Either break alone kills the fader, so both are now pinned.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Tracks-pane faders and other row controls can be dragged without accidentally reordering tracks.
    • Dragging from the track body continues to reorder tracks as expected.
    • Improved handling of pointer interactions to prevent unintended drag behavior.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bdcface5-ba09-4d2b-8300-0c7b3778c561

📥 Commits

Reviewing files that changed from the base of the PR and between 5e6c34e and b7ab4d8.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • src/track-session.js
  • tests/track_session_fader_row_drag.test.mjs

📝 Walkthrough

Walkthrough

Track-row controls now temporarily disable row dragging during pointer gestures, preventing accidental reordering from faders and other controls. Row-body dragging remains enabled, and regression tests cover restoration, cancellation, and listener cleanup.

Changes

Track control drag handling

Layer / File(s) Summary
Guard control gestures from row dragging
src/track-session.js, CHANGELOG.md
Pointer interactions beginning on inputs, selects, textareas, or buttons temporarily set the row as non-draggable until the gesture ends; the changelog documents the fix.
Validate control and row drag behavior
tests/track_session_fader_row_drag.test.mjs
Regression tests cover faders, rename inputs, buttons, row-body dragging, pointer cancellation, restoration, and pointerup listener cleanup.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main user-facing fix: tracks-pane faders are draggable again.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/editor-track-fader-row-drag

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Two testers hit this: a fader could only be clicked to jump the thumb to a new
position, and "you have like a split second to move before it goes into drag-
the-track mode".

Track rows carry draggable="true" for reorder, so a native drag beginning
anywhere inside one steals the gesture. A plain click looked fine only because
it never moved far enough to pass the browser's drag threshold; any real drag
handed the pointer to the row reorder.

The guard cannot live in dragstart. The drag source is the ROW, so
dragstart.target is the row and not the control under the pointer — the two are
indistinguishable there. Confirmed in Chromium against a minimal repro:

    dragstart.target on a row containing a range input:
        "guard | closestInput=false"
    guard at dragstart   : value 53.0 -> 55.0   dragover=24  (drag stole it)
    draggable toggle     : value 53.0 -> 101.0  dragover=0   (fader kept it)

draggable="false" on the input is inert for the same reason: the drag source
resolves to the nearest draggable ancestor regardless.

So the row is taken out of the drag on pointerdown when the gesture starts on a
form control, and put back on pointerup/pointercancel. Reorder from the row body
is untouched.

Note this leaves the existing rename-input branch in the dragstart handler as
dead code — it tests the same target that can never match. Left alone here to
keep the diff to the reported bug; worth removing on its own.

Tests: tests/track_session_fader_row_drag.test.mjs — the row leaves the drag on
a fader press (fails on main), comes back on release, comes back on cancel, is
untouched by a press on the row body, and does not leak a pointerup listener per
gesture. Distinct from tests/track_session_fader_drag.test.mjs, which covers the
innerHTML rebuild destroying the slider mid-drag; either break alone kills the
fader, so both are pinned.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: ChrisBeWithYou <chris@rifflarr.local>
@ChrisBeWithYou
ChrisBeWithYou force-pushed the fix/editor-track-fader-row-drag branch from 5990b1b to 7c976d9 Compare July 19, 2026 08:20
ChrisBeWithYou and others added 2 commits July 19, 2026 03:30
The rename-input branch in the track-row dragstart handler tested
event.target.closest('[data-track-rename-input]'). The drag source is the ROW,
so event.target is always the row and never the control under the pointer —
the selector could not match, and the branch has never fired.

It was trying to keep a control's gesture out of the row reorder, which the
preceding commit now does correctly at pointerdown by taking the row out of the
drag. The rename input is a form control, so it is covered by that path; the
suite now pins it, which is what makes deleting this safe rather than merely
tidy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: ChrisBeWithYou <chris@rifflarr.local>
@ChrisBeWithYou
ChrisBeWithYou merged commit a4de31c into main Jul 19, 2026
4 checks passed
@ChrisBeWithYou
ChrisBeWithYou deleted the fix/editor-track-fader-row-drag branch July 19, 2026 21:30
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