Get running in seconds.

AUR package, Windows installer, manual setup, or build from source. Pick your path.

Choose your platform.

HPR ships as a single compiled binary. No runtime dependencies. No package managers pulling in half the internet.

AUR Package

HPR is available on the AUR. Install with your preferred AUR helper.

Terminal
yay -S hpr

Or with paru:

paru -S hpr
AUR

The AUR package handles everything — building, dependencies, and placing config files. The simplest path for Arch users.

System-Wide Desktop Entry

When installed via the AUR, the system-wide desktop entry at /usr/share/applications/hpr.desktop is managed by the package. HPR detects this automatically and skips the per-user entry entirely.

After Install

Launch HPR from your application menu or terminal. Config files are placed automatically. Start tracking immediately.

Manual Install (Any Distro)

Download the release binary and run the setup script. Three commands.

Terminal
# 1. Make the install script executable
chmod +x installHPRConfigAndUi.sh

# 2. Run the setup (copies config + UI files)
./installHPRConfigAndUi.sh

# 3. Launch HPR
./HPR
Safe Overwrite

The setup script provides safe-overwrite prompts. If you've already customized your config or UI files, it asks before replacing them.

Desktop Entry — Automatic

On first launch HPR automatically creates a desktop entry at ~/.local/share/applications/hpr.desktop. This registers HPR with your desktop environment so it appears in your application launcher and the taskbar/dock correctly associates the window with its icon. No manual .desktop setup required.

The entry is only written when missing or stale. On subsequent launches HPR checks whether the Exec= and Icon= fields already point to the current binary. If they match, the file is left completely untouched.

File Locations

Config:
~/.config/HPR/
  ├── config.csv
  ├── aliases.csv
  ├── tabAliases.csv
  ├── projectAliases.csv
  └── ui/
      └── app-window.slint

Data:
~/.local/share/HPR/HPR_DB/
  └── MM-YY/
      └── DD-MM-YY.db

Platform Requirements

Hyprland: No extras (native JSON parsing)
GNOME: gdbus + extension
KDE 6+: qdbus6 or qdbus-qt6
Cinnamon: No extras

Windows Installer

Download and run the setup executable. Inno Setup handles everything automatically.

What the installer does

1 Places aliases.csv, tabAliases.csv, projectAliases.csv, config.csv, and ui/ folder into your config directory
2 Prompts before overwriting any existing customized files
3 Drops latest default UI into ui-REFERENCEONLY/ for diffing
Download Latest Release

File Locations

Config:
%APPDATA%\HPR\HPR_Config\
  ├── config.csv
  ├── aliases.csv
  ├── tabAliases.csv
  ├── projectAliases.csv
  └── ui\
      └── app-window.slint

Data:
%APPDATA%\HPR\HPR_DB\
  └── MM-YY\
      └── DD-MM-YY.db
Tray Mode

Built without a console window on Windows. Sits in your system tray and stays out of your way. No terminal flash on launch.

Build From Source

Clone, install Slint, build. HPR bundles and uses slightly patched versions of sol2, lua, and sqlite3 to ensure clean, warning-free builds on modern compilers.

Clone
git clone https://github.com/plexescor/HPR
cd HPR
Install Slint (Linux)
# System-wide (requires sudo)
sudo ./installDependencies.sh

# User-local (no sudo needed)
./installDependencies.sh
Install Slint (Windows)
# Pulls Slint 1.16.1, slint-lsp, slint-viewer
installDependencies.bat
Build
mkdir build && cd build

# If install script ran without sudo:
cmake .. -DCMAKE_PREFIX_PATH="$HOME/.local"

# If install script ran with sudo:
cmake ..

cmake --build . --parallel 8

Requirements

req CMake 3.21+
req GCC 13+, Clang 16+, or MSVC 2022+
req C++23 support
auto Slint 1.16.1 (install script handles)
bundled Patched sol2, lua, & sqlite3 in external/

Linux-Only Dependencies

Runtime: gdbus for GNOME and Cinnamon · qdbus6 / qdbus-qt6 for KDE Plasma 6+ (auto-detected) · hyprctl for Hyprland

Build-time and Extensions: libdbus-1 (needed to compile the tray) and libcurl development library (e.g. libcurl4-openssl-dev on Debian/Ubuntu, libcurl-devel on Fedora/RHEL) for extension networking support.

Patched Dependencies

HPR uses slightly patched versions of sol2, lua, and sqlite3 to mitigate compile errors and warnings. Swapping these for unpatched or system-installed libraries may cause compile errors, strict C++23 const-correctness warnings, or linker warnings (e.g., regarding tmpnam). Using the bundled versions ensures a warning-free build.

Build Output

CMake copies aliases.csv, tabAliases.csv, projectAliases.csv, config.csv, ui/, assets/, and install scripts next to the output binary automatically. A fresh build is immediately runnable from the build directory.

First run checklist.

HPR works out of the box. These are optional enhancements.

1

Check Platform

HPR auto-detects your desktop via $XDG_CURRENT_DESKTOP. GNOME users need to install the extension first. If it's missing, HPR doesn't crash silently — it sets its own "active window" display to the exact command you need to run, printing it directly in the UI header bar so the fix is impossible to miss:

# What HPR shows in the top bar if extension is missing:
RUN THE "installWindowCallsExtension.sh" SCRIPT
NEXT TO THE HPR BINARY AND THEN RESTART PC
2

Customize Aliases

Edit aliases.csv to add your own application name mappings. Hot-reloads — no restart needed. Format: raw,Display Name.

3

Try Interpreted Mode

Set use-interpreter,true in config.csv to load the UI from disk. Edit app-window.slint to customize HPR's entire interface.

Adding new platforms & tracked data.

HPR has well-defined extension points for platform backends and new data types.

Adding a New Platform

Platform window detection is fully contained inside CurrentWindowManager. Four steps:

1. Declare getCurrentWindow_YourPlatform()
   in getCurrentWindow.hpp

2. Implement in getCurrentWindow.cpp
   Return raw title as std::string.

3. Add else if branch in
   getCurrentWindow()

4. Add init checks in constructor
   inside preprocessor guard

// New backends inherit all normalization
// and noise filtering automatically.

Adding New Tracked Data

Five steps, fixed order:

1 Slint: Add property, struct, or UI element to app-window.slint
2 State: Add field to AppState::AppState in appState.hpp
3 Collection: Populate in getCurrentWindow_Loop()
4 Bridge: Thread through modelManager.update() using syncModel
5 Persistence: Add table in initDatabase, flush in writeLoop

Read the codebase in one sitting.

Go in this order and the entire architecture makes sense.

Reading Order
main.cpp              →  startup, config loading, thread orchestration
appState.hpp          →  the shared data model, the center of everything
getCurrentWindow.cpp  →  platform-specific window polling per backend
databaseManager.cpp   →  persistence, WAL, lock file, midnight rollover
uiModelManager.cpp    →  how C++ state becomes Slint models in both UI modes
One Rule

Anything that touches shared state goes through AppState::stateMutex. Lock, copy, release, work on the copy. Every existing access follows this pattern.