Skip to content

Readable everywhere: contrast floors, glyphs, search and details - #55

Open
thisisgm wants to merge 61 commits into
omacom:mainfrom
thisisgm:readable-everywhere
Open

thisisgm wants to merge 61 commits into
omacom:mainfrom
thisisgm:readable-everywhere

Conversation

@thisisgm

@thisisgm thisisgm commented Nov 11, 2026 •

Copy link
Copy Markdown

A pass over contrast, glyphs, search and the details pane, so text and marks read on every Omarchy theme, a search says what it found and why, and each glyph draws what it stands for. It builds on #18 and #19, so its own commits start after theirs. One commit per change; each says what was wrong and what it does now. The suite goes from 207 to 227 tests, and every test it adds passes with TMPDIR set to a folder with a space in its name.

Readable on every theme

The floor works from each theme's own colors and leaves a color alone wherever it already reads, so most themes change only where they fell short.

  • Secondary text keeps 4.5:1 on the background, tiles and panels. A fixed mix of foreground into background drew under that on Rose Pine, Catppuccin Latte and Gruvbox's tiles; the mix is now raised just enough.
  • Accent frames keep 3:1. Focus, cursor and drop frames and the selection band use the accent raised just enough to reach 3:1; fills and tints keep the accent itself.
  • The other pane's ring and disabled glyphs keep 3:1, and a disabled glyph stays clearly dimmer than an off toggle.
  • Accent, red and yellow words keep 4.5:1: drop to pin, the preview's extension, rename problems, a plugin mark's error and warning status (Dropbox's "stopped" and "syncing"), and the format dialog's warning. Fills and the dialogs' edges keep the theme's own red. A theme whose red is a grey (Vantablack, Solitude, White) writes those words in the foreground instead.
  • A folder card's fill keeps 1.4:1 against the pane, so folder tiles read as cards on every theme (Improvement request: poor contrast for folder icons #24).
  • Tile badges write their extension in an ink that reads on the kind color.
  • The drop verb ("Move here", "Copy here") draws in the foreground, and it now follows the pointer instead of sitting at the foot of the frame.
  • Text draws gray, without LCD color fringes. Qt Quick gave new glyph nodes subpixel antialiasing and reused ones gray, so neighbours in one color drew two ways.

Glyphs and the top bar

  • A drive has a sloped top, the list view bullets, and an archive a lidded box, in its row and on its tile.
  • A split button ends the first pane's bar beside details. Off, it opens the second pane; on, it closes it as Ctrl+W does. The details and split glyphs now draw as two different things.
  • The sidebar's Home row leads its section on its own, without a "HOME" heading straight above it.
  • The audio stand-in draws bars of varied height, with the same extension chip as the page stand-in.

Search

  • The field says how many were found once the results settle, "N found in X and below", and "Searched X and below" when nothing was.
  • The part of a name that matched draws bright and bold, in the grid, list and columns.
  • A search that found nothing says under "Nothing matches" that Escape ends it.
  • In a narrow split pane the hint elides, then hides, so typed text stays inside the field.
  • A long path keeps its parent beside the current folder before folding it.

Details pane, menus and dialogs

  • Open With shows each app's own icon, and a row without a key asks for no key column, so a menu sized to its entries fits the longest name.
  • Markdown is rendered in the details pane and in the preview window, as one page: room after each block, padded table cells between quiet rules, a ground under code, and links in the text's own color. It is converted off the UI thread with every picture replaced by its alt text, so selecting a file fetches nothing. In the details pane a table stops at 300 cells, so the pane lays it out within one 10 ms frame.
  • File, drive and app names draw as plain text, so a name like <b>x</b>.txt shows as written.
  • The permanent delete dialog names what it deletes: "Delete “notes.txt” permanently?", and its body says only that it can't be undone.
  • The shortcut sheet lists dragging, and Ctrl turning a drop into a copy.
  • "This folder is empty" stays level with "Nothing selected" while a band shows.

Screenshots

Before on the left, after on the right, 1100x700 on native Omarchy. Taken on this branch before its last rebases onto main; what they show is unchanged. The two Markdown pictures are of its newest commit.

Rose Pine: names' secondary lines and counts rise to 4.5:1.

Rose Pine: names' secondary lines and counts rise to 4.5:1.

Catppuccin Latte, the same.

Catppuccin Latte, the same.

Rose Pine: folder cards keep a fill that reads on the pane (#24).

Rose Pine: folder cards keep a fill that reads on the pane (#24).

Catppuccin Latte, the same.

Catppuccin Latte, the same.

Rose Pine: the cursor's frame reaches 3:1.

Rose Pine: the cursor's frame reaches 3:1.

Jade Horse: the other pane's ring reads.

Jade Horse: the other pane's ring reads.

Rose Pine: a rename problem in red at 4.5:1.

Rose Pine: a rename problem in red at 4.5:1.

Vantablack, whose red is a grey: the problem draws in the foreground.

Vantablack, whose red is a grey: the problem draws in the foreground.

Badges in an ink that reads on their color; the archive's lidded box; the audio stand-in's bars.

Badges in an ink that reads on their color; the archive's lidded box; the audio stand-in's bars.

Gray text, without LCD color fringes.

Gray text, without LCD color fringes.

The list view's bullets and the archive's box in its row.

The list view's bullets and the archive's box in its row.

The split button at the end of the bar.

The split button at the end of the bar.

The Home row leads the sidebar on its own.

The Home row leads the sidebar on its own.

Once the results settle, the field says how many were found.

Once the results settle, the field says how many were found.

The matched part of each name draws bright and bold.

The matched part of each name draws bright and bold.

A search that found nothing says Escape ends it.

A search that found nothing says Escape ends it.

In a narrow split pane, the typed text stays inside the field.

In a narrow split pane, the typed text stays inside the field.

Open With shows each app's icon.

Open With shows each app's icon.

Markdown rendered in the details pane.

Markdown rendered in the details pane.

Markdown rendered in the preview window.

Markdown rendered in the preview window.

Names with markup draw as written.

Names with markup draw as written.

The shortcut sheet lists dragging.

The shortcut sheet lists dragging.

"This folder is empty" stays level with "Nothing selected" while a band shows.

"This folder is empty" stays level with "Nothing selected" while a band shows.

Not pictured: the drop verb and drop to pin (a held drag cannot be shot), a plugin mark's warning, the disabled glyph and the preview's extension (in the preview window), and the drive glyph (no extra drive on the capture machine).

thisisgm added a commit to thisisgm/folio that referenced this pull request Nov 11, 2026
Before and after pairs for omacom#55: contrast floors on four themes, glyphs,
search, the details pane and the folder card fill.
@greptile-apps

greptile-apps Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The latest changes appear safe to merge; the earlier table-limit issue remains non-blocking.

Findings

  1. P2 Tables exceed the cell limit ▶

Summary

This PR improves contrast, glyphs, search feedback, and the details pane.

The latest changes:

  • Theme colors keep text, frames, and folder cards readable.
  • File glyphs and pane controls show what they stand for.
  • Search tells you how many files matched and where they live.
  • File drops show whether they will move or copy items.
  • Details show richer file information and formatted Markdown.
  • Dialogs and empty states explain their next step more clearly.

The earlier search-footer finding was correctly disputed by thisisgm and retracted: Qt 6.12 supports the deliberate multi-value String.arg() call.

Reviews (7) · Last reviewed commit: "Give a rendered Markdown page room betwe..." · Reviewed by Greptile

Comment thread src/FileTile.qml Resolved
@thisisgm
thisisgm force-pushed the readable-everywhere branch 3 times, most recently from b03facb to 467385d Compare November 11, 2026 19:52
The selected item's name was drawn in the accent on the accent tint, which
read dimmer than the names around it (3.8:1 on osaka-jade). It now uses the
bright text color, and its size and date the normal one, as a lit menu row does.
Moving the cursor by key past the edge of the grid left it out of sight.
The view now scrolls just enough to show it.
With nothing selected (Alt+click on the last selected item), Delete, F2
and Return still act on the cursor's item, but nothing showed which one.
That item now carries a thin accent frame, the selection ring at 1 px.
In a split both panes drew their selection in the accent, so nothing said
which pane the keys go to beyond the thin line at the top. The pane the
keys don't go to now draws its selection and cursor in a neutral tint.
The details pane wrapped its title and text preview at any letter, so a
name or a line of text broke mid-word. Both now break between words and
split a word only when it is wider than the pane.
The notice line elided its end, which is where a restore names the folder
it put the file back in. It now elides the middle, so the start and the
folder stay readable on a narrow pane.
With several items selected, the details pane still showed only the one
under the cursor, as if it were the whole selection. It now says how many
are selected and their size together, or how many of them are folders.
A search result was named by its whole path from the searched folder, so
deep results led with folders and their own names were cut. Each now shows
its file's name, with the folder it is in quieter beside or under it; a
plugin's item keeps its own name.
Rename, delete, mount, name clash and format dialogs were drawn inside their
folder pane, so in a split, and beside the details pane, the rest stayed lit.
They now dim the whole window, no pane takes keys while one is open, and
the keyboard goes back to the pane once the last one closes.
The fitted shortcut sheet's scroll bar showed only in use, so nothing said
rows were below; it now stays shown in the card's margin. In the preview
window the sheet takes the keyboard, so its keys scroll it, not the preview.
A drop on the same drive always moved, with no way to copy as most file
managers do with Ctrl. Holding Ctrl at the drop now copies, and a drop
that copies tells the source app so instead of saying it moved.
The sheet's scroll bar, shown at rest as the only sign of rows below,
was 1.9:1 on its card. A bar shown at rest now takes the theme's quiet
text color, 3:1 or more on every Omarchy theme; others are unchanged.
A menu could rest on the window's edge, and an open submenu's parent row
wore the same accent as the row under the pointer. Menus now stop 8 px
short of the edge, and the open parent keeps a neutral wash.
Qt's en_US time puts a narrow no-break space before AM and PM, which the
font draws as none, so times read "4:04PM". Format.js now swaps it for a
plain space, and the details pane's date and time go through it too.
@thisisgm
thisisgm force-pushed the readable-everywhere branch from 467385d to 13af2ec Compare November 12, 2026 23:48
Comment thread src/backend.cpp Outdated
// Table cells cost the UI thread most to lay out; this many keep the card under a 10 ms frame.
constexpr int markdownCells = 300;
if (mime == "text/markdown")
read.insert("markdown", Previewer::markdownHtml(Previewer::markdownOpening(text, markdownCells)));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Tables exceed the cell limit

The new Markdown preview can exceed its 300-cell limit. markdownOpening() counts written | characters, but a GitHub-style table fills short rows out to the header’s width. A 100-column header and separator followed by 39 |x| rows uses only 280 pipes, yet produces about 4,000 cells. This fits within the file-reading limits and can make selecting the file pause the details pane.

Limit the rendered table’s rows × columns, including empty cells.

With several selected, the details pane drew one of them under "N items
selected", and a selection with no cursor showed "Nothing selected". A
selection is now counted with or without a cursor, under a plain glyph.
A search result tile's line led with its folder, then size and date, so
the date was cut mid-number on a 140 px tile. When the folder leads, the
line holds folder and size; the details pane still gives the date.
A drop could move or copy, but its frame said neither, so the verb was
known only after letting go. Each drop target, columns included, now says
"Move here" or "Copy here", from Ctrl and whether every file is on another
drive.
A right click on a file in the other pane selected it there, but the keys
stayed with the first pane, so Delete and F2 after the menu acted on the
wrong file. A right click now gives the keys to its pane first.
"Nothing selected" sat 8 px above "This folder is empty" beside it,
since the folder view starts 16 px lower than the details pane. It now
drops by half that, so the two read as one line.
While the caret was in the search field, or Tab had put the keyboard in
the sidebar or the details, the selection wore the full accent ring, as if
the keys were on it. The view now draws it as the other pane's until the
keys come back to the files.
A path wider than its bar was cut through the middle of a crumb. Crumbs
that do not fit now fold whole into a leading ellipsis that goes to the
deepest folded folder and names the folded path in a tooltip; only a lone
current folder elides. Mirrored, the ellipsis leads from the right.
The HOME heading was the only mouse route home and looked like the inert
labels. Home is now the first row of the first section, with its glyph,
taking drops like any folder row; Recents and Trash end that section in
place of a Views heading.
The first section's heading read "HOME" straight above the Home row, so
the same word showed twice 30 px apart. The Home row now leads the
section on its own; Pinned, Devices and Tailnet keep their headings.
The disabled ink was a translucent foreground the stroke blended twice,
so it drew at 4.0:1 beside an off toggle's 5.1:1 and the two looked
alike. It is now an opaque half mix, 3.4:1 on osaka-jade and 1.5:1 from off.
Splitting was only Ctrl+Alt+N, with nothing on screen to find it by. The
first pane's bar now ends with a split toggle beside details. Off, it opens
the second pane; on, it closes it as Ctrl+W does, lit by brightness alone.
Its tooltip names it without the key, as the bar's other buttons do.
A drive was a flat box, the list view three bars like a menu, and an
archive took the plain page every unknown file gets. A drive now has a
sloped top, the list view bullets, and an archive row a lidded box.
The secondary ink was a fixed mix of foreground into background, which drew
under 4.5:1 on Rose Pine and Catppuccin Latte and on Gruvbox's tiles.
It is now raised toward black or white just enough to reach 4.5:1 on the
background, tiles and panels, and a theme that already reads keeps its mix.
Focus, cursor and drop frames and the selection band used the raw accent,
which drew under 3:1 on Rose Pine and on White's tiles. They now use
accentMark, the accent raised just enough to reach 3:1, while fills and
tints keep the accent itself.
The other pane's selection ring and a disabled toolbar glyph were fixed
blends that drew near 2.3:1 on Rose Pine and Catppuccin Latte. They now use
quietMark and disabledForeground, raised to 3:1, and a disabled glyph stays
clearly dimmer than an off toggle at 4.5:1.
Rename problems, a plugin mark with the "error" tone and the format
dialog's warning drew in the theme's red, down to 2.3:1 on Miasma. They now
use redText, the red raised just enough to reach 4.5:1 on the background,
while fills and the dialogs' edges keep the theme's own red.
Drop to pin and the preview window's file extension drew in the raw
accent, down to 2.5:1 on Rose Pine over the pin box's tint. They now use
accentText, the accent raised just enough to reach 4.5:1 on the background,
the preview window and that tint, while fills and marks keep their colours.
A plugin mark with the "warning" tone (Dropbox syncing) drew its status in
the theme's yellow, down to 2.1:1 on Rose Pine and 2.3:1 on Catppuccin Latte
and Flexoki Light. It now uses yellowText, the yellow raised just enough to
reach 4.5:1 on the background.
Vantablack, Solitude and White set red to a grey, so a rename problem, a
Dropbox that is not running or the format warning drew in a grey that
does not read as red. When the red's saturation is 0.2 or less those
words take the foreground; fills and the dialogs' edges keep the colour.
A page stand-in's badge wrote its extension in the background color on the
kind color, down to 2.1:1 on Rose Pine's yellow. It now takes the background
where that reads at 4.5:1, else the foreground, else whichever reads better
raised to 4.5:1, and the badge keeps the theme's own kind color.
Side by side in the top bar, the details glyph and the split glyph were
both a box with one upright bar. Details now holds two short lines in its
side panel, and split's two boxes stand 4 units apart.
In the grid an archive drew the ruled page every text file draws, while
its list row drew the lidded box. The page now holds the archive glyph in
the kind's colour instead of the lines; the extension badge stays.
With no results the field hint read "0 found in X and below", which looks
like a counter beside the pane's "Nothing matches". At no results it now
says "Searched X and below", and the pane gives the result.
"Move here" and "Copy here" on the drop frame, a list or column row and a
sidebar row drew in secondary ink on the accent tint, 4.45:1, under the
4.5:1 text floor. All three now draw in the theme's foreground.
A search result named the file with nothing to show why it was found. The
run that matched, found as the search finds it (ignoring case), now draws
in bright ink in the grid, list and columns; the rest stays as it was.
A file named like markup, such as "<b>x</b>.txt", drew as rich text, bold
and without its tags, because name labels took Text's AutoText default.
Every label that shows a file, folder or drive name now draws plain text.
The Open With menu listed bare app names. Each row now carries the icon
from the app's desktop entry, 16 px from the icon theme, in a column kept
empty for an app without one so the names stay aligned. App names draw as
plain text, so markup in a desktop entry's Name shows as written.
The matched run was only a brighter colour, close to the rest of the name
and invisible on the selected result, whose whole name is bright. It is
now bold as well; the monospace face keeps its advance, so nothing reflows.
A row with no key or arrow still counted the key column and its 40 px gap
in its width, so a menu fitted to its widest row stood wide of Open With's
longest name. The gap now counts only when a row has a key or an arrow.
The details pane showed a Markdown file's opening lines raw. It now renders
them, converted off the UI thread to HTML with every picture replaced by its
alt text, so selecting a file fetches nothing; raw HTML stays text. Rich text
cannot elide, so the card ends on the last line that fits whole, and a table
stops at 300 cells, which the card lays out in under one 10 ms frame.
The audio stand-in drew 18 bars of nearly one height, a comb that read
as a barcode, and its extension as bare grey text. The name is hashed
once and the bars spread from 20 to 48 px, and the extension wears the
chip the page stand-in wears, in the same corner.
In a split window the search hint could be wider than the field, so the
typed text had no room and drew left of the field over the other pane.
The hint now elides its place name, then hides, keeping room for typing,
and the field clips. At full width nothing changes.
A split pane's path folded straight to "… / Exports" when its parent did
not fit whole, leaving no hint of where the folder is. The parent now
elides to stay beside the current folder, ending where its name ends, and
folds only when fewer than about six characters of it would show.
Qt Quick gives a text's new glyph nodes subpixel antialiasing and the
nodes it reuses on a redraw gray, so neighbours in one color drew two
ways. Folio now asks for gray distance field text, unless the
environment already sets QSG_DISTANCEFIELD_ANTIALIASING.
On many themes the lighter background sits within 1.05 to 1.3:1 of the
background, so grid folder cards nearly vanished. The card fill is now
the lighter background raised to 1.4:1; the hover, current and drop
tints still draw on top of it.
The Open button's "Open with %1" and the button that picks what a file
opens with took Text's AutoText, so markup in a desktop entry's Name
drew as rich text. Both now draw plain text, as file names and the
Open With menu already do.
@thisisgm
thisisgm force-pushed the readable-everywhere branch from 13af2ec to 36d0614 Compare November 13, 2026 00:19
Qt reads Markdown with a heading on its text and a table on the lines
around it. The page now has room after each block, padded table cells
between quiet rules, a ground under code, and links in the text's own
color; the preview window shows the same page as the details pane.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant