Patina
Patina is a philosophy for building apps on the Unix-like desktop. An app is there to help someone get something done, and its design is built around what a desktop is: a large screen, a keyboard and a pointer, with the space used to match.
Pro software like 3D and photo editors has dense controls because people work in it all day. Patina gives any app that feel, even one as everyday as Weather. Most of the room is won in the window frame itself: Patina's title bar fits the menus, the tabs and the buttons into the strip most apps spend on a title and a colour.
That doesn't mean plain. Every app can be skinned until it looks like nothing else, but the look never takes room from the work. Underneath it's patina-ui, a Rust crate for egui apps.
Start from the problem
A Patina app starts from what someone is trying to do with it, not from the app it would otherwise copy. One example is the Process Manager. You open a process manager when something has gone wrong: the machine is slow, an app has hung, something crashed. So it opens on an overview that answers most of that before you click anything.
The top line says which machine it is, what it runs and how long it's been up. Below it, a tile for each resource gives its number and the last minute as a graph, so you can see whether the CPU, memory, GPU, disk or network is the one under load. A click on a tile opens it in full.
Then Problems: what went wrong on the machine, found in the kernel's log, in how long programs have been waiting for the CPU, memory and disks, and in the list of processes. Crashes, GPU errors and processes left behind by their parents are usually nowhere on a desktop. Here they're the second thing you read, and hovering one says what it means.
Last, the busiest apps on the CPU, the GPU and memory, so whatever is slowing the machine down is usually named on the first screen and a right click away from being ended. A browser is counted together with every process it started, because that's the thing you'd close. The lists hold still: they are averaged over a few readings, and a row keeps its place until something clearly beats it, so you can read them.
What we fix
Patina's rules come from things that get in the way on the desktops we use every day:
- Title bars that do nothing. Most apps spend a strip of the screen on a name and a colour. Patina's carries the menus, the tabs and the buttons.
- Windows that freeze. A slow disk or a hung network share can slow a view down, but never freezes the window.
- Scrolling that stops dead. On Linux a touchpad scroll stops the moment your fingers lift, unless the toolkit makes up the glide. Patina apps glide, as they would on a Mac.
- Every app its own way. Skin menus with different entries, messages turning up wherever they happened. Patina apps share the same menus, tabs and shortcuts, and every message goes to the status bar.
Room for the work
The frame is where it starts. Inside the window, the same habits keep the work in front:
- Say it once. Nothing on screen is repeated. The title bar has the app's name, so the status bar doesn't, and a view doesn't label what it already shows.
- Guide with help text. A short line says what a figure means, and hover text explains a control where you're looking.
- Use what egui is for. egui was built for tools that show a lot of data at once. Patina apps use it for dense views: graphs, gauges and linked panels.
- Behave the same everywhere. Menus, tabs, the status bar and the shortcuts work the same in every app, so what you learn in one carries over.
Weather shows it well. The title bar carries the menus, the place, and the switch between Overview, Week and Day. Every tile says what its number means, and hovering any of a day's graphs shows that hour across all of them.
The apps
-
Photograph
A photo browser and editor for colour grading, with non-destructive edits. It starts in Patina's Dark Orange skin, the look it was built in. -
UnAmp
A music player in the spirit of Winamp, on Unix: album art, a big time display, a bar spectrum analyzer and a 10-band equalizer. It starts in Default, plain egui. -
Teleprinter
A terminal emulator: tiled panes you drag about like a tiling window manager, tabs in the title bar, and the terminal's colours from the skin. It starts in Default. -
Process Manager
What's running and what's wrong: an overview of the machine, the apps and their processes, graphs of each resource, and the kernel's log. Not released yet. -
Notebook
Notes for a folder of markdown files, edited as rich text. It starts in the Notebook skin, leather brown over cream paper. Not released yet. -
Calendar
A desktop calendar for a CalDAV server. It starts in the Calendar skin, a deep red bar over warm paper. Not released yet. -
Weather
The weather now, the next hours and the days ahead, with graphs of each day, from Open-Meteo with no account needed. It starts in Default. Not released yet.
The rules
- Room for the work. The title bar does work, nothing is said twice, and help text guides the user.
- Never block the UI. A hung network share can slow a view down, but never freeze the window.
- Feel native to the desktop. Behave well on it, without copying its look. Moving, resizing and tiling are left to the compositor, and light or dark follows the desktop.
- Stock egui first. With no skin chosen, an app is plain egui, following the desktop's light or dark setting.
- Skinnable all the way down, window frame included. A skin someone writes must never crash the app.
- Unity in variety. The structure is shared and the skin varies. What's particular to one app stays in that app.
- Record decisions, as ADRs, in every Patina app.
The whole of it is in the design language.
Skins
The structure is fixed, the look isn't. Every app can be skinned, window frame included, and a skin can make it look like nothing else, but it never moves things or changes how they work. That's unity in variety: a terrace of identical houses painted in different colours is lovely, and a street where everything differs at once is noise.
With no skin chosen, an app is plain egui. An app can start in a skin that suits it, as Photograph, Notebook and Calendar do, but every app offers every skin.
A skin is a small TOML file. Shared sections colour what every app has, and each app reads its own section and skips the others. Anything you leave out keeps egui's default, so a skin can be this small:
format = 1
name = "Just Purple"
base = "dark"
[colors]
accent = "#8A2BE2"
Put it in an app's own skins folder, such as ~/.config/notebook/skins/, and that
app offers it. Copy it into another app's folder to use it there too. The format is in
Skinning.
This site is drawn as a Patina window and reads the same skin files, so it offers them too:
The site opens in Everforest Dark. Default is Patina's own: it follows your system's light or dark setting, as a Patina app does. The idea of unity in variety is Thomas Sharp's, from Town and Townscape (1968); The School of Life's How to Make an Attractive City makes the same case.
What's in it
- The window frame. A header bar with the window buttons, resize edges and rounded corners, with moving and resizing left to the compositor. Its menus fill the bar's full height and light up like a hovered tab. Where the desktop can't minimise or maximise, those buttons are left out.
- Tabs in the title bar, after the menus and in place of the title. They have icons, titles or both, and can be dragged into another order. Some can be launchers, faded icons for something that isn't open yet. Ctrl+T, Ctrl+W, Ctrl+PageUp/PageDown and Alt+1 to Alt+9 work in every app, and a terminal takes Ctrl+T and Ctrl+W with Shift.
- Menus with one style everywhere, context menus included.
- A status bar along the bottom of every app: the version, then the latest message coloured by its level, then the app's own status. Menus don't show messages themselves; the results go to the bar.
- Skins with each app's own skins folder, and a skin menu that's the same in every app.
- Markdown, shown as Notebook shows it, with no syntax on screen: an editor that edits in place or only shows, with tables, highlighted code, images and whole source files with lines marked.
- Kinetic scrolling, so a flick on the touchpad keeps scrolling after your fingers lift.
- A folder tree that lists folders on worker threads, so a slow network share never blocks the UI.
- Light and dark following the desktop, and files and folders opened in the desktop's own app for them.
What changed in each version, and what an app has to change to take it, is in the Changelog.
Build a Patina app
[dependencies]
patina-ui = "0.1"use patina::frame::{self, FrameStyle, TitleBar};
let style = FrameStyle::from_visuals(ui.visuals());
let radius = frame::corner_radius(ui.ctx(), style.radius);
egui::Panel::top("header")
.frame(frame::header_frame(ui.style(), &style, radius))
.show(ui, |ui| {
// The bar's full height, for the menus (and any tabs) to fill.
let span = frame::header_span(ui);
TitleBar::new("My App", &style)
.menu_bar(true)
.span(span)
.show(ui, |ui| { ui.menu_button("File", |ui| { /* ... */ }); }, |ui| { /* right */ });
});
Patina re-exports egui, and an app has to use the same egui version. The gallery example,
make gallery in the repo, shows every component and is the best place to start.
- Design language: the rules, the window and the components.
- Skinning: the skin format, key by key.
- Decisions: why Patina is the way it is.
- Changelog: what each version changed, and what to change in an app to take it.
- Known issues.
- API docs on docs.rs, and the source on GitHub. BSD-3-Clause.