| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Sixteen panes was far too few for a real session. MAX_PANES is now 64 on a
desktop and stays 16 on the board; the 48 more slots cost about 3.7 KB each
in fixed tables (the core 1.33 to 1.45 MB, its surface 19 to 72 KB), and a
pane itself (84 KB and its terminal) is allocated only when it opens. At the
cap, pane/new fails with `pane/new: no pane slots: 64 max` and an err
record rather than a bare ENFILE, a 9P look or exec that would open a pane
fails its write with the same words and reads back empty, and New, Tty,
Tutor and Alt-n say it on the message row (their ctl writes fail with it).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |\ |
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The flavours looked alike because Lift, the only motion that read them,
moves a shadow a few pixels: overshoot and wind-up were sub-pixel. By design
now: crisp leaves at full speed and never passes its mark; smooth (the
default) eases in and out in twice crisp's time, a slide arriving in 208 ms
(inside §8.1's 220); bouncy passes its mark by ~30% and settles twice;
playful winds up, passes by ~40%, and stretches and squashes, text included
(the user's choice). Small motions are exaggerated by the flavour's gain.
Motion gains launch, gain, span and norm, and ease(u)/speed(u) for moves of
fixed length. The notice drop follows ease() over its fall (alpha never
behind its position) and stays inside its pane's body past its row. Panel
tracks carry the flavour in Track.motion (the old padding byte; macOS header
name follows); opening and moving slides, zooms and rises follow it over
span x their frames; landed, a pane is exactly its target; closing keeps
its own exit. A pane past its mark never takes a neighbour's click; a
rising one stays in its box.
Tests: each flavour's lift trajectory distinct; flavour character; exact
landing bit for bit; a stretched pane's drawn cells map back; the overshoot
hit rule; the vertical clip at peak; legacy tests pinned to crisp. GUI
golden 18-mid-transition changes (the retuned smooth slide at frame 6).
Shared files: src/animation.zig, src/Presentation.zig, src/Messages.zig,
src/macos.zig, src/config.zig, src/pardes.zig tests, src/ninep/screen.zig
test, docs/effects.md, docs/config.md.
|
| |/
|
|
|
|
|
|
| |
active pane's
A session builtin written to /ctl runs at the active pane, so its messages were logged under that pane's serial, as if the pane had said them. They are now `msg -`, and still shown on the active pane.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |\ \ |
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
of rows; wire v8
src/Layer.zig merges TagLayer and BodyLayer. `rows` (0 = no layer) and a
cursor at {x, y}. A tag of N rows is ONE layer of N grid rows: tagHit answers
the row as `line`, bodyHit keeps its meaning, and the per-line layer bases
(TAG_LINE_LAYER_BASE, HEADER_LINE_LAYER_BASE) are gone, not aliased.
Wire v8, the one bump: tag layers carry rows and cursor y, and the frame
carries the placed region list. v7 and v9 peers are refused in both
directions (server test over both, a new frontend test over both).
web: tag_layer_value 11 = rows, 12 = cursor y; app.mjs lays every row.
macOS: the Zig side compiles against Layer; pardes.h still sees one row
per tag layer (accepted, the macOS shell is ignored for now).
No visual change: snapshot goldens and the 17 GUI goldens byte-identical.
Shared files touched: pardes.zig, Messages.zig, gui.zig, macos.zig,
detached/client.zig, detached/server.zig, detached/wire.zig (plus web.zig,
app.mjs, edit.zig, look.zig). Not touched: mouse.zig, tagline.zig,
colors.zig, tty.zig, dump.zig, exec.zig, host_io.zig, panes.zig.
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
A shell now answers Host.now, its monotonic clock in ns, and the pump
advances core animation to it: one .tick per whole 16 ms frame since core
time last stood still. The same animation therefore takes the same time at
60, 120 and 144 Hz, over ssh and after a slow frame (the GUI's re-armed
clock ran them ~25% slow at 144 Hz; the tty's post-frame sleep drifted).
nextWake() lists every core animation in one place: a frame from now while
anything moves, the end of the wait while something only waits (a message
lingering, the look-hover delay), null when idle. Shells sleep exactly that
long, and a wait is jumped to its end in one step, so an 800 ms linger
costs one frame instead of fifty. An overshoot under 1.5 ms after a step is
let go: at 60 and 120 Hz every display frame takes exactly one step (a 16 ms
frame against a 16.67 ms vsync would otherwise double-step every 24th).
The six tick drivers are gone: tty's timer thread only times the wait,
interruptibly (a newer, shorter request cuts short a sleep still timing a
longer one); the GUI's
AnimationClock, web's JS tick bank (pardes_tick now takes rAF's timestamp),
the detached server's and the board's ticks; grid mode steps a virtual
clock straight to each wake. PARDES_TEST_CLOCK, set by the snapshot
harness, gives tty and the detached server the same virtual clock.
Every stepped frame is drawn. The old pump never drew the last frame of a
fade (a .tick asks for no frame, and the fade was over by the check), so a
theme switch stopped at 9/10 of the way until the next input: theme.golden,
themesel.golden and the GUI's acme-light scene move to the theme's true
colours, and nothing else changes. The frozen previous grid is captured only
while a panel transition is chosen, not on every idle frame.
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Pure moves, no behaviour change. draw.zig holds the whole core frame in
order: render, the pane, tag, header and notice painters it calls, and the
character-effect composition (Pardes.render stays a declaration alias).
Presentation.zig is the panel presentation state as a file struct, and
animation.zig the easing curves, transition kinds, tracks and boxes, the
character effects' sources and the generic displayed-value transition, all
of which lived in layout.zig. layout.zig keeps only layout.
|
| |/ /
| |
| |
| |
| |
| | |
A failure read `Del k|j: InvalidArgument`, `Kill: NoSuchCommand`, `ill-formed control message`, or nothing at all. reportError now spells an error's name as words, and the refusals name their accepted forms: pty/ctl lists its verbs, a flag file takes 1 or 0, a setting word takes on or off, Del takes k, j or nothing, Repl takes - or a language. Kill with nothing to stop says so, /focus says pane, a Look that found nothing says no match, and pty/run on a command pane says it is not a shell. A ctl write's failure has room for the Repl list and is cut between words, the Repl word at a character.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
language's files
Repl python in a terminal's tag or on its ctl binds it (Repl - unbinds, Repl
bare says the binding, the same word again changes nothing), with an id,
python-a, python-b, in its tag. An exec made by a gesture on the body of a
file in that language -- a middle click or the execute key, on any text, a
single word too -- or on the REPL's own body is typed into it, bracketed if
its program asked for that, else line by line with a once-said warning for
Python's blank lines, then Enter; the message row says -> python-a in the
tag's name tint, the log send <from> <to> <id>. Several bound for the
language: the pane asks which on its notice band, as Del asks, one key
answering, Esc none, nothing remembered. The gesture is known where it is
dispatched (mouse.zig, the execute key), so the tag's words, Exec <text> run
by name and a command word @`cmd` stay commands, and a 9P exec is never
sent. A finished command pane is no REPL; bindings are not dumped. The docs
spell out the escapes, the pdb and input() caveat and the no-bracketed-paste
papercut.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
request is served
serveFs expired them, but a read is answered while a step is out in a
syscall, because reads change nothing, and this one changed pane messages
and needs_frame from under the step. The detached session's loop now expires
them between steps, and while nobody is attached and a message is up it
looks again every 100 ms rather than waiting for something to wake it.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |/
|
|
|
|
|
|
|
|
|
|
| |
A message lingers until input dismisses it, and a detached session with nobody
attached has no input: its messages, and /screen, kept what was said long ago.
The session now marks the core unattended while no client is attached, and
the core drops a pane's messages once the newest has been up MessageLinger on
the clock, checked as it is stepped or served. A pane's older lines go with
its newest rather than each on its own clock; the render pipeline's clock is
the place for that.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
Kill queued a signal effect for later, so the job it saw running by its marks
could have ended, and another started, before the signal went; and with job
control off the job shares the shell's process group, so the host skipped it
and Kill reported nothing. Kill now calls the host's kill_job while it holds the
turn, and when the only job is the shell's own group says 'Kill: no job to
signal', which also fails a write of Kill to ctl.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
argument is refused before anything runs
A ctl write failed only on a malformed line: Mount x reported its error
in the editor while the write succeeded, and a bare Mount failed only as
it ran, after earlier lines of the write. acme's ctl answers a command's
error (editors/acme/xfid.c:700). Builtins now declare requires_arg beside
takes_arg (settings: those with a value to set), and the check refuses a
bare one as wrong #args before any line runs; while a ctl runs, the first
error a builtin reports fails the write, quoted with its line, and the
prompt refusal quotes its line too. Docs say what a failure mid-write
leaves done.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
A tag that is a text can hold a newline, and the tagline, the body under it
and the pointer all assumed one row. The pane's tag now takes a row per line
(up to eight, and never the body's last row); the body starts below it, the
rows a pointer counts start the body after the tag's lines, a click on any
line puts the tag's cursor there, and a pixel shell gets a tag layer per
line. A tag of one line draws exactly as before.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Not a pure move: state moves. Pardes's three message-log fields
(`messages: [message_log]LoggedMessage`, `messages_head`, `messages_len`)
become the fields of Messages.zig itself (`log`, `head`, `len`), and
Pardes embeds one as `messages: Messages = .{}`. messageLog reads only the
ring, so it now takes `m: *const Messages` and is called
`p.messages.messageLog(i)` (Output's +Messages view and the log test);
logMessage still needs the panes and the 9P event log, so it keeps
`p: *Pardes` and writes `p.messages.log/head/len`. No behaviour change.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
|
|
Pure move, no behaviour change: the Message stamp helpers, LoggedMessage,
setStatus, setMessage, showMessage, dismissMessage, dismissLine,
advanceMessages, advanceLine, messagesAnimating, MessageMotion,
messageFrames, messageMotion, noticeText, noticeLife, blendRgb,
logMessage, messageLog, reportError, the notice painters (leaderText,
noticeCols, Printed, printRight), collectNotices, and the six message
tests go verbatim to Messages.zig.
The methods become free functions taking `p: *Pardes`. setStatus,
setMessage and reportError are called from ~170 places as `p.setMessage(..)`,
so Pardes keeps three declaration aliases (`pub const setMessage =
Messages.setMessage;`) and those call sites stay as they are; every other
call changes from `p.x(..)` to `Messages.x(p, ..)` (46 of them). The five
shells' `pardes.Pardes.Message` become `pardes.Messages.Message`. The
message ring's fields stay on Pardes for now; moving them into Messages is
a separate change.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|