Skip to content

Releases: allenguarnes/vomd

VOMD v1.2.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 20:44

Added

  • Select and copy text. Drag to select (a drag that starts on a link selects, and a click still follows it), double-click for a word, triple-click for a paragraph, heading, code block or table row, Shift+click to extend, Ctrl+A for everything, and drag past the top or bottom of the window to scroll. Ctrl+C (also Ctrl+Insert, Ctrl+Shift+C and the Copy key) copies plain text: list items start with - , quoted lines with > , table cells are tab-separated, an image is its alt text and a link its text. The text is made only when a program pastes it, so copying a whole 5 MB document costs no memory until then (X11 INCR and Wayland pipes, in pieces of 64 KiB). On X11 and Wayland a selection made with the mouse (and Ctrl+A) is also the primary selection, pasted with a middle click; the new primary_selection = on|off setting turns that off. As the window closes on X11 the clipboard manager, if there is one, is asked to keep the clipboard. Needs the new clipboard feature, on by default; the smallest build leaves it out.
  • Esc clears the selection before it quits (after closing the toolbar's menu, as before).
  • A copy button on code blocks, as on GitHub: while the pointer is over a fenced or indented code block, a button shows in its upper right corner, and a click copies the block's code to the clipboard (not the primary selection, and a selection is left alone). The code is as written, with its tabs, indentation and blank lines, without the language tag, without the quote marks or list indent of what holds the block, and without a line break after the last line; a block of several MB is made only when something pastes it. The button turns into a check mark for two seconds, lights up and shows the hand under the pointer, scales with the zoom and the display, and is left off blocks too small for it. If there is no clipboard, a note says so. Part of the clipboard feature, so the smallest build has none.

Fixed

  • An image decode that started just as the images wanted changed is counted in the room the image cache keeps free. Before, the cache could briefly fill the memory that decode used.
  • With remote images on, a picture near the window could be fetched again and again after a few arrived at once: each body let in was the first thing the next one's room was made from.
Budgets, measured on the release runner

A shared runner is two to three times slower than the machine the time budgets
are for, so start and scroll times are reported here, not gated.

Metric Build Measured Budget
✅ stripped binary default 3.91 MB ≤ 4.0 MB
⚠️ not gated cold start, tiny.md default 115.5 ms ≤ 100 ms (first of 20 runs)
✅ warm start, tiny.md default 38.7 ms ≤ 50 ms (median of 19)
✅ cold start, readme.md default 48.7 ms ≤ 100 ms (first of 20 runs)
✅ warm start, readme.md default 43.9 ms ≤ 50 ms (median of 19)
✅ cold start, spec.md default 45.4 ms ≤ 100 ms (first of 20 runs)
✅ warm start, spec.md default 41.8 ms ≤ 50 ms (median of 19)
⚠️ not gated cold start, huge.md default 147.1 ms ≤ 100 ms (first of 20 runs)
⚠️ not gated warm start, huge.md default 140.6 ms ≤ 50 ms (median of 19)
✅ idle RSS, 50 KB doc, 1080p default 17928 KB ≤ 30000 KB
✅ idle CPU, 50 KB doc (idle at 65 ms) default 0 ticks/3s ≤ 1 tick
✅ idle RSS, 5 MB doc, 1080p default 32528 KB ≤ 60000 KB
✅ idle CPU, 5 MB doc (idle at 2295 ms) default 0 ticks/3s ≤ 1 tick
✅ stripped binary --no-default-features 2.99 MB ≤ 3.0 MB
✅ cold start, tiny.md --no-default-features 28.3 ms ≤ 100 ms (first of 20 runs)
✅ warm start, tiny.md --no-default-features 40.4 ms ≤ 50 ms (median of 19)
✅ cold start, readme.md --no-default-features 49.2 ms ≤ 100 ms (first of 20 runs)
✅ warm start, readme.md --no-default-features 45.9 ms ≤ 50 ms (median of 19)
✅ cold start, spec.md --no-default-features 46.6 ms ≤ 100 ms (first of 20 runs)
✅ warm start, spec.md --no-default-features 44.0 ms ≤ 50 ms (median of 19)
⚠️ not gated cold start, huge.md --no-default-features 150.1 ms ≤ 100 ms (first of 20 runs)
⚠️ not gated warm start, huge.md --no-default-features 139.9 ms ≤ 50 ms (median of 19)
✅ idle RSS, 50 KB doc, 1080p --no-default-features 18108 KB ≤ 25000 KB
✅ idle CPU, 50 KB doc (idle at 64 ms) --no-default-features 0 ticks/3s ≤ 1 tick
✅ idle RSS, 5 MB doc, 1080p --no-default-features 35256 KB ≤ 55000 KB
✅ idle CPU, 5 MB doc (idle at 2090 ms) --no-default-features 0 ticks/3s ≤ 1 tick
✅ scroll frame, 4K, p95 default 5.45 ms ≤ 8 ms
✅ scroll frame, 4K, p95 --no-default-features 5.11 ms ≤ 8 ms
✅ image RSS, 50 local PNGs default 44700 KB ≤ 62768 KB
✅ image RSS, 50 remote PNGs default 41796 KB ≤ 62768 KB
✅ image RSS, 50 remote PNGs in view, polled every 16 ms default 41876 KB ≤ 62768 KB
✅ image RSS, 50 remote PNGs in view, polled every 50 ms default 41888 KB ≤ 62768 KB
✅ image RSS, 16,384 remote JPEGs of 325 KB cut to 178 bytes default 28368 KB ≤ 62768 KB

VOMD v1.1.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 12:38

Added

  • Open a file from the window: Ctrl+O or the toolbar's folder button shows the desktop's file dialog (the XDG portal's, so KDE's, GNOME's or the GTK one, else zenity or kdialog), starting in the document's folder. The empty window says so, and offers dropping a file only on X11, where it works.
  • A Debian package (vomd_<version>-1_amd64.deb, Debian 12+ and Ubuntu 24.04+) with a man page, and an AppImage for any x86-64 distribution with glibc 2.36 or newer, both attached to each release and checked by CI on Debian 12, Debian 13 and Ubuntu 24.04, on X11 and Wayland.
  • The Arch packages list the file dialogs Open can use as optional dependencies: xdg-desktop-portal-gtk, zenity and kdialog. KDE and GNOME already have a portal file chooser.

Fixed

  • On X11 the portal's file dialog belongs to the VOMD window, so the desktop keeps it in front of it. (On Wayland it still has no parent window.)
  • A portal that crashes or stops answering no longer blocks Ctrl+O: the dialog's calls give up after 25 seconds, and if the portal leaves the session bus while its dialog is up, the window says so and Ctrl+O works again. Before, "A file dialog is already open" stayed until VOMD was restarted.
  • The empty window offers dropping a file only on X11, decided by the display VOMD connected to, not by environment variables.
  • The toolbar's settings button opens settings.ini in a terminal editor set as the default (Terminal=true, such as Neovim) through xdg-terminal-exec. Before, on desktops xdg-open doesn't know (Hyprland, Sway) the editor started with no terminal and waited unseen. If the file can't be opened, a note in the window says why.
  • Release binaries are built on Debian 12 (glibc 2.36), so a glibc older than 2.39 no longer prints "weak version `GLIBC_2.39' not found" at every start.
  • Documents over 1 MB, which are parsed in pieces, render the same as when parsed whole when the line that ends an HTML block looks like a table, a code fence or another HTML block, or when a code fence is left open in a list item. Before, the piece could be cut inside a code block or a table, and the rest of the document rendered differently.
Budgets, measured on the release runner

A shared runner is two to three times slower than the machine the time budgets
are for, so start and scroll times are reported here, not gated.

Metric Build Measured Budget
✅ stripped binary default 3.73 MB ≤ 4.0 MB
✅ cold start, tiny.md default 94.5 ms ≤ 100 ms (first of 20 runs)
✅ warm start, tiny.md default 27.4 ms ≤ 50 ms (median of 19)
✅ cold start, readme.md default 35.0 ms ≤ 100 ms (first of 20 runs)
✅ warm start, readme.md default 32.4 ms ≤ 50 ms (median of 19)
✅ cold start, spec.md default 35.1 ms ≤ 100 ms (first of 20 runs)
✅ warm start, spec.md default 30.3 ms ≤ 50 ms (median of 19)
⚠️ not gated cold start, huge.md default 115.8 ms ≤ 100 ms (first of 20 runs)
⚠️ not gated warm start, huge.md default 82.8 ms ≤ 50 ms (median of 19)
✅ idle RSS, 50 KB doc, 1080p default 17808 KB ≤ 30000 KB
✅ idle CPU, 50 KB doc (idle at 44 ms) default 0 ticks/3s ≤ 1 tick
✅ idle RSS, 5 MB doc, 1080p default 32556 KB ≤ 60000 KB
✅ idle CPU, 5 MB doc (idle at 1391 ms) default 0 ticks/3s ≤ 1 tick
✅ stripped binary --no-default-features 2.99 MB ≤ 3.0 MB
✅ cold start, tiny.md --no-default-features 75.9 ms ≤ 100 ms (first of 20 runs)
✅ warm start, tiny.md --no-default-features 30.9 ms ≤ 50 ms (median of 19)
✅ cold start, readme.md --no-default-features 68.3 ms ≤ 100 ms (first of 20 runs)
✅ warm start, readme.md --no-default-features 33.3 ms ≤ 50 ms (median of 19)
✅ cold start, spec.md --no-default-features 93.6 ms ≤ 100 ms (first of 20 runs)
✅ warm start, spec.md --no-default-features 30.9 ms ≤ 50 ms (median of 19)
⚠️ not gated cold start, huge.md --no-default-features 106.2 ms ≤ 100 ms (first of 20 runs)
⚠️ not gated warm start, huge.md --no-default-features 78.1 ms ≤ 50 ms (median of 19)
✅ idle RSS, 50 KB doc, 1080p --no-default-features 18264 KB ≤ 25000 KB
✅ idle CPU, 50 KB doc (idle at 42 ms) --no-default-features 0 ticks/3s ≤ 1 tick
✅ idle RSS, 5 MB doc, 1080p --no-default-features 32848 KB ≤ 55000 KB
✅ idle CPU, 5 MB doc (idle at 1297 ms) --no-default-features 0 ticks/3s ≤ 1 tick
✅ scroll frame, 4K, p95 default 3.60 ms ≤ 8 ms
✅ scroll frame, 4K, p95 --no-default-features 3.41 ms ≤ 8 ms
✅ image RSS, 50 local PNGs default 44736 KB ≤ 62768 KB
✅ image RSS, 50 remote PNGs default 41912 KB ≤ 62768 KB
✅ image RSS, 50 remote PNGs in view, polled every 16 ms default 42036 KB ≤ 62768 KB
✅ image RSS, 50 remote PNGs in view, polled every 50 ms default 41948 KB ≤ 62768 KB
✅ image RSS, 16,384 remote JPEGs of 325 KB cut to 178 bytes default 28440 KB ≤ 62768 KB

VOMD v1.0.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 22:37

The first release, for Linux (x86-64; Windows and macOS compile but are unsupported).

Added

  • CommonMark and GitHub Flavored Markdown: tables, task lists, strikethrough, footnotes, alerts, extended autolinks, hidden YAML front matter. Raw HTML is stripped, never run; a few tags are styled as on GitHub.
  • Our own text layout and renderer on swash, winit and softbuffer, with embedded Inter and JetBrains Mono subsets and a lazy system-font fallback for other scripts and emoji.
  • Light and dark themes following the system, zoom 50–300%, HiDPI.
  • Links: anchors, relative Markdown files in the same window with Back, web links in the browser; a URL preview on hover.
  • Reload on R/F5 and when the window regains focus, keeping the reading position.
  • A slim toolbar (hidden with B) with an overflow menu on narrow windows.
  • settings.ini with live apply, written back without losing comments.
  • Local PNG and JPEG images, decoded lazily at their displayed size under a 32 MB cache.
  • Remote images, off by default: loaded per document with I, through the system curl.
  • A one-line notice for files over 10 MB, which still render.
  • Packaging: Arch PKGBUILDs vomd (from source) and vomd-bin, and a release tarball with a desktop entry, icon and the README's image.
  • The app icon (an eye over the Markdown mark). The window's Wayland app ID and X11 WM_CLASS are vomd, so the desktop shows it for the window.
  • The system theme comes from the desktop portal's color-scheme (Plasma's and GNOME's dark mode, followed live, and back to winit and GTK_THEME when the preference is withdrawn), which say nothing on Wayland. Only the portal's own broadcasts count (not a signal another client addresses to VOMD), none is missed while starting (the first read is reported at once; signals are followed in order, and one that races a read triggers a backed-off re-read, 50 ms doubling to 5 s, until a read completes undisturbed), and the bus going away also returns to winit and GTK_THEME.
  • Wide layout: W, the toolbar's button (next to the theme's) or wide = true in settings.ini lets the text span the window instead of stopping at line_width; it is saved. A change of the column's width (this, or resizing the window) rescales every height, until its block is measured again, by how its estimate changed, so the scrollbar is right while measuring goes on; the estimates read what the prepass stored (20 bytes per block), not the text, so this costs two to three times the plain remeasure (0.5 ms on a 42,000-block document).
  • The scrollbar also shows while the pointer is over its column.
  • Budgets measured by cargo xtask budgets: binary size, cold and warm start, idle RSS, idle CPU, 4K scroll frame time. CI gates size, memory and idle CPU and reports the times (--timings-advisory). Fuzz targets for the parser, layout and settings.
Budgets, measured on the release runner

A shared runner is two to three times slower than the machine the time budgets
are for, so start and scroll times are reported here, not gated.

Metric Build Measured Budget
✅ stripped binary default 3.70 MB ≤ 4.0 MB
✅ cold start, tiny.md default 46.3 ms ≤ 100 ms (first of 20 runs)
✅ warm start, tiny.md default 37.6 ms ≤ 50 ms (median of 19)
✅ cold start, readme.md default 47.3 ms ≤ 100 ms (first of 20 runs)
✅ warm start, readme.md default 43.5 ms ≤ 50 ms (median of 19)
✅ cold start, spec.md default 44.7 ms ≤ 100 ms (first of 20 runs)
✅ warm start, spec.md default 42.5 ms ≤ 50 ms (median of 19)
⚠️ not gated cold start, huge.md default 145.7 ms ≤ 100 ms (first of 20 runs)
⚠️ not gated warm start, huge.md default 136.3 ms ≤ 50 ms (median of 19)
✅ idle RSS, 50 KB doc, 1080p default 17704 KB ≤ 30000 KB
✅ idle CPU, 50 KB doc (idle at 64 ms) default 0 ticks/3s ≤ 1 tick
✅ idle RSS, 5 MB doc, 1080p default 32268 KB ≤ 60000 KB
✅ idle CPU, 5 MB doc (idle at 2281 ms) default 0 ticks/3s ≤ 1 tick
✅ stripped binary --no-default-features 2.95 MB ≤ 3.0 MB
✅ cold start, tiny.md --no-default-features 28.5 ms ≤ 100 ms (first of 20 runs)
✅ warm start, tiny.md --no-default-features 38.3 ms ≤ 50 ms (median of 19)
✅ cold start, readme.md --no-default-features 46.3 ms ≤ 100 ms (first of 20 runs)
✅ warm start, readme.md --no-default-features 43.5 ms ≤ 50 ms (median of 19)
✅ cold start, spec.md --no-default-features 45.8 ms ≤ 100 ms (first of 20 runs)
✅ warm start, spec.md --no-default-features 42.4 ms ≤ 50 ms (median of 19)
⚠️ not gated cold start, huge.md --no-default-features 141.3 ms ≤ 100 ms (first of 20 runs)
⚠️ not gated warm start, huge.md --no-default-features 137.1 ms ≤ 50 ms (median of 19)
✅ idle RSS, 50 KB doc, 1080p --no-default-features 18112 KB ≤ 25000 KB
✅ idle CPU, 50 KB doc (idle at 65 ms) --no-default-features 0 ticks/3s ≤ 1 tick
✅ idle RSS, 5 MB doc, 1080p --no-default-features 34564 KB ≤ 55000 KB
✅ idle CPU, 5 MB doc (idle at 2093 ms) --no-default-features 0 ticks/3s ≤ 1 tick
✅ scroll frame, 4K, p95 default 7.50 ms ≤ 8 ms
✅ scroll frame, 4K, p95 --no-default-features 4.92 ms ≤ 8 ms
✅ image RSS, 50 local PNGs default 44632 KB ≤ 62768 KB
✅ image RSS, 50 remote PNGs default 41744 KB ≤ 62768 KB
✅ image RSS, 50 remote PNGs in view, polled every 16 ms default 41856 KB ≤ 62768 KB
✅ image RSS, 50 remote PNGs in view, polled every 50 ms default 42024 KB ≤ 62768 KB
✅ image RSS, 16,384 remote JPEGs of 325 KB cut to 178 bytes default 28896 KB ≤ 62768 KB