Releases: w-p/pain
Release list
v1.11.4
-
Fixed: copying text while scrolled back copied the wrong text. Selecting
worked against the live screen rather than the history you were looking
at, so what you got was whatever occupied those rows at the bottom of the
buffer — further off the further back you had scrolled. The highlight was
drawn from the same place, so it appeared correctly under the pointer
while the copy came from somewhere else, which is what made it easy to
miss.The highlight also stays where it belongs now when a selection is scrolled
out of view, instead of collapsing onto the top row. -
Fixed: the scroll wheel and trackpad did nothing inside full-screen
programs — Claude Code,htop,lazygit,less,man,vim. Scrolling
was only ever applied to this terminal's own history, and a full-screen
program has none: it draws on a separate screen that deliberately keeps no
scrollback. The wheel was also the one mouse input never passed on to the
program, so applications that handle scrolling themselves never heard
about it.Now, in order: a program that asked for mouse input receives the scroll;
a full-screen program that didn't gets arrow keys instead, which is how
lessandmanhave always scrolled; and otherwise it moves through this
terminal's history as before. Holding Shift always means the last of
those, so a pane's own history stays reachable whatever is running in it. -
Horizontal scrolling works. Sideways trackpad movement was discarded
before anything looked at it. -
Middle-click is passed on to programs that want mouse input. Right-click
is not, and stays the pane menu whatever is running — that menu should be
in the same place every time. -
Programs that ask to be told when the terminal gains or loses focus are
now told.vimandtmuxuse this to refresh, and had been waiting for
a message that never came.
v1.11.3
-
Fixed, macOS: a trackpad couldn't scroll the terminal at all. A trackpad
reports scrolling in pixels, as a stream of small movements while your
fingers move, and each one was converted to whole lines and rounded on its
own — so anything shorter than half a text row became zero and was thrown
away. On a Retina display a row is about 33 pixels tall and those
movements are usually under ten, so every one of them was discarded and
the terminal never scrolled however long you swiped.Leftover movement now carries over between events until it adds up to a
line. A mouse wheel, which reports whole notches rather than pixels, was
never affected and still scrolls immediately.
v1.11.2
-
Fixed, macOS: the settings window opened completely empty, and could then
crash. The window ran its interface and then asked for somewhere to draw
it — and on macOS that request routinely fails the first time for a window
that has just been created. Taking that path threw away the font texture
that had been prepared alongside the frame, and it is only ever offered
once, so from then on every character was drawn using a texture that was
never received: the window painted its background and nothing else.The terminal window asks for somewhere to draw before it builds a frame,
which is why its own menus were unaffected on the same machine.Also fixed alongside it: those failed frames neither asked for another
attempt — so a window could stop drawing entirely — nor released the
textures they were finished with.
v1.11.1
-
Fixed: the settings window could open blank and stay that way. It repaints
only when something asks it to — when it opens, when it is resized, and
while a widget is animating — so a first frame that rendered nothing had
nothing to rescue it. On Windows and Linux a resize almost always follows
window creation and covered this up by accident; a platform that creates
the window at exactly the requested size sends none.It now keeps asking for frames until one actually renders, and re-points
the surface at the window whenever the two disagree about its size. If it
still can't render after a couple of seconds it says so on stderr rather
than repainting silently forever. -
--settingsopens the settings window at startup, instead of needing a
right-click and a menu entry to get to it.
v1.11.0
-
Retro eras, off by default. An era is a period look for a specific machine —
green(IBM 5151),amber,cga(IBM 5153),bbs,c64— bundling a
palette, scanlines, a curved-glass vignette, and a typeface. Set[retro] era, pick one in Settings under Retro, or try one for a session with
pain --era=amber.pain --era=listshows what's available.An era overrides your theme while active but never writes to it, so turning
it off restores what you had. Anything you set explicitly — background
colour, scanline or vignette strength — still wins over the era.Scanlines and the vignette have sliders in Settings, each showing the era's
value until you move it, with a button to hand control back to the era. -
Eras name period typefaces — VT323 for the phosphor eras,
Px437 IBM VGA 8x16for the DOS ones, C64 Pro Mono forc64— and use one if it's
installed. None are bundled; the README says where to get them. The font
makes more difference to a period look than the palette does, so it's worth
installing one. -
A drifting hum bar, the soft band that crept up an old monitor when its
power supply and the mains were slightly out of step. It's the only effect
that moves, and so the only one that keeps the terminal drawing while idle —
it stops when the window loses focus, redraws well below your display's
rate, andhum = 0turns it off entirely. -
Eras can also be set live by a shell or script, with this terminal's own
escape sequence:printf '\e]7331;era=green\a'
Session-only and never saved, and the payload is an era name rather than
colours — so program output can't leave you with an unreadable screen. -
The scanline and vignette effects are static: they add one draw to a frame
that was already being rendered, so with the hum bar off an idle terminal
still renders nothing and still sleeps.
v1.10.0
-
The process scan behind the pane title bars now collects only what those
titles actually read (a process's name, parent, and start time). It had
been collecting memory and CPU counters, disk I/O, and the thread list of
every process on the system, every half second, and keeping it all. -
Settings opens in its own window now, rather than as a panel floating
inside the terminal. It can be dragged anywhere, including onto another
monitor, and no longer competes with your panes for space or has to be
shrunk to fit a small terminal window.Everything else about it is unchanged: edits still preview live in the
terminal as you make them, Save writesconfig.toml, and Cancel — or
closing the window — reverts the preview.
v1.9.0
-
Removed shell integration on Windows. To track a pane's working
directory, pain wrote a startup script to the temp directory and spawned
the shell against it —--rcfilefor bash,-Commandfor PowerShell,
and a script executed inside WSL. Windows Defender flagged the result as
Behavior:Win32/DefensiveEvasion.A!mland moved to quarantine it, which
is a fair reading of what that looks like from the outside.What it cost: on Windows, a restored session reopens panes in your home
directory rather than their last working directory. Layout, window size,
shell and group still restore. cmd.exe never had it. Linux and macOS are
unaffected — they read the working directory from the OS process table
and never had anything injected.Windows bash also goes back to reading its own startup files rather than
a generated one. -
font_sizeandtransparencyare whole numbers now.transparencyis a
percentage, so1.0becomes100and0.7becomes70. A config file
written before this is read and converted rather than rejected — TOML
tells70and0.7apart by type — so nothing else in the file reverts.
v1.8.0
Warning
Use v1.9.0 instead.
Windows Defender flags this build as Behavior:Win32/DefensiveEvasion.A!ml
and will quarantine it. The cause is pain's Windows shell integration: to
track a pane's working directory it wrote a startup script to the temp
directory and spawned the shell against it, including across the WSL
boundary. That is a fair thing for a behavioural classifier to object to.
The detection is a false positive — the binary is built by GitHub Actions
from the tagged source and no dependency changed from v1.7.0 — but the
behaviour it flagged was real, and v1.9.0 removes it.
-
Fixed: every color rendered noticeably brighter and more washed out than
the color it was supposed to be. Themes made this obvious — Ayu's greens
arriving as pale mint — but it applied to the default palette and the
app's own chrome just as much. The window is an sRGB-format surface, so
the GPU applies gamma encoding to whatever is drawn; colors were being
handed over already encoded and so got encoded a second time. Colors now
match their published hex values.The window background also renders correctly at transparency levels
below 1.0, where it was previously composited without being scaled by its
own alpha and read brighter than the opaque one. -
Fixed: many standard keys did nothing.
Home,End,Page Up,
Page Down,Insert,DeleteandF1–F12had no encoding at all and
were silently dropped.Shift+Tabsent a plain tab, so it moved forward
through a form or completion menu instead of back. Modified cursor keys
(Ctrl+Left,Shift+End, ...) lost their modifier.Altwas not sent as
Meta, so readline's word-wise motions —Alt+B,Alt+F,Alt+D— did
nothing. Application cursor mode was ignored, so arrow keys used the wrong
form insidevim,lessand anything else that enables it.Keyboard input is now the full xterm-compatible encoding rather than the
handful of keys the first version implemented. -
The kitty keyboard protocol is now supported, which is what lets a program
tellShift+Enter,Ctrl+Enterand plainEnterapart. These are the
same byte in the traditional encoding and cannot be distinguished in it at
all; editors and CLI tools that offerShift+Enterfor a newline ask for
this protocol to get it. Programs that don't ask are unaffected. -
Fixed, theme picker: clicking the filter box closed the dropdown, so the
filter could not be used. The list also stopped at the first 100 of 600
themes with a "keep typing" note at the bottom, and had two nested
scrollbars, the visible one belonging to the wrong thing. The whole list
now scrolls, filtering works, and it shows twelve themes at a time. -
Ctrl+PlusandCtrl+Minuschange the font size by a point, andCtrl+0
returns it to the default. The new size is saved, so it survives a
restart.These chords previously did something else entirely: nothing had bound
them, so the UI toolkit's own handler claimed them and scaled the app's
menus and panels instead of the terminal font — which is what was leaving
the right-click menus offset from the pointer afterwards. -
Fixed: the text cursor was partly transparent, so at any transparency
setting below fully opaque the desktop showed through it. It is now a
solid block with the character under it drawn in reverse video, which is
what other terminals draw. The selection highlight had the same problem
and keeps its blended appearance without being see-through. -
The title bar color is now configurable, in Settings or as
appearance.title_bar_color. Its text color follows automatically, so a
pale title bar gets dark text. Grouped panes still take their color from
their group — that is the only way to tell groups apart. -
Keybindings are written with spaces instead of
+:"ctrl shift e",
"ctrl +","ctrl -". It reads better, and it means+and-are
writable as themselves rather than spelled out — a separator that is also
a key on the keyboard can't represent that key. The space key is written
space.Existing config files are unaffected: the older
"ctrl+shift+e"form is
still read. -
Fixed, Settings: the scroll bar overlapped the right edge of the controls
beside it. It now has a margin of its own.
v1.7.0
-
Fixed, Windows: starting pain opened a console window that then sat there
for as long as the terminal was running, and a shell you launched it from
stayed blocked until you closed it. The executable was built as a console
application — the default, and the wrong one for something that opens its
own window — so Windows gave it a console whether it wanted one or not.
It's now built as a normal windowed application, which is why neither
macOS nor Linux ever showed this.--help,--versionand--verbosestill print to the terminal you ran
them from, and redirecting to a file still works. One difference is
unavoidable now that the shell no longer waits: their output arrives just
after the prompt comes back, which is how every windowed Windows program
with a command line behaves. -
Panes now show a dot in their title bar when something has happened —
blue when the shell produced output, red when a program rang the terminal
bell. This is for the side pane running a build or tailing a log: you can
tell it moved without watching it. The terminal bell was previously read
and discarded, so a program ringing it did nothing at all.The two clear differently, on purpose. Output only matters for a pane you
aren't watching, so focusing it is enough. A bell is a program asking for
attention and usually rings the instant a command starts — while its own
pane is still focused, because you just pressed Enter there — so it
survives focus and clears when you next type into that pane. -
Over 600 built-in color themes, compiled into the binary —
Dracula,
Tokyo Night,Gruvbox Dark,Catppuccin Mocha,Solarized Lightand the
rest of the familiar names. Pick one from Settings, where the list is
filterable, or setappearance.themeby hand. A theme supplies the 16 ANSI
colors programs draw with plus the default foreground and background, so
switching restyles panes that are already open.The default is unchanged:
Graphite, exactly the palette the app has always
shipped, so upgrading doesn't restyle anything on its own.
appearance.background_coloris now an override — leave it empty and the
background follows the theme, which is what you want since a theme's
background is part of its design. A config that already set it keeps that
value and keeps overriding. -
Links a program explicitly marks with the OSC 8 escape sequence — what
cargoandgccemit — are nowCtrl+click-able. Previously only text
that looked like a URL was matched, so a link whose visible text was an
ordinary word was invisible. The same scheme restriction applies either way:
onlyhttp,https,ftp,sshandmailtoare ever handed to the
operating system, so program output can't turn a click into opening an
arbitrary local file. -
Emoji now render in color. They previously came out as flat monochrome
silhouettes, because the color information a font provides was being
thrown away and only the shape kept.Color glyphs get their own small texture rather than widening the existing
one, so ordinary text keeps exactly as much room as it had. Symbols that
programs print as text —✓,✗,★,➜— deliberately stay
monochrome and one cell wide; they have emoji forms, but a test suite's
worth of checkmarks turning into colored pictures is not an improvement.
Needs a color emoji font installed, which every mainstream desktop has:
Noto Color Emoji on Linux, Apple Color Emoji on macOS, Segoe UI Emoji on
Windows. -
Optional ligature support, off by default:
appearance.ligatures, or the
checkbox in Settings. Renders!=as≠and=>as⇒with a font that
provides them (Fira Code, JetBrains Mono, Cascadia Code, Iosevka). Never
applied across a color change or across the cursor, so editing!=still
shows which character you're on.Off by default deliberately, and it stays a separate rendering path rather
than replacing the existing one: shaping hands glyph positioning to the
font's own advances instead of the cell grid, and costs real per-frame work.
Neither is worth imposing on someone who didn't ask for ligatures.
v1.6.1
- Fixed: changing the font size a few times crashed the terminal. Every
size you passed through kept its own permanent copy of the character
set in the glyph texture, and once that texture filled up the next
character written to it ran off the end — which the graphics driver
treats as fatal. Only one font size is kept now, the texture is four
times larger, and running out of room falls back to reusing it rather
than crashing. (#1) - Fixed:
scrollback_linesdid nothing. The setting was saved, shown in
the settings panel and documented as defaulting to 5000, but the number
never reached the terminal grid — every pane kept a fixed 10000 lines
regardless. It now works, and changing it applies to panes that are
already open rather than only new ones. If you never set it, panes now
keep 5000 lines of history instead of 10000 — raise it in the settings
panel or your config file if you want the old depth back. - Fixed: a multi-command paste could skip the confirmation prompt. The
check counted only line feeds, but a carriage return submits a command
just as well, so text separated with those ran every command it
contained without asking. Both count now, and the prompt reports the
line count correctly for either. - Fixed: hand-editing
font_sizeto 0 crashed the app the moment the file
was saved, and a negative value froze it at 100% CPU with no way back.
Numeric settings are now clamped to their documented ranges on load —
font_sizeto 6–48,transparencyto 0.0–1.0,scrollback_linesto at
most 1000000 — and say so on stderr. - Fixed: dragging a pane divider and releasing the mouse over an open menu
or the settings panel left the divider stuck to the pointer, resizing on
every later mouse movement with no button held. Losing window focus
mid-drag did the same. Text selections and mouse-driven programs had the
same problem. All of them now end properly. - Fixed: when a pane's shell failed to start while restoring a saved
session, the pane stayed in the layout as a dead blank rectangle that
could take focus and silently swallow everything typed into it. It is
now removed, and the remaining panes take the space. - Fixed: if a split failed to start its shell, the pane that was split kept
a terminal sized for half the space while drawing at full width.