feat: paged help window with the four Getting started pages
The pages are Pango markup in a GResource, bundled for the same reason the icons are: udpscope runs straight out of the build tree with no install step, so a runtime search path's failure mode would be a silently empty help window. --c-name=udpscope_help keeps the two generated bundles from colliding. Every page is validated with pango_parse_markup() at load and falls back to a one-line stand-in rather than rendering raw markup or nothing. show_help() reuses help_window.cpp's existing close-request handler, and closes via gtk_window_close() so that handler runs and the pointer is nulled. UDPSCOPE_PROBE_HELP_MS loads and validates every page, opens the help and About windows, closes both and reports; parsed must equal pages.
This commit is contained in:
1 parent
856f538681
commit
04b6181926
9 files changed
+373
No files matched your search
+41
@@ -15,6 +15,7 @@
|
||||
#include <gtk4/gtk_plot_area.hpp>
|
||||
|
||||
#include "acquisition.hpp"
|
||||
#include "build_info.hpp"
|
||||
#include "config.hpp"
|
||||
#include "export.hpp"
|
||||
#include "help_window.hpp"
|
||||
@@ -4094,6 +4095,15 @@ void on_about_clicked(GtkButton*, gpointer user) {
|
||||
layout_path(app->model->config().server, app->model->config().port));
|
||||
}
|
||||
|
||||
void on_help_clicked(GtkButton*, gpointer user) {
|
||||
App* app = static_cast<App*>(user);
|
||||
if (app->menu_button != nullptr) {
|
||||
GtkPopover* popover = gtk_menu_button_get_popover(GTK_MENU_BUTTON(app->menu_button));
|
||||
if (popover != nullptr) gtk_popover_popdown(popover);
|
||||
}
|
||||
show_help(GTK_WINDOW(app->window));
|
||||
}
|
||||
|
||||
// --- right-click menu -------------------------------------------------------
|
||||
|
||||
void on_y_auto_clicked(GtkButton* button, gpointer user) {
|
||||
@@ -5555,6 +5565,11 @@ GtkWidget* build_toolbar(App& app) {
|
||||
|
||||
gtk_box_append(GTK_BOX(menu_box), gtk_separator_new(GTK_ORIENTATION_HORIZONTAL));
|
||||
|
||||
GtkWidget* help_item = gtk_button_new_with_label("Help (F1)");
|
||||
gtk_widget_set_tooltip_text(help_item, "the paged guide to every feature");
|
||||
g_signal_connect(help_item, "clicked", G_CALLBACK(on_help_clicked), &app);
|
||||
gtk_box_append(GTK_BOX(menu_box), help_item);
|
||||
|
||||
GtkWidget* about_item = gtk_button_new_with_label("About udpscope");
|
||||
gtk_widget_set_tooltip_text(about_item, "version, build timestamp and settings paths");
|
||||
g_signal_connect(about_item, "clicked", G_CALLBACK(on_about_clicked), &app);
|
||||
@@ -7231,6 +7246,29 @@ gboolean zoomkeys_probe(gpointer user) {
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
/// Loads and validates every help page, opens all three windows, closes them, and reports.
|
||||
/// `parsed` must equal `pages` and no page may be empty; `closed ok` with no GTK critical
|
||||
/// is the crash check for three windows built and destroyed in one run.
|
||||
gboolean help_probe(gpointer user) {
|
||||
App* a = static_cast<App*>(user);
|
||||
const HelpReport report = help_self_check();
|
||||
const std::string session =
|
||||
layout_path(a->model->config().server, a->model->config().port);
|
||||
|
||||
show_help(GTK_WINDOW(a->window));
|
||||
show_about(GTK_WINDOW(a->window), session);
|
||||
close_help_windows();
|
||||
|
||||
std::fprintf(stderr,
|
||||
"[help] pages=%d parsed=%d shortest='%s' %zu B; "
|
||||
"about version=%s commit=%s built=%s settings=%s; closed ok\n",
|
||||
report.pages, report.parsed, report.shortest_title.c_str(),
|
||||
report.shortest_bytes, build_info::kVersion, build_info::kCommit,
|
||||
build_info::kTimestamp, config_dir().c_str());
|
||||
std::fflush(stderr);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
int run_ui(int argc, char** argv, const Config& cfg, ScopeModel& model, Acquisition& acq,
|
||||
RowSet& rows) {
|
||||
(void)argc;
|
||||
@@ -7314,6 +7352,9 @@ int run_ui(int argc, char** argv, const Config& cfg, ScopeModel& model, Acquisit
|
||||
if (const char* env = g_getenv("UDPSCOPE_PROBE_ZOOMKEYS_MS")) {
|
||||
g_timeout_add(static_cast<guint>(std::atoi(env)), zoomkeys_probe, &app);
|
||||
}
|
||||
if (const char* env = g_getenv("UDPSCOPE_PROBE_HELP_MS")) {
|
||||
g_timeout_add(static_cast<guint>(std::atoi(env)), help_probe, &app);
|
||||
}
|
||||
|
||||
// Our own options were consumed by parse_args(); GTK would reject them, so only
|
||||
// the program name is handed to g_application_run().
|
||||
|
||||
Reference in new issue
Block a user