fix: the guided tour selects the page a stop's target lives on
A stop whose target is on another page of a stack was entered without switching to that page, so the spotlight aimed at a widget that was not on screen. A stop now declares the page it stands on (`TourStop::page`) and the tour selects it as the step is entered -- the window's trigger and signals stops put the sidebar on Signals, the chooser's tabs stop shows the Waveforms page and stepping off it brings Sources back. The stop filter moved into `tour_begin()` and now runs on `gtk_widget_get_mapped()`: GTK 4.24's `is_visible()` ignores `child_visible`, so it kept a stop on another page *and* one in a collapsed pane alike. A wrong page is kept and selected; a collapsed pane, whose stack is unmapped too, is still dropped.
This commit is contained in:
1 parent
829176248a
commit
d549223889
9 files changed
+385
-89
No files matched your search
+21
-4
@@ -67,10 +67,15 @@ enum class EventGroupKind {
|
||||
// is only the *stops*: a stop's target is a widget the owner resolves, so each window keeps its own
|
||||
// table (the chooser runs before `App` exists and could not name one of `App`'s fields).
|
||||
|
||||
/// One stop of a guided tour: the widget to spotlight, and the two paragraphs of text beside it.
|
||||
/// The target is resolved when the tour starts, so the table may name widgets that do not exist yet.
|
||||
/// One stop of a guided tour: the widget to spotlight, the page it stands on, and the two paragraphs
|
||||
/// of text beside it. The target is resolved when the tour starts, so the table may name widgets that
|
||||
/// do not exist yet.
|
||||
struct TourStop {
|
||||
GtkWidget* target;
|
||||
/// The named page of the view's `page_stack` the target lives on, or nullptr when the stop needs no
|
||||
/// page. The tour selects it as the stop is entered, so a target on a page the user has left is
|
||||
/// made visible instead of being walked over or spotlighted where it is not.
|
||||
const char* page;
|
||||
const char* title;
|
||||
const char* body;
|
||||
};
|
||||
@@ -93,6 +98,10 @@ struct TourView {
|
||||
bool running = false;
|
||||
int index = 0;
|
||||
std::vector<TourStop> plan;
|
||||
/// The stack whose pages the stops' `page` names select. A window has exactly one such surface (the
|
||||
/// sidebar; the chooser's two pages), so it is the view's and not each stop's. Set where the walk
|
||||
/// begins, when the widgets exist; null leaves every stop on the page it finds.
|
||||
GtkWidget* page_stack = nullptr;
|
||||
/// Runs when the walk passes its last stop (Next/Finish, never Skip): the chooser's hands the tour
|
||||
/// on to the application through `Config::tour_pending`.
|
||||
void (*on_done)(void* user) = nullptr;
|
||||
@@ -312,6 +321,8 @@ struct App {
|
||||
/// left nothing behind.
|
||||
int dbg_helpui_step = 0;
|
||||
int dbg_helpui_controllers = -1;
|
||||
/// `UDPSCOPE_PROBE_TOUR_SURFACE_MS`: which step of that probe runs next.
|
||||
int dbg_tour_surface_step = 0;
|
||||
/// Where the panel controls ended up, decided once at build time: the dump runs after the window
|
||||
/// is destroyed and cannot ask GTK anything about a widget.
|
||||
std::string dbg_panel_controls;
|
||||
@@ -1745,6 +1756,10 @@ gboolean keys_probe(gpointer user);
|
||||
gboolean help_probe(gpointer user);
|
||||
void helpui_probe_next(App& a, int step, guint delay_ms);
|
||||
gboolean helpui_probe_step(gpointer user);
|
||||
/// `UDPSCOPE_PROBE_TOUR_SURFACE_MS`: a stop that stands on another page of a stack, entered from the
|
||||
/// page it is not on -- the sidebar put on Measure, the walk to the signals stop, the reading of the
|
||||
/// page and of the spotlight, and then the same walk with the sidebar *collapsed*.
|
||||
void tour_surface_probe_next(App& a, guint delay_ms);
|
||||
|
||||
// --- the help affordance layer (ui_context_help.cpp, ui_tour.cpp) ----------
|
||||
//
|
||||
@@ -1784,8 +1799,10 @@ void context_help_size(App& app, int* width, int* height);
|
||||
/// Builds a tour's overlay children (the four dim rectangles, the spotlight outline and the card)
|
||||
/// inside `overlay`. Called once, as the overlay is inserted, by either window that draws a tour.
|
||||
void tour_build(TourView& view, GtkWidget* overlay);
|
||||
/// Starts at the first stop. `stops` is the walk, already filtered to what is on screen; `on_done`
|
||||
/// (may be null) runs when the walk passes its last stop, and is how the chooser hands off.
|
||||
/// Starts at the first stop. `stops` is the whole table, in walk order: the stops whose surface is
|
||||
/// not on screen are filtered out here, by the one rule both windows use (a wrong page is kept and
|
||||
/// selected, a collapsed pane is dropped). `on_done` (may be null) runs when the walk passes its last
|
||||
/// stop, and is how the chooser hands off.
|
||||
void tour_begin(TourView& view, std::vector<TourStop> stops, void (*on_done)(void* user),
|
||||
void* done_user);
|
||||
/// Moves `delta` stops, finishing the walk (and calling `on_done`) on the way past the last one.
|
||||
|
||||
Reference in new issue
Block a user