Screen Time
Daily app usage tracking for the focused Hyprland window, shown in the Omarchy bar with a today / week / month popup. Inspired by macOS Screen Time, but focused on graphical apps rather than background daemons.
Only the focused window is counted. A second monitor with another app visible does not add time, so a two-screen day cannot report more hours than the clock.
Install
omarchy plugin add https://github.com/vitally/omarchy-screen-time.git --enable
Move it on the bar with:
omarchy bar move vt.screentime --section right
Remove
omarchy plugin remove vt.screentime
rm -rf ~/.local/state/omarchy/vt.screentime
omarchy plugin remove only uninstalls the widget. Usage history lives
outside the plugin checkout and is not deleted unless you remove that
directory.
How it works
The widget reads the focused Wayland / Hyprland toplevel once per second.
When a window is focused and the session is in use, that second is added to
the app's total for today. Tracking pauses while you are idle, while the
session is locked, and while Omarchy's screensaver/idle cycle is running —
a focused Ghostty window still counts as focused behind the lock screen.
App identity comes from the window's appId / initialClass. The display
name and icon come from the desktop entry, not the window title.
Data is stored in SQLite:
~/.local/state/omarchy/vt.screentime/usage.db
That directory is created 0700 and the database (plus WAL / SHM / journal
sidecars) is kept 0600, so only the owning user can read the history. The
helper store.sh talks to sqlite3 already on the system and re-applies
those permissions on every init, load, and save. The file is written every
30 seconds, when the focused app changes, when you go idle, and when the
shell exits, so a restart loses at most a few seconds.
Configure
| Setting | Type | Default | Description |
|---|---|---|---|
show |
string | total |
total shows today's total in the bar; current shows the focused app's time. |
idleMinutes |
number | 2 |
Pause tracking after this many minutes of inactivity. Set to 0 to disable the idle timeout. Lock and screensaver still pause tracking. |
keepDays |
number | 730 |
How many days of history to keep in the database. |
Example ~/.config/omarchy/shell.json entry:
{
"id": "vt.screentime",
"show": "current",
"idleMinutes": 2,
"keepDays": 730
}
Usage
- Left click — toggle the detail panel.
- Escape — close the panel.
The panel shows:
- A Today / Week / Month switch. Week is the last seven days. Month is this calendar month so far.
- The range total and the focused app's time in that range.
- A per-day sparkline on week and month views.
- A per-app breakdown with desktop names and icons.
- A reminder that only the focused window is counted.
- A toggle for the bar display mode.
- A reset button that clears today after confirm.
Tests
node test/model.test.js
bash test/store.test.sh
Dependencies and safety
The plugin requires Omarchy Quattro and runs as QML inside the existing
omarchy-shell process. It imports the shell's qs.Commons and qs.Ui
components, plus Quickshell's Hyprland, Wayland, and idle-monitor bindings.
Persistence is a small store.sh that calls sqlite3 (already on Omarchy's
PATH) and keeps the usage directory owner-only. There is no Python,
network call, background service, installer, remote build, shell hook, or
elevated operation. Like all Omarchy plugins, it runs unsandboxed with the
user's permissions; review the source before enabling it.