DEV Community

Ishwor Subedi
Ishwor Subedi

Posted on

SitBlinkSip Desktop: A Native App That Watches Your Blinks, Posture, and Water Breaks — With No Server, No Database, No Browser Tab

A complete walkthrough of installing, configuring, and actually living with the open-source background app that keeps developers healthier during long screen sessions

SitBlinkSip live health monitoring overlay showing blink rate and posture status

If you read my last post, you know why SitBlinkSip exists: developers forget to blink, slouch for hours, and skip water breaks, and a webcam is a genuinely good tool for catching all three in real time.

This post is the practical one. I'm going to walk through SitBlinkSip Desktop — the native companion app — end to end: what it does differently from the web dashboard, how to install it on your OS, and how to actually configure it so the nudges help instead of annoy you.

Repo: github.com/ishworrsubedii/desktop-sitblinksip

Why a separate desktop app?

The original SitBlinkSip is a web dashboard: Next.js frontend, FastAPI backend, OpenCV + dlib for the computer vision, the whole thing running in Docker. It's great if you want the full dashboard experience with charts in your browser.

But most days, I don't want to keep a browser tab and a Docker container alive just to get blink reminders. So the desktop app strips it down to the essentials:

  • No server. No FastAPI process running in the background.
  • No database. Nothing is logged or persisted beyond your local settings file.
  • No browser tab. It lives in your system tray (or menu bar on macOS) and stays out of your way.
  • Entirely local. Just the webcam and a timer, processed on-device.

It reuses the exact same detection logic as the web app — eye-aspect-ratio for blinks, head-tilt-angle and forward-displacement for posture — but swaps dlib for MediaPipe FaceMesh/Pose, which means no giant landmark model file to download and no compiled dependency to build from source. The alert tones are shared with the web dashboard too, so it genuinely feels like the same product, just lighter.

What it does, feature by feature

  • Blink counter — no camera feed shown by default, just a small always-on-top widget with your blink count and blinks/minute. Press F6 (or use the tray menu) any time to reveal the live camera preview, and press it again to hide it.
  • "Blink now" nudge — if your blink rate over the last minute drops below a healthy minimum, your screen blanks for a couple of seconds with a short alert tone, then resumes. It's deliberately more forceful than the other two alerts, because a missed blink is the most time-sensitive of the three.
  • Posture corrector — the same webcam feed is periodically checked for head tilt and forward lean. When your posture score drops too low, you get a sound + notification — no screen blank, since posture drift is gradual rather than urgent.
  • Water break reminders — an independent timer nudges you on a configurable interval regardless of whether blink/posture tracking is paused, so you never skip hydration just because you turned off the other checks.
  • System tray control — pause/resume tracking, toggle the camera preview, open settings, or quit, all from one menu.

Installing it on your OS

SitBlinkSip Desktop ships as a native package for Linux, Windows, and macOS, all built from the same source tree and the same PyInstaller spec.

OS Package Notes
Linux .deb Any desktop with a system tray. X11 recommended (see the hotkey note below).
Windows setup.exe (Inno Setup) Windows 10/11, 64-bit. Global F6 hotkey works out of the box.
macOS .dmg (.app bundle) macOS 11+, Apple Silicon and Intel. Runs as a menu-bar app, no Dock icon. Needs two permission grants on first run.

Linux

./packaging/linux/build-deb.sh
sudo apt install ./dist/sitblinksip-desktop_0.1.0_amd64.deb
Enter fullscreen mode Exit fullscreen mode

Launch SitBlinkSip Desktop from your applications menu, or run sitblinksip-desktop from a terminal. Uninstall any time with sudo apt remove sitblinksip-desktop.

Windows

powershell -ExecutionPolicy Bypass -File packaging\windows\build-windows.ps1
Enter fullscreen mode Exit fullscreen mode

This produces a runnable frozen app directory, and — if you have Inno Setup 6.3+ installed — a full setup.exe installer. It defaults to a per-user install, so no admin/UAC prompt is required. Since the build isn't code-signed, Windows SmartScreen will flag it on first run — click More info → Run anyway.

macOS

./packaging/macos/build-macos.sh
Enter fullscreen mode Exit fullscreen mode

