Skip to content

Add scope controls - for remote display - #120

Open
fabiojvalente wants to merge 18 commits into
developfrom
feautre/video-tx-add-screen-buttons
Open

Add scope controls - for remote display#120
fabiojvalente wants to merge 18 commits into
developfrom
feautre/video-tx-add-screen-buttons

Conversation

@fabiojvalente

@fabiojvalente fabiojvalente commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Continues #96 after #97 landed the Radio Display capture. Clicks on the MJPEG picture never reach the TFT, so this PR drives the radio’s own scope over CAT (SS) from a Controls button on the video bar instead of drawing overlays on the frame.

That matches the approach in #109 and the Index Radio Scope card already on develop. With Radio Display on, those buttons live in a modeless dialog (same pattern as Mic & Gain): they do not cover the picture, and they work on Index and on the /RadioDisplay pop-out.

  • Shared _RadioScopeButtonsPartial so the dialog and the standalone Radio Scope card stay in sync.
  • Enabling Radio Display hides the standalone card so the same controls are not shown twice.
  • Controls: span, W/F vs 3DSS, Center/Cursor/Fix, L/N/S, speed, Level, Peak, Marker, Color, AF-FFT / OSC attenuators and timebase.
  • FTdx101MP/D: MAIN / SUB plus narrow-band colour (SupportsScopeNarrowBandColor). FTdx10: single receiver, no NB Col row (CAT P4/P5 are fixed at 0; confirmed on the radio). FT-710 stays gated until ss-write-probe.ps1 has been run on one.
  • MULTI still has no CAT command; the group is collapsed with a tooltip to press it on the TFT.
  • Unit tests for colour / AF-FFT packing and the FTdx10 NB Col gate (ScopeCommandsTests). Manual and design note updated.

Test plan

  • FTdx10 or FTdx101: Radio Display on → Controls opens a floating dialog; span / mode / speed / level / peak / marker / colour change the radio’s TFT and the highlighted buttons follow the front panel.
  • FTdx101: MAIN / SUB each drive their own scope; NB Col appears and paints the roofing-filter passband.
  • FTdx10: no MAIN/SUB row, no NB Col row; Colour 1–11 still works.
  • /RadioDisplay pop-out has the same Controls button; dialog is draggable and does not sit on the picture.
  • Radio Display off: standalone Radio Scope card is back (including Hold). Radio Display on: that card is hidden.
  • dotnet test Tests/YaesuWebControl.Tests/YaesuWebControl.Tests.csproj

@fabiojvalente
fabiojvalente changed the base branch from main to develop August 18, 2026 21:57
@fabiojvalente fabiojvalente changed the title Feautre/video tx add scope controls Add scope controls - For remote display Aug 19, 2026
@fabiojvalente fabiojvalente changed the title Add scope controls - For remote display Add scope controls - for remote display Aug 19, 2026
@mm5agm

mm5agm commented Aug 19, 2026

Copy link
Copy Markdown
Owner

@fabiojvalente I know this is still marked Work in Progress, so some of the
below may already be on your list. I would rather send it now than after you
have built more on top of it.

It builds clean here on net10.0 (0 warnings) and the test project passes 29/29.
Thank you for adding ScopeCommandsTests - that is the first cover the scope
commands have had, and it is the part where a wrong answer is silent rather
than visible.

I have now bench-tested it on the FTdx101MP. Everything I drove from the dialog
matched the radio's own front panel exactly, MAIN and SUB. Putting the toolbar
inside the video panel is still the right call, and this PR is that idea
properly done.

Three things I think are real

1. Hold has nowhere left to live. data-setting="hold" exists only in
_RadioScopePartial, and Index.cshtml now renders that partial only when
!Model.VideoDisplayEnabled. _RadioScopeButtonsPartial, which the Controls
dialog uses, has no Hold button. So with Radio Display enabled there is no way
to reach Hold short of turning Radio Display back off in Settings.

Everything else for Hold is already in place, which is what makes it look like
an oversight rather than a decision: SupportsScopeHold returns true for the
FtdX10 as well as the '101, and ScopeController handles it at both the write
and the read. Only the button is missing.

2. NB Col is not gated, and the FtdX10 does not appear to have it. This is
the one I would most like you to check, because it is a write to your radio
rather than mine.

The FTDX10 CAT manual gives SS P2=3 as:

P3  0: COLOR-1 - A: COLOR-11 (DIRECT SAMPLING)
P4 - P7: 0: Fixed

and the FTDX10 operating manual describes COLOR as changing the scope colour
"from 11 types" - the direct sampling palette only. The '101 is the one with a
second axis (COLOR-12..18 narrow band, plus an on/off). Your radio has the
hybrid dual SDR display, but as far as both manuals go it has no separate
colour for the narrow band trace.

_RadioScopeButtonsPartial renders the NB Col row unconditionally, with no
capability check - unlike AF-FFT and MULTI immediately around it. So on an
FtdX10 the row appears, and SetColor emits SS{band}3{color}{nb}{on}00;,
putting non-zero values into two parameters your manual documents as fixed at
zero. Leaving it on Off is harmless; clicking On or a colour 1-6 is not.

RadioCapabilities already has the shape for this - a
SupportsScopeNarrowBandColor alongside HasPerReceiverScopes, true for
"FTdx101MP" or "FTdx101D" only, would drop straight in.

I cannot test this, so if your FtdX10 does show a narrow band colour setting on
its front panel then the manuals are incomplete and I am wrong - but it seems
worth ten seconds on the rig before this merges.

3. Colour and AF-FFT clicks can write axes the operator never touched.
_sendColor and _sendAfFft always emit all three packed axes out of
this.state, falling back to '0' per axis when it is null. If the initial
read did not land - a 503 "Radio busy", or a short disconnect - the first click
sends 0 for the two axes that were never touched. In practice that is NB
colour forced to Off, palette back to 1, OSC attenuation to 0 dB, timebase to
1 ms.

What makes me fairly confident this one is real rather than theoretical: the
merge logic already in ScopeController (supplied < 2/3) looks like it was
written to guard exactly this, but nothing can reach it, because the client
never sends the short form. Sending only the axis that changed would light that
path up.

NB Col - your tooltip is right, and I nearly filed it as a bug

Worth recording because I got this wrong first, in the other direction. The
screenshots may be useful to you given your radio probably cannot show any of
this.

