Skip to content

feat(config): configurable monitor config filename - #46

Merged
ToRvaLDz merged 2 commits into
mainfrom
feat/configurable-monitor-config-filename
Aug 2, 2026
Merged

feat(config): configurable monitor config filename#46
ToRvaLDz merged 2 commits into
mainfrom
feat/configurable-monitor-config-filename

Conversation

@ToRvaLDz

@ToRvaLDz ToRvaLDz commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Closes #40.

Summary

The generated monitor config filename was hardcoded per compositor (monitors.kdl / monitors.conf / monitors.lua). This adds a single monitor_config_name setting: a base name without extension, relative to the compositor's config directory, that drives all three backends. Each backend appends its own extension.

Example with monitor_config_name = "cfg/display":

Compositor File(s) written
Niri ~/.config/niri/cfg/display.kdl
Sway ~/.config/sway/cfg/display.conf
Hyprland ~/.config/hypr/cfg/display.conf and/or cfg/display.lua

The default is monitors, reproducing the historical filenames, so existing setups are untouched after upgrading.

Design

Per the discussion on #40, this is one setting covering Niri, Hyprland and Sway rather than a Niri-only option, with the value taken as a path relative to the compositor config directory.

  • Validation (utils.sanitize_monitor_config_name): rejects absolute paths and .. traversal, normalizes separators, drops a mistakenly typed known extension (display.kdl won't become display.kdl.conf), and falls back to the default on invalid input. Subdirectories are supported and created on write.
  • Single source of truth: filename resolution lives in config_paths / hypr_config, which the GUI already uses for backup/revert, so the written files and the backed-up files can't diverge.
  • Niri include sync: the include line in config.kdl uses the configured name. On a rename, the stale Monique-managed include is swapped out (matched via the // Monique monitor configuration marker) so Niri never applies two conflicting layouts — while user include lines and user-added output blocks are preserved. Output-block stripping still only happens on a true first run.

UI

New "Monitor config filename (no extension)" row in Preferences → Config Output; its subtitle previews the effective filenames.

Tests

tests/test_config_name.py (22 tests): sanitize rules, propagation to all three backends, back-compat with the historical names, and the Niri include cases (first run, rename swap, user-managed include, user output blocks preserved). Full suite: 133 passed.

Notes

  • Renaming on Hyprland still requires updating your source / require lines by hand (documented in the README), same as the existing config-format switch.
  • The privileged greetd path (/etc/greetd/monique-monitors.conf) is intentionally out of scope.

Closes #40. The monitor config filename was hardcoded per compositor
(monitors.kdl / monitors.conf / monitors.lua). Add a single
`monitor_config_name` setting — a base name without extension, relative
to the compositor config directory — that drives all three backends;
each appends its own extension.

- utils: `sanitize_monitor_config_name` (reject absolute paths and `..`
  traversal, normalize separators, strip a mistakenly typed known
  extension, fall back to the default) and `get_monitor_config_name`
- config_paths / hypr_config: resolve filenames from the setting, keeping
  config_paths the single source of truth used for backup/revert
- niri/sway/hyprland: cross-writes go through the shared paths; the Niri
  `include` line in config.kdl stays in sync with the configured name,
  and a stale Monique-managed include is swapped out on rename without
  touching user includes or user-added output blocks
- window: "Monitor config filename" row in Preferences → Config Output
- Subdirectories are supported (e.g. `cfg/display`); the default
  `monitors` reproduces the historical filenames, so existing setups are
  untouched
- tests: sanitize rules, path propagation to all backends, back-compat,
  and Niri include first-run / rename / user-managed cases
- README: document the new setting
Adw.EntryRow has no subtitle, so the config-name change handler would
raise AttributeError the moment the user typed in the field. Move the
live filename preview to the row tooltip (EntryRow supports
set_tooltip_text) and state in the Config Output group description that
the filename is a base name relative to the compositor's config
directory.
@ToRvaLDz
ToRvaLDz force-pushed the feat/configurable-monitor-config-filename branch from 7d1e5c8 to b454b59 Compare August 2, 2026 08:26
@ToRvaLDz
ToRvaLDz merged commit 616271a into main Aug 2, 2026
10 checks passed
@ToRvaLDz
ToRvaLDz deleted the feat/configurable-monitor-config-filename branch August 2, 2026 08:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add the config output option (add output filename instead of hardcode monitors.kdl)

1 participant