Skip to content

Releases: w-p/pain

v1.11.4

Choose a tag to compare

@github-actions github-actions released this 11 Aug 02:00
  • 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
    less and man have 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. vim and tmux use this to refresh, and had been waiting for
    a message that never came.

v1.11.3

Choose a tag to compare

@github-actions github-actions released this 01 Aug 15:27
  • 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

Choose a tag to compare

@github-actions github-actions released this 31 Jul 19:04
  • 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

Choose a tag to compare

@github-actions github-actions released this 31 Jul 14:50
  • 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.

  • --settings opens the settings window at startup, instead of needing a
    right-click and a menu entry to get to it.

v1.11.0

Choose a tag to compare

@github-actions github-actions released this 30 Jul 14:40
  • 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=list shows 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 8x16 for the DOS ones, C64 Pro Mono for c64 — 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, and hum = 0 turns 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

Choose a tag to compare

@github-actions github-actions released this 30 Jul 02:14
  • 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 writes config.toml, and Cancel — or
    closing the window — reverts the preview.

v1.9.0

Choose a tag to compare

@github-actions github-actions released this 29 Jul 16:58
  • 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 — --rcfile for bash, -Command for PowerShell,
    and a script executed inside WSL. Windows Defender flagged the result as
    Behavior:Win32/DefensiveEvasion.A!ml and 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_size and transparency are whole numbers now. transparency is a
    percentage, so 1.0 becomes 100 and 0.7 becomes 70. A config file
    written before this is read and converted rather than rejected — TOML
    tells 70 and 0.7 apart by type — so nothing else in the file reverts.

v1.8.0

v1.8.0 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 29 Jul 16:12

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, Delete and F1F12 had no encoding at all and
    were silently dropped. Shift+Tab sent 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. Alt was 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 inside vim, less and 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
    tell Shift+Enter, Ctrl+Enter and plain Enter apart. These are the
    same byte in the traditional encoding and cannot be distinguished in it at
    all; editors and CLI tools that offer Shift+Enter for 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+Plus and Ctrl+Minus change the font size by a point, and Ctrl+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

Choose a tag to compare

@github-actions github-actions released this 29 Jul 00:39
  • 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, --version and --verbose still 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 Light and the
    rest of the familiar names. Pick one from Settings, where the list is
    filterable, or set appearance.theme by 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_color is 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
    cargo and gcc emit — are now Ctrl+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:
    only http, https, ftp, ssh and mailto are 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

Choose a tag to compare

@github-actions github-actions released this 28 Jul 15:16
  • 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_lines did 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_size to 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_size to 6–48, transparency to 0.0–1.0, scrollback_lines to 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.