I changed the IF WIDTH expecting the NB colour region to follow it, saw nothing
move, and went to the CAT manual - which names the two palettes but never says
where the second one is painted. I wrongly concluded it was unrelated to the
filter. Your tooltip is what sent me back to the bench, and the bench agrees
with you.

The refinement I would make: the width of that region comes from the roofing
filter
(R.FIL), not the DSP WIDTH knob, which works downstream of it. Swept
at 100 kHz span with NB Col On, nothing else touched:

Screenshot 2026-08-19 104337

R.FIL 12 kHz - the narrow band region is the wide orange block.

Screenshot 2026-08-19 104434

R.FIL 3 kHz - same settings, the block is now a narrow stripe.

Screenshot 2026-08-19 104539

R.FIL 600 Hz - down to a sliver.

Screenshot 2026-08-19 104629

And the same thing read backwards - R.FIL 600 Hz at 1 kHz span, where the
narrow band region now fills most of the display.

One detail worth knowing if anything you build depends on where that region
sits: it is not centred on the dial frequency. It follows the passband actually
being received, so in DATA-U here it sits roughly 1.5 kHz above the dial
reading. I have only looked at DATA-U, so I would not assume more than that.

That is also why I saw nothing the first time, and the reason turns out to be
simpler than the one I first reached for: I was turning the DSP WIDTH knob, and
WIDTH does not move this region at all. Only R.FIL does. Saying "roofing filter"
rather than "IF filter passband" in the tooltip would have saved me the trip.

One limit on all of the above, so nobody takes it further than the evidence
goes: at R.FIL 12 kHz on a 5 kHz span the visible region is about 3.5 kHz wide,
not 12 kHz. Whether the outer edge there is the roofing filter or the DSP width
taking over as the narrower of the two, I cannot tell from what I have run.

MULTI, and the two-receiver layout

Screenshot 2026-08-19 110333

Same settings with MULTI pressed on the radio, so you can see what your AF-FFT
and OSC controls are actually aimed at - the oscilloscope and AF-FFT panes
appear below the scope, and your collapsed MULTI section drives them from
there. The note you put in the UI about pressing MULTI on the TFT first is
exactly right; there is no CAT command for it that I can find either.

One thing these shots show that is worth knowing if you are reasoning about the
'101 from an FtdX10: the two settings rows across the top are both receivers,
MAIN on the left and SUB on the right, and the two S-meters likewise. But the
scope underneath belongs to whichever one Band is set to. In these shots Band
is MAIN, and it is the left-hand R.FIL that changes - the right stays on 3 kHz
throughout. Your MAIN/SUB selector is doing the right thing; this is just the
part that has no equivalent on a single-receiver radio.

Two smaller ones

ReadStateAsync grew from 6 reads to 8. With the 150 ms settle that puts a
button press at roughly 10 serial round trips, on a port already carrying the
10 Hz meter poll. Not wrong, and I have not measured it - flagging it because
the scope reads and the meter poll are now competing harder than they were.

USER_MANUAL.md still says the FTdx10 scope is switched off at the old line,
which now contradicts the 19.4 wording added in this same PR.

One thought rather than a finding

The Controls button lives inside #radioDisplayContainer, so hiding the video
panel takes the CAT scope controls with it. There is no trap - Show Radio
Display brings it straight back - but CAT scope control needs no video at all,
and someone who prefers to keep the picture hidden loses it until they bring
the panel back. May well be deliberate; your call.

On the FtdX10 gate

You have removed the FTdx10 gate on SupportsSpectrumScopeCat, and I am glad
you did - that was the part I could not do. Finding 2 above is the kind of
thing a write probe would catch, so I want to check what you ran rather than
assume.

My bench run on the 101 turned up two things the manual does not mention: span
is stored per display mode, and a read straight after a write can hand back the
old value. Neither cost me anything once I knew.

If you have already driven each control from the FtdX10 front panel and back,
that is the probe and I am happy. If it was mostly the screenshot pass, one
deliberate run before merge would be worth it, purely because we are writing to
somebody else's front panel.

What I have not bench-tested

Finding 2 I cannot test - no FtdX10 here. Finding 3 is from reading the diff,
not from provoking it; I have not tried forcing a failed initial read and then
clicking Colour. Everything in the screenshots was driven against the radio.

73 Colin MM5AGM

@fabiojvalente

Copy link
Copy Markdown
Collaborator Author

@mm5agm this is great value, and I will take a look

In the meantime, feel free to contribute and commit into this branch, specially as the dx10 doesn't show narrow band region in the scope for ex

PS: I'm still amazed we can now share screenshots :)

@mm5agm

mm5agm commented Aug 19, 2026

Copy link
Copy Markdown
Owner

Thanks Fabio - and that one line about the FtdX10 answers the thing I could not
test myself. If your radio does not show a narrow band region at all, then
finding 2 stands: NB Col should be gated off for the FtdX10 rather than writing
values its manual documents as fixed at zero.

One thing before you read the review properly, though. I edited that comment at
10:40, after you had already replied, and GitHub does not notify on edits - so
the version you read had two claims in it that were wrong. Both were in the NB
Col section, and both are now corrected:

  • I said the coloured region covered the whole display at R.FIL 12 kHz, so
    there was no edge left to see. That is false - there is a clear edge. The
    real reason my first test showed nothing is that I was turning the DSP WIDTH
    knob, and WIDTH does not move the region at all. Only R.FIL does.

  • I said the region starts at the carrier and runs upward. Also false - it
    follows the passband actually being received, so in DATA-U it sits about
    1.5 kHz above the dial frequency, not at it.

Everything else is unchanged, including all three findings. It is only that one
section worth re-reading.

Sorry for the moving target. I reasoned from the CAT manual three times on this
and was wrong each time; it took a controlled A/B on the bench to settle it.

On your offer to commit into the branch - thank you, I will take you up on it.
The obvious candidate is the NB Col gate, since you have now confirmed the
FtdX10 side of it: a SupportsScopeNarrowBandColor alongside HasPerReceiverScopes
in RadioCapabilities, true for FTdx101MP and FTdx101D only, with the NB Col row
wrapped in it. Small and self-contained. Tell me if you would rather keep the
branch to yourself and I will leave it well alone.

Hold I will not touch, because where it should sit in the dialog is a layout
decision and the dialog is yours.

