Electron Angle Patcher
Patch Electron and Chrome applications on macOS to use OpenGL rendering through the use-angle@1 setting.
Features
- macOS Optimized: Designed specifically for macOS Electron applications
- Auto-Discovery: Automatically finds apps in standard locations
- Deep Scanning: Recursively searches directories comprehensively
- Special App Support: Handles complex apps (Logitech G Hub, Teams, Brave)
- Executable Wrapping: Modifies executables to pass
--use-angle=gl - Network Mount Protection: Avoids scanning network-mounted volumes
Installation
Quick Start (Recommended)
Using uv (fast, 10-100x faster than pip):
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Clone and setup
git clone https://github.com/martin-juul/electron-angle-patcher.git
cd electron-angle-patcher
make init
Using venv (standard, built-in):
git clone https://github.com/martin-juul/electron-angle-patcher.git
cd electron-angle-patcher
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
Using the setup script (interactive):
git clone https://github.com/martin-juul/electron-angle-patcher.git
cd electron-angle-patcher
./scripts/setup.sh
The setup script will:
- Check Python version (requires 3.10+)
- Optionally install uv for faster setup
- Create virtual environment
- Install dependencies
- Offer to run tests
From Source (Manual)
git clone https://github.com/martin-juul/electron-angle-patcher.git
cd electron-angle-patcher
# Option 1: With uv (fast)
uv venv
uv pip install -e ".[dev]"
# Option 2: With venv (standard)
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
Using pip (when published)
pip install electron-angle-patcher
Usage
Basic Usage
# Patch all detected applications
electron-angle-patcher
# List applications without patching
electron-angle-patcher --list-only
# Dry run: show what would be patched without making changes
electron-angle-patcher --dry-run
# Perform deep scan of home directory
electron-angle-patcher --deep-scan
# Enable verbose output
electron-angle-patcher -v
Advanced Usage
# Patch a specific application
electron-angle-patcher --app-path ~/Library/Application\ Support/MyApp/Local\ State --app-name "My App"
# Scan a custom directory
electron-angle-patcher --scan-dir ~/path/to/apps
# Specify custom Brave Browser path
electron-angle-patcher --brave-path ~/Applications/Brave\ Browser.app
# Specify custom lghub path
electron-angle-patcher --lghub-path ~/Applications/lghub.app
Running as Module
python -m electron_angle_patcher.cli --list-only
Development
Environment Management
This project supports uv (fast, recommended) or venv (standard).
Why uv?
- 10-100x faster than pip
- Better dependency resolution
- Built-in lockfile support
- From the creators of Ruff (which we also use)
Using uv (recommended):
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# All make commands auto-detect and use uv if available
make init # Set up environment with uv
make test # Run tests with uv
make fmt # Format with uv run ruff
Using venv (fallback):
# Standard setup
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
# Make commands auto-detect and use venv if uv is not available
make test
make fmt
Project Structure
electron-angle-patcher/
├── src/
│ └── electron_angle_patcher/
│ ├── __init__.py # Public API exports
│ ├── app.py # Main orchestrator (ElectronAnglePatcher)
│ ├── cli.py # Command-line interface
│ ├── config.py # Configuration constants
│ ├── models.py # Data models (enums, dataclasses)
│ ├── utils.py # Utility functions
│ ├── executable_patcher.py # Executable wrapping logic
│ ├── settings_patcher.py # Local State file patching
│ └── scanner.py # Directory scanning logic
├── tests/
│ ├── conftest.py # Pytest configuration
│ ├── unit/ # Unit tests
│ └── sandbox/ # Test fixtures
├── scripts/
│ └── setup.sh # Interactive setup script
├── pyproject.toml # Project configuration
├── Makefile # Common tasks (auto-detects uv)
└── README.md
Module Overview:
__init__.py- Public API exports, maintains backward compatibilityapp.py-ElectronAnglePatchermain application classcli.py- Command-line interface using argparseconfig.py-Configclass with all constants and settingsmodels.py-AngleVariant,PatchResultenums;AppInfo,PatchSummarydataclassesutils.py- Helper functions (logging, permissions, file operations)executable_patcher.py-ExecutableWrapper,BraveExecutablePatcher,LghubPatchersettings_patcher.py-ChromiumSettingsPatcherfor Local State filesscanner.py-LocalStateScannerfor finding applications
Running Tests
# Run all tests
make test
# Run with coverage
make test-cov
# Run specific test file
pytest tests/unit/test_config.py
# Run with verbose output
pytest -v
# Run only unit tests
pytest -m unit
# Skip slow tests
pytest -m "not slow"
Code Quality
# Format code with ruff
make fmt
# Check linting
make lint
# Run type checking
make typecheck
# Run all checks
make check
Building and Installing
# Build Python package (wheel/source)
make build
# Build standalone binary (single executable)
make build-binary
# Build single-file binary (smaller, slower startup)
make build-binary-onefile
# Install locally
make install
# Install in development mode
make dev-install
# Generate/update lockfile (uv only)
make lock
# Update all dependencies (uv only)
make update-deps
CI Pipeline
For continuous integration or automated builds, use the CI target:
# Run complete CI pipeline:
# 1. Install dependencies (creates venv if needed)
# 2. Run all tests
# 3. Build standalone binary
make ci
The CI target:
- Auto-detects and uses
uvif available, otherwise falls back tovenv - Creates a virtual environment if it doesn't exist
- Installs all dependencies
- Runs the test suite
- Builds the standalone binary
- Reports success/failure at each step
Building Standalone Binaries
This project can be compiled into a standalone binary that doesn't require Python installation:
# Option 1: Directory-based binary (faster startup)
make build-binary
# Output: dist/electron-angle-patcher
# Option 2: Single-file binary (smaller, slower startup)
make build-binary-onefile
# Output: dist/electron-angle-patcher
# Run the binary directly
./dist/electron-angle-patcher --help
./dist/electron-angle-patcher --list-only
Binary Features:
- Self-contained: No Python or dependencies required
- macOS optimized: Creates native macOS executables
- Code signed: Uses ad-hoc signature for macOS
- Smaller size: Only includes required dependencies
Building Manually with PyInstaller:
# Install PyInstaller
pip install pyinstaller
# Build using spec file (recommended)
pyinstaller electron_angle_patcher.spec
# Or build single-file directly
pyinstaller --onefile --name electron-angle-patcher \
--console src/electron_angle_patcher/cli.py
Make Targets
| Target | Description |
|---|---|
make help |
Show all available commands |
make init |
Initialize dev environment (auto-detects uv) |
make install-uv |
Install uv package manager |
make ci |
CI pipeline: install deps, run tests, build |
make build |
Build Python package |
make build-binary |
Build standalone binary |
make build-binary-onefile |
Build single-file binary |
make test |
Run all tests |
make test-cov |
Run with coverage report |
make fmt |
Format code with ruff |
make lint |
Check code with ruff |
make typecheck |
Run mypy type checking |
make check |
Run all quality checks |
make run |
Run the patcher |
make run-list |
Run in list-only mode |
Configuration
The patcher searches for Chromium/Electron applications in the following locations:
Standard Directories
~/Library/Application Support~/Library/Caches~/Library/Preferences~/Library/Containers
Specific Apps
The following apps are handled specifically:
- Logitech G Hub (Standard, Main Container, Helper)
- Microsoft Teams (Classic and New)
- Microsoft Edge
- Brave Browser (executable wrapping)
Skipped Directories
The following directories are skipped during scanning:
.Trashnode_modulesLibrary/DeveloperLibrary/Caches/HomebrewLibrary/Logs- Network-mounted volumes
How It Works
Settings Patching
For most apps, the patcher modifies the Local State file to add:
{
"browser": {
"enabled_labs_experiments": [
"use-angle@1"
]
}
}
Executable Wrapping
For apps like Brave Browser and lghub, the patcher wraps the executable to pass the --use-angle=gl argument at runtime.
The original executable is backed up as <name>.original and replaced with a shell script:
#!/bin/bash
DIR="$(cd "$(dirname "$0")" && pwd)"
exec "$DIR/<name>.original" --use-angle=gl "$@"
Requirements
- Python 3.10 or higher
- macOS (Darwin)
codesigncommand (for re-signing apps, optional)xattrcommand (for stripping attributes, optional)
License
MIT License
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Run
make checkto ensure quality - Submit a pull request
Troubleshooting
"Cannot write to app" Error
Run the script with sudo:
sudo python -m electron_angle_patcher.cli
App Not Detected
Use --list-only to see what apps are detected, or use --app-path to target a specific app.
Changes Not Taking Effect
Some apps may need to be restarted for changes to take effect. Try:
- Quit the app completely
- Re-launch the app
- Check the flag is active (use
chrome://flagsin Chrome-based apps)
Metadata
Release files for electron-angle-patcher 2026.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| electron_angle_patcher-2026.0.2.tar.gz | 100.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| electron_angle_patcher-2026.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 121.2 kB
Release files / electron_angle_patcher-2026.0.2.tar.gz
| Download URL | electron_angle_patcher-2026.0.2.tar.gz |
|---|---|
| Size | 100.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
74ce5a07be7ab0e85b4cce185c2b400d716108a0fb8098447036bd091745e66e
|
|
BLAKE2b-256 checksum How to use checksums |
f3db8a80ae2c6e1ec572da4df9764a5b3bd8f8e0e62fc3e2a78873196083eae0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.12
|
Release files / electron_angle_patcher-2026.0.2-py3-none-any.whl
| Download URL | electron_angle_patcher-2026.0.2-py3-none-any.whl |
|---|---|
| Size | 20.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5adcc300d794c49ce3df8b89ccd52ab8b69d34b4ccaa60589e7a9770ab90f9a8
|
|
BLAKE2b-256 checksum How to use checksums |
b536490ad293f0c5881f935ae87adeb208ed16bd850a3273007b0c81c85068ed
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.12
|
Security for electron-angle-patcher 2026.0.2
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.