ui: the sidebar is two tabs, and a toggle disables its pane

Replace the sidebar's five-panel scrolling column with an AdwViewStack
carrying two pages — Measure (cursors + measurements) and Signals
(trigger + math + channel list) — with an AdwViewSwitcher above it. The
trigger and cursors toggles change from "reveal/hide my pane" to
"enable/disable my feature, leaving the pane insensitive", following the
disable-not-hide principle. The keys probe loses a duplicate registration
that was toggling the sidebar back on before the exit probe captured its
state; the exit-probe captures now read adw_overlay_split_view_get_show_
sidebar() instead of gtk_widget_get_visible(), which AdwOverlaySplitView
never changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino FerrariandClaude Sonnet 4.6 committed 2026-10-14 11:11:21 +02:00
1 parent e10a92fc52
commit 44d2fd35dc
11 files changed
+227 -232

No files matched your search

+45 -43
View File
@@ -74,24 +74,36 @@ gboolean exit_probe_step3(gpointer user) {
a->window = nullptr; // stop the tick before the widgets go
a->dbg_side_w = gtk_widget_get_width(a->side_box);
a->dbg_side_h = gtk_widget_get_height(a->side_box);
a->dbg_signal_w = gtk_widget_get_width(a->signal_revealer);
a->dbg_signal_h = gtk_widget_get_height(a->signal_revealer);
a->dbg_trigger_w = gtk_widget_get_width(a->trigger_revealer);
a->dbg_trigger_h = gtk_widget_get_height(a->trigger_revealer);
a->dbg_signal_w = gtk_widget_get_width(a->signal_panel);
a->dbg_signal_h = gtk_widget_get_height(a->signal_panel);
a->dbg_trigger_w = gtk_widget_get_width(a->trigger_panel);
a->dbg_trigger_h = gtk_widget_get_height(a->trigger_panel);
// The height of one signal row, which is the thing "the channel toggle is too tall"
// was about. The revealer's own height cannot stand in for it: it also covers the
// was about. The panel's own height cannot stand in for it: it also covers the
// heading, the hint and the box margins.
if (GtkWidget* first = gtk_widget_get_first_child(a->signal_list)) {
a->dbg_signal_row_h = gtk_widget_get_height(first);
}
if (a->area != nullptr) a->dbg_frames_painted = static_cast<int>(a->area->frames_painted());
a->dbg_reset_visible = a->cursors_reset != nullptr && gtk_widget_get_visible(a->cursors_reset) ? 1 : 0;
a->dbg_signal_revealed =
gtk_revealer_get_child_revealed(GTK_REVEALER(a->signal_revealer)) ? 1 : 0;
a->dbg_trigger_revealed =
gtk_revealer_get_child_revealed(GTK_REVEALER(a->trigger_revealer)) ? 1 : 0;
a->dbg_side_visible = gtk_widget_get_visible(a->side_box) ? 1 : 0;
a->dbg_side_scroll_after_hide = gtk_widget_get_visible(a->side_scroll) ? 1 : 0;
a->dbg_reset_sensitive = a->cursors_reset != nullptr && gtk_widget_get_sensitive(a->cursors_reset) ? 1 : 0;
// A page, not a revealer: a stack's hidden page measures 0x0 the way an unrevealed revealer
// did, so the reading asks about *state* -- is this page the current one -- and never about size.
const char* page = a->side_stack != nullptr
? adw_view_stack_get_visible_child_name(ADW_VIEW_STACK(a->side_stack))
: nullptr;
const int on_signals = page != nullptr && std::strcmp(page, "signals") == 0 ? 1 : 0;
a->dbg_signal_page_current =
on_signals && gtk_widget_get_first_child(a->signal_list) != nullptr ? 1 : 0;
a->dbg_trigger_sensitive = on_signals && gtk_widget_get_sensitive(a->trigger_panel) ? 1 : 0;
// `gtk_widget_get_visible` on the sidebar's GtkBox is always 1: AdwOverlaySplitView hides its
// sidebar child via `gtk_widget_set_child_visible()`, not `gtk_widget_set_visible()`. The useful
// reading is whether the split view is currently showing the sidebar panel.
const int sidebar_shown = a->side_view != nullptr &&
adw_overlay_split_view_get_show_sidebar(ADW_OVERLAY_SPLIT_VIEW(a->side_view)) ? 1 : 0;
a->dbg_side_column_after_hide = sidebar_shown;
a->dbg_switcher_visible =
a->side_switcher != nullptr && gtk_widget_get_visible(a->side_switcher) ? 1 : 0;
a->dbg_side_visible = sidebar_shown;
if (a->trigger_signal_drop != nullptr) {
GListModel* model = gtk_drop_down_get_model(GTK_DROP_DOWN(a->trigger_signal_drop));
a->dbg_trigger_items = model != nullptr ? static_cast<int>(g_list_model_get_n_items(model)) : 0;
@@ -100,9 +112,6 @@ gboolean exit_probe_step3(gpointer user) {
}
// `dbg_window_text` is kept by `sync_window_display()`, the only place that knows the span the
// window control is showing: there is no label to read it back from any more.
a->dbg_toggles_visible =
(gtk_widget_get_visible(a->signal_toggle) && gtk_widget_get_visible(a->trigger_toggle)) ? 1
: 0;
if (window != nullptr) gtk_window_destroy(GTK_WINDOW(window));
return G_SOURCE_REMOVE;
}
@@ -2186,8 +2195,7 @@ gboolean export_probe(gpointer user) {
gboolean exit_probe_step1(gpointer user) {
App* a = static_cast<App*>(user);
// Record the panel states before the toggles are exercised.
a->dbg_trigger_revealed_default =
gtk_revealer_get_child_revealed(GTK_REVEALER(a->trigger_revealer)) ? 1 : 0;
a->dbg_trigger_sensitive_default = gtk_widget_get_sensitive(a->trigger_panel) ? 1 : 0;
if (a->trigger_toggle != nullptr) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(a->trigger_toggle), TRUE);
}
@@ -2227,13 +2235,10 @@ void cursors_probe_report(App& a, const char* what) {
double my = 0.0;
const bool have_mark = a.rows->crossing_at(0, 0, false, mx, my);
std::fprintf(stderr,
"[cursors-probe] %-14s mode=%-10s on=%d pane=%d t0=%.6f t1=%.6f dt=%.6f "
"[cursors-probe] %-14s mode=%-10s on=%d pane_sensitive=%d t0=%.6f t1=%.6f dt=%.6f "
"T=[%s] lines=%d marks=%d [%s]\n",
what, kModes[mode], a.rows->cursors_visible() ? 1 : 0,
a.cursors_revealer != nullptr &&
gtk_revealer_get_reveal_child(GTK_REVEALER(a.cursors_revealer))
? 1
: 0,
a.cursors_panel != nullptr && gtk_widget_get_sensitive(a.cursors_panel) ? 1 : 0,
a.rows->cursor_a_x(), a.rows->cursor_b_x(),
a.rows->cursor_b_x() - a.rows->cursor_a_x(), t_text.c_str(), n,
a.rows->crossings_visible(), lines.c_str());
@@ -2498,7 +2503,7 @@ gboolean measures_probe_step(gpointer user) {
m.options.show_on_plot = measure_can_show_on_plot(m.type);
a->measures.push_back(std::move(m));
}
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(a->measures_toggle), true);
select_side_tab(*a, "measure");
rebuild_measures_pane(*a);
std::fprintf(stderr, "[measures-probe] added %zu measurements on '%s'\n", a->measures.size(),
signal.c_str());
@@ -4027,29 +4032,26 @@ gboolean keys_probe(gpointer user) {
before_after("t: trigger panel", a->trigger_toggle, AppAction::TriggerPanel);
before_after("c: cursors", a->cursors_toggle, AppAction::CursorsPane);
before_after("m: measures", a->measures_toggle, AppAction::MeasuresPane);
before_after("g: math", a->math_toggle, AppAction::MathPane);
{
const std::string before_tab = a->side_tab;
run_app_action(*a, AppAction::SideTabMeasure);
const std::string after_tab = a->side_tab;
char buf[96];
std::snprintf(buf, sizeof(buf), " m: tab %s->%s |", before_tab.c_str(), after_tab.c_str());
line += buf;
}
{
const std::string before_tab = a->side_tab;
run_app_action(*a, AppAction::SideTabSignals);
const std::string after_tab = a->side_tab;
char buf[96];
std::snprintf(buf, sizeof(buf), " g: tab %s->%s |", before_tab.c_str(), after_tab.c_str());
line += buf;
}
before_after("l: layout", a->layout_toggle, AppAction::LayoutEditor);
before_after("s: side panel", a->sidebar_toggle, AppAction::SidePanel);
// An accel must be refused while text is being typed. Focus the window entry, send 'm'
// through the real handler, and require the measurements toggle not to move.
int refused = -1;
if (a->window_entry != nullptr) {
gtk_menu_button_popup(GTK_MENU_BUTTON(a->window_button));
gtk_widget_grab_focus(a->window_entry);
const int before = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(a->measures_toggle))
? 1 : 0;
const gboolean handled = on_app_key_pressed(nullptr, GDK_KEY_m, 0,
static_cast<GdkModifierType>(0), a);
const int after = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(a->measures_toggle))
? 1 : 0;
refused = (handled == FALSE && before == after) ? 1 : 0;
gtk_menu_button_popdown(GTK_MENU_BUTTON(a->window_button));
}
char tail[64];
std::snprintf(tail, sizeof(tail), " editable focused: 'm' refused=%d\n", refused);
line += tail;
line += "\n";
std::fprintf(stderr, "%s", line.c_str());
std::fflush(stderr);