Skip to main content
AlienFX LEDs icon

AlienFX LEDs

Keyboard and chassis lighting for Alienware and Dell machines on Linux.
Per-key colors, effects, a typing ripple, and a toggle in GNOME Quick Settings, all driven by a small, locked-down service.

CI CodeQL SLSA 3 Ruff uv
License: GPL-3.0-or-later Linux Python 3.10+ GTK 4 + libadwaita GNOME 46
Verified: Alienware m15 R7 49 community models No raw device access

Features · Supported machines · Install · Usage · Security · Development

The Keyboard page on an Alienware m15 R7: every key drawn to scale, lit as a left-to-right rainbow

✨ Features

⌨️ Per-key colors The keyboard drawn to scale from its real geometry. Click or Ctrl/Shift-click keys, pick a color, apply.
🌈 Effects 5 firmware effects (breathing, wave, pulse, two-color pulse, sweep) plus 5 rendered by the service (rainbow, spectrum, color morph, starlight, gradient). One effect can go to any mix of keyboard and chassis lights.
💡 Chassis lights Power button, lid logo, rear light strip: static color, pulse, morph. The power button keeps its color asleep and off.
💧 Typing ripple A ring of color from every key you press, over the current effect or a plain color. Adjustable color and speed (2 to 40 keys per second).
🎛️ Quick Settings On/off, brightness, presets and the ripple, straight from the GNOME panel.
🖥️ Command line alienfix does everything the app does, for scripts.
🧭 Any model Unknown machine? A generic model is built from the controllers found, and the “does it blink?” wizard maps a per-key keyboard in 3 to 5 minutes.
💾 Persistent Settings survive reboots and are re-applied after suspend.
Effects page: one effect applied to several lighting groups
Effects: one effect, applied to any mix of lights.
Ripple page: enable switch, color, speed and what shows under the ripple
Ripple: color, speed and what shows underneath.
Chassis page: power button, lid logo and the two rear-strip channels
Chassis: power button, lid logo, rear strip.
Machine page: detected model, lighting map source, key map wizard
Machine: detected model, key map, wizard.

💻 Supported machines

Status Machines
🟢 Verified
checked with a camera, key by key and zone by zone
Alienware m15 R7: per-key keyboard, power button, lid logo, rear strip (two channels). See docs/m15-r7.md.
🟠 Reported
community mappings from other projects, not verified here
49 models: m15 R1, R3, R4, R6, m16, m17, m18, x17, Area-51m, Aurora R12, Dell G15 5510–5535, G5, G7, and 2010–2017 machines (M11x, M14x, M17x, M18x, 13, 15, 17, Area-51, Aurora R4). Full list: docs/supported-models.md.
⚪ Anything else with these controllers Detected by its USB HID descriptor. The service builds a generic model with neutral zone names, and a per-key keyboard can be mapped with the blink wizard.
Controllers
Controller USB What it drives
AW-ELC (“API v4”) 187c:0550, 187c:0551 Chassis lights and 4-zone keyboards: static color, pulse, morph. Power buttons are programmed for every power state.
Darfon per-key keyboard (“API v5”) 0d62:*, FEATURE report 0xCC Per-key colors, 5 firmware effects, 5 effects rendered by the service, hardware dimmer, live mode, typing ripple.
Legacy AlienFX (“API v2/v3”) 187c:0511..0530 Zone masks, static color.
Kernel alienware-wmi rgb_zones sysfs Pre-2018 desktops (X51, Alpha): static color.

A Dell G15 with a 4-zone keyboard
A Dell G15: its 4-zone keyboard is listed as zones.

📦 Install

1. Dependencies (Python 3, PyGObject, GTK 4, libadwaita). On Ubuntu 24.04:

sudo apt install python3-gi gir1.2-gtk-4.0 gir1.2-adw-1

2. Install the service, the command line, the app and the GNOME extension:

./install.sh        # asks for sudo

3. Enable the Quick Settings toggle (GNOME 46). On X11, reload the shell with Alt+F2, r, Enter; on Wayland, log out and back in. Then:

gnome-extensions enable alienfix@zeecka.github.io

To remove everything, ./uninstall.sh deletes exactly what install.sh installed (it keeps a manifest).

🚀 Usage

The app

Open AlienFX LEDs from the GNOME menu. The pages follow your machine:

  • Keyboard: the per-key drawing to scale, or the keyboard zones.
  • Effects: one effect applied to any mix of lighting groups.
  • Chassis: one color per zone, applied at once.
  • Ripple: a ring of color from each key typed on the built-in keyboard, in any window. Color, speed and what shows underneath (the current colors or effect, or a plain color) are saved by the service.
  • Machine: the detected model, the choice of model, key map import/export and the key map wizard.

The header bar holds the master switch and the brightness slider.

Quick Settings

The Lighting tile turns everything on or off. Its menu has the brightness slider, effect presets, the Typing ripple switch and a shortcut to the app.

Command line

alienfix status | layout | zones | models
alienfix color '#0050ff'                         # whole keyboard
alienfix keys ESC=#ff0000 Q=#00ff00              # per key (names from `alienfix layout`)
alienfix effect wave --tempo 5 '#ff0000' '#0000ff'
alienfix zone lid pulse --tempo 6 '#ff0000'      # zone ids from `alienfix zones`
alienfix model dell-g15-5520 | auto
alienfix brightness 60 | on | off

