Add a refresh-rate picker to the display panel - #10195
Open
kidskript3 wants to merge 2 commits into
Open
Conversation
The rows called `hyprctl keyword monitor <name>,disable`, which the
non-legacy Lua parser refuses ("keyword can't work with non-legacy
parsers. Use eval.") while hyprctl still exits 0, so nothing surfaced and
the display never toggled.
Switch the toggle to `hyprctl eval` and spell out `disabled = false` when
an output comes back; restating a mode alone returns ok and leaves an
already-disabled output off.
Coming back on also has to land where it was. Scale and position can only
be read dependably while an output is on, and "auto" for both re-places
the display and drops a scaled one to 1, so `omarchy-monitor-state` now
carries each display's scale and position and the panel remembers the last
values it saw while an output was on.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A monitor comes up at the rate it reports as preferred, which on plenty of high-refresh panels is 60Hz. Raising it meant hand-editing monitors.lua and knowing the mode syntax — a barrier for the people who need it most, since low refresh rates make some viewers motion sick. Add a REFRESH section below SCALE listing the rates the focused monitor offers at its current resolution, and a companion CLI shaped like omarchy-hyprland-monitor-scaling. The panel defers to the CLI the way it already does for scaling, so the rate is applied and persisted in one place. Persisting keeps the output's own rule if it has one, rewriting only its mode; otherwise it appends a rule that inherits omarchy_monitor_scale, so monitor scaling keeps reaching that output afterwards. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Builds on #10194 — that branch is the base, so the diff here is only the refresh work once #10194 lands.
Why
Low refresh rates are not only a smoothness preference. For people who get cyber sickness or simulator sickness, a panel running at 60Hz when the hardware can do 144 or 240 means nausea and headaches within minutes of use. It is the same mechanism that makes a VR headset or a shaky camera unpleasant, and it does not go away by getting used to it.
A monitor comes up at whatever rate it reports as preferred, and on plenty of high-refresh panels that is 60Hz. Raising it today means opening
~/.config/hypr/monitors.lua, knowing thatmodetakes aWIDTHxHEIGHT@RATEstring, and knowing which rates the monitor actually offers. That is a barrier in front of exactly the people who most need the setting.So this puts the rate one click away, next to the scale control that already lives there.
The panel with the new REFRESH row — this laptop's built-in display supports 240 Hz and was running at 60.
What it adds
A REFRESH section in the display panel, below SCALE and built the same way: the rates the focused monitor offers at its current resolution, highest first, with the active one marked. It appears only when there is more than one rate to choose from, so single-rate displays see no change. Keyboard navigation matches SCALE —
h/lwalks the row, Enter applies.omarchy hyprland monitor refresh, a companion toomarchy-hyprland-monitor-scalingand shaped like it:The panel defers to the CLI the way
setScalealready defers to the scaling command, so applying and persisting live in one place.Notes on the details
143.979where the mode string says144; the spec sheet and the user both say 144.position = "auto"to re-derive and no reason to make the other displays jump.moderewritten, so a hand-written position or transform survives. An output with no rule gets one appended that inheritsomarchy_monitor_scalewhere the file still defines it — otherwise a lateromarchy hyprland monitor scalingwould stop reaching that output. Setting a second rate rewrites that rule instead of stacking another one, and commented example lines are left alone.omarchy-monitor-statecarriesrefreshRateandavailableModesper display, so the panel needs no secondhyprctlprocess. Filtering and rounding are pure functions inModel.js.Tests
test/shell.d/monitor-refresh-test.sh(new, modelled onmonitor-scaling-test.sh) — reporting, listing, refusing a rate the resolution has no mode for, applying in place, appending a rule, rewriting it instead of stacking, leaving commented examples alone, and preserving a user-written rule's other fields.test/shell.d/monitor-test.sh—availableRatesandactiveRate, including duplicate rates that round to the same number and a display with no mode list.test/shell.d/monitor-state-test.sh— fixtures and expectations extended.test/shell: the only failures are the ones that fail identically on an unmodified checkout on this host (bar-icon-geometry,config,snapper,unowned-system-paths, andruntime-smokewhenever two displays are attached).Verified on hardware
Alienware m15 R7 with an external 5120x1440 ultrawide on DP-1 at scale 1.25, Hyprland 0.56.2:
Scale and position survive the change,
hyprctl configerrorsstays empty, and the persisted rule was rewritten rather than duplicated on the second call. In the panel the four pills (144 / 100 / 85 / 72) fit the section width without clipping, and the active one is marked.Also
manual/33-monitors.mdgains a short "Refresh rate" section, including the motion-sickness note — it is the part users are least likely to guess on their own.🤖 Generated with Claude Code