fix: the sidebar button follows the panel, and the wish survives having no source

The toolbar button was the panel's only input: `update_side_visibility()` derived the
panel from the button and never the other way, so the button went on saying "shown" in
two cases where the panel was off -- while there were no signals to show, and after
anything else moved the split view's state.

Binding the two together is not the fix. AdwOverlaySplitView writes `show-sidebar`
itself, at startup and when it collapses, with no user involved; a binding pushes that
into the button, the button's handler reads it as the user's wish, and the sidebar then
never comes back when a source connects -- a worse bug than the one reported, and one
that a "was this our own write" flag does not catch either, because the toggle's signal
may fire after the write returns.

So the direction is stated instead of inferred: `show-sidebar` is an output, the button
is the only input, and `App::sidebar_wanted` holds the wish between them. The wish is
written by the toggle's handler alone (guarded while we set the button ourselves), the
no-signals case forces the panel off without touching the wish, and tick() re-asserts
both from the wish when the widget disagrees -- so a hide gesture does not stick either.

[sidebar-probe] now reads the pair (shown vs button) in both states and against a hide
that did not come from the button; shown=1 button=1 with a source, shown=0 button=0
without, and the source reconnecting brings both back is the reading this exists for.
This commit is contained in:
Martino Ferrari committed 2026-10-12 13:23:40 +02:00
1 parent bb01278d88
commit 2d9f327da7
5 files changed
+95 -16

No files matched your search

+17 -6
View File
@@ -1046,19 +1046,30 @@ library measures and draws the rect in tests of its own.
## `[sidebar-probe]`
```
[sidebar-probe] beside window=756 sidebar=320 collapsed=1
[sidebar-probe] overlaid window=756 sidebar=320 collapsed=1
[sidebar-probe] beside window=756 sidebar=320 collapsed=1 shown=1 button=1(sens=1)
[sidebar-probe] regained window=756 sidebar=320 collapsed=1 shown=1 button=1(sens=1)
```
`UDPSCOPE_PROBE_SIDEBAR_MS` reads the sidebar's width in both of the split view's states: beside the plot,
and **overlaid** on it (`collapsed`, which is the state a window with no room beside the plot produces).
`UDPSCOPE_PROBE_SIDEBAR_MS` reads the sidebar in the two states a window can put it in, and against a hide
that did not come from the toolbar: `beside` first, then the sidebar is forced into the **overlaid** state
(`collapsed`, which is what a window with no room beside the plot produces), then the split view's own
`show-sidebar` is **turned off behind the button's back** — an overlay swipe, or the widget hiding itself —
and `regained` reads 400 ms later.
- **`sidebar` must never be 0.** It was, for every window narrower than the 940 px the divider used to sit
at, and the pane could only be found by dragging the divider back — the report this reading exists for.
It must read its own width (320) in *both* states: `collapsed` changes where the sidebar is, never how
wide it is.
- `collapsed=1` on the `beside` line means the window is narrower than `kSidebarRoom` (900), which is the
expected reading on a scaled display, where the logical width is half what the screen looks like.
- **`shown` and `button` must agree, always.** They are the panel and the toolbar button, and a button that
says "shown" over a hidden panel is the report this reading exists for. `shown=1 button=1` on `regained`
is also the rule that a hide not asked for through the button does not win.
- **`sens=0` with no source is correct.** The button is insensitive and un-pressed while there is nothing to
put in the sidebar; `button=0` is the button telling the truth about the panel rather than the panel
having forgotten the wish. A source reconnecting must give `shown=1 button=1` again — that is the reading
a `wanted` that got eaten by the no-signals frame shows as `shown=0 button=0(sens=1)`, which is the
regression.
- `collapsed=1` means the window is narrower than `kSidebarRoom` (900), which is the expected reading on a
scaled display, where the logical width is half what the screen looks like.
## `[prefs-probe]`