ui: cap and cheapen the dock's events rebuild

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino FerrariandClaude Sonnet 4.6 committed 2026-11-03 06:56:24 +01:00
1 parent baf1c73b21
commit cb098eff75
4 files changed
+133 -34

No files matched your search

+39 -9
View File
@@ -5579,14 +5579,19 @@ void report_live_restored(App& a, const char* what) {
/// The dock's Events block against the pane's list. `same_titles` compares each dock row's title label
/// with the pane row's, in order (both are rebuilt from the same list by `refresh_events_pane()`, and both
/// are marked by `mark_events_on_screen()`); `on_screen` counts the dock rows with the filled marker, and
/// `marked` is the index of the first one (-1 for none).
static void report_dock_events(App& a, const char* what) {
/// `marked` is the index of the first one (-1 for none). `max_ok` is the cap: no more than
/// `kDockEventsMax` event rows and one "more" row. `expected_marked` is read after a replay of a record
/// the caller names by file (`expected_file`): 1 when exactly one dock row is filled and its record is that
/// one (record identity, not a count), 0 otherwise, -1 when the caller names none.
static void report_dock_events(App& a, const char* what, const std::string& expected_file = std::string()) {
std::vector<std::string> dock_titles;
std::string filled_file;
int dock_children = 0;
std::vector<std::string> pane_titles;
int on_screen = 0;
int marked = -1;
int members = 0;
const auto titles = [&members](GtkWidget* list, std::vector<std::string>* out, int* filled, int* first) {
const auto titles = [&members, &filled_file](GtkWidget* list, std::vector<std::string>* out, int* filled, int* first) {
if (list == nullptr) return;
int i = 0;
for (GtkWidget* row = gtk_widget_get_first_child(list); row != nullptr;
@@ -5603,22 +5608,41 @@ static void report_dock_events(App& a, const char* what) {
if (filled != nullptr && marker != nullptr &&
std::strcmp(gtk_label_get_text(GTK_LABEL(marker)), "\xE2\x97\x8F") == 0) {
++*filled;
if (first != nullptr && *first < 0) *first = i;
if (first != nullptr && *first < 0) {
*first = i;
filled_file = static_cast<const EventRecord*>(g_object_get_data(G_OBJECT(row), "udpscope-event"))->file;
}
}
}
};
for (GtkWidget* row = a.dock_events_list != nullptr ? gtk_widget_get_first_child(a.dock_events_list) : nullptr;
row != nullptr; row = gtk_widget_get_next_sibling(row)) {
++dock_children;
}
titles(a.dock_events_list, &dock_titles, &on_screen, &marked);
titles(a.events_list, &pane_titles, nullptr, nullptr);
// The dock shows the newest `kDockEventsMax` only: its titles are the pane's first ones, in order.
if (pane_titles.size() > kDockEventsMax) pane_titles.resize(kDockEventsMax);
std::fprintf(stderr,
"[events] dock events: rows=%zu pane_rows=%zu same_titles=%d sensitive=%d dock_w=%d "
"on_screen=%d marked=%d members=%d at=%s\n",
"on_screen=%d marked=%d members=%d max_ok=%d expected_marked=%d at=%s\n",
dock_titles.size(), pane_titles.size(), dock_titles == pane_titles ? 1 : 0,
a.dock_events_box != nullptr && gtk_widget_is_sensitive(a.dock_events_box) ? 1 : 0,
a.dock_events_box != nullptr ? gtk_widget_get_width(a.dock_events_box) : -1, on_screen,
marked, members, what);
marked, members, dock_children <= static_cast<int>(kDockEventsMax) + 1 ? 1 : 0,
expected_file.empty() ? -1 : (on_screen == 1 && filled_file == expected_file ? 1 : 0), what);
std::fflush(stderr);
}
/// The file of the record the Nth row of a list carries ("" for a row without one).
static std::string listed_file(GtkWidget* list, int index) {
if (list == nullptr) return std::string();
GtkListBoxRow* row = gtk_list_box_get_row_at_index(GTK_LIST_BOX(list), index);
if (row == nullptr) return std::string();
const auto* r = static_cast<const EventRecord*>(g_object_get_data(G_OBJECT(row), "udpscope-event"));
return r != nullptr ? r->file : std::string();
}
void events_probe_next(App& a, int step, guint delay_ms) {
a.dbg_events_step = step;
g_timeout_add(delay_ms, events_probe_step, &a);
@@ -5805,7 +5829,9 @@ gboolean events_probe_step(gpointer user) {
a->events_thumb != nullptr && gtk_widget_get_mapped(a->events_thumb) ? 1 : 0,
rows_kept ? 1 : 0, selected_now, a->dbg_events_selected);
std::fflush(stderr);
report_dock_events(*a, "after pane replay");
// The pane replayed its own row 0; the dock's list is the same list, so the dock's filled marker has to
// be on the row whose record is that one.
report_dock_events(*a, "after pane replay", listed_file(a->events_list, 0));
// One click on a dock row, the gesture: a *second* event when there is one, so the marker has to
// move. Through `row-activated`, which is what a single click emits.
{
@@ -5813,6 +5839,9 @@ gboolean events_probe_step(gpointer user) {
GtkListBoxRow* row = gtk_list_box_get_row_at_index(dock, 1);
if (row == nullptr) row = gtk_list_box_get_row_at_index(dock, 0);
const bool real = row != nullptr && g_object_get_data(G_OBJECT(row), "udpscope-event") != nullptr;
const std::string clicked_file =
real ? static_cast<const EventRecord*>(g_object_get_data(G_OBJECT(row), "udpscope-event"))->file
: std::string();
const std::string before = a->waveform_name;
if (real) g_signal_emit_by_name(dock, "row-activated", row);
// Already replaying (the pane's click above), so `replaying` alone cannot tell the click from the
@@ -5821,7 +5850,7 @@ gboolean events_probe_step(gpointer user) {
std::fprintf(stderr, "[events] dock replay: clicked=%d replaying=%d waveform_changed=%d\n",
real ? 1 : 0, a->replaying ? 1 : 0, before != a->waveform_name ? 1 : 0);
std::fflush(stderr);
report_dock_events(*a, "after dock click");
report_dock_events(*a, "after dock click", clicked_file);
}
events_probe_next(*a, 2, 1200);
return G_SOURCE_REMOVE;
@@ -6054,10 +6083,11 @@ gboolean events_group_probe_step(gpointer user) {
GtkListBox* dock = GTK_LIST_BOX(a->dock_events_list);
GtkListBoxRow* row = gtk_list_box_get_row_at_index(dock, 1);
const bool real = row != nullptr && g_object_get_data(G_OBJECT(row), "udpscope-event") != nullptr;
const std::string clicked_file = real ? listed_file(a->dock_events_list, 1) : std::string();
if (real) g_signal_emit_by_name(dock, "row-activated", row);
std::fprintf(stderr, "[events] dock replay: clicked=%d replaying=%d (second click, live before)\n",
real ? 1 : 0, a->replaying ? 1 : 0);
report_dock_events(*a, "second dock click");
report_dock_events(*a, "second dock click", clicked_file);
}
return G_SOURCE_REMOVE;
}