Repository navigation
Conversation
Read the monitor layout from Hyprland with `hyprctl monitors all -j` and surface it in a new Displays tab. Each monitor reports its orientation (portrait or landscape), scale, native resolution and position, drawn to scale so rotation is visible at a glance. Assign a wallpaper per display through a per-display background service that keeps Omarchy's `background` IPC target and adds `setForScreen` and `clearForScreen` (for example the Backdrop plugin). Aether matches assignments by the serial-backed `make:model:serial` key and falls back to the connector name. Without such a service the tab still reports the layout and applies the single global wallpaper as before. Any display's wallpaper can be used as the color-extraction source, so a theme can be generated from either monitor. - internal/platform: parse hyprctl monitors, orientation, logical size - internal/omarchy: display model, key matching, per-screen IPC integration - internal/omarchy, internal/platform: unit tests for parsing and keys - frontend: Displays tab, store, thumbnails and regression tests - docs: docs/displays.md and README feature list
A per-display background service may resolve a display by its connector name rather than the serial-backed key. Backdrop stores whatever key it is given, but looks displays up serial-first then connector, so writing only the serial key left a stale connector entry winning and the wallpaper never changed. Pass the display's full key list to the service and apply the wallpaper (or clear it) for every candidate key. This keeps a display's state consistent regardless of which key the service prefers.
Wallhaven can filter by aspect ratio and exact resolution. Add both to the search params and the filter bar, and let a connected display fill them in: picking a display maps its physical resolution to the nearest wallhaven ratio (1440x2560 -> 9:16, 3440x1440 -> 21:9) and sets the exact resolution, so portrait monitors can find native portrait wallpapers. - internal/wallhaven: ratios/resolutions query params + test - frontend: aspect helpers, wallhaven store state/persistence, filter UI
…refresh - Monitors overlay the hero in the editor; clicking one elects it, which drives the existing wallpaper tools (edit, blur, eyedropper, change). - Palette source panel: Individual (extract from one monitor) or Blended (mix any subset equally). Selecting a monitor extracts immediately. - Wallhaven: choose a monitor to assign wallpapers to it and stay in the browser; the "set" state is session-only and auto-advances to the next monitor. - "Use", "apply without changing palette", and the hero's change all update the elected monitor's assignment, keeping the hero and per-display state in sync. - Equal-weight blending: every image contributes 1/N samples regardless of size. - Hyprland monitor hotplug watcher refreshes the display list live. - Remove the redundant Displays tab; the layout preview now lives in the editor.
The display picker, monitor overlay, palette-source panel, and per-monitor assignment on Use / change-wallpaper all require a background service that implements setForScreen. Gate them on the per-screen capability so Aether falls back to the original single-wallpaper behavior when only the stock renderer is present, instead of showing controls that error.
Add contrib/quickshell/background: an omarchy.background clone that keeps the stock global background, reveal transition, theme payload, and desktop double-click, and adds per-display assignments through setForScreen/clearForScreen/assignments. An output uses its assignment when it has one and the global background otherwise, so with no assignments the behavior is identical to stock. Missing assignment files fall back to the global background instead of a blank desktop. The desktop global actions (wallpaper selector and theme switcher) clear per-display assignments, so they reset every monitor to the chosen background. Wire the service into the plugin installer so per-display works with no external dependency.
- Wallhaven: a "=" / "≥" toggle next to the resolution dropdown switches between an exact resolution and "this resolution or higher". Wallhaven ignores `resolutions` when `atleast` is also sent, so only one is ever set. - Editor: the Apply theme menu's "Save as new folder" becomes "Save as new blueprint", opening the blueprint dialog instead of writing an Omarchy theme folder. Ctrl+J and the command palette follow.
With the resolution shown to the left, '<= reads this resolution or higher', matching the mathematical reading of (resolution) <= value.
Rewrite docs/displays.md for the shipped background service, the editor monitor overlay, Individual/Blended palette sources, and per-display blueprints. Note the service in the shell plugin docs and README.
…folder "Apply theme" becomes "Apply blueprint": it names a blueprint, then applies the theme, so the primary flow no longer writes into Omarchy's theme directory. The Apply menu keeps a blueprint save without applying, and Ctrl+Enter still applies only.
Apply applies the theme; the arrow menu's "Save as new blueprint…" saves without applying, so applying a loaded blueprint no longer forces a save.
Member
|
Hey, this is not what Aether is made for, Aether is made to create themes for Omarchy, not handle lifecycles like backgrounds etc. That is more the role of a settings application for Omarchy. |
Member
|
Thanks for the PR and your thoughts. Maybe you should look into building an app tweaking stuff like this? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds multi-monitor support to Aether: it reads the Hyprland layout, assigns a wallpaper per display (so a portrait monitor gets a native image instead of a crop), draws the palette from one display or an equal blend of several, and can find wallpapers for a display by aspect ratio and resolution. It ships its own per-display background service so it works with no external dependency, and falls back to the original single-wallpaper behaviour when that service isn't present.
Multiple displays
hyprctl monitors all -j: name, make/model/serial, position, scale, rotation, native resolution. Rotated outputs are treated as portrait; monitors are labelled Monitor 1, 2, … in layout order.×to clear. The hero and all its tools are preserved.The per-display background service
contrib/quickshell/backgroundis a clone ofomarchy.backgroundthat keeps the stock global background, reveal transition, theme payload, and desktop double-click, and adds:background setForScreen
background clearForScreen
background assignments
An output uses its assignment when it has one and the global background otherwise, so with no assignments the behaviour is identical to stock. It is installed by the existing plugin installer (
make install-omarchy-plugins) alongside the wallpaper/blueprint selectors. Missing assignment files fall back to the global background instead of a blank desktop.Global actions (the desktop wallpaper selector and the theme switcher) clear per-display assignments, so the chosen wallpaper/theme applies to every monitor. Aether's own per-display assignments use stable paths and are not affected.
Fallback
When no per-screen service is present, the per-display UI is hidden and Aether behaves exactly as before. Aether also works with any other service that implements the same IPC (e.g. the Backdrop plugin).
Saving / applying
The primary editor action is now Apply (apply only); Apply ▾ → Save as new blueprint… (Ctrl+J) saves one, so the default flow no longer writes into Omarchy's theme directory. (The old "save as new folder" dialog is now unreachable and can be removed in a follow-up.)
Blueprint names are now case-insensitive, matching how Omarchy lowercases theme names: saving
Cyber3andcyber3updates one blueprint instead of creating two, and deleting either removes all of its case variants. This also fixes pre-existing duplicate names that could not be deleted.Testing
go test ./internal/... ./cli/...andgo vetpass, with new tests for monitor parsing/orientation/logical size, display key matching, assignment decoding, equal-weight blending, hotplug event parsing, the wallhaven query params, blueprint displays, and case-insensitive blueprint names.npm run check: 0 errors, 0 warnings.npm test: 139 pass.Could this live in Omarchy itself?
Per-display rendering needs a per-screen background service, and Aether bundles one so the feature works today with no external dependency. But the interface is only three methods —
setForScreen,clearForScreen,assignments— on the existingbackgroundIPC target. If Omarchy's ownomarchy.backgroundadopted them, this bundled plugin would become unnecessary and per-display would work out of the box. Aether already talks to that IPC, so it would keep working unchanged.