| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
A native theme `lapis` (src/themes/lapis.zig) from web/theme/lapis.css:
a lapis-deep page, lapis tags with gold names, vellum text, vermilion
rubrics, gold rules and a vermilion tag rule, gold selection in lapis ink.
Its ornament is the theme's new `decor` (colors.Decor), drawn by a pixel
shell inside the chrome it already has (decision 1), all of it off every
focus indicator:
- page_dots: the site's gold dot grid (#e8c46a22, 22 px), drawn by the
cell shader on page-coloured cells alone (flag 0x10000000), so it lies
under the text and never under a selection, a tag or the cursor; fixed
to the window, a page the panes lie on.
- rail_checker: the dither frame's gold and lapis checker in the scroll
track (a decor kind, flag 0x08000000), anchored to its rail; the thumb
stays solid gold.
- tag plaques (tag_border, tag_shadow, tag_stripe): every tag a raised
plaque inside its own band, the site's trail: a 2px gold frame and a
hard 5px vermilion shadow down and right, both within the band's rows
and columns (down, what the slack under the text leaves), so no shadow
reaches a body, a grip or the next pane. The focused pane's plaque is
the code window's title bar, gold and lapis stripes of 2px, its words
on plates of the focused ground; unfocused ones are plain; column and
workspace tags take the object-label language (1px frame, 2px shadow
toward the page). Drawn as decor under the cells (a group's under
range), with blank tag cells see-through and the cells blended
premultiplied (pipeline_over) on such frames; opaque windows only.
- title_shadow: the titles' vermilion offset shadow under a file name's
letters, sampled in the cell shader inside the letters' own cells (flag
0x08000000), none on a cursor.
Chrome carries the decor (decor_*, name_ink, active_name_ink); a theme
file folds a nested decor literal field by field. Left out, with why, in
docs/effects.md: the fonts, the ornaments, a decor crossfade, and in the
tty anything but the colours (a tag row has no spare cell for a shadow).
An empty column is the page. The effect id is masked to 27 bits (ui.vert/ui.frag) for the
fifth flag.
Tests: the cell flags land only on page ground and file-name cells, never
a cursor, nothing without decor; lapis's plaques stay inside their tag's
band, clear of every grip, only the focused one striped; its checker is in
the track; no other theme draws any; the separator and focus
tests cover lapis. Goldens: theme and themesel (the ring gains lapis after
acme). Gates as G4. Feel review: .scratch/render/lapis/ (lapis.png, lapis-2x.png,
tags-focused-vs-unfocused-2x.png, a PanelSlide at 60 fps and a quarter).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The core owns the motion, as Lift: animation.CursorGlide keeps the focused
cursor's four corners on springs (leading corners at the flavour's pace x2.4,
trailing ones x follow, so a jump smears and collapses; a long jump bows by
the flavour's arc), sampled at each frame's own time. A step of a cell or
less, insert mode, a focus change and any scroll (a file's view, a
terminal's output) land at once; a snap lands a glide under way too. The
quad is clamped to the focused pane when drawn (never its springs). Chrome
carries it on the wire (cursor_glide: bit 1 a cursor, bit 0 gliding;
cursor_alpha; cursor_quad, grid cells; cursor_idle_ms): the GUI draws the
quad as an overlay in the cursor's colour, at 85% (70% on the long
flavours) rising to solid as it lands, and hides the cells' cursors while it
does: one or the other every frame. Only the focused cursor glides.
Blink (CursorBlink, on by default in pixel shells) is the shell's: from
cursor_idle_ms and when the frame arrived, solid while typing and 500 ms
after, 530 ms halves with 80 ms eased edges, solid after 10 s idle, and
never while the window is unfocused or minimized or on a virtual clock. An
edge redraws the last frame with no core render (level B, blink_redraws);
an attached GUI blinks from the same field without a frame per edge.
Tests: snaps a cell, glides a jump with smear and bow, arrives under a pixel
by 150 ms on smooth and lands exactly, shifts with a scroll; blink holds,
eases, stops; the core glides a jump (ge) frame by frame (gliding exactly
while it moves, alpha rising, exact at rest), snaps a step (j) and a switch
to insert mid-glide; a terminal's scrolling output lands its cursor; wire
round-trip of the cursor record.
Shared files: src/animation.zig, src/pardes.zig, src/config.zig (toggle
CursorBlink), src/surface.zig, src/detached/wire.zig.
|
| |\ \ |
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
rules
acme takes plan9port's own colours (acme.c iconinit, draw.h): selections
#eeee9e in the body and #9eeeee in the tag, black ink; exec and look sweeps
#aa0000 and #006600, white ink; a #99994c scrollbar under a #ffffea thumb;
black rules; a #8888cc tag/body rule and column button.
Every theme: the grip is acme's button, its tag row's full height, in one
scroll column with the scrollbar (rail_px, 12 at a 17px tagline, scaled,
times GripWidth, a percent, default 150; same x0/x1 to the pixel):
focused clean = solid box; focused dirty = box_dirty filled to a box ring
(acme's modbutton); unfocused clean = a box_border ring round the tag's
ground; unfocused dirty = box_dirty a pixel inside that ring. The grid, which
has no ring, marks dirty with a bold * on box_dirty in the grip's second cell
and fills an unfocused grip halfway to its ring. Regions carry a dirty flag.
Column buttons are the same shape, solid. 2px rules between columns and
stacked panes (inside the tag band's slack), none at the window edge; a 1px
tag/body rule halfway between tag and page.
Theme data: tag_sel_bg, sweep_bg/fg, tag_rule, rule_px, rail_px, box_border,
box_dirty. Chrome: rule_px, tag_rule, rail_px, grip_border, grip_focus_ring;
a comptime guard on Chrome's layout forces a wire bump once v8 ships.
Structural rules are exempt from the focus-indicator rule (docs/effects.md).
Tests: acme widths; stacked rule in the slack at two tagline sizes; every
grip-column pixel is band, button, ring or rule, and the button shares the
scrollbar's x0/x1 (4 metrics x top/bottom x focus x dirty); the four grip
states distinct in every native theme with a non-colour dirty cue in the
grid; wire round-trip of the new fields.
Shared files: src/colors.zig, src/surface.zig, src/body_layer.zig,
src/tagline.zig, src/detached/wire.zig, docs/themes.md, docs/config.md,
docs/effects.md, 21 snapshot goldens (the grip cells only),
test/gui-goldens.txt.
Motion flavours differ by design, and drive notice drops and pane moves
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
recedes the other panes (InactiveDim)
Motion off|crisp|smooth|bouncy|playful is one parameter set (animation.Motion)
every fx animation reads. One focus spring per pane drives both the lift and
the dim, at the flavour's pace; a grid snaps.
Lift drops glow and surface. A shadow falls on pane bodies and rails only,
capped so text and the selection keep min(contrast, 4.5); rim is a hairline
along the focused tag's top. auto is a shadow on a light page; on a dark page
the core recedes the unfocused panes' text (InactiveDim, ported from 2e4d97f,
default 30 under auto) with the same floor. Tests: focused text contrast is
never below unfocused in any style, dim or theme; the focused pane's cells and
tag are untouched by a dim.
Shared files: src/config.zig, src/builtins.zig, src/ninep/ctl.zig,
src/surface.zig, src/detached/wire.zig, docs/config.md,
test/snapshots/builtins.snap (one more wheel for the longer help).
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The user wants Lift to read on dark themes, where a shadow has nothing to
darken. `Lift shadow|surface|rim|glow|auto` (`on` is auto, bare flips
auto and off): surface lightens the lifted part's ground about 5.5%
(Material-dark), rim is a thin soft light off its top and left edges,
glow a faint halo in the theme's accent (Chrome.accent, the focused box
colour), auto a shadow on a light page and surface with half a rim on a
dark one (by the page's luminance). Rim and glow are the soft kernel in a
light colour (no pre-warp: coloured light is laid on as is, within §8.2's
budget); each style is capped per theme so text keeps min(its contrast,
4.5) (tests: darkening and lightening over the native themes). The style
travels in the palette (Chrome.lift_style, one byte on the wire). Config
reports and ctl reads `Lift <style>`.
Shared files touched: config.zig, builtins.zig, ninep/ctl.zig,
detached/wire.zig (palette byte), gui.zig. Not touched: pardes.zig,
Messages.zig, mouse.zig.
|
| | |/
|/|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
`Lift` (a GUI toggle, capability lift) lifts the focused pane on a
critically damped spring (animation.Spring: closed form, about 240 ms to
settle, velocity kept across retargets, settled = no frames) and floats
notices. The core puts the lift on the regions (Region.lift, on the wire);
the GUI casts from it: a soft shadow is decor, an erf rectangle on one
quad grown by 3 sigma (decor.frag, flag 0x10000000), in the quad's own
space so a track's transform carries it; darken-only, the caster's rect
left alone, alpha pre-warped for linear light and IGN-dithered. Cast last
in its group, so a neighbour's rails and rules darken with its text; a
notice's before its rule. Strength is capped per theme so text over the
darkest shadow keeps min(its contrast, 4.5) (test over the native themes).
Opt-in until the focus lift/dim default is decided. Feel review material:
docs/effects.md. Test-mode PARDES_TEST_SERIES keeps every captured frame.
Shared files touched: pardes.zig (two fields, one nextWake line),
detached/wire.zig (lift on the region), config.zig, builtins.zig
(capability), gui.zig. Not touched: Messages.zig, mouse.zig, tty,
host_io.
|
| |/
|
|
|
|
|
|
|
|
|
|
|
|
| |
makenewwindow puts them
Newcol makes an empty column; closing a column's last pane leaves it empty with
the keyboard on its tag; Delcol and Joincol alone take a column away; the
session's last pane closing quits. The +New stand-in and replaceStillborn /
stillborn_joiner are gone. Every new pane goes through exec.placeNew, which
follows acme's makenewwindow (active column, empty column whole, blank space,
halving the biggest) or, with Placement pardes, the old rules. ColumnTags is
gone: column tags are always shown. A grip drag shows acme's box cursor.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
mark_hover is gone
Open point 6 of docs/render-pipeline.md: notice words are Look and Exec
targets, so the hover affordance headers have is back on notices, painted
once in the notice's layer and joined into the grid from it. Deleted:
Surface.mark_hover, Cell.hover and render's per-frame reset of it, none of
which had been set since stage 5 (macOS loses its glass hover rect; its
build is ignored for now). Snapshot goldens unchanged.
Shared files touched: macos.zig (the hover bit's removal). Not touched:
pardes.zig, Messages.zig, mouse.zig, gui.zig, detached/*.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Stage 8 of docs/render-pipeline.md. The frame is drawn in groups: tier 0,
one per track in paint order (tiers 2 and 3), tier 4 (notices, then guides
and the debug box), tier 5 (bar cursors), each cells, images, decor. Decor
(rules, rails, thumbs, grip marks, spines, the workspace and column rules,
the bottom band, notice rules, bar cursors) is whole-pixel rects through
the new decor.frag over ui.vert, so it carries its track's transition and
clip. A closing pane's chrome comes from Surface.previous_regions.
Deleted: taglineBaseRgb, topbarPaneBorderHeight, bottomTaglinePresent,
frameChromeBg, cellBackgroundIs and the rail inference, paneGripCell's
scan, transient_on, PaintPlan. One cover map (coverFrame) is marked from
the layers and regions once a frame. New regions column, guide and debug;
Surface.chrome is the palette, carried in wire v8 (not shipped yet), so an
attached GUI draws the same chrome (test). A per-instance clip replaces the
vertical transition's scissor.
Goldens: 01-12 byte-identical. 13-17 differ only past the grid: the image
pass left its scissor at the grid's size, cutting rule ends, rail feet and
the bottom band in the leftover pixels whenever a picture was on screen.
16-debug now shows the debug box, which a context-row layer had hidden.
18-mid-transition is new: virtual clock (PARDES_TEST_CLOCK in the GUI),
PanelSlide Newcol with the picture, frame 6 of 12.
Also: the GUI sleeps when idle instead of polling every 16 ms, and a
minimized or occluded window sleeps through animation. Tracy 'gui frame
build' at 200x60: 992/1015 us median before, 989/987 us after.
Shared files touched: pardes.zig (one export), detached/client.zig,
detached/server.zig, detached/wire.zig (all additive), gui.zig. Not touched:
Messages.zig, mouse.zig, tagline.zig, colors.zig, tty.zig, host_io.zig,
dump.zig, exec.zig, panes.zig.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 pane's tag rows, each notice chip and the workspace and column tags are
painted once, as their tag layers, and the grid's cells for them are copies
of those layers (joinCells): the second paint of every tag, the grid's own
notice pass and paintHeaders' grid text, hover, selection and caret are
gone, and so is renderTagLayers. The grid's caret for a tag, a header or a
prompt is the layer's, projected to grid columns. A wide glyph cut by the
edge of the copy is left as the band's blank, as the grid's print never drew
half of one (a test proves it, and fails without the re-clip).
Where the two copies disagreed, the grid's behaviour is kept, so every
snapshot golden is byte-identical:
- a notice highlighted the hovered word only as a layer; now it never does;
- a column tag's hover was suppressed during a column move only on the
grid; now in both;
- a header under edit showed the hovered word only on the grid; now in
both, under the selection;
- a notice's leading padding carried the band's ink only as a layer; the
grid copy keeps it blank;
- a notice whose band is wider in tagline pitch than in grid cells (a GUI
core) now shows the band's right end on the grid, where its text is, and
its prompt caret there.
A sweep begun on a tag and dragged into the body still shows on the body
rows it crossed, on the grid only (paintPointerSelection's from_row).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
draw.place builds the Surface's region list at the head of render: the
page; each pane's grip, tag rows, body, rail with its thumb, and notice
chips; each column's grip and tag; the workspace tag. The painters read
their geometry from it instead of working it out again: the grid's notice
chips and the notice layers share one chip rectangle, the rails (file,
terminal, image, PDF page) paint the placed thumb (a native PDF measures
its own into the region as it places its pages), and the body, tag, notice
and column layers take their viewports from their regions. A collapsed pane
places only its grip and tag. The column-move rail's one-cell clip of the
layers under it is now a region field set in place, not a mutation of the
built layers. No behaviour change; a test checks every region against the
old geometry, the painted rail and the layer viewports across tag bottom,
column tags, notices, a collapsed pane and a multi-line tag.
|
| |
|
|
|
|
|
|
|
|
| |
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.
|
|
|
Pure move: Color, FontRole, CellStyle, Cell, AsciiDiff, PanelCellDiff,
ImageCacheKey, NativePlacement, ImagePatch, ImagePlace and Surface, with
their eight tests, go verbatim to the new surface.zig with the imports they
use. pardes.zig keeps one `pub const X = @import("surface.zig").X;` line
per type, as it already does for Pane, Rect and the tag layers, so the
shells' `pardes.Cell` / `pardes.Surface` spellings do not change.
Surface.print, clearRect and overlayDash become pub because render calls
them from pardes.zig. surface.zig is added to pardes.zig's test block and
to the embedded source list.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|