diff options
| author | user <user@clank> | 2026-09-29 14:26:28 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-09-29 14:26:28 +0200 |
| commit | ca1b5bdf5bf7b5ff01ab515846802b3487599d3a (patch) | |
| tree | a047fc09bccbe077b98acd0bf2648c2e02616b04 /include/app.h | |
| parent | panes: read and write a pane by id, without taking focus (diff) | |
| download | slosh-ca1b5bdf5bf7b5ff01ab515846802b3487599d3a.tar.gz slosh-ca1b5bdf5bf7b5ff01ab515846802b3487599d3a.tar.xz slosh-ca1b5bdf5bf7b5ff01ab515846802b3487599d3a.zip | |
layouts, moves: build panes without pulling the view to them
Applying a layout landed on the first tab it made, and moving a pane into a
tab took focus there. For a program building a pane in the background that
is two failures at once: it yanks the view off the human mid-sentence, and
it leaves the *next* caller to read focus as "where I am" and put its work
in a stranger's tab.
`apply-layout focus:false` builds the tabs and keeps looking at whatever was
on screen; a layout naming an `active` tab still wins, because that is a
statement about where to be. `move-pane` gains `beside` (which pane in the
destination to split, rather than whatever it has focused) and `focus:false`
-- the two things a caller placing a pane next to *itself* needs.
That uncovered a sizing bug that was unreachable before: a pane's size comes
from a layout pass, and a tab nobody has looked at never had one, so a pane
built in the background stayed 1x1 and its program drew into a single cell.
The jump is what used to size it. layout_tab() gives a background tab a real
pass, borrowing the tab cursor for its length -- nothing composes, reads
input or draws a frame in between.
Diffstat (limited to 'include/app.h')
| -rw-r--r-- | include/app.h | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/include/app.h b/include/app.h index 6de3d8d..d656d03 100644 --- a/include/app.h +++ b/include/app.h @@ -168,6 +168,12 @@ bool app_set_tab_purpose(app_t *a, uint32_t id, const char *purpose, * Purposes a layout declares are locked (D8). A relative `cwd=` in a *file* * resolves against that file's directory, so a project's layout can be checked * in beside the project; text has no directory and keeps meaning what it said. */ +/* Apply the *next* layout without changing which tab is on screen. Consumed by + * the one apply that follows, so it cannot leak into a later one. For a program + * building panes in the background: landing on the tab it just made moves the + * view out from under whoever is watching, and leaves the next caller to read + * focus as "where I am". A layout that names an `active` tab still wins. */ +void app_layout_keep_view(app_t *a); bool app_apply_layout_text(app_t *a, const char *text, bool replace, char *err, size_t errcap); bool app_apply_layout_file(app_t *a, const char *path, bool replace, char *err, @@ -272,6 +278,14 @@ bool app_minimize(app_t *a, uint32_t id); bool app_move_pane_to_tab(app_t *a, uint32_t pane_id, uint32_t tab_id, bool rows); +/* The same move, saying where in the destination to land and whether to take + * focus there. `beside_id` is a pane in that tab to split (0 = whatever it has + * focused, the old behaviour); `take_focus` false leaves focus, and therefore + * the view, exactly where it was. What a program placing a pane beside itself + * in the background wants; refused if `beside_id` is not in `tab_id`. */ +bool app_move_pane_beside(app_t *a, uint32_t pane_id, uint32_t tab_id, + uint32_t beside_id, bool rows, bool take_focus); + /* The same, into a tab of its own; returns that tab's id, or 0 -- including for a * pane that is already alone in its tab, which has nowhere to go. */ uint32_t app_move_pane_to_new_tab(app_t *a, uint32_t pane_id, const char *name); |
