https://github.com/torvaldz/monique
MONitor Integrated QUick Editor — graphical monitor configurator for Hyprland and Sway
https://github.com/torvaldz/monique
archlinux gtk4 hyprland linux monitor-configuration python sway wayland
Last synced: 26 days ago
JSON representation
MONitor Integrated QUick Editor — graphical monitor configurator for Hyprland and Sway
- Host: GitHub
- URL: https://github.com/torvaldz/monique
- Owner: ToRvaLDz
- License: gpl-3.0
- Created: 2026-02-19T08:19:22.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-02-22T18:06:32.000Z (29 days ago)
- Last Synced: 2026-02-25T00:17:03.267Z (27 days ago)
- Topics: archlinux, gtk4, hyprland, linux, monitor-configuration, python, sway, wayland
- Language: Python
- Size: 857 KB
- Stars: 64
- Watchers: 0
- Forks: 1
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
Monique
MONitor Integrated QUick Editor
Graphical monitor configurator for Hyprland, Sway and Niri
---
## Screenshots
Layout editor
Workspace rules
Quick setup
SDDM integration
## Features
- **Drag-and-drop layout** — arrange monitors visually on an interactive canvas
- **Multi-backend** — auto-detects Hyprland, Sway, or Niri from the environment
- **Profile system** — save, load, and switch between monitor configurations
- **Hotplug daemon** (`moniqued`) — automatically applies the best matching profile when monitors are connected or disconnected
- **Display manager integration** — syncs your layout to the login screen for SDDM (xrandr) and greetd (sway), with polkit rule for passwordless writes
- **Workspace rules** — configure workspace-to-monitor assignments (Hyprland/Sway)
- **Live preview** — OSD overlay to identify monitors (double-click)
- **Workspace migration** — automatically moves workspaces to the primary monitor when their monitor is disabled or unplugged (reverted if you click "Revert")
- **Clamshell mode** — disable the internal laptop display when external monitors are connected (manual toggle in the toolbar or automatic via daemon preferences); the daemon also monitors the lid state via UPower D-Bus
- **Confirm-or-revert** — 10-second countdown after applying, auto-reverts if display is unusable
## Installation
### AUR (Arch Linux / CachyOS)
```bash
yay -S monique
```
Or manually:
```bash
git clone https://aur.archlinux.org/monique.git
cd monique
makepkg -si
```
### PyPI
```bash
pip install monique
```
### From source
```bash
git clone https://github.com/ToRvaLDz/monique.git
cd monique
pip install .
```
**Runtime dependencies:** `python`, `python-gobject`, `gtk4`, `libadwaita`
**Optional:** `python-pyudev` (hardware hotplug detection for Niri)
## Usage
### GUI
```bash
monique
```
Open the graphical editor to arrange monitors, set resolutions, scale, rotation, and manage profiles.
### Daemon
```bash
moniqued
```
Or enable the systemd user service:
```bash
systemctl --user enable --now moniqued
```
The daemon auto-detects the active compositor and listens for monitor hotplug events. When a monitor is connected or disconnected, it waits 500ms (debounce) then applies the best matching profile. On Niri, the daemon uses udev DRM events (via `pyudev`) for reliable hardware hotplug detection. Orphaned workspaces are automatically migrated to the primary monitor on Hyprland/Sway (configurable via **Preferences > Migrate workspaces**).
#### Clamshell mode
On laptops, the daemon can automatically disable the internal display when external monitors are connected. Enable it from the GUI: **Menu > Preferences > Clamshell Mode**.
The daemon also monitors the laptop lid state via UPower D-Bus: closing the lid disables the internal display, opening it re-enables it. On desktop PCs (no lid detected), clamshell mode simply disables any internal-type output (`eDP`, `LVDS`) whenever external monitors are present.
> **Note:** if your system suspends on lid close, set `HandleLidSwitch=ignore` in `/etc/systemd/logind.conf` so the daemon can handle it instead.
### Behavior per environment
| Environment | Detection | Events |
|---|---|---|
| Hyprland | `$HYPRLAND_INSTANCE_SIGNATURE` | `monitoradded` / `monitorremoved` via socket2 |
| Sway | `$SWAYSOCK` | `output` events via i3-ipc subscribe |
| Niri | `$NIRI_SOCKET` | udev DRM subsystem (with `pyudev`), IPC fallback |
| Neither | Warning, retry every 5s | — |
## Display manager integration
Monique can sync your monitor layout to the login screen for supported display managers.
| Display Manager | Method | Config path |
|---|---|---|
| SDDM | xrandr via `Xsetup` script | `/usr/share/sddm/scripts/Xsetup` |
| greetd (sway) | sway `output` commands | `/etc/greetd/monique-monitors.conf` |
A polkit rule is included to allow passwordless writes:
```bash
# Installed automatically by the PKGBUILD to:
# /usr/share/polkit-1/rules.d/60-com.github.monique.rules
```
Toggle from the GUI: **Menu > Preferences > Update SDDM Xsetup** or **Update greetd config**.
## Configuration
All configuration is stored in `~/.config/monique/`:
```
~/.config/monique/
├── profiles/
│ ├── Home.json
│ └── Office.json
└── settings.json
```
Monitor config files are written to the compositor's config directory:
- **Hyprland:** `~/.config/hypr/monitors.conf`
- **Sway:** `~/.config/sway/monitors.conf`
- **Niri:** `~/.config/niri/monitors.kdl`
## Project structure
```
src/monique/
├── app.py # Application entry point
├── window.py # Main GTK4/Adwaita window
├── canvas.py # Monitor layout canvas
├── properties_panel.py # Monitor properties sidebar
├── workspace_panel.py # Workspace rules dialog
├── models.py # MonitorConfig, Profile, WorkspaceRule
├── hyprland.py # Hyprland IPC client
├── sway.py # Sway IPC client (binary i3-ipc)
├── niri.py # Niri IPC client (JSON socket)
├── daemon.py # Hotplug daemon (moniqued)
├── profile_manager.py # Profile save/load/match
└── utils.py # Paths, file I/O, helpers
```
## License
[GPL-3.0-or-later](LICENSE)