Repository navigation
T-bar as a real lever (ping-pong), flicker fixed, T-bar widget - #113
Merged
Merged
Conversation
…T-bar widget - The mixer keeps where the lever rests (panel.tbar_end, saved) and flips it when the T-bar, an Auto or a Cut of a held transition completes. POST /mixer/position takes `lever` (0 top .. 1 bottom, counted from the resting end; 2 % deadband) besides `position` (unchanged); GET /console -> tbar. position 1 straight from rest no longer answers 500. - GUI: shared TBar (src/tbar.ts): relative grab, one request at a time in order, latched at the end until release, no native drag/selection cancelling the pointer, Auto runs the handle to the other end. - /widget/tbar[?me=<n>][&buttons=false] with Cut and Auto. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01St7QwmonpoG9EEEqaLFXLi
- A lever request carries `from` (the end its drag began at): a drag from an end another console's Auto or Cut changed is ignored (no take back); the GUI latches such a drag. A lever without `from` (hardware) is picked up at the new resting end after each change of the end. - Stinger / BKGD off: one Auto per drag (GUI latches after the first send; the server flip plus from/pickup ignore the rest). - Auto flips the lever's end only once it has started. - A held lever snaps within 2 % of either end. - GUI: the handle resyncs to the mixer after a drag that did not complete (also when the pointer capture is lost); newest-wins send queue as createSender, tested. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01St7QwmonpoG9EEEqaLFXLi
- A lever without `from` counts only after pickup at the resting end, also
while a transition is held; pickup is armed at start, on engine restart,
on a loaded state and on each change of the end; several hardware levers
are told apart by `source`.
- A `from` that is not the resting end is ignored also while something is
held.
- Ignored values answer {status: "ignored", reason: stale_from|pickup}
(logged at debug).
- GUI: each queued lever value keeps the `from` of its own drag.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01St7QwmonpoG9EEEqaLFXLi
This was referenced Oct 23, 2026
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.
Adrian's T-bar item (2026-10-23).
1. The T-bar is a real lever (ping-pong)
Before: at the bottom (transition complete) the GUI handle jumped back to the top; a mouse at the end of travel kept sending positions near 1, which started the next transition (and positions sent in parallel could arrive out of order) → flicker between full up and full down.
Server state (so every console, the widget and a hardware panel agree):
MixerPanel.tbar_end(top|bottom, defaulttop, saved and exported): where the lever rests. Each transition the T-bar or an Auto completes (and a Cut of a held one) flips it. A Cut at rest leaves it.POST /mixer/positiontakeslever(0 top … 1 bottom, where the lever physically is) as an alternative toposition. The mixer turns it into the progress from the resting end (leverfrom the top,1 − leverfrom the bottom). Within 2 % of the resting end it starts nothing (end-of-travel hysteresis, also for hardware panels).positionkeeps its meaning (the transition's progress); the engine API is unchanged. Exactly one of the two is required (422 otherwise).GET /console→tbarper ME:end,position(of a held transition),lever.position: 1straight from rest answered 500 (KeyError); now it completes the transition.GUI (
components/TBar.tsx, logic insrc/tbar.ts, shared with the widget):preventDefaulton pointerdown, no native drag,user-select: none: Chrome cancelled the pointer mid-drag when text was selected (pointercancel, found while testing; likely the "sometimes" in the flicker).2. T-bar widget
/widget/tbar[?me=<n>][&buttons=false][&theme=…], registered like the others:widget.tsxroute, nginxlocation = /widget/tbar(checksme,buttons,theme; CSP frame-ancestors),GET /api/v1/widgets(paramsmedefault 1,buttonsdefault true; min 120×240), README. It shows the same lever with Cut and Auto (as in the bus widget).Tests
tests/test_tbar.py: a drag down that completes and stays at the bottom, wiggling at the end starts nothing, the reverse drag up completes the next one, back to the start without the swap, Auto (from rest and from a held position) and Cut (at rest and held) leave the lever at the right end, the API withlever/position/neither/both, consoletbar,tbar_endin the export. Widgets list updated.gui/scripts/check-tbar.ts(in CI): a drag down that completes (latched, handle stays), the reverse drag up, the deadband at both ends, back to the start, picking up a transition held elsewhere, no repeats, the Auto travel time.~/mxl-lab/shots/fxfb-tbar-1-bottom.jpg,fxfb-tbar-2-held-up.jpg,fxfb-tbar-3-after-auto.jpg,fxfb-tbar-5-widget-held.jpg.🤖 Generated with Claude Code
https://claude.ai/code/session_01St7QwmonpoG9EEEqaLFXLi