Lighter is a GNOME Shell extension that improves your videocall lighting at night by adding adjustable light borders around your screen edges — a software ring light. Perfect for laptop users who need extra illumination without external gear.
- Per-side thickness: Adjust each border (top, bottom, left, right) independently, or keep them linked. Set a side to 0 to disable it — e.g. only bottom + sides for a lower fill light.
- Profiles: Save your setups as named profiles (e.g. Google Meet) and switch between them from the panel menu or the preferences window.
- Automatic profile switching (optional): Apply a profile automatically when a matching window is focused — match by application ID or by a regex on the window title (works for Meet running in a browser tab).
- Customizable color & temperature: Full RGB color picker, plus a warm↔cold temperature slider when the color is white.
- Opacity control: Adjust the light intensity to your comfort level.
- Maximize brightness: Optionally push the screen backlight to 100% while active, restoring your previous level when turned off.
- Multi-monitor support: Show on the primary monitor or all screens.
- Seamless integration: Native GNOME Shell feel with a toggle in the top bar.
- Convenient shortcut:
Ctrl + Alt + Lopens the preferences. - Scriptable: apply a profile or toggle the light from any other program by writing the extension's GSettings keys — see Controlling Lighter from another program.
- GNOME Shell 45, 46, or 47
git clone https://github.com/joaoferrete/Lighter.git
cd Lighter
make installThen restart GNOME Shell (log out/in on Wayland, or Alt + F2 → r → Enter on X11)
and enable the extension:
gnome-extensions enable lighter@gnome-shell-extensions.ferrete.com-
Click the ☀ indicator in the top bar to toggle the light, pick a profile, or adjust the color temperature.
-
Open the full preferences with
Ctrl + Alt + Lor:gnome-extensions prefs lighter@gnome-shell-extensions.ferrete.com
On the Profiles page of the preferences, click + to save the current settings as a named profile. Each profile stores thickness, opacity, color, temperature, brightness, and monitor options.
To switch profiles automatically, enable Auto-switch profiles and give a profile a
match rule — an application ID (e.g. firefox.desktop) and/or a window title regex
(e.g. Meet). When a focused window matches, the profile is applied; when nothing
matches, the optional default profile is applied. Manual selection always works and
takes effect immediately.
Every appearance setting lives in GSettings, and the extension reacts to external
writes. That makes gsettings a supported entry point: another program can drive the
borders without reimplementing them, and without knowing how your borders are
calibrated.
The schema is not in the default search path, so --schemadir is required:
SCHEMA_DIR="$HOME/.local/share/gnome-shell/extensions/lighter@gnome-shell-extensions.ferrete.com/schemas"
SCHEMA=org.gnome.shell.extensions.lighter
# Turn the light on and off
gsettings --schemadir "$SCHEMA_DIR" set $SCHEMA enabled true
gsettings --schemadir "$SCHEMA_DIR" set $SCHEMA enabled false
# Apply a saved profile by its id
gsettings --schemadir "$SCHEMA_DIR" set $SCHEMA active-profile '<profile-id>'Look profile ids up by name, never hardcode them. They are UUIDs generated when
the profile is created, so a hardcoded id breaks as soon as you recreate the profile.
The profiles key holds a JSON document shaped like
{"version": 1, "profiles": [{"id": "…", "name": "Meet", "settings": {…}}]}:
gsettings --schemadir "$SCHEMA_DIR" get $SCHEMA profiles \
| sed "s/^'//; s/'$//" \
| jq -r '.profiles[] | select(.name == "Meet") | .id'Writing active-profile applies the profile, including turning the light on. The
appearance keys (thickness-*, opacity, color, temperature, multi-monitor,
maximize-brightness) can also be set individually and take effect immediately.
Two things worth knowing:
- Turn off Auto-switch profiles while an external program is in charge, or the window watcher will apply its own profile on the next focus change and overwrite what your program just did. The two are independent controllers of the same state.
- Changes to the extension's own code need a logout/login on Wayland, because the GNOME Shell cannot reload an extension there. Changes to settings apply immediately — only code changes need the session restart.
See CONTRIBUTING.md for the full guide. Quick start:
make install # pack and install locally
make nested # test in a nested GNOME Shell session (Wayland)
make lint # run ESLint (requires `npm install` once)
make pot # regenerate the translation templateIf the extension shows an ERROR state after code changes, restart GNOME Shell to reload the updated code. Check logs with:
journalctl /usr/bin/gnome-shell -b | grep -i lighter