Contributing¶
Thank you for your interest in contributing! This guide covers development setup, conventions, and the pull request process.
Quick Start¶
Prerequisites:
- GNOME Shell 46, 47, 48, or 49
glib-compile-schemas(fromlibglib2.0-devor equivalent)power-profiles-daemon(for power profile features)
Note
If you already have the extension installed from extensions.gnome.org, disable and remove it first to avoid conflicts: gnome-extensions disable hara-hachi-bu@ZviBaratz
# Clone the repository
git clone https://github.com/ZviBaratz/hara-hachi-bu.git \
~/.local/share/gnome-shell/extensions/hara-hachi-bu@ZviBaratz
# Compile schemas
cd ~/.local/share/gnome-shell/extensions/hara-hachi-bu@ZviBaratz
make schemas
Mock Mode¶
Test the extension without battery hardware by enabling mock mode:
mkdir -p ~/.config/hara-hachi-bu
touch ~/.config/hara-hachi-bu/use_mock
This activates an in-memory device backend that simulates threshold and force-discharge controls. Remove the file to return to real hardware.
Development Workflow¶
Makefile Targets¶
| Target | Description |
|---|---|
make dev | Compile schemas and start a nested GNOME Shell session |
make nested | Start a nested GNOME Shell session only |
make schemas | Compile GSettings schemas |
make install | Install extension to ~/.local/share/gnome-shell/extensions/ |
make pack | Create release zip via package.sh |
make logs | Follow GNOME Shell logs (journalctl) |
make clean | Remove temporary/build files |
Testing on X11 vs Wayland¶
- X11: Reload the extension with Alt+F2 →
r→ Enter. - Wayland: JavaScript changes require a full logout and login. Disabling/enabling the extension alone does not reload code.
Viewing Logs¶
# Follow all GNOME Shell logs
make logs
# Filter for extension output
journalctl -o cat /usr/bin/gnome-shell --since "5 minutes ago" | grep -i hara-hachi-bu
Helper Script¶
Battery threshold control requires a privileged helper script. To test threshold features:
sudo ./install-helper.sh
Commit Convention¶
This project uses Conventional Commits.
Format¶
<type>(<scope>): <subject>
[optional body]
[optional footer(s)]
Types¶
| Type | Description |
|---|---|
feat | New feature or user-facing functionality |
fix | Bug fix |
refactor | Code change that neither fixes a bug nor adds a feature |
perf | Performance improvement |
style | Formatting, whitespace, missing semicolons (no logic change) |
docs | Documentation only |
chore | Build process, packaging, dependencies, tooling |
ci | CI/CD changes |
test | Adding or updating tests |
Scopes¶
| Scope | Component |
|---|---|
prefs | Preferences UI (prefs.js) |
panel | Quick Settings panel (quickSettingsPanel.js) |
state | StateManager |
power | PowerProfileController |
battery | BatteryThresholdController |
device | Device backends |
profiles | ProfileMatcher, profile management |
rules | RuleEvaluator, ParameterDetector |
helper | Helper script and utilities |
schema | GSettings schema |
i18n | Translations and internationalization |
Examples¶
feat(panel): add battery health percentage to status display
fix(battery): correct threshold write ordering for end-only devices
refactor(state): extract profile validation into separate method
chore: update metadata for GNOME 47 compatibility
docs: document multi-battery support in README
Breaking Changes¶
Append ! after the type/scope and include a BREAKING CHANGE: footer:
feat(schema)!: remove legacy profile settings
BREAKING CHANGE: Removed profile-docked and profile-travel settings.
Profiles are now stored exclusively in custom-profiles JSON format.
Architecture Overview¶
The extension follows a Controllers → StateManager → UI signal flow:
- Hardware controllers (
PowerProfileController,BatteryThresholdController) detect changes and emit signals StateManageraggregates these into a unifiedstate-changedsignal- The Quick Settings panel subscribes to
StateManagerfor UI updates
See Hardware Compatibility for device backend information.
Key Code Patterns¶
- Async
_destroyedflag: Controllers setthis._destroyed = trueat the start ofdestroy(). All async callbacks and promise chains check this flag before accessing object state. - Resource cleanup in
destroy(): Timeouts, signal connections, file monitors, and D-Bus proxies must all be cleaned up. - Threshold write ordering: When changing battery thresholds, start and end values must be written in the correct order to avoid kernel errors. See
GenericSysfsDevice.setThresholds().
Translations¶
The extension uses GNU gettext for internationalization.
Adding a New Language¶
mkdir -p po
cp hara-hachi-bu.pot po/<LANG>.po
# e.g., po/de.po for German, po/fr.po for French
Edit the .po file with a translation editor (Poedit, GNOME Translation Editor, or any text editor) and submit a pull request.
Updating the Template¶
After adding or changing translatable strings:
make pot
Commit the updated .pot alongside your code changes.
Pull Request Guidelines¶
- One logical change per PR — separate unrelated fixes into different PRs
- Follow the commit convention described above
- Test on real hardware or mock mode — mention which you used in the PR description
- Compile schemas if you changed the GSettings schema (
make schemas) - Check logs for warnings or errors after your changes (
make logs)
Issues and pull requests welcome at github.com/ZviBaratz/hara-hachi-bu.
License¶
By contributing, you agree that your contributions will be licensed under the GPL-3.0-or-later license.