Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: CI

on:
push:
branches: [main]
pull_request:

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm install
- run: npm run lint

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install GNOME tooling
run: |
sudo apt-get update
sudo apt-get install -y libglib2.0-bin gnome-shell-common gnome-shell gettext
- name: Validate GSettings schema
run: glib-compile-schemas --strict --dry-run schemas/
- name: Pack extension
run: make pack
- uses: actions/upload-artifact@v4
with:
name: extension-zip
path: dist/*.shell-extension.zip
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
.claude
.claude
schemas/gschemas.compiled
dist/
node_modules/
po/*.mo
42 changes: 42 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.0] - Unreleased

### Added
- Independent border thickness per side (top/bottom/left/right); setting a side to 0
disables it entirely.
- Named profiles: save the current appearance as a profile (e.g. "Google Meet") and
switch between profiles from the panel menu or the preferences window.
- Optional automatic profile switching based on the focused window (match by
application ID or a regular expression on the window title).
- Build tooling: `Makefile` (build/lint/pot/pack/install/nested), ESLint config,
GitHub Actions CI, and gettext translation scaffolding (`po/`).
- `CONTRIBUTING.md` and this changelog.
- Brazilian Portuguese translation.

### Changed
- Borders are now drawn with `St.Widget` and CSS colors instead of the deprecated
`Clutter.Color` API (removed in GNOME 47).
- The color picker in preferences uses `Gtk.ColorDialogButton` instead of the
deprecated `Gtk.ColorButton`.
- The preferences keyboard shortcut is now only active in normal mode
(`Shell.ActionMode.NORMAL`).
- `make install` refuses to run when the extension is installed as a symlink into
the repository, because `gnome-extensions install --force` would delete the
repository contents through the symlink.

### Fixed
- Toggling "Maximize Brightness" in preferences now takes effect immediately.
- `schemas/gschemas.compiled` is no longer tracked in the repository.

## [1] - 2025

### Added
- Initial release: adjustable white screen borders for videocall lighting, with
thickness, opacity, color, temperature, multi-monitor support, automatic screen
brightness maximization, and a panel indicator.
107 changes: 107 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Contributing to Lighter

Thanks for your interest in contributing! Lighter is a GNOME Shell extension written in
GJS (GNOME JavaScript) using ES modules, targeting GNOME 45+.

## Development setup

Build dependencies: `glib2` (for `glib-compile-schemas`) and `gettext` (for
`make pot` and for compiling translations at pack time) — on Debian/Ubuntu:
`sudo apt install gettext`.

```bash
git clone https://github.com/joaoferrete/Lighter.git
cd Lighter
make install # packs and installs the extension for your user
```

Alternatively, for a symlink-based workflow (edits picked up on shell restart):

```bash
ln -s "$PWD" ~/.local/share/gnome-shell/extensions/lighter@gnome-shell-extensions.ferrete.com
make build # compiles the GSettings schema locally
```

> **Warning:** pick ONE of the two workflows. Never run `make install` while the
> extension is installed as a symlink into your working copy —
> `gnome-extensions install --force` deletes the previous installation, and with a
> symlink that means deleting your repository's contents. `make install` detects
> this and refuses to run, but don't bypass it.

Enable it with:

```bash
gnome-extensions enable lighter@gnome-shell-extensions.ferrete.com
```

## Testing your changes

The safest way to test is a nested GNOME Shell session (Wayland):

```bash
make nested
```

Inside the nested session, enable the extension and open its preferences
(`gnome-extensions prefs lighter@...`).

On X11 you can instead reload the running shell with `Alt+F2`, type `r`, press Enter.
On Wayland (non-nested) you must log out and back in.

Watch the logs while testing:

```bash
journalctl -f -o cat /usr/bin/gnome-shell
```

And watch settings changes live:

```bash
dconf watch /org/gnome/shell/extensions/lighter/
```

## Code style

We follow the [GNOME Shell JavaScript style](https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/docs/js-coding-style.md):
4-space indent, single quotes, semicolons, `camelCase`.

Run the linter before submitting:

```bash
npm install
npm run lint
```

A few project rules:

- `preferences/` and `prefs.js` run in a GTK process: never import anything from
`resource:///org/gnome/shell/ui/*` there.
- `extension.js` and shell-side modules in `lib/` run inside the compositor: never
import `Gtk`/`Adw` there.
- `lib/colorUtils.js` and `lib/profileManager.js` are shared by both sides: keep them
free of both Shell UI and GTK imports (only `GLib`/`Gio`).
- Everything created in `enable()` must be destroyed/disconnected in `disable()`
(signals, timeouts, actors, keybindings). This is a hard requirement for
extensions.gnome.org review.
- User-visible strings must be wrapped in `_()` for translation.

## Translations

1. Regenerate the template: `make pot`
2. Create or update your language file, e.g.:
`msginit -i po/lighter.pot -o po/pt_BR.po -l pt_BR.UTF-8` (new) or
`msgmerge -U po/pt_BR.po po/lighter.pot` (update)
3. Translate the entries and open a pull request. Compiled `.mo` files are generated
automatically at pack time — do not commit them.

## Submitting changes

1. Fork and create a topic branch.
2. Make your changes, run `npm run lint`, and test in a nested session.
3. Update `CHANGELOG.md` under the *Unreleased* heading.
4. Open a pull request describing what changed and why.

## Reporting bugs

Open an issue with your GNOME Shell version (`gnome-shell --version`), the extension
version, whether you're on Wayland or X11, and any relevant `journalctl` output.
57 changes: 57 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
UUID = lighter@gnome-shell-extensions.ferrete.com
ZIP = dist/$(UUID).shell-extension.zip
EXT_DIR = $(HOME)/.local/share/gnome-shell/extensions/$(UUID)

SOURCES = extension.js prefs.js $(wildcard lib/*.js) $(wildcard preferences/*.js)

.PHONY: all build lint pot pack install uninstall nested clean

all: build

# Compile schemas for local development (a symlinked install needs this;
# `gnome-extensions install` compiles them automatically since GNOME 44)
build:
glib-compile-schemas --strict schemas/

lint:
npx eslint $(SOURCES)

pot:
mkdir -p po
xgettext --from-code=UTF-8 --keyword=_ --keyword=N_ \
--package-name=lighter --output=po/lighter.pot $(SOURCES)

pack:
mkdir -p dist
gnome-extensions pack --force --out-dir=dist \
--extra-source=lib \
--extra-source=preferences \
--extra-source=LICENSE \
--podir=po

# DANGER: `gnome-extensions install --force` deletes the existing installation
# before extracting the zip. If the installation is a symlink into this repo,
# that deletes the repo contents THROUGH the symlink. Refuse to proceed.
install: pack
@if [ -L "$(EXT_DIR)" ]; then \
echo "ERROR: $(EXT_DIR) is a symlink (likely into this repo)."; \
echo "Running 'gnome-extensions install --force' would delete the"; \
echo "symlink target's contents — i.e. this repository."; \
echo "If you use the symlink workflow, just run 'make build' and"; \
echo "restart GNOME Shell. To switch to zip installs, first run:"; \
echo " rm \"$(EXT_DIR)\""; \
exit 1; \
fi
gnome-extensions install --force $(ZIP)
@echo "Restart GNOME Shell (or log out/in on Wayland) and enable with:"
@echo " gnome-extensions enable $(UUID)"

uninstall:
gnome-extensions uninstall $(UUID)

# Run a nested GNOME Shell session for testing (Wayland)
nested:
dbus-run-session -- gnome-shell --nested --wayland

clean:
rm -rf dist schemas/gschemas.compiled
110 changes: 70 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,69 +1,99 @@
# Lighter (GNOME Extension)

![Lighter Icon](https://img.icons8.com/color/96/sun.png)
![CI](https://github.com/joaoferrete/Lighter/actions/workflows/ci.yml/badge.svg)
![GNOME 45+](https://img.shields.io/badge/GNOME-45%20%7C%2046%20%7C%2047-blue)
![License: GPL-3.0](https://img.shields.io/badge/License-GPL--3.0-green)

**Lighter** is a GNOME Shell Extension that improves your videocall lighting at night by adding adjustable white borders around your screen edges. Perfect for laptop users who need extra illumination without external gear.
**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.

<!-- TODO: add screenshots to docs/ -->
<!-- ![Borders on screen](docs/screenshot-borders.png) -->
<!-- ![Preferences window](docs/screenshot-prefs.png) -->

## Features
- **Adjustable Thickness**: From thin lines to thick light bars.
- **Customizable Color**: Full RGB color picker support (warm/cool white, or any color).
- **Opacity Control**: Adjust the brightness to your comfort level.
- **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**: Quick access to settings with `Ctrl + Alt + L`.

- **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 + L` opens the preferences.

## Requirements

- GNOME Shell 45, 46, or 47
- `glib2` (provides `glib-compile-schemas`, usually pre-installed on GNOME systems)

On Debian/Ubuntu, ensure the required packages are installed:
## Installation

### From source

```bash
sudo apt install gnome-shell-extensions glib-2.0-dev
git clone https://github.com/joaoferrete/Lighter.git
cd Lighter
make install
```

On Fedora:
Then restart GNOME Shell (log out/in on Wayland, or `Alt + F2` → `r` → `Enter` on X11)
and enable the extension:

```bash
sudo dnf install gnome-shell gnome-extensions-app glib2-devel
gnome-extensions enable lighter@gnome-shell-extensions.ferrete.com
```

## Installation & Development
## Usage

To run this extension locally:
- 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 + L` or:

### 1. Clone & Link
Clone this repository and create a symbolic link in the GNOME extensions directory:
```bash
mkdir -p ~/.local/share/gnome-shell/extensions
ln -s "$(pwd)" ~/.local/share/gnome-shell/extensions/lighter@gnome-shell-extensions.ferrete.com
```
```bash
gnome-extensions prefs lighter@gnome-shell-extensions.ferrete.com
```

### 2. Compile Schemas
The settings schema must be compiled for the extension to work:
```bash
glib-compile-schemas schemas/
```
### Profiles

### 3. Restart GNOME Shell
- **X11**: Press `Alt + F2`, type `r`, and hit `Enter`.
- **Wayland**: Log out and log back in, or restart your session.
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.

### 4. Enable the Extension
Once the shell has restarted, enable the extension:
```bash
gnome-extensions enable lighter@gnome-shell-extensions.ferrete.com
```
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.

## Development

See [CONTRIBUTING.md](CONTRIBUTING.md) for the full guide. Quick start:

### 5. Open Preferences
To configure the borders (thickness, color, etc.), open the preferences window from the GNOME Extensions app or run:
```bash
gnome-extensions prefs lighter@gnome-shell-extensions.ferrete.com
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 template
```

**Shortcut:** You can also press `Ctrl + Alt + L` at any time to open the preferences directly.

### Troubleshooting
If the extension shows as ERROR state after code changes, you must restart GNOME Shell (step 3) to reload the updated code. Check logs with:

If the extension shows an ERROR state after code changes, restart GNOME Shell to reload
the updated code. Check logs with:

```bash
journalctl /usr/bin/gnome-shell -b | grep -i lighter
```

## License

[GPL-3.0](LICENSE)
Loading
Loading