Linux desktop tray utility that automatically locks the session when a trusted Bluetooth Low Energy device (your phone, watch, AirPods, BLE keychain tag) moves out of range. Functional and architectural mirror of the macOS and Windows apps — same algorithm, same proximity logic, same safety defaults.
Phase 0 — Spike validation. The production tree under
linux/src/does not exist yet. Thespike/subdirectory contains three small Rust binaries that validate the risky dependencies (bluerfor BLE,loginctlfor screen lock,ksnifor the system tray) on real hardware. Once the spike passes on Ubuntu GNOME and Fedora KDE Plasma, Phase 1 (production code) begins.If you want to track or contribute, start with
spike/README.md.
- Linux desktop with a graphical session (X11 or Wayland).
- BlueZ ≥ 5.55 and a working Bluetooth Low Energy adapter.
- systemd-logind (for the primary screen-lock strategy via
loginctl). - Rust toolchain (stable) to build from source.
- For GNOME users: the AppIndicator and KStatusNotifierItem Support extension — without it, GNOME silently drops tray icons.
Target distributions for the first release:
- Ubuntu 22.04+ (GNOME, with AppIndicator extension)
- Fedora 39+ (KDE Plasma works out of the box; GNOME needs the same extension)
- Debian 12+, Arch / EndeavourOS (community-supported)
Once production code lands under linux/src/, the canonical build will be:
cd linux
cargo build --release
./target/release/signallockA future release will also ship distribution-native packages (AppImage, Flatpak, .deb, .rpm). Packaging choices will be documented here once decided.
For now, see spike/README.md for how to run the three validation binaries.
A direct port of the macOS and Windows logic:
BluetoothScannersubscribes tobluerevents and streams every BLE advertisement with its RSSI.ProximityMonitorkeeps a moving average of recent RSSI samples (default window 5).- The trusted device is considered away when either:
- The smoothed RSSI is below the configured threshold (default -80 dBm), or
- No advertisement has been received for longer than the away delay (default 20 seconds).
- The away condition must persist for the full away-delay grace period before a lock fires. Exactly one lock fires per away episode.
- After locking, SignalLock listens on the D-Bus session for the
org.freedesktop.login1Unlocksignal. When you unlock with your password / PIN, the proximity monitor is rearmed.
LockService will call loginctl lock-session via D-Bus (org.freedesktop.login1.Session.Lock) as the primary strategy. Fallback chain for non-systemd desktops:
loginctl lock-session(systemd-logind — works on GNOME, KDE, XFCE on most modern distros)xdg-screensaver lock(FreeDesktop fallback)- Desktop-specific commands (
gnome-screensaver-command --lock,qdbus org.freedesktop.ScreenSaver /ScreenSaver Lock,xscreensaver-command -lock)
The exact order will be confirmed by the spike's lock_test binary across desktops. Whichever strategy fires is logged so users can debug stuck setups.
- Bluetooth — your user must be in the
bluetoothgroup sobluercan talk to BlueZ without sudo. The README explains this in the spike instructions. - No root, no elevated capabilities, no PolicyKit prompt.
- No network access — the app never opens a socket.
Toggling Start at login will write a desktop entry to ~/.config/autostart/signallock.desktop. Per-user, no root required, no systemd-user unit needed. The XDG autostart spec is honoured by GNOME, KDE Plasma, XFCE, Cinnamon, MATE, and LXQt.
linux/
├── Cargo.toml
├── README.md
├── LICENSE
└── src/
├── main.rs — entry point; tokio runtime; tray bootstrap
├── app_state.rs — single orchestrator; channels into scanner/monitor
├── models.rs — AppSettings, TrustedDevice, DiscoveredDevice
├── logging.rs — env_logger setup; categories: app, lock, proximity, bluetooth
├── storage/
│ ├── paths.rs — XDG dirs (~/.config/signallock, ~/.local/share/signallock)
│ ├── settings_store.rs — TOML or JSON persistence of AppSettings
│ └── trusted_device.rs — persistence of the selected TrustedDevice
├── bluetooth/
│ └── scanner.rs — bluer::Adapter wrapper; discovery + monitoring scan modes
├── proximity/
│ └── monitor.rs — moving average + grace period + lock trigger
├── lock/
│ └── service.rs — loginctl + xdg-screensaver + desktop-specific fallbacks
├── login_item/
│ └── service.rs — ~/.config/autostart/signallock.desktop toggle
└── ui/
├── tray.rs — ksni tray icon + menu
├── settings.rs — settings dialog (toolkit TBD — likely gtk-rs or iced)
└── device_picker.rs — BLE picker dialog
State flow will be one-directional: BluetoothScanner → AppState → ProximityMonitor → LockService. Same as on macOS and Windows.
- iPhones rotate BLE advertising addresses for privacy. As on macOS and Windows, an iPhone is the least consistent trusted device; recommend Apple Watch, Galaxy Watch, AirPods, fitness bands or BLE keychain tags.
- Wayland imposes some restrictions on global hotkeys and screen-lock APIs; the
loginctlpath bypasses both, so this should not affect SignalLock. - GNOME without the AppIndicator extension will silently drop the tray icon. This is a GNOME design choice, not a SignalLock bug — see the spike README for the workaround.
- No code-signed packages yet. The first packaged release will be unsigned; verify the SHA-256 to confirm the file came from the official repository.
- Default RSSI threshold: -80 dBm.
- Default away delay: 20 seconds.
- Default smoothing window: 5 samples.
- Auto-start on launch will be enabled when a trusted device is configured.
- The first lock cannot fire until the device has been seen at least once after monitoring starts.
Until production code lands:
- Run the three spike binaries on your distribution and desktop environment (
spike/README.md). - Open an issue with which combination you tested, which strategy worked, and any failure modes. This directly informs which fallbacks ship in the first production release.
Once Phase 1 starts, contribution guidelines and a code-style note will be added here.
SignalLock is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License v3.0 as published by the Free Software Foundation. See the LICENSE file in this directory for the full text, or https://www.gnu.org/licenses/gpl-3.0.html.
SignalLock is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose.
- The default desktop file
~/.config/autostart/signallock.desktopand any future package identifiers (Flatpak app-id,.debpackage name) are tied to the upstream project. If you redistribute a fork, rename them so your packages do not collide with upstream installs. - The Bluetooth permission model assumes the user is in the
bluetoothgroup; this is a BlueZ requirement, not a SignalLock choice. Forks should not work around it (e.g., by running as root). - This repository contains only the Linux app. The marketing website is maintained separately and is not GPL-licensed.