fix: the sidebar keeps its own width, so a small window can no longer hide it

The sidebar's width was a GtkPaned divider position: `window - 940` in pixels. On any window
narrower than 940 px the divider landed past the right edge and the sidebar came up 0 px wide,
reachable only by dragging the divider back.

Every attempt that kept the paned failed for that reason -- deriving the position from the paned's
own width, re-parenting the column, property-form children, code-set size requests. The mechanism was
the fault, so it is gone: the row is an AdwOverlaySplitView, which is what a utility sidebar is in
GNOME, with min-sidebar-width = max-sidebar-width = 320 in pixels. Its width is therefore its own at
any window size, and when there is no room beside the plot it *overlays* the plot (collapsed, set from
the window's width in tick()) instead of being squeezed to nothing.

Two things found on the way, both recorded in the invariants:

- sidebar-width-fraction is a 0..1 fraction of the window whatever sidebar-width-unit says. Setting a
  pixel count there is a GObject critical and it falls back to 0.25, which is why the sidebar first
  read 560. The width is pinned with min/max instead.
- the window opened at its content minimum (756 px, the plot column plus the sidebar) because the
  explicit gtk_window_set_default_size() was dropped when the window moved into the .ui. Restored.

[sidebar-probe] reads both states and is the guard: window=756 sidebar=320 under a 2x scale, which is
the case that used to read 0.
This commit is contained in:
Martino Ferrari committed 2026-10-12 12:17:56 +02:00
1 parent a8c25f0cb3
commit bb01278d88
7 files changed
+165 -54

No files matched your search

+34
View File
@@ -1633,6 +1633,40 @@ gboolean boxzoom_probe(gpointer user) {
return G_SOURCE_REMOVE;
}
/// `UDPSCOPE_PROBE_SIDEBAR_MS`: the sidebar's width, in both of the split view's states.
///
/// The small-window case is the one a divider position got wrong: with the sidebar's width derived from
/// the window, a window narrower than that number gave it nothing at all. The split view takes its size
/// from its own properties instead, and when there is no room beside the plot it *overlays* it
/// (`collapsed`) rather than shrinking to nothing. Both states are read here, so "the sidebar is never
/// zero" is a number rather than a claim.
gboolean sidebar_probe(gpointer user) {
App& a = *static_cast<App*>(user);
if (a.side_view == nullptr) return G_SOURCE_REMOVE;
const auto report = [](App& app, const char* what) {
const int side = app.side_box != nullptr ? gtk_widget_get_width(app.side_box) : -1;
const int win = app.window != nullptr ? gtk_widget_get_width(app.window) : -1;
std::fprintf(stderr, "[sidebar-probe] %-10s window=%d sidebar=%d collapsed=%d\n", what, win,
side, adw_overlay_split_view_get_collapsed(ADW_OVERLAY_SPLIT_VIEW(app.side_view)) ? 1
: 0);
};
report(a, "beside");
// The state a window with no room produces: the sidebar goes over the plot, and its width is still its
// own. If this ever reads 0, the sidebar is being given a share of a width that is not there.
adw_overlay_split_view_set_collapsed(ADW_OVERLAY_SPLIT_VIEW(a.side_view), TRUE);
g_timeout_add(400, +[](gpointer u) -> gboolean {
App& app = *static_cast<App*>(u);
const int side = app.side_box != nullptr ? gtk_widget_get_width(app.side_box) : -1;
std::fprintf(stderr, "[sidebar-probe] %-10s window=%d sidebar=%d collapsed=%d\n", "overlaid",
app.window != nullptr ? gtk_widget_get_width(app.window) : -1, side,
adw_overlay_split_view_get_collapsed(ADW_OVERLAY_SPLIT_VIEW(app.side_view)) ? 1 : 0);
adw_overlay_split_view_set_collapsed(ADW_OVERLAY_SPLIT_VIEW(app.side_view), FALSE);
return G_SOURCE_REMOVE;
}, &a);
return G_SOURCE_REMOVE;
}
gboolean prefs_probe(gpointer user) {
App& a = *static_cast<App*>(user);
open_preferences(a);