mm5agm added a commit that referenced this pull request Aug 19, 2026
The NB Col row rendered unconditionally, unlike AF-FFT and MULTI either
side of it. On an FtdX10 that put non-zero values into SS P2=3 P4 and P5,
which the FTDX10 CAT manual documents as "0: Fixed" -- its COLOR setting
is the direct-sampling palette alone. Fabio confirmed on his own radio
that it shows no narrow-band region at all (#120).

Adds RadioCapabilities.SupportsScopeNarrowBandColor, true for FTdx101MP
and FTdx101D, and wraps the row in it. _sendColor already falls back to
'0' for both axes, so the plain Color buttons keep emitting exactly what
the manual specifies once the row is hidden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@mm5agm

mm5agm commented Aug 19, 2026

Copy link
Copy Markdown
Owner

Fabio - I have taken you up on the offer and pushed the NB Col gate to the branch: 5eced2b.

RadioCapabilities.SupportsScopeNarrowBandColor, true for FTdx101MP and FTdx101D only, with the NB Col row in _RadioScopeButtonsPartial wrapped in it - the same shape as the hasAfFft / hasMulti gates either side of it. The doc comment carries the reasoning and credits your confirmation, since that is the part I could not test.

Nothing else touched. _sendColor already falls back to '0' for both axes, so with the row hidden the plain Color buttons emit exactly what the FTDX10 manual specifies. Both TFMs build 0 warnings; tests are 34/34 - I added five cases to your ScopeCommandsTests covering the new gate, on the grounds that a capability that silently writes to the wrong radio is exactly the kind of wrong answer nobody sees.

Hold I have left alone, as I said - where it belongs in the dialog is your call.

73, Colin MM5AGM

fabiojvalente pushed a commit that referenced this pull request Aug 28, 2026
The NB Col row rendered unconditionally, unlike AF-FFT and MULTI either
side of it. On an FtdX10 that put non-zero values into SS P2=3 P4 and P5,
which the FTDX10 CAT manual documents as "0: Fixed" -- its COLOR setting
is the direct-sampling palette alone. Fabio confirmed on his own radio
that it shows no narrow-band region at all (#120).

Adds RadioCapabilities.SupportsScopeNarrowBandColor, true for FTdx101MP
and FTdx101D, and wraps the row in it. _sendColor already falls back to
'0' for both axes, so the plain Color buttons keep emitting exactly what
the manual specifies once the row is hidden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@fabiojvalente
fabiojvalente force-pushed the feautre/video-tx-add-screen-buttons branch from 5eced2b to 434adab Compare August 28, 2026 15:52
@mm5agm

mm5agm commented Aug 29, 2026

Copy link
Copy Markdown
Owner

@fabiojvalente Three things, none of them blocking - the branch is still
marked draft and I am not asking you to act on any of this today.

1. There is a merge ahead of you, and it is smaller than it looks

PR #113 (the CW reader) also touches Pages/Index.cshtml. That is the only
file the two branches have in common - I checked the full file lists, nothing
else overlaps.

The good news is that they touch different parts of it:

#120 #113
~720 CW Read button
~800 scope card gated on VideoDisplayEnabled
~875 Controls button on the video card
~2420 scope toolbar partial
~2500 CW reader styles + <dialog>
~2600 radioScopeControls array
~2880 cwReaderPanel init
~3790 radioDisplayScopeDialog added to the drag list

The one line I expected to collide is the draggable-dialog id list, since you
add an id to it - but #113 does not, because the CW reader carries its own
drag handling. So whichever of us merges second should get an automatic merge,
or at worst a hunk that has drifted by a line count. Nothing semantic.

I mention it only so it is not a surprise. Neither of us needs to change
anything now.

2. Your new dialog will inherit an existing drag bug

makeDraggable (Index.cshtml, around line 3830) seeds from
getBoundingClientRect(), which is viewport coordinates, then writes
style.left / style.top on a <dialog> that was opened with .show() -
and a dialog shown that way is position: absolute, so those are document
coordinates. The two only agree when the page is scrolled to the top.

Repro: scroll the page down, then grab a dialog by its header. It jumps
upwards by exactly the scroll offset.

Since radioDisplayScopeDialog goes into that same list, it gets the same
behaviour for free. This is read off the code, not something I have watched
happen to your dialog specifically - your Controls dialog is the one part of
the branch I have not driven yet.

The fix is one line, dialog.style.position = 'fixed' next to the existing
transform = 'none'. I hit the identical thing in the CW reader panel and
that is what cured it there. Every dialog in the list has the bug, so it is
arguably not yours to fix inside this PR - say the word and I will do it as a
separate one against develop instead, which would be tidier for you.

3. Tests

Tests/YaesuWebControl.Tests/ScopeCommandsTests.cs is in the right project.
There used to be two test projects with confusingly similar names and CI only
ran one of them; that is now cleaned up, and the one you picked is the one
that runs. Nothing for you to change - I am saying it because if you had
guessed the other one your tests would have been silently green forever.

fabiojvalente pushed a commit that referenced this pull request Aug 31, 2026
The NB Col row rendered unconditionally, unlike AF-FFT and MULTI either
side of it. On an FtdX10 that put non-zero values into SS P2=3 P4 and P5,
which the FTDX10 CAT manual documents as "0: Fixed" -- its COLOR setting
is the direct-sampling palette alone. Fabio confirmed on his own radio
that it shows no narrow-band region at all (#120).

Adds RadioCapabilities.SupportsScopeNarrowBandColor, true for FTdx101MP
and FTdx101D, and wraps the row in it. _sendColor already falls back to
'0' for both axes, so the plain Color buttons keep emitting exactly what
the manual specifies once the row is hidden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@fabiojvalente
fabiojvalente force-pushed the feautre/video-tx-add-screen-buttons branch from 434adab to bb88145 Compare August 31, 2026 10:50
fabiojvalente added a commit that referenced this pull request Aug 31, 2026
…F-FFT

Move Hold into the shared scope buttons partial so Radio Display Controls
has it when the standalone card is hidden; send only the Color or AF-FFT
axis that changed so a failed initial read cannot zero the others; align
USER_MANUAL §5.20 with §19.4 and the NB Col roofing-filter tooltip.
@fabiojvalente

Copy link
Copy Markdown
Collaborator Author

@mm5agm
Updates on the last commit:

Hold in Controls dialog
Hold lived only on the standalone Radio Scope card, which is hidden when Radio Display is on. It’s now in the shared _RadioScopeButtonsPartial (next to Marker), so the Controls dialog on the video bar has it too. Still gated on SupportsScopeHold (FTdx101 + FTdx10).

Bench: FTdx10 Hold works over CAT
Confirmed on my FTdx10 — Hold toggles the trace on the radio’s TFT as expected. Operators can freeze the scope from YWC (standalone card or Radio Display Controls), not only from the front panel. Same SS P2=8 the manual lists for the '101; worth noting that FTdx10 Hold is bench-probed, not just documented.

Packed Color / AF-FFT writes
_sendColor / _sendAfFft no longer send all three axes with '0' fallbacks. The client sends only the axis that changed (n3, o1, a2, t5, etc.); the server merges from a radio read. Avoids resetting palette / NB / OSC on a failed initial GET. Parsers + tests in ScopeCommands.

Docs
USER_MANUAL §5.20 aligned with §19.4 (FTdx10 scope on, FT-710 still gated). NB Col tooltip: roofing filter (R.FIL), not DSP WIDTH.

Tests
ScopeCommandsTests — 34/34 pass on net10.0.

Not in this commit

Dialog drag jump when the page is scrolled; merge/rebase onto develop (#113).

Am not marking as ready to merge as I want to improve the location of the controls (probably a vertical split so scope is on one column and controls on another with the option to detach/hide them

@fabiojvalente

Copy link
Copy Markdown
Collaborator Author

Radio Display scope controls — docked layout
Scope controls now default to a 50/50 side column beside the video instead of a floating overlay on top of the stream. Controls only shows/hides the panel; Undock / Dock switch between column and floating modes.

Also fixes Fill centring in fullscreen, Undock opening the floating panel (was hiding it), and dialog drag jump on scrolled pages (position: fixed).

image

Ready to bench test @mm5agm

@mm5agm

mm5agm commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Looks good Fabio - I had to change Yaesu_Web_Control.csproj to get it to build on my PC and i'll change it back when I've finished.

  1. Controls can move about the screen - You said "Scope controls now default to a 50/50 side column beside the video instead of a floating overlay on top of the stream." but they still float about on the version I just checked. I checked out "feautre/video-tx-add-screen-buttons"
  2. Main Sub changes the spectrum to whatever you choose
  3. In Multi all the controls in your side panel work
  4. Tuning around quickly your video follows the radio. There is no apparent lag
    Is there anything you particularly want checked? I've not got Claude until tomorrow afternoon - Weekly Limit hit. I've been concentrating on getting a CW decoder working.
Fit Main Multi Pop_Out Sub

@fabiojvalente
fabiojvalente marked this pull request as ready for review August 31, 2026 17:29
@mm5agm

mm5agm commented Sep 1, 2026

Copy link
Copy Markdown
Owner

@fabiojvalente

Retested at aca6047. My earlier test was against a stale local copy of the
branch from 19 August, taken before you rebased, so it predated the scope
controls work. Ignore what I said last time.

Also: it builds clean here with no change to Yaesu_Web_Control.csproj. The
csproj edit I mentioned in my earlier comment was a symptom of the stale
tree, so there is nothing to change back.

Working:

  • Dock and Undock, both directions.
  • Hold in the Controls dialog. Took me a moment to find it, it is in the
    Peak row next to Marker.
  • The per-axis controls all render, and the radio reads them back over CAT
    on both MAIN and SUB: nbColor, nbOn, fftAtt, oscAtt, oscTime, plus span,
    speed, colour and level.
  • The controls column stays intact in every layout I tried: docked in the
    page, popped out, and full screen.

One thing to look at:

The Fit / Fill button caption shows the mode you are currently in, rather
than the action the button performs. So when it reads "Fit" you are already
fitted, and pressing it puts you into Fill. I read it as "click here to
fit", pressed it, and lost part of the picture.

That is what was behind the missing edges I first reported as a layout
fault. It is not a layout fault. In Fill the frame is scaled to cover the
pane and overflows both ways, so it centre-crops:

  • Docked in the page, the pane is wide and short, so the S meter row at the
    top and the soft key row at the bottom are cropped.
  • Popped out, the pane is narrow and tall, so it crops horizontally instead.
    The bottom row reads "AN 3DSS MONO MULTI EXPAND HOL", losing "CURSOR SP"
    at the left and "D MULTI PEAK" at the right.
Popped out in Fill Popped out, in Fill. Bottom row shows the crop at both ends, and you can see the empty space under the controls column.

The toggle itself is fine and reverses cleanly, and the mode persists across
dock and pop out as you would expect. It is only the caption that misleads.

Minor, take it or leave it: in the popped out window the controls column
takes about half the width but only about a third of the height, leaving a
large empty area below it. That is what squeezes the video into the tall
narrow shape where Fill crops hardest.

Nice work, the scope controls are a real improvement.

73 Colin MM5AGM

@fabiojvalente

Copy link
Copy Markdown
Collaborator Author

@mm5agm ready for another pass :)

Two small UX follow-ups on the Radio Display scope column:

Hide from the column itself. The red was already wired and worked on the floating panel, but CSS hid it while docked — so the only way to close the column was the Controls button on the video bar, which isn’t obvious. now shows in both layouts. It hides the panel without changing docked vs floating; Controls brings it back in the same layout.

Icon-only undock/dock. The labelled Undock control (generic window icon + text) is replaced with a picture-in-picture icon; hover for “Undock to a floating panel”. The floating panel’s Dock control is the same pattern (sidebar icon, “Dock beside the video”). Keeps the header compact next to .

USER_MANUAL §19.4 updated to match.

Verified in the browser on the Index Radio Display card: hides the docked column and recentres the video; the pip icon undocks; the sidebar icon docks again; tooltips show on hover.


I have also found a bug where I'd appreciate your input: at least on the dx10 the scope controls work mostly 1 way, from browser tor radio it works, but updating on the radio doesn't necessarily update in YWC
Question is, should we try to have it fixed or follow up on a different PR ?
I more tempted to go on a different PR

@mm5agm

mm5agm commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Different PR - I agree with your instinct, and I think the reason is stronger
than just PR size.

First, your client wiring here is fine. I went looking for a missing
subscription, on the theory that site.js is the only consumer of ScopeSetting
and RadioDisplay.cshtml does not load site.js - but you already built your own
hub connection in the page and it routes both ScopeSetting and ActiveVfo,
notifyRadioScopeControls fans out to every instance, and setActiveBand guards
the single-receiver case by checking a band button exists before switching.
So an FTdx10 on VFO B does not flip the panel to "sub" and start dropping
frames. Nothing to fix on your side that I can see.

That points the finger at the radio, and there are two candidates:

  1. The FTdx10 may simply not announce SS unsolicited. That the FTdx101 does was
    a bench discovery on 2026-08-15, not something Yaesu documents - see section
    6 of docs/design/scope-control-via-cat.md. It has never been verified on any
    other model, and there is no reason in either CAT manual to assume it
    carries over.

  2. Or it announces in a shape we throw away. CatMessageDispatcher has
    "if (ss.Length == 9)" as an exact-equality guard with nothing logged on the
    else path, so an FTdx10 frame of any other length disappears with no trace
    in any log.

One measurement tells you which: drop a temporary log line on the SS opcode in
the dispatcher, put a hand on the front panel, and watch. That is exactly how
the FTdx101 side was established. If frames arrive, it is a small dispatcher
fix; if nothing arrives, there is nothing to fix in software at all and the
answer is that live sync is a '101 feature.

Either way it is a separate concern from what this PR is for, and it needs a
bench session on your rig rather than more code. The important point is that
one-way is not a regression: on develop the FTdx10 has no CAT scope control at
all, so this PR is a strict improvement even if sync stays one-way. I would not
hold it up for this.

One other thing worth having on record. I watched the FTdx101MP on develop
today and front-panel changes do come through - pressing SPAN moves the span
buttons in the browser. But with HOLD engaged the HOLD indicator blinks about
once a second. There is no timer, animation or flash anywhere in radio-scope.js
or the CSS, and nothing polls SS, so the radio must be alternating SS0810000
and SS0800000 at roughly the sweep rate. Section 6 only ever recorded a single
ON and a single OFF. Not your problem here, but if you do add that log line it
would be interesting to see whether the FTdx10 does anything similar.

@mm5agm

mm5agm commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Follow-up: there is a third candidate, and it is the one I would bet on.

CatMultiplexerService strips the trailing ';' from answers - that is the trap
already recorded in section 6 of docs/design/scope-control-via-cat.md, which bit
the SS parser once before. The dispatcher's SS case guards on
"message.Length >= 10" BEFORE it does TrimEnd(';'). So an announcement that
arrives already stripped is 9 characters, fails that outer guard, and is thrown
away before the length-9 check it would have passed. Nothing was logged on that
path either, so it leaves no trace at all.

That fits your symptom better than the other two: writes work, because they go
out through a different path and their read-back repaints the panel; only the
unsolicited announcements vanish.

Temporary instrumentation for the SS case is now on develop (23b227a) to settle
it. It logs the raw frame plus both drop paths, at Information rather than Debug
so you do not have to change your log level:

[SS] raw='SS0810000;' length=10
[SS] DROPPED: trimmed length 8 is not 9 - 'SS081000'
[SS] DROPPED: shorter than 10 characters - 'SS0810000'

Pull develop, work SPAN and HOLD on the FTdx10 front panel, and those lines
answer all three candidates at once: nothing logged at all means the radio
does not announce, a DROPPED line means we are discarding frames it does send,
and which DROPPED line says which fix. It is a couple of minutes at the rig
rather than any more code reading.

Still a separate PR in my view - this is dispatcher-side and needs the
measurement first.

mm5agm added a commit that referenced this pull request Sep 2, 2026
Nothing but the FTdx101MP has ever been watched announcing SS, and PR #120
turns scope control on for the FTdx10 with one-way sync as the symptom. The
handler had no logging at all, and two paths that discard a frame silently:
the exact-equality length-9 check, and the outer length>=10 guard that runs
BEFORE TrimEnd(';') - so an announcement arriving already stripped by
CatMultiplexerService is 9 characters, fails the outer guard, and vanishes
before reaching the check it would have passed.

Information rather than Debug so a reporter can capture it without changing
their log level. To be removed once the FTdx10 question and the '101MP's
apparent once-a-second HOLD alternation are both answered at the bench.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
fabiojvalente and others added 6 commits September 2, 2026 11:48
- Added a new CAT scope toolbar for the Radio Display, allowing users to control the radio's own scope directly from the video panel.
- Updated the user manual to include instructions for using the new CAT scope toolbar and its functionalities.
- Refactored the Index and RadioDisplay pages to conditionally render the toolbar based on the video display settings.
- Enhanced JavaScript handling to support multiple instances of the scope controls, ensuring real-time updates across the UI.
- Introduced new partial views for better organization of scope control buttons and toolbar elements.
- Replaced the existing CAT scope toolbar with a modeless controls dialog for the Radio Display, enhancing user interaction by allowing adjustments without leaving the video panel.
- Updated the user manual to reflect changes in the controls and their functionalities.
- Refactored the Index and RadioDisplay pages to integrate the new dialog, ensuring consistent rendering based on video display settings.
- Enhanced JavaScript functionality to manage the dialog's state and interactions, including drag-and-drop support for better usability.
- Adjusted CSS styles for the new dialog to improve visual presentation and user experience.
- Updated the layout of the radio scope controls in the partial views to improve organization and accessibility.
- Introduced new CSS classes for better styling and alignment of control elements, ensuring a more compact and visually appealing interface.
- Adjusted the maximum width of the radio display scope dialog to enhance usability on various screen sizes.
- Improved the visual presentation of buttons and labels within the radio scope controls for a more consistent user experience.
- Implemented functionality to set and retrieve color settings for the radio scope, including color, narrow-band color, and narrow-band on/off states.
- Updated the user manual to include new color control options and their functionalities.
- Enhanced the UI to support color selection, including tooltips for better user guidance.
- Refactored related JavaScript and CSS to accommodate the new color controls and improve overall layout and accessibility.
The NB Col row rendered unconditionally, unlike AF-FFT and MULTI either
side of it. On an FtdX10 that put non-zero values into SS P2=3 P4 and P5,
which the FTDX10 CAT manual documents as "0: Fixed" -- its COLOR setting
is the direct-sampling palette alone. Fabio confirmed on his own radio
that it shows no narrow-band region at all (#120).

Adds RadioCapabilities.SupportsScopeNarrowBandColor, true for FTdx101MP
and FTdx101D, and wraps the row in it. _sendColor already falls back to
'0' for both axes, so the plain Color buttons keep emitting exactly what
the manual specifies once the row is hidden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…F-FFT

Move Hold into the shared scope buttons partial so Radio Display Controls
has it when the standalone card is hidden; send only the Color or AF-FFT
axis that changed so a failed initial read cannot zero the others; align
USER_MANUAL §5.20 with §19.4 and the NB Col roofing-filter tooltip.
- Updated the layout of the radio display controls to support a docked column beside the video stream, improving accessibility and user experience.
- Refactored the JavaScript to manage the state of the controls, allowing users to toggle between docked and floating modes.
- Adjusted CSS styles for better alignment and presentation of the radio display components.
- Updated the user manual to reflect changes in the controls and their functionalities, ensuring clarity for users.
- Improved the interaction model for the radio scope controls, allowing for seamless adjustments without disrupting the video display.
- Added a condition to refresh the radio scope control when the card is a dialog and open, enhancing responsiveness.
- Updated the undockScopeControls function to refresh the scope controls when undocking, ensuring the latest state is displayed to the user.
Replace the single Fit/Fill button with a btn-check toggle so both modes
are labeled and the active choice is obvious. Size the docked scope column
to content (~22rem) so the pop-out video pane is not squeezed to 50%.
Update USER_MANUAL for FTdx10 Hold and the new scaling control.
- Changed the close button's aria-label to "Hide scope controls" for better accessibility.
- Updated the user manual to clarify the functionality of the controls, including the new method for hiding the controls.
- Adjusted CSS to ensure proper display of the close button in various states.
- Updated the user manual to clarify the functionality of the scope controls, including the new picture-in-picture and sidebar icons for undocking and docking.
- Improved the tooltip functionality for the undock and dock buttons to enhance user experience.
- Refactored JavaScript to manage tooltips for better interaction when toggling scope controls.
@fabiojvalente
fabiojvalente force-pushed the feautre/video-tx-add-screen-buttons branch from 2e738d4 to 5376873 Compare September 2, 2026 10:49
@mm5agm

mm5agm commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Small practical note: you do not need to build for this. The nightly
unstable-20260902 pre-release was cut from develop at 23b227a, so the SS
instrumentation is already in it:

https://github.com/mm5agm/Yaesu_Web_Control/releases/tag/unstable-20260902

The Windows installer and both macOS CAT-only DMGs are attached, and the
logging sits in the shared CatMessageDispatcher, so the macOS build gives you
the same [SS] lines against the FTdx10. Install it, work SPAN and HOLD on the
front panel, and send whatever turns up in the log - including nothing at all,
which is itself one of the three answers.

Nothing from this PR is in that build - it is develop only, and #120 is still
open, so none of your commits are in it.

@fabiojvalente

Copy link
Copy Markdown
Collaborator Author

No prob, let me know when you've tested the latest changes 👍

@mm5agm

mm5agm commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Tested on the FTdx101MP, 146/146 unit tests passing on the branch.

Working:

  • Scope controls dock and undock
  • Colour control changes the radio's own screen, confirmed on the TFT
  • Hold and release both behave
  • NB Col is visible on the '101MP as intended
  • Fit is correct
  • Pop out is perfect, and the controls work in it
  • Front panel SPAN and HOLD now drive the app - this is the one-way sync
    problem solved, thank you

Two things:

  1. Fill is unusable in the docked view at a wide window. The 800x600 source
    scales up so far that only the top strip of the radio's screen is visible
    • the MAIN / FIX / SLOW2 / SPAN 10kHz header fills the full width and
      everything below it is off-frame. Fit is fine, and Fill in the pop-out is
      fine, so it looks like the docked container rather than the video. 2 screenshots showing 40 inch screen and 27 inch screen.
27_Inch_Screen 40inch_Screen
  1. Docking the pop-out back into the main screen loses the controls panel -
    it has to be reopened by hand.

In the pop-out, Fit and Fill give slightly different sizes, but everything
stays visible so I am not counting that as a fault.

I cannot test the FTdx10 un-gating from here - that half still needs you.

@mm5agm

mm5agm commented Sep 2, 2026

Copy link
Copy Markdown
Owner

To be clear about which is which: the 27 inch shot is the one that is fine -
Fill is perfectly usable there. The 40 inch shot is the fault.

So the trigger looks like window aspect ratio rather than screen size. The two
screenshots are 2.05:1 and 2.82:1, against a 4:3 source, and the wider the
window gets relative to its height the more Fill has to crop off to cover it.
If you cannot reproduce it, try making the browser window short and wide
rather than looking for a big monitor.

@fabiojvalente

Copy link
Copy Markdown
Collaborator Author

Testing a fix atm, should push it shortly

Index Fill now sizes to source aspect so wide cards no longer crop the TFT to its header strip. Reattach restores the scope panel from the last visible/hidden preference instead of leaving it closed.
@mm5agm

mm5agm commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Tested 2473101 on the FTdx101MP. 146/146 unit tests passing.

First, a correction to my earlier report, because it sent you the wrong way.

I said "Fill in the pop-out is fine" and used that to argue the fault was the
docked container rather than the video. That was wrong. I had only ever looked
at the pop-out at 50% browser zoom, which is my normal setting and happens to
be the one place it holds. Above 50% the pop-out crops as well. Apologies -
that was a false clue to build a fix on top of.

I also went back and built 5376873, the commit before your fix, to check
whether the pop-out cropping was something your change introduced. It is not.
It behaves identically there, so it predates this branch and is not a
regression.

The wider point that follows from both: Fill is meant to crop. Fit contains and
letterboxes, Fill covers and loses the overflow, so cropping is the feature
rather than the fault. Measured on the pre-fix build:

  • Fit, popped out: no crop anywhere from 50% to 400%
  • Fill, popped out: crops above 50%
  • Fill, docked: crops, but not uniformly - clean at 300% and 400%, top and
    bottom missing at 500%

That is all consistent with one rule: Fill crops whenever the container is not
4:3, by more the further from 4:3 it gets. The 300-400% clean patch is where
the container happens to sit near the source aspect.

So the only part of my original report that was a real defect is the one you
have fixed: docked Fill at a wide window cropping so hard that only the header
strip was left.

On 2473101:

  1. Docked Fill at a wide window - fixed, and more thoroughly than I asked for.
    My maximised 40 inch window is the 2.82:1 case that failed, and Fill is
    correct in it now. I then swept the zoom from 33% to 500% and the radio's
    screen stayed fully visible at every step. Note that Ctrl +/- does not
    change viewport aspect ratio, only how many CSS pixels fit, so that sweep
    tested container size rather than the aspect trigger.
  2. Docking the pop-out back - fixed, the controls are still there.

Regression sweep, all still correct: Fit docked, Fit and Fill both in the
pop-out, controls working in the pop-out, and the colour control still
reaching the radio's own TFT.

Two observations, neither of them a blocker, both for you to judge:

  • Since docked Fill now never crops at any zoom I tried, it and Fit look the
    same in the docked view. If that is the clamp you intended, ignore this. If
    Fill is still meant to cover and crop when docked, it no longer does.
  • Above 200% the scope controls themselves start to crop. The video is fine,
    it is the controls panel. I have not checked whether that predates your
    branch, and at that zoom plenty of UI is going to be unhappy, so I am
    recording it rather than reporting it.

I still cannot test the FTdx10 un-gating from here.

Use pane-fill with object-fit when the controls column is beside the video so Fit and Fill differ again; keep aspect-capped Fill on undocked wide cards.
@fabiojvalente

Copy link
Copy Markdown
Collaborator Author

@mm5agm — ready for another pass on Fit/Fill.

e74af89 addresses your observation on 2473101 that docked Fit and Fill looked the same.

What changed

  • With the scope column docked beside the video, Fit and Fill now use the same pane-fill model as the pop-out (object-fit: contain vs cover), so the toggle should be visibly different again.
  • On an undocked wide card, Fill still uses the aspect-capped box so we don’t regress to the header-strip crop on a short, wide window.

Please check

  1. Index, scope docked: Fit vs Fill — do they differ as expected?
  2. Index, scope hidden/floating on a wide window: Fill still shows the whole TFT (no header-only crop)?
  3. Pop-out: Fit/Fill still behave as before (Fill may crop when the pane isn’t ~4:3 — that’s expected)?
  4. Reattach still restores the controls panel?

Hard-refresh (Ctrl+Shift+R / Cmd+Shift+R) to pick up radio-display-panel.js?v=10.

FTdx10 scope: I’ve bench-tested this on my FTdx10 — scope controls over CAT work from the browser to the radio (span, mode, speed, level, peak, marker, colour, hold). NB Col stays hidden as intended; no MAIN/SUB row.
It’s been covered on mine throughout multiple continuous days of usage . :)

@mm5agm

mm5agm commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Tested e74af89 on the FTdx101MP. 146/146 unit tests passing.

Short version: this does what I asked for, and what I asked for was wrong.
Please put 2473101's docked behaviour back.

Check 1, docked Fit vs Fill: yes, they are visibly different again. That part
works.

Check 2 is the problem. With cover restored for the docked pane, Fill now crops
at most zooms, and in particular it crops at the setting I actually operate at:

  • 40 inch monitor: Fill is only usable at 80% and 90%. I normally run at 50%,
    and it is cropped there.
  • 27 inch monitor: Fill is only usable at 67%.
  • Fit is correct at every zoom on both monitors.

That narrow usable band is the pane passing near 4:3 on the way past. Which is
cover behaving exactly as cover should - the fault is not your implementation,
it is that cover is the wrong model for this pane. A 4:3 radio screen in a
docked column that is much wider than it is tall has to lose most of its height
to cover the pane, and what it loses is the part you are trying to read. That
is the header-strip crop from my first report, arriving by a different route.

Check 3, pop-out: fine up to 50% and crops above it. That is identical to what
I measured on 5376873 before any of this, so nothing has regressed there, and
it is the expected cover behaviour you flagged.

Check 4, Reattach: passes, the controls are still there.

So my earlier observation - that docked Fit and Fill looked the same after
2473101 - was a bad steer, and I am sorry for sending you round this loop. They
looked the same because the aspect cap had made Fill do the only sensible thing
available to it in that pane. Two controls that agree are a much smaller problem
than a control that hides the radio at the default zoom.

My suggestion, though it is your call:

  • Keep 2473101's aspect-capped Fill when docked, and accept that Fit and Fill
    are near-identical there. If you want the toggle to still mean something,
    having Fill fill the pane's width while Fit leaves margin would be enough of
    a difference without cropping.
  • Keep the true contain/cover distinction in the pop-out, where the window can
    actually be shaped to suit and where cropping is a reasonable thing to ask
    for.

I have screenshots I can add if required.

On the FTdx10: that is excellent news, and it is the evidence the un-gating
needed. One question so I do not over-claim it. What you describe is the write
direction, browser to radio. Do you also see the app follow when you change
span, mode or hold using the FTdx10's own front panel? That reverse direction
is what the temporary SS logging currently on develop exists to answer, and I
would like to remove that logging once someone has actually watched it on a
'10.

True cover in the docked pane cropped the TFT at normal browser zoom. Index Fill is aspect-capped again (Fit and Fill may look similar); pop-out keeps real contain/cover.
@fabiojvalente

Copy link
Copy Markdown
Collaborator Author

@mm5agm

8f182ff puts Index Fill back to the 2473101 behaviour:

  • Index (docked or undocked card): Fill is aspect-capped again — whole TFT stays visible. Fit and Fill may look nearly the same there; that is intentional.
  • Pop-out: unchanged — true contain/cover, cropping when the window isn’t roughly 4:3 is expected.

Please re-check docked Fill on the 40" at your usual ~50% zoom, plus Reattach still restoring controls.

FTdx10 reverse direction: I have confirmed browser → radio writes. I have not yet sat with the temporary SS logging on develop to confirm front-panel → app. I will do that separately and report what the log shows (or that nothing arrives).

@fabiojvalente

Copy link
Copy Markdown
Collaborator Author

Forgot to add: will push soon one more commit where you should be able to adjust hte controls width when docked

@mm5agm

mm5agm commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Tested 8f182ff on the FTdx101MP. 146/146 unit tests passing.

This fixes it. Thank you for turning it round so quickly, and sorry again for
the round trip - the request you were answering was mine and it was wrong.

Docked Fill on the 40 inch monitor at 50%, which is the case that failed on
e74af89 and the setting I actually operate at: the whole TFT is visible, no
crop. I then swept the zoom and it is correct at every step - the scope sits
inside the pane at 25, 33, 50, 67% and on up to 175%.

Also checked, all correct:

  • Fill undocked on a wide window: no header-strip crop
  • Reattach: controls panel still restored

One observation, recorded rather than reported, and explicitly NOT a request
for a change. The rendered scope grows with zoom up to a point and then stops:
115x70 mm at 25%, 155x90 at 33%, 205x125 at 50%, and then 205x125 unchanged
from 67% right up to 175%. That plateau is the aspect cap doing its job, and at
205x125 the pane is about 1.64:1 against a 4:3 picture, so the image is
letterboxed inside it. That is the 2473101 behaviour I asked to have back, and
it is also why docked Fit and Fill look nearly the same. I am content with
that trade - a control that is redundant is a far smaller problem than one that
hides the radio at my default zoom. Please do not change it on the strength of
this paragraph.

Still open from my last comment, and the only thing I am waiting on: the
FTdx10 direction question. What you bench-tested is the write direction,
browser to radio, and that is good evidence. What I still cannot confirm from
here is the reverse - when you change span, mode or hold using the FTdx10's
own front panel, does the app follow? That is what the temporary SS logging
currently sitting on develop exists to answer, and I would like to take that
logging back out once someone has actually watched it on a '10.

Operators can drag the column edge (or use keyboard) so span/colour rows fit across resolutions; width persists in the browser.
22rem clipped the last Span buttons; default is now 33rem, and saved widths at or below the old default are treated as unset.
@fabiojvalente

Copy link
Copy Markdown
Collaborator Author

@mm5agm

Glad 8f182ff landed where you wanted — and no worries about the round trip.

Added one experiment - Resizable docked column (e67b3fc)
The fixed 22rem / 42% width was making Span / Color wrap awkwardly across resolutions. You can now drag the left edge of the docked controls column to set the width (keyboard Left/Right nudge, Home/End for min/max; double-click the edge restores the default). The choice is remembered in the browser. Worth a quick play on the 40″ at your usual zoom — if you don’t like it, say the word and we can revert that commit with no fuss.

FTdx10 reverse direction
Confirmed on my FTdx10: changing span / mode / hold on the radio’s own front panel does not update the buttons in YWC. Browser → radio writes are fine; the reverse is not. I’ll pick that up in a separate PR (including the temporary [SS] logging on develop so we can tell whether the radio never announces or we are dropping frames).

Agreed this shouldn’t hold #120.

73
Fabio

@mm5agm

mm5agm commented Sep 3, 2026

Copy link
Copy Markdown
Owner

Tested 70aaf6f on the FTdx101MP. 146/146 unit tests passing.

70aaf6f does what it says. At the default docked width Span now fits on one
line. Before it, Span was clipped at the right edge, Display wrapped L/N/S onto
a second row, AF-FFT and OSC stacked, and the column had a horizontal
scrollbar. All of that is gone at the new default.

The resize works, mouse and keyboard. Dragging the edge resizes, the width
survives a reload, and Tab then Left/Right nudges it. Home/End reach the limits.

Three things found, one of them a bug.

1. Keyboard narrowing wraps round to wide. Holding Right past the narrow
limit does not stop - the column jumps back to the wide default and starts
again. Dragging to the same limit with the mouse stops cleanly, so this is
specific to the keyboard path.

A possible lead, for you to confirm or dismiss - the keydown handler derives the
current width as:

const current = dlg.getBoundingClientRect().width
  || getSavedScopeColumnWidthPx()
  || remToPx(SCOPE_WIDTH_DEFAULT_REM);

and the width it jumps back to is that default. The drag path uses pointer
position instead, which is the one that behaves. That is circumstantial and I
have not traced it.

2. Focus is indistinguishable from hover. Both give the same blue line, and
:focus-visible { outline: none } removes the browser's own ring, so a keyboard
user cannot tell they have landed on the splitter. I only found the keyboard
path because I went looking for it. This matters more here than it normally
would - a good part of why this app exists is the partially sighted operators
using it, and an invisible focus indicator is the difference between a control
existing and a control being usable.

3. The tooltip does not mention the keyboard. It reads "Drag to resize;
double-click to restore default", so nothing tells you the keys are there.

None of this needs the commit reverted - the feature is worth having and the
default width fix is a clear improvement. Item 1 is the one I would want fixed
before merge; 2 and 3 are small and I would take them in the same pass if you
are willing.

On the FTdx10: thank you for measuring the reverse direction, and for saying
plainly that it does not work. A null result is exactly what that question
needed. Agreed it should not hold this PR, and I am happy for the temporary SS
logging to travel with it into the separate PR rather than being stripped from
develop first.

…cursor

- Keyboard ArrowRight past min no longer wraps to default (current width read from CSS var, not || chain)
- Focus ring is yellow and distinct from hover (blue); outline: none replaced with proper :focus-visible styling
- Three grip dots (::before) make the splitter discoverable at a glance
- col-resize cursor now wins: makeDraggable skips the splitter div, CSS uses !important as fallback
- Tooltip and aria-label mention Arrow keys, Home/End
- USER_MANUAL updated accordingly
@fabiojvalente

Copy link
Copy Markdown
Collaborator Author

Colin I've removed the earlier comment as I caught a bug right after, please hold

Apologies

@fabiojvalente

Copy link
Copy Markdown
Collaborator Author

And pushed

All three items from your review are addressed — db67a2e and 0f1e874.

1. Keyboard wrap-around (db67a2e) — your lead was correct. getBoundingClientRect().width can return 0 before layout completes, causing the || chain to fall through to the default. Replaced with ?? throughout so the fallback only fires when the value is genuinely null/undefined. Home/End now jump cleanly to the clamped limits.

2. Focus indistinguishable from hover (db67a2e) — added a distinct amber (#ffc107) :focus-visible outline with a matching yellow line and grip dots. Mouse hover stays blue. The two states are now visually distinct.

3. Tooltip doesn't mention the keyboard (db67a2e + 0f1e874) — the tooltip text was updated to mention Arrow keys, Home/End and double-click, but it wasn't rendering at all: native title tooltips are suppressed inside <dialog> elements in most browsers. Fixed in 0f1e874 by explicitly initialising a Bootstrap Tooltip on the splitter with container: 'body' so it escapes the dialog stacking context, and moving title to data-bs-title on init. Tooltip placement and whether to keep it once keyboard shortcuts get a proper global treatment may be revisited — treating it as provisional for now.

Cursor col-resize also fixed (0f1e874)makeDraggable in Index.cshtml was setting cursor: grab inline on the splitter at init time, which overrides CSS even with !important when the dialog is floating. Fixed by clearing the inline style in bindScopeColumnResize immediately after setup.

Ready for another look when you get a chance.

73
Fabio

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.

2 participants