Patch Electron and Chrome applications on macOS to use OpenGL rendering through the use-angle@1 setting.
- 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
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 initUsing 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.shThe setup script will:
- Check Python version (requires 3.10+)
- Optionally install uv for faster setup
- Create virtual environment
- Install dependencies
- Offer to run tests
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]"pip install electron-angle-patcher# 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# 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.apppython -m electron_angle_patcher.cli --list-onlyThis 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 ruffUsing 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 fmtelectron-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
# 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"# Format code with ruff
make fmt
# Check linting
make lint
# Run type checking
make typecheck
# Run all checks
make check# 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-depsFor 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 ciThe 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
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-onlyBinary 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| 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 |
The patcher searches for Chromium/Electron applications in the following locations:
~/Library/Application Support~/Library/Caches~/Library/Preferences~/Library/Containers
The following apps are handled specifically:
- Logitech G Hub (Standard, Main Container, Helper)
- Microsoft Teams (Classic and New)
- Microsoft Edge
- Brave Browser (executable wrapping)
The following directories are skipped during scanning:
.Trashnode_modulesLibrary/DeveloperLibrary/Caches/HomebrewLibrary/Logs- Network-mounted volumes
For most apps, the patcher modifies the Local State file to add:
{
"browser": {
"enabled_labs_experiments": [
"use-angle@1"
]
}
}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 "$@"- Python 3.10 or higher
- macOS (Darwin)
codesigncommand (for re-signing apps, optional)xattrcommand (for stripping attributes, optional)
MIT License
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
Run the script with sudo:
sudo python -m electron_angle_patcher.cliUse --list-only to see what apps are detected, or use --app-path to target a specific app.
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)