Tempo goes from 1 to 30; higher is slower.

🔒 Security model

  • One owner. Only alienfixd opens the hidraw nodes. No udev rule opens them to users.
  • Confined service. alienfixd runs as root but with no capabilities: empty CapabilityBoundingSet=, DevicePolicy=closed (hidraw, plus input devices read-only for the ripple), ProtectSystem=strict, PrivateNetwork=yes, SystemCallFilter=@system-service.
  • Narrow API. The D-Bus interface only has lighting verbs, with no raw report pass-through. Every argument is re-parsed, bounded and rebuilt before it reaches a device (validate.py). The interface is described in docs/dbus-api.md.
  • polkit. The active local session may change the lighting. Remote and inactive sessions may not.

🔬 How it was built

The Alienware m15 R7 support was reverse-engineered with a webcam pointed at the keyboard, because a successful command proves nothing about an LED. The full method, dead ends included, is in the write-up on the author's blog.

The other models come from the community mappings of alienfx-tools (MIT), akbl (GPL-3.0), OpenRGB (GPL-2.0) and AWCC (GPL-3.0). Only facts were taken from them (USB ids, light indices and masks, zone names), and tools/import_models.py records the exact source of each model. Thanks to their authors and contributors. 🙏

🛠️ Development

The project uses uv. PyGObject needs its build headers (sudo apt install libgirepository-2.0-dev libcairo2-dev pkg-config python3-dev), or skip it with uv sync --no-install-package pygobject --no-install-package pycairo: only the service and the app need it, not the tests.

uv sync                                                     # dev tools: ruff, ty, pylint
uv run python -m unittest discover -s tests                 # validation, encoders, models, ripple
uv run ruff check . && uv run ruff format --check .         # lint and format
uv run ty check                                             # types
uv run pylint src tests tools bin/alienfix bin/alienfixd gui/alienfx-leds

MOCK_MODEL=dell-g15-5520 python3 tests/mock_daemon.py &     # the real service, fake hardware, session bus
ALIENFIX_BUS=session gui/alienfx-leds                       # the app against it

Every push and pull request runs these checks in CI, plus ShellCheck, actionlint, zizmor, the GNOME extension and the data files; CodeQL scans the Python and JavaScript code weekly. Dependabot keeps the actions and tools up to date.

Releasing
  1. Bump version in pyproject.toml and __version__ in src/alienfix/__init__.py, commit.
  2. Tag and push: git tag v0.2.0 && git push origin v0.2.0.

The release workflow then builds the sdist and wheel, creates the GitHub release, attaches a signed SLSA level 3 provenance (alienfx-leds.intoto.jsonl), and publishes to PyPI with Trusted Publishing (no token) and PEP 740 attestations. Verify a download with slsa-verifier:

slsa-verifier verify-artifact alienfx_leds-0.2.0-py3-none-any.whl \
  --provenance-path alienfx-leds.intoto.jsonl --source-uri github.com/Zeecka/alienfx-leds --source-tag v0.2.0

One-time setup: on PyPI, add a trusted publisher for alienfx-leds (repository Zeecka/alienfx-leds, workflow release.yml, environment pypi), and create the pypi environment in the repository settings. The provenance goes to the public Rekor transparency log, so the generator only runs on a public repository.

Repository layout
Path What
src/alienfix/ The service: D-Bus API, validation, report encoders, effects, models, key maps
gui/alienfx-leds The GTK 4 / libadwaita app
bin/alienfix The command line
gnome-extension/ The Quick Settings toggle
data/models/ One file per machine model
data/chassis/, data/profiles/ Keyboard geometry, and the shipped key maps
tests/ Unit tests and the mock service
.github/ CI, CodeQL, release (SLSA, PyPI), Dependabot

📄 License

GPL-3.0-or-later.

Metadata

Release files for alienfx-leds 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for alienfx-leds 0.1.0
File Size Uploaded
alienfx_leds-0.1.0.tar.gz 50.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for alienfx-leds 0.1.0
File Interpreter ABI Platform
alienfx_leds-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 101.1 kB

Release files / alienfx_leds-0.1.0.tar.gz

Download URL alienfx_leds-0.1.0.tar.gz
Size 50.9 kB
Tags Source
SHA-256 checksum
How to use checksums
0c54ec2beb52b497af52f5bc1bd96b25b25f840745607b0ab2eff2061b8f673c
BLAKE2b-256 checksum
How to use checksums
99655536a6a3ce7a7756cbf6007b357ca52d4aff7846bac5a6c821cb0d338ac6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release files / alienfx_leds-0.1.0-py3-none-any.whl

Download URL alienfx_leds-0.1.0-py3-none-any.whl
Size 50.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8753a94b7870e67856311d24bc48db5dd06cc04064810ff6820e96c6c74518a5
BLAKE2b-256 checksum
How to use checksums
3bb63f279842cccf860a9e803de6bc4946d1be193e3463891f5b2054fa623766
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 6, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page