diff options
| author | user <user@clank> | 2026-08-16 01:06:42 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-16 01:06:42 +0200 |
| commit | 3b9c1d987db7dae1db68a8ea304e8227344a1cdb (patch) | |
| tree | b2aa66a61e2111720115442611ca092d261c161c /docs | |
| parent | sl0ppty: a reply is never a request (diff) | |
| download | slosh-3b9c1d987db7dae1db68a8ea304e8227344a1cdb.tar.gz slosh-3b9c1d987db7dae1db68a8ea304e8227344a1cdb.tar.xz slosh-3b9c1d987db7dae1db68a8ea304e8227344a1cdb.zip | |
sl0ppty: a pane can set its own shaders
printf '\033]5577;1;shader;chrome;tint color="#ff5fd7" amount="abs(t / 8 % 510 - 255)"\033\\'
The field after `shader` is which rect -- `content` or `chrome` -- and the
rest of the payload is a chain in exactly the syntax a `shaders { }` block
uses, taken verbatim so that `;` can go on separating entries. Empty text
clears that chain. The session answers on the program's stdin, `shader-reply;ok`
or `shader-reply;error;bad amount for tint: ...`, because a prototyping loop
that gets no answer cannot tell a typo from a build without the feature.
`contrib/shader-repl` is the prompt this exists for: type a chain, watch the
pane, and `:paste` prints what you have as a config block. Both ends are the
same parser, so what you arrive at is what you can keep -- verified by
pasting `:paste`'s output into a file, linting it, and checking the frame
comes out the same colour.
**D13 said this was impossible on purpose, and the reasoning stands**: a
program that can restyle the session it happens to be running in is a hazard,
and `cat hostile.txt` should not dim your panes. But *impossible* was the
wrong shape for it -- editing a file, saving, looking and guessing again is
slow enough that shaders go unwritten. So it takes `in_band_shaders true`,
one line of consent, and it is scoped to the pane that asked: its own two
chains, never its neighbour's, never what the config said about anyone else.
There is a test for the neighbour.
Each chain owns the programs its expressions compiled to, and is swapped in
whole, so a chain that turns out not to read leaves the pane looking like it
did rather than half-restyled. Measured: 1,800 replacements of an animated
chain, resident size flat after the first pass.
Also here, because it is the same paint order: the chrome chain now sits
between the config's and policy's, exactly where the content chain does.
Dead code out -- `app_shade_add`/`app_shade_clear`/`app_shade_count` had no
callers and their comment claimed the opposite of what this commit does.
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/config.md | 2 | ||||
| -rw-r--r-- | docs/scripting.md | 11 | ||||
| -rw-r--r-- | docs/shaders.md | 28 |
3 files changed, 40 insertions, 1 deletions
diff --git a/docs/config.md b/docs/config.md index b504111..57b816c 100644 --- a/docs/config.md +++ b/docs/config.md @@ -104,7 +104,7 @@ theme { frame_focus "#00ff88" } // ...but that one colour is mine |---|---| | geometry | `gap` `gap_aspect` `padding` `rounded` `title_align` `title_inset` `min_pane` `min_split` | | chrome | `status_bar` `status_line` `status_pad` `hints` `version_banner` `pane_buttons` and the marks (`zoom_mark` `zoom_on_mark` `close_mark` `min_mark` `newtab_mark` `bell_mark`) | -| behaviour | `focus_follows_mouse` `scroll_lines` `toast_ms` `hover_delay_ms` `double_click_ms` `anim_ms` `modal_scrim` `dim_unfocused` `keep_dead` `shell` `editor` `shader_dir` | +| behaviour | `focus_follows_mouse` `scroll_lines` `toast_ms` `hover_delay_ms` `double_click_ms` `anim_ms` `modal_scrim` `dim_unfocused` `keep_dead` `in_band_shaders` `shell` `editor` `shader_dir` | | colour | `theme { }` | | effects | `shaders { }`, `states { }` — see [shaders](shaders.md) and [chrome](chrome.md) | | keys | `keys { }` — see [keys](keys.md) | diff --git a/docs/scripting.md b/docs/scripting.md index 0c27565..298ae17 100644 --- a/docs/scripting.md +++ b/docs/scripting.md @@ -58,6 +58,17 @@ printing a prompt and hoping. `purpose` is the other verb: `printf '\033]5577;1;purpose;logs\033\\'`. A purpose declared by a layout or the control API wins and cannot be overwritten this way. +`shader` is the third, and the only one the session can refuse: it sets the +shader chain for the pane that asked, in the config's own syntax, and needs +`in_band_shaders true` because a program restyling your session is a hazard +before it is a convenience. See [shaders](shaders.md#prototyping-in-a-pane). + +Anything the session sends *back* to a program ends its verb in `-reply` -- +`hello-reply`, `shader-reply` -- and no request verb may. A pane that echoes what +it is sent (`cat`, a shell with echo on, a REPL waiting for a line) would +otherwise be answered into a loop, which is exactly what `hello` used to do: +4 MB of hellos in a second and a half. + ## Headless `sl0ppty --script` is the whole program without a terminal: commands on stdin, diff --git a/docs/shaders.md b/docs/shaders.md index 7e32d09..95550f0 100644 --- a/docs/shaders.md +++ b/docs/shaders.md @@ -88,6 +88,34 @@ your cursor. Each is a file you can paste into your config or `include`. `contrib/shadertoy.html` previews the language in a browser (a test cross-checks that preview against the real compiler, so it cannot lie to you). +## Prototyping in a pane + +Edit, save, look, guess again is a slow way to arrive at a colour. A program can +set the chains for the pane it is running in, in the same syntax the config uses: + +```bash +printf '\033]5577;1;shader;chrome;tint color="#ff5fd7" amount="abs(t / 8 %% 510 - 255)"\033\\' +printf '\033]5577;1;shader;content;dim amount=90\033\\' +printf '\033]5577;1;shader;chrome;\033\\' # nothing: back to normal +``` + +The field after `shader` is which rect (`content` or `chrome`), and the rest of +the payload is the chain, verbatim -- `;` separates entries, so several passes fit +on one line. The session answers on the program's stdin, `\033]5577;1;shader-reply;ok\033\\` +or `shader-reply;error;bad amount for tint: ...`, so a typo says so instead of +looking like a shader that does nothing. + +`contrib/shader-repl` is that loop with a prompt on it: type a chain, see the +pane change, and `:paste` prints what you have as a `shaders { }` block for your +config. What you prototype and what you paste are parsed by the same code, which +is the point of using the config's syntax for a thing typed at a terminal. + +**Off by default.** It needs `in_band_shaders true`, because a program that can +restyle the session it happens to be running in is a hazard first and a +convenience second: `cat` the wrong file and your panes go dark. With it on, a +pane can only paint *itself* -- not its neighbour, and not anything the config +said about anybody else. + ## Your own, compiled A shader is a C function from one cell to that cell's colours. Any `*.so` in |
