EyeKi is a small Linux reminder daemon that counts active session time and prompts the user to apply eye drops. It can send a desktop notification or display a fullscreen GTK popup.
Status: early, pre-release prototype. Core scheduling, configuration, reload, presentation-lifecycle, and session-selection unit tests run in CI, but there are no verifiable tagged releases or production-ready packages. Localization and release validation remain before general distribution. See the roadmap.
EyeKi only provides configurable reminders; the repository contains no clinical validation or medical guidance. Users should choose an interval appropriate to guidance from their healthcare professional.
- Counts time in ten-second polling cycles and discards accumulated active time when the selected logind session reports at least 60 seconds of idle time.
- Resolves an active, local graphical logind session owned by the EyeKi process user instead of trusting global session-list order.
- Uses either a ten-second libnotify desktop notification or a fullscreen GTK 3 popup with a focused keyboard-operable acknowledgement button.
- Stores the interval and reminder mode in a local plain-text configuration file.
- Observes atomic settings replacements with inotify and restarts active-time counting from zero under the complete new configuration.
- Initializes a presentation backend before activating its mode, including live mode changes, and reports initialization or notification-delivery failures.
- Provides command-line operations to show and change those settings.
- Includes a systemd user unit and tracked metadata for an unreleased Debian package.
Notification and popup are intentionally mutually exclusive modes (XOR), not capabilities intended to be combined. Notification is the gentler prompt; popup is the stronger acknowledgement flow. The --daemon option runs the same foreground loop as starting without arguments—it does not fork or detach.
Configuration is intentionally CLI-only. A graphical settings application is not planned.
No screenshots are committed yet.
TODO(maintainer): Add a notification screenshot with personal desktop details removed.TODO(maintainer): Add popup screenshots from supported display-server sessions.
The first public-release target is Ubuntu. The current implementation is Linux-specific and requires a graphical desktop session, system D-Bus, and systemd-logind. The source uses GTK 3, libnotify, and libsystemd. X11 and Wayland behavior has not been systematically tested; fullscreen and keep-above requests may be compositor-dependent. Other Linux distributions and macOS are possible later targets but are not currently supported. Windows is not supported by the current architecture.
The intended Ubuntu release must be ready to use through one package-manager command, with runtime dependencies resolved automatically. End users should not need to install a compiler, development headers, or individual libraries manually. The project does not yet publish such a package, so the commands below are currently developer/source-build instructions rather than the finished installation experience.
- A C compiler and Make
pkg-config- GTK 3 development files (
gtk+-3.0) - libnotify development files (
libnotify) - libsystemd development files (
libsystemd) - At runtime: a notification service for notification mode and an available GTK display for popup mode
The Debian metadata names libgtk-3-dev, libnotify-dev, libsystemd-dev, pkg-config, and debhelper as build dependencies. Package names differ across distributions.
make
./eyeki --help
./eyeki --version
./eyeki --show-config
./eyeki --daemonmake clean removes the local eyeki build output. The build command is defined by the repository Makefile and is exercised with warnings treated as errors on the fixed Ubuntu 24.04 CI build baseline. That baseline verifies source compilation and tests; it does not establish desktop-runtime support.
make test builds and runs the desktop-independent scheduler, runtime reload, config-watch, interval/config-persistence, presentation-readiness, popup/process-lifecycle, and logind session-selection unit tests.
For a system-wide install, inspect eyeki.service first, then run with suitable privileges:
make
sudo make install
systemctl --user daemon-reload
systemctl --user enable --now eyeki.serviceThis installs the binary under /usr/bin and the user unit under /usr/lib/systemd/user with the default Makefile settings. It does not enable or start the user service. For development, run the binary directly instead of installing it. The Makefile is the only supported source-build installation path.
See Development for setup, diagnostics, safe manual validation, and the exact limitations of the current toolchain.
The default configuration is:
interval=60
mode=popup
Use a whole number from 10 through 300 minutes (five hours). Values outside that range, signs, whitespace, trailing characters, and numbers that cannot be represented are rejected without changing the saved configuration:
./eyeki --set-interval 60
./eyeki --set-mode n
./eyeki --set-mode p
./eyeki --show-confign selects desktop notifications and p selects the fullscreen popup. If XDG_CONFIG_HOME is non-empty and absolute, settings are stored at $XDG_CONFIG_HOME/eye_reminder/config; otherwise EyeKi uses $HOME/.config/eye_reminder/config. Missing parents are created. The EyeKi directory is restricted to 0700, and each complete configuration is written to a 0600 temporary file before an atomic replacement. A save error is printed and the setting command exits nonzero instead of reporting success.
When an XDG override is active but its EyeKi config does not exist, EyeKi reads the legacy $HOME/.config/eye_reminder/config file. The next successful setting change writes the complete configuration to the XDG path and leaves the legacy file untouched. Relative XDG_CONFIG_HOME values are ignored.
Every successful settings command atomically replaces the configuration file. The running daemon observes that replacement through inotify, initializes the selected presentation backend if needed, loads the complete new configuration, resets accumulated active time to zero, and starts counting under the new interval and mode. Rapid consecutive replacements may be coalesced into one reload of the latest complete configuration, which has the same reset result. Both live mode-transition directions are supported. If the newly selected backend cannot initialize, EyeKi reports the failure, stops without activating that configuration in the current process, and must be restarted after the desktop-session problem is corrected.
Persian is the initial product language. The current messages are hard-coded and mention one hour even when a different interval is configured; future localization work must separate text from program logic and handle RTL/accessibility before adding other languages or custom text. There is no snooze action, history, combined presentation mode, graphical settings screen, or automatic updater.
- A setting command exits with a filesystem error: check ownership and permissions for the active XDG config path, or
$HOME/.configwhen no absolute XDG override is set. - No notification appears: confirm the desktop notification service is running and inspect stderr or the user journal for EyeKi's initialization or delivery error. A failed delivery restarts the timer and retries only after the next configured interval.
- Popup cannot open: start EyeKi inside the intended graphical session and check the display environment. EyeKi reports a failed GTK display initialization and exits instead of activating popup mode.
- The timer reports no or ambiguous graphical session: run EyeKi as the intended desktop user. A directly launched process uses its own eligible login session; the user service prefers logind's primary display session and otherwise requires one unambiguous active local graphical session. Lookup failures and unresolved states reset progress.
- Service loops or fails: use
systemctl --user status eyeki.serviceandjournalctl --user -u eyeki.service; the unit restarts failures after five seconds. makereports missing build dependencies: on Ubuntu 24.04, installbuild-essential,pkg-config,libgtk-3-dev,libnotify-dev, andlibsystemd-dev, then verify all three modules withpkg-config --modversion gtk+-3.0 libnotify libsystemd. Package names differ on other distributions.
The source contains no network client or telemetry. It stores only the interval and selected mode locally, queries session idle metadata over the system bus, and sends reminder content to the local desktop notification service. Startup logs include the configured interval and mode. See Privacy and Security for limitations and reporting guidance.
- CI builds and runs the scheduler, runtime reload, config-watch, interval/config-persistence, presentation-readiness, popup/process-lifecycle, and session-selection unit tests on Ubuntu 24.04, but there is no desktop integration suite, static analysis, formatting check, multi-baseline matrix, or verified release process.
- Invalid persisted interval values are ignored so they cannot replace the default or a preceding valid value; other malformed configuration fields are not diagnosed.
- Current-session resolution and idle queries still depend on systemd-logind metadata and have not been manually verified across the intended Ubuntu desktop/session matrix; missing, ambiguous, or failed lookups reset progress until resolution recovers.
- Notification initialization/delivery errors are reported, but configuration-read/parse errors are ignored and concurrent one-shot settings changes can still overwrite one another's fields.
- Accessibility, right-to-left layout, translations, and Wayland behavior are untested.
- Debian packaging remains unreleased; the generated source archive and systemd integration still need release-level and supported-desktop validation.
- Project context
- Architecture
- Development
- Contributing
- Roadmap
- Release and distribution
- AI-assisted workflow
- Repository audit
- Changelog
EyeKi is available under the MIT License.