session: remember extra windows, and reopen them from the menu
A scope or detached window was never written to the session, and a detached figure vanished from the layout at the next start -- the figure had been removed from the main rows, and nothing kept the window that held it. Each window is now a `[[window]]` block in the session -- `name`, `detached`, and its own `[[window.plot]]` rows with the same keys the main `[[plot]]` rows carry (signals, row weight, cell width). `collect_layout()` writes the open windows' present arrangement plus the ones already closed; loading puts **all** of them in `App::closed_windows` and never opens one: a window is a view the user closed, and a launch that tiled windows onto the desktop would take that decision for them (a tiling WM would tile them straight away). The overflow menu gains **Reopen closed windows (N)**, which opens every remembered window through `open_scope_window_from_state()` -- the one window constructor, then its rows, weights and signals dealt into its row set. Closing a window records it, by name (a close/reopen cycle replaces its entry rather than multiplying them), and schedules the save; **attaching** records nothing, because that window's figure is on the main window again. A detached figure therefore survives a quit through its window's entry. Probe: `[scope-probe] loaded closed=N scopes=0` (remembered, none opened) and `reopen scopes=..->.. remembered=.. left=0` (close, remember, the menu item's own click reopens). Docs: README, the Mallard layout page, the probe readings and the session invariant.
This commit is contained in:
1 parent
0c9333858c
commit
a29f38eaa9
9 files changed
+326
-12
No files matched your search
@@ -225,6 +225,10 @@ struct App {
|
||||
/// carries the attach control and can be put back. A copied or empty window is a plain second
|
||||
/// view, and has no attach control.
|
||||
bool detached = false;
|
||||
/// False while attaching: the window is closing *because* its figure went back to the main
|
||||
/// window, so there is nothing to remember (remembering it would offer to reopen a window
|
||||
/// whose figure is on screen again).
|
||||
bool remember_on_close = true;
|
||||
/// The overlay wrapping the GL widget: the corner controls (attach, the layout toggle, the
|
||||
/// layout editor's own buttons) all live on it. Its motion controller keeps the pointer state
|
||||
/// they are revealed by.
|
||||
@@ -252,6 +256,12 @@ struct App {
|
||||
std::unique_ptr<RowSet> rows;
|
||||
};
|
||||
std::vector<std::unique_ptr<ScopeWindow>> scopes;
|
||||
/// The **closed** extra windows, as the session remembers them: a window's arrangement is kept
|
||||
/// when it is closed (and across a restart), and the *Reopen closed windows* entry opens them --
|
||||
/// a launch never does, because a window is a view the user closed on purpose.
|
||||
std::vector<LayoutState::Window> closed_windows;
|
||||
/// The menu entry that reopens them, so its label can carry the count.
|
||||
GtkWidget* reopen_scopes_item = nullptr;
|
||||
/// Every empty scope window is numbered from this, so two of them never share a name.
|
||||
int scope_seq = 0;
|
||||
|
||||
@@ -2090,6 +2100,16 @@ bool assign_signal_to_scope(App& app, App::ScopeWindow& scope, std::size_t signa
|
||||
/// the application through `run_app_action()`.
|
||||
gboolean on_scope_key(GtkEventControllerKey* controller, guint keyval, guint keycode,
|
||||
GdkModifierType state, gpointer user);
|
||||
/// The session record of a window: its name, whether it was detached, and its plot rows.
|
||||
LayoutState::Window scope_window_state(const App::ScopeWindow& scope);
|
||||
/// Remembers a window as closed (`closed_windows`, replaced by name) -- what its destroy handler
|
||||
/// does, and what keeps a closed window reopenable.
|
||||
void remember_closed_window(App& app, const App::ScopeWindow& scope);
|
||||
/// Opens a window from a remembered state: an empty scope window, then its rows, weights and
|
||||
/// signals. Returns the opened window (nullptr when it could not be made).
|
||||
App::ScopeWindow* open_scope_window_from_state(App& app, const LayoutState::Window& state);
|
||||
/// Refreshes the *Reopen closed windows* entry: its count and whether it is sensitive.
|
||||
void sync_reopen_scopes_item(App& app);
|
||||
/// Turns a scope window's own layout editor on or off, building or taking down its buttons.
|
||||
void set_scope_layout_editing(App& app, App::ScopeWindow& scope, bool on);
|
||||
/// The scope window's own right-click menu: the same row menu's actions, aimed at **that
|
||||
|
||||
Reference in new issue
Block a user