The contextual help was on by default, so a first run met a window with a "?" beside every surface it had not asked to have explained; `contextual_help` now defaults to false and the layer is asked for from the Help menu, from the chooser's new help menu, or with Ctrl+H. The source chooser runs before `App` exists, which makes it the window a user who does not know how to start is looking at, so it now carries the same three help affordances the window's Help view does: Documentation (the manual is another process and needs nothing of the app), Enable contextual help (a row whose check *is* the setting, written to the file the app reads a moment later), and Guided tour. The tour is drawn on the app's own window, so the chooser can only record the wish: it sets `Config::tour_pending` -- the value `main()` owns and hands to both `choose_source()` and `run_ui()` -- and `on_activate()` starts it once the window is up and laid out, through its own callback so the readings can tell a request from the first-run auto-start. The rows are the window's own `menu_button()`/`menu_toggle()`; `install_css()` therefore runs from `choose_source()` (it is idempotent now) so the popover gets the `.udpscope-menu` rules before it is shown. Opening the manual could also fail with a message that blamed the handler whatever was missing. `help_installed_path()` now resolves `help:<id>` the way the specification does and the failure alert says which of the two it is: with the set installed it names the viewer, without it it names the identifier, the expected installed path and the install command. `show_help()` gained an optional reporter, which `UDPSCOPE_PROBE_HELP_MS` uses for a new reading -- `[help] launch attempted= done= ok= error='' installed=` -- since a successful launch leaves no window of ours to observe. Tested: clean --clean-first build, three warnings as documented; test-ui 13/13 and test-help pass; no Gtk-CRITICAL in the help, helpui and chooser runs.
70 lines
3.6 KiB
C++
70 lines
3.6 KiB
C++
// SPDX-License-Identifier: MIT
|
|
#pragma once
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include <cstddef>
|
|
#include <functional>
|
|
#include <string>
|
|
|
|
namespace udpscope {
|
|
|
|
/// The About dialog: the app icon, version, commit, build timestamp and where the session
|
|
/// files live. An `AdwAboutDialog`, so it is modal on `parent` by being presented on it, and
|
|
/// it is an `AdwDialog` rather than a `GtkWindow`. `session_path` is this run's own session
|
|
/// file; it goes on the Troubleshooting page, which has a copy button.
|
|
void show_about(GtkWindow* parent, const std::string& session_path);
|
|
|
|
/// The icon name the open About dialog carries, or "" when it is not open. The probe reads it
|
|
/// so the dialog is asserted to *show* the app icon rather than merely to open.
|
|
const char* about_icon_name();
|
|
|
|
/// Opens the installed Mallard manual in the desktop help viewer — Yelp, through the
|
|
/// `help:` URI the freedesktop Help System Specification defines — rather than drawing a
|
|
/// window of our own. `parent` is the window the launch is attributed to (and the one an
|
|
/// error is reported on); the viewer is a separate process, so nothing here can be closed
|
|
/// with `close_help_windows()`.
|
|
///
|
|
/// `done`, when the caller gives one, is called with the *launch*'s outcome: whether the
|
|
/// `help:` URI was handed to a viewer, and the error text when it was not. It says nothing
|
|
/// about the viewer itself — that process may fail for its own reasons and this side cannot
|
|
/// see them — so it is the self-check's reading of the path and not a promise that a window
|
|
/// appeared. The failure alert is shown either way; the callback is an extra, not instead.
|
|
void show_help(GtkWindow* parent, std::function<void(bool ok, const std::string& error)> done = {});
|
|
|
|
/// Where `help:<id>` resolves to on this system: the first of `$XDG_DATA_HOME/help/<lang>/<id>/`
|
|
/// and `$XDG_DATA_DIRS/help/<lang>/<id>/` that holds an `index.page`, or an empty string when no
|
|
/// such directory does. This is the specification's own resolution, and the distinction a launch
|
|
/// failure turns on: a missing *document* (install it) and a missing *handler* (install a viewer)
|
|
/// are different problems with different fixes, and only the file system can tell them apart.
|
|
std::string help_installed_path();
|
|
|
|
/// What UDPSCOPE_PROBE_HELP_MS reports about the manual *in the tree*. `topics` is the
|
|
/// number of `<id>.page` files other than `index.page`, and `index` says whether
|
|
/// `index.page` is present: the manual is now a set of files on disk (installed by the
|
|
/// `install()` rule, and read by Yelp), not a GResource in the binary, so the self-check
|
|
/// asserts the set is *there* and must be read as a file-system finding — `topics=0
|
|
/// index=0` means the manual is missing from `UDPSCOPE_HELP_DIR`.
|
|
struct HelpReport {
|
|
int topics = 0;
|
|
bool index = false;
|
|
int figures = 0;
|
|
};
|
|
|
|
/// Scans the manual's directory without opening a viewer. Safe to call headless.
|
|
HelpReport help_self_check();
|
|
|
|
/// The shortcut overview: the application accelerators and the plot's own interactions,
|
|
/// in the sections the tables name. An AdwShortcutsDialog, because GtkShortcutsWindow is
|
|
/// deprecated as of GTK 4.18 and this project builds warning-free.
|
|
void show_shortcuts(GtkWindow* parent);
|
|
|
|
/// Closes whichever of the two dialogs are open. Both are `AdwDialog`s, which are not
|
|
/// `GtkWindow`s: they close with `adw_dialog_close()`, which emits `::closed`, and the
|
|
/// file-scope pointer is nulled by the handler that prevents a second open presenting a dead
|
|
/// widget. There is no help window left to close -- the manual opens in a separate viewer
|
|
/// process. Used by the probe.
|
|
void close_help_windows();
|
|
|
|
} // namespace udpscope
|