A lightweight, privacy-first desktop time tracker with a modern Fluent Design UI, supporting Windows & macOS.
True Hours automatically monitors your active window to track productivity, calculate earnings based on hourly rates, and generate detailed session reports. It features crash recovery, auto-exclusion of system apps, customizable external HTML templates, offline app icon extraction, and flexible export options (TXT, HTML).
| Feature | Description | |
|---|---|---|
| π | Time Tracking | Detects the foreground app and logs usage with second-level precision. Features retroactive idle deduction. |
| π | Analytics Dashboard | Interactive PyQt6 donut & bar charts with live and historical category breakdowns. |
| π | HTML Templates | Editable invoice and session report templates in templates/ β easy to customize externally. |
| π©Ί | Self-Healing Templates | Missing template files are auto-regenerated at runtime, preventing crashes. |
| π§Ύ | Invoice Builder | Dynamic invoicing with multi-email chip inputs, masked addresses, QR code graphics, and A4 PDF printing. |
| π° | Earnings Calculator | Set an hourly rate and watch earnings accumulate live during active sessions. |
| π‘οΈ | Smart Exclusions | Auto-ignores system processes, manually exclude apps, and automatically ignores TrueHour itself via PID matching. |
| π | Anti-Tamper Security | Monotonic clock protection, NTP validation, and SHA-256 hash chaining with real-time integrity scoring. |
| πΎ | Crash Recovery | Unexpected closures are auto-saved to an autosave folder for later recovery. |
| π€ | Export Options | Export to TXT, HTML Invoice, or HTML Session Report. |
| π¨ | Modern UI | Clean, light-themed interface inspired by Windows 11 Fluent Design, built with PyQt6. |
Main Tracker, Session Report, and Dashboard
Generated Invoice
Professional HTML invoice output
-
Clone the Repository:
git clone https://github.com/yourusername/TrueHours.git cd TrueHours -
Install Dependencies:
- Windows:
pip install PyQt6 pywin32 psutil Pillow
- macOS:
pip install PyQt6 pyobjc-framework-AppKit psutil Pillow
- Windows:
-
Run the Application:
- Windows: Use the batch file
run.bator run:python app.py
- macOS: Run the shell launcher script
./run.sh(or manually runpython3 app.py):chmod +x run.sh ./run.sh
- Windows: Use the batch file
If you want to package a standalone binary that runs without requiring Python to be installed:
-
Install PyInstaller:
pip install pyinstaller
-
Build Binary:
- Windows:
Double-click
build.bator run:pyinstaller --noconsole --onefile --windowed --name="TrueHours" --icon="icon.ico" app.py
- macOS:
Run the build script
./build.sh(or manually runpyinstaller):(This automatically installs dependencies, runs PyInstaller, cleans up temp files, and places a standard double-clickablechmod +x build.sh ./build.sh
TrueHours.appbundle in your root directory!)
- Windows:
Double-click
TrueHours/
βββ icon.ico # Application Icon
βββ app.py # Main UI Entry Point (PyQt6)
βββ tracker.py # Core Logic: Polling loop, state management, crash recovery
βββ report.py # Data formatting, export utilities (TXT/HTML)
βββ appinfo.py # Windows API wrappers: Get foreground window, extract icons/names
βββ config.py # Configuration helpers: Data directory management
βββ secure_time.py # Anti-tamper security: Monotonic clocks, hash chaining, NTP sync
βββ run.bat # Windows launcher script
βββ run.sh # macOS/Linux launcher script
βββ build.bat # Automated Windows PyInstaller build script
βββ build.sh # Automated macOS PyInstaller build script
βββ requirements.txt # Python dependencies
βββ README.md # This file
βββ SECURITY_FEATURES.md # Detailed documentation of anti-tamper protections
βββ templates/ # A4 HTML templates (invoices, session reports)
...
True Hours stores user data in the local app data directory:
%LOCALAPPDATA%\TrueHour (or ~\TrueHour if env var is missing).
True Hours comes with a default list of system apps to ignore (e.g., explorer.exe, svchost.exe). You can customize this list. Additionally, TrueHour automatically ignores its own window using real-time PID detection, ensuring your tracking sessions aren't interrupted when you open the app to check your progress.
- Open Settings in the app.
- Click "Edit Auto-Exclusions".
- This opens
auto_excluded_apps.txt. - Add or remove
.exenames (one per line). Lines starting with#are comments. - Click "Reload" in Settings to apply changes immediately without restarting.
If an app displays a confusing technical name (e.g., chrome.exe instead of Google Chrome), you can force a friendly name.
- Open Settings.
- Click "Edit Name Overrides".
- Format:
exename=Friendly Namechrome=Google Chrome code=VS Code
Set your currency and hourly rate in the Settings menu.
- Currency Symbol: Choose from USD, EUR, GBP, JPY, etc.
- Hourly Rate: Enter your rate (e.g.,
50.00). - Note: Earnings are calculated based on Counted Work Time only (excluded apps do not earn money).
True Hours allows you to fully customize how client invoices and session reports look when printed to PDF or exported.
- Open the
templates/folder in the True Hours root directory. - Open
invoice.htmlorreport_template.htmlin a code/text editor (e.g., VS Code). - Modify the styling (CSS), fonts, layout structures, and text as you like.
- Keep placeholders in place (e.g.,
{{BUSINESS_NAME}},{{ITEMS}},{{TIMELINE_ITEMS}}) so the application can dynamically populate your tracking details. - Self-Healing: If you ever make a mistake or break a file, simply delete the file or the
templates/directory, and True Hours will instantly recreate a fresh default copy at runtime.
- Total Session Time: The entire duration from Start to Stop/Pause.
- Counted Work Time: Time spent in apps that are not excluded. This is the basis for earnings calculations.
- Excluded Apps: Apps you have manually or automatically marked as "non-work." They appear in the report but are marked
[EXCLUDED]and do not contribute to earnings.
sessions/: Contains manually saved session reports (.json).autosave/: Contains automatic backups every 10 seconds (configurable) and crash recoveries.- *Files prefixed with
auto_: Regular backups. - *Files prefixed with
recovery_: Sessions recovered after a crash.
The heart of the application.
AppTrackerClass: Manages the polling thread._poll_loop(): Runs every 1 second (default). Checksget_foreground_app_info().- Crash Recovery: Uses
active_session.jsonto store state. If the app restarts and finds this file, it offers to recover the session.
Handles Windows-specific interactions.
get_foreground_app_info(): Useswin32guiandpsutilto find the active window's PID and executable path.resolve_name(): Tries to get the "File Description" from the EXE version info for a friendly name. Falls back to overrides or filename.get_icon_image(): Extracts the small icon from the EXE usingwin32gui.ExtractIconExand converts it to a PIL Image for PyQt6.
Handles data serialization.
build_report_data(): Aggregates raw tracker data into a structured dictionary.export_txt(): Generates a clean text file summary of the session.save_to_autosave(): Atomic write to prevent corruption during crashes.
- New Export Format: Add a function in
report.py(e.g.,export_pdf) and call it fromapp.py's_exportmethod. - Dark Mode: Currently, the app forces Light Mode via
ctypesinapp.py. To support Dark Mode, you would need to dynamically switch theBG_*color constants and remove theSetPreferredAppMode(3)call.
Q: Why is my timer not updating?
A: Ensure the app has permission to run in the background. Some "Game Modes" or aggressive power savers may pause Python scripts.
Q: How do I stop tracking specific games or social media?
A: Click the "+ Exclude App" button in the main UI while the app is running, or add the .exe name to auto_excluded_apps.txt.
Q: Where are my saved sessions?
A: Click the π (Folder) icon in the top right header to open the Session Manager. You can also open the folder directly via Settings.
Q: Does this send data online?
A: No personal or sensitive tracking data is ever sent online. By default, only the official prebuilt application releases (compiled .exe or .app binaries) have anonymous tracking via PostHog enabled to help monitor active usage and app stability. If you compile or run the application from the open-source source code yourself, tracking is completely disabled by default (unless you explicitly set up your own local .env file).
By using the prebuilt binary releases, you agree to the collection of three basic events:
app_started: Triggered when the application is launched (includes operating system platform and version).tracking_started: Triggered when you start the tracking timer.tracking_stopped: Triggered when you stop the tracking timer (includes anonymous aggregate session duration and app counts).
All metrics are bound to a randomly generated, anonymous installation ID stored locally in your settings. No emails, billing details, names, active window titles, or keystrokes are ever captured. You can easily disable this tracking at any time by leaving the POSTHOG_API_KEY empty in your local .env file in the application directory.
Q: Was AI Used in this Project?
A: Yes Gemini <3 , Claude <3 , Deepseek <3 , QWEN <3 Thank you so much!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- Three-Theme UI & Stylesheet Caching: Upgraded the interface to support three selectable themes ("Light", "Modern Dark", "Classic Dark") via a dropdown selector in the Settings dialog, with caching of QSS stylesheets and optimized theme application.
- Encrypted Profile Backups: Added password-protected encrypted backup support for settings and banking details, utilizing PBKDF2HMAC (100,000 iterations) for secure password key derivation while maintaining compatibility for legacy backups.
- Asynchronous Startup Optimization: Deferred heavy startup tasks, including database initialization and auto-exclusions loading, and added non-blocking incremental icon loading to eliminate UI freezes on application launch.
- Unit Test Coverage & Refactoring: Converted cryptography tests to standard
unittest.TestCaseand added tests specifically verifying PBKDF2 and SHA-256 legacy fallback validation.
- App-Specific Distraction Auto-Pause: Automatically pauses tracking when switching to a designated distracting application (e.g. Chrome, games, Spotify) and auto-resumes when returning to a productive task.
- App List Context Menu: Right-click any application in the live tracking list to quickly mark or unmark it as distracting.
- Manage Distraction Apps: Added a dedicated checklist dialog in Settings to manage, search, and manually add custom application executables.
- Dynamic Build Naming: Updated the unofficial build script to query both version and build number from
version.pyand programmatically construct the output filename at compile time.
- Priority Counted Time View: Swapped the primary display elements: the big main UI clock now displays the productive Counted Work Time (
00:00:00), while the bottom footer displays the overall Total Session Time (Xh XXm XXs). - Retroactive Idle Deduction: Integrated smart idle auto-pause math. The moment the idle threshold (e.g. 2 minutes) is reached, the inactive period is retroactively deducted from both the active foreground application's tracked time and the overall session duration.
- Process-Level Self-Exclusion: Implemented native self-exclusion. TrueHour now detects its own Process ID (PID) on both Windows and macOS and automatically marks itself as ignored, allowing you to open the tracker to check stats without interrupting your active tracking.
This project is licensed under the PolyForm Noncommercial License 1.0.0.
You are free to:
- Use, modify, and distribute the software for personal, research, academic, or other private non-commercial requirements.
Under the following terms:
- NonCommercial β You may not make any commercial use of the software. Commercial use is any use of the software by a business or for business purposes, or as part of a commercial service, or in any way that is intended for or directed toward commercial advantage or monetary compensation.
- Commercial Permission β Custom commercial licensing or custom permission is available for businesses, sales, or partnerships by contacting the licensor.
See the LICENSE file for the full legal text.
- Built with Python and PyQt6.
- Icon extraction powered by pywin32 and Pillow.
- Process monitoring via psutil.
- Vectors and icons by Saeedworks in CC Attribution License via SVG Repo. We thank him very much for his amazing work!
We would like to express our heartfelt gratitude to the following AI assistants and teams who contributed to this project:
- Alibaba QWEN Coder Agentic - For exceptional coding assistance and guidance.
- Google Antigravity Team - For their innovative support and insights.
- Claude AI - For valuable contributions and problem-solving expertise.
Thank you all for making True Hours possible! β€οΈ