High-performance display manager for SteelSeries devices written in Go.
VU.mp4
- Windows 10/11
- SteelSeries Engine or SteelSeries GG (optional with direct driver)
- Go 1.21+ (for building from source)
- Linux with hidraw support
- PipeWire or PulseAudio (for audio widgets)
- GTK 3 and libayatana-appindicator3 (for system tray)
- Go 1.21+ (for building from source)
- System Tray Integration: Runs in background with system tray icon
- Configuration Profiles: Switch between multiple configurations via tray menu
- Live Configuration Reload: Edit and reload config without restarting
- Multiple Widgets: Clock, CPU, Memory, Battery, Network, Disk, Keyboard indicators, Keyboard layout, Volume control, Audio visualizer, Winamp integration, Telegram notifications, Matrix digital rain, Weather, Game of Life, Hyperspace, Star Wars intro
- Display Modes: Text, horizontal/vertical bars, graphs, analog gauges, etc
- Per-Core CPU Monitoring: Grid layouts showing individual core usage for all display modes
- Widget Transparency: Overlay widgets using
background_color: -1for layered displays - Gauge Displays: Semicircular analog gauges with needles for CPU/Memory/Volume, dual concentric gauges for Network (RX/TX)
- Auto-Hide Widgets: Widgets can appear temporarily and hide automatically (ideal for notifications and volume indicators)
- Volume Control: Real-time Windows system volume monitoring via Core Audio API
- Low Resource Usage: Minimal CPU and memory footprint (~0.5% CPU, ~15MB RAM)
- Single Executable: no dependencies, no DLLs required
- Automatic Logging: All output logged to
steelclock.logwith timestamps - JSON Schema Support: Full IDE autocomplete and validation via included schema file
And it also runs DOOM.
-
Build the application:
build.cmd # Or from WSL/bash: ./build.sh # For light build (smaller, excludes telegram widgets): build.cmd light ./build.sh --light
-
Run the application:
steelclock.exe
-
Install dependencies:
sudo apt-get install libgtk-3-dev libayatana-appindicator3-dev
-
Build the application:
./build-linux.sh # For light build (smaller, excludes telegram widgets): ./build-linux.sh --light -
Install udev rules for device access (one-time setup):
sudo cp profiles/99-steelseries.rules /etc/udev/rules.d/ sudo udevadm control --reload-rules sudo udevadm trigger # Unplug and replug your keyboard, or reboot -
Run the application:
./steelclock
The application starts in the background with a system tray icon. Right-click the tray icon to access the menu for switching profiles, editing config, or exiting.
# Build for Windows (GUI mode - no console window)
GOOS=windows GOARCH=amd64 go build -ldflags="-s -w -H windowsgui" -o steelclock.exe ./cmd/steelclock
# Build for Linux
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o steelclock ./cmd/steelclock
# Light build (add -tags light to exclude telegram widgets)
go build -tags light -ldflags="-s -w" -o steelclock-light ./cmd/steelclockSteelClock provides two build variants:
| Variant | Size | Description |
|---|---|---|
| Full | ~15 MB | All widgets included (default) |
| Light | ~10 MB | Excludes widgets with external API dependencies |
Widgets excluded in light build:
telegram- Telegram notifications (requires Telegram API)telegram_counter- Telegram unread counter (requires Telegram API)
To modify the exclusion list, edit cmd/steelclock/imports_light.go.
-config string
Path to configuration file (bypasses profile system)
The application uses steelclock.json as the main configuration file. The application supports live reload via the tray menu.
For complete configuration documentation, see:
- CONFIG_GUIDE.md - Comprehensive guide with all properties and examples
- config.schema.json - JSON schema for IDE autocomplete and validation
- profiles/ - Example configurations for each widget type
SteelClock supports multiple configuration profiles that can be switched via the tray menu.
- Main config:
steelclock.jsonin the current working directory - Additional profiles: JSON files in the
profiles/subdirectory - Profile names: Set via
config_namefield in JSON, or filename is used as fallback - State persistence: Last active profile is saved to
.steelclock.stateand restored on restart
Profile 1 (checkmark indicates active)
Profile 2
...
Profile N
─────────
Edit Active Config
Reload Active Config
─────────
Exit
{
"$schema": "schema/config.schema.json",
"config_name": "My Gaming Profile",
"refresh_rate_ms": 50,
"display": { ... },
"widgets": [ ... ]
}The config_name field determines how the profile appears in the tray menu. If omitted, the filename (without .json extension) is used.
| Widget | Description | Modes | Windows | Linux |
|---|---|---|---|---|
| clock | Current time display | text, analog | Yes | Yes |
| cpu | CPU usage (per-core support) | text, bar, graph, gauge | Yes | Yes |
| memory | RAM usage | text, bar, graph, gauge | Yes | Yes |
| battery | Battery level and charging status | text, bar, graph, gauge | Yes | Yes |
| network | Network I/O (RX/TX) | text, bar, graph, gauge | Yes | Yes |
| disk | Disk I/O (read/write) | text, bar, graph | Yes | Yes |
| keyboard | Lock indicators (Caps/Num/Scroll) | icons, text, mixed | Yes | No |
| keyboard_layout | Current keyboard input language | text (ISO 639-1, ISO 639-2, full name) | Yes | No |
| volume | System volume level and mute | text, bar, gauge | Yes | Yes* |
| volume_meter | Realtime audio peak meter | bar, gauge (stereo & VU support) | Yes | Limited* |
| audio_visualizer | Realtime audio spectrum/waveform | spectrum, oscilloscope | Yes | Yes* |
| winamp | Winamp player info display | text (with scrolling support) | Yes | No |
| telegram | Telegram notifications display | text (with scrolling/transitions) | Yes | Yes |
| telegram_counter | Telegram unread message counter | text | Yes | Yes |
| doom | Interactive DOOM game display | game | Yes | Yes |
| game_of_life | Conway's Game of Life simulation | - | Yes | Yes |
| hyperspace | Star Wars hyperspace animation | - | Yes | Yes |
| starwars_intro | Star Wars opening crawl text | - | Yes | Yes |
| matrix | Matrix "digital rain" effect | - | Yes | Yes |
| weather | Current weather conditions | icon, text | Yes | Yes |
* See Linux Limitations section below.
See CONFIG_GUIDE.md for detailed widget properties and configuration examples.
SteelClock supports two connection backends for communicating with your SteelSeries device:
| Backend | Description | Refresh Rate | Requirements |
|---|---|---|---|
gamesense |
Uses SteelSeries GG/Engine API | 100ms (10 Hz) | SteelSeries GG/Engine running |
direct |
Direct USB HID communication | ~16-30ms (30-60 Hz) | Device VID/PID, udev rules on Linux |
| (omitted) | Auto-select: tries gamesense, then direct | Varies | - |
{
"backend": "direct",
"direct_driver": {
"vid": "1038",
"pid": "1612",
"interface": "mi_01"
}
}If "direct_driver" section is empty, app will try to detect your hardware automatically.
- Higher refresh rates: Up to 60 Hz vs 10 Hz with GameSense
- Lower latency: Direct USB communication without HTTP overhead
- No SteelSeries software required: Works without GG/Engine installed
- Better for real-time visualizations: Audio visualizer, smooth animations
- Cross-platform: Works on both Windows and Linux
- Device-specific configuration: Need to know VID/PID of your device
- Exclusive access: May conflict with SteelSeries GG if running simultaneously
- Limited testing: Only tested with specific SteelSeries keyboards (Apex Pro)
- Linux requires udev rules: Need to install udev rules for non-root access
Windows:
- Open Device Manager
- Find your SteelSeries device under "Human Interface Devices"
- Check device properties for VID (Vendor ID) and PID (Product ID)
Linux:
lsusb | grep -i steelseries
# Output: Bus 001 Device 005: ID 1038:1612 SteelSeries ApS SteelSeries Apex Pro
# ^^^^ ^^^^
# VID PIDCommon values: VID 1038 (SteelSeries), PID varies by model.
- Direct mode bypasses the GameSense API entirely
- Some devices may have multiple HID interfaces - use
interfaceto specify (e.g.,mi_01) - If experiencing issues, omit the
backendfield to enable auto-selection with fallback - Direct mode reconnects automatically if the device is disconnected and reconnected
On Linux, some widgets have reduced functionality compared to Windows:
| Widget | Reason |
|---|---|
| keyboard | Requires Windows GetKeyState API for lock key detection |
| keyboard_layout | Requires Windows input language API |
| winamp | Winamp is Windows-only software |
| Widget | Limitation |
|---|---|
| volume | Uses command-line tools (wpctl, pactl, amixer) instead of native API. Polling-based, not event-driven. |
| volume_meter | Real-time audio peak metering is limited. Falls back to volume level as a proxy when actual audio levels are unavailable. |
| audio_visualizer | Requires PipeWire with parec for audio capture. May need additional configuration for proper audio routing. |
For audio widgets to work properly on Linux:
-
PipeWire (recommended):
# Ensure PipeWire is running systemctl --user status pipewire # Install PipeWire tools if needed sudo apt-get install pipewire-audio-client-libraries
-
PulseAudio:
# Check PulseAudio is running pactl info -
Audio capture for visualizer: The audio visualizer captures system audio output. On PipeWire, this should work automatically. On PulseAudio, you may need to configure a monitor source.
- If using
gamesensebackend: Verify SteelSeries Engine/GG is installed and running - If using
directbackend: Verify device VID/PID are correct and device is connected - Check if
steelclock.jsonexists and is valid JSON - Review
steelclock.logfor initialization errors and stack traces
- Check configuration file syntax (must be valid JSON)
- Verify widget configurations are correct
- Check
steelclock.logfor specific validation errors
"Permission denied" when accessing device:
# Install udev rules
sudo cp profiles/99-steelseries.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
sudo udevadm trigger
# Unplug and replug your keyboard"cannot read /sys/class/hidraw" error:
- Ensure the
hidrawkernel module is loaded:lsmod | grep hidraw - Check if your device appears:
ls /dev/hidraw*
System tray icon not appearing:
- Ensure you have a system tray implementation (e.g.,
gnome-shell-extension-appindicatorfor GNOME) - Check that
libayatana-appindicator3is installed
Audio widgets not working:
- Check which audio system is running:
pactl infoorwpctl status - Ensure audio tools are installed:
wpctl,pactl, oramixer - For audio visualizer, PipeWire is recommended
All application output is logged to steelclock.log in the same directory as the executable. The log includes:
- Startup and shutdown events
- Configuration loading and validation errors
- Widget initialization
- GameSense API communication (Windows) / HID communication (Linux)
- Runtime errors and warnings
Check this file if you encounter any issues or unexpected behavior.
# Run all tests
go test ./... -cover
# Run with race detection
go test -race ./...
# Run with verbose output
go test ./... -v
# Check coverage
go test ./... -coverprofile=coverage.out
go tool cover -html=coverage.outgithub.com/shirou/gopsutil/v4- System monitoringgithub.com/getlantern/systray- System tray icongolang.org/x/image- Font rendering and image processinggithub.com/moutend/go-wca- Windows Core Audio APIgithub.com/go-ole/go-ole- COM interface support for Windows APIsgithub.com/mjibson/go-dsp- Digital signal processinggithub.com/go-toast/toast- Windows toast notificationsgithub.com/AndreRenaud/gore- DOOM engine port
GNU General Public License v3.0