This produces SitBlinkSip Desktop.app and a .dmg. Two things worth knowing before you try it:

  • The build is architecture-native (not universal2), because one of the vision dependencies (opencv-contrib-python, pulled in by MediaPipe) doesn't publish a fat binary — build on Apple Silicon for Apple Silicon, Intel for Intel.
  • The bundle is ad-hoc signed but not notarized, so the first launch needs right-click → Open → Open — a plain double-click will be blocked by Gatekeeper.

macOS will also ask for two permissions on first run:

Permission Needed for Where
Camera Blink and posture tracking (required) System Settings → Privacy & Security → Camera
Accessibility Global F6 hotkey (optional) System Settings → Privacy & Security → Accessibility

If you skip Accessibility, F6 still works while a SitBlinkSip window is focused — you just lose the global hotkey, and the app tells you once via notification rather than leaving it silently dead.

Running from source (any OS)

If you'd rather run it without building a package:

cd desktop-sitblinksip
python3 -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -r requirements.txt
python -m sitblinksip_desktop
Enter fullscreen mode Exit fullscreen mode

You'll need Python 3.9–3.12 — MediaPipe is pinned to a version range that dropped support for the older mediapipe.solutions API this app relies on above 3.12, so 3.13 isn't compatible yet. The requirements.txt handles per-platform quirks (Windows needs one MediaPipe release lower than the others) automatically via environment markers, so a plain pip install -r requirements.txt just does the right thing.

Using it day to day

Everything is driven from the tray icon (system tray on Linux, notification area on Windows, menu bar on macOS):

Action How
Show/hide the blink counter Tray icon → "Show/Hide counter"
Minimize the counter to just the blink count button on the counter widget
Show/hide the camera preview F6, or tray icon → "Show camera preview"
Pause/resume tracking Tray icon → "Pause tracking"
Enable/disable posture checks Tray icon → "Posture checks" checkbox
Enable/disable water reminders Tray icon → "Water break reminders" checkbox
Adjust sensitivity / thresholds Tray icon → "Settings…"
Quit Tray icon → "Quit"

Settings are organized into Blink / Posture / Water / General tabs, and persist to a local config.json:

  • Blink — camera device index, EAR threshold, minimum blinks/minute, break-screen duration, cooldown between breaks.
  • Posture — head-tilt angle threshold, forward-lean threshold, posture score alert threshold, cooldown between alerts.
  • Water — reminder interval.
  • General — sound on/off, launch on login.

My honest recommendation after running it for a while: turn the water reminder interval up slightly from the default if you already have a habit of keeping a bottle at your desk, and leave the blink threshold alone — it's tuned around the same clinical minimum blink-rate research the whole project is built on.

A note on the global F6 hotkey

This is the one feature that genuinely behaves differently per platform, because each OS decides independently whether a regular app is allowed to listen for keys system-wide:

Platform Global F6 Why
Windows ✅ Works Installs a Win32 low-level keyboard hook, no permission needed.
Linux (X11) ✅ Works Hooks X11 directly.
macOS ⚠️ After granting Accessibility See the permissions table above.
Linux (Wayland) ❌ Blocked Wayland's security model forbids system-wide key listeners for regular apps — a platform limitation, not a bug in the app.

Wherever F6 isn't available globally, it still works while a SitBlinkSip window has focus, and the tray/menu-bar menu always has a manual toggle — you're never stuck without a way to open the camera preview.

Under the hood, briefly

The stack is PySide6 + MediaPipe + OpenCV + NumPy + pynput, and it's genuinely cross-platform — most of the codebase is shared. The platform-specific differences (settings paths, camera backend, tray behavior, launch-on-login mechanism) are deliberately concentrated into two files, platform_support.py and autostart.py, rather than scattered through the feature code as sys.platform checks. If you're curious how a cross-platform PySide6 app handles things like DirectShow vs. V4L2 vs. AVFoundation camera backends, or XDG autostart vs. registry Run keys vs. launchd agents, the source is short enough to read in an afternoon.

Try it

git clone https://github.com/ishworrsubedii/desktop-sitblinksip.git
cd desktop-sitblinksip
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python -m sitblinksip_desktop
Enter fullscreen mode Exit fullscreen mode

It's Apache-2.0 licensed, actively developed, and contributions are welcome — especially around the packaging scripts, which are the trickiest part of shipping a native app on three OSes from one codebase.

If you try it, I'd genuinely like to know what default threshold felt wrong for you — those are the kind of small tuning issues that are hard to catch alone and easy to fix with a GitHub issue.


Tags: Open Source, Software Engineering, Cross Platform Development, Python, Developer Tools

Top comments (0)