Skip to content

x11: add CompositorRefreshRate setting for mixed-refresh-rate displays#34

Open
arkroyal01 wants to merge 1 commit into
Sonic-DE:masterfrom
arkroyal01:mixed-refresh
Open

x11: add CompositorRefreshRate setting for mixed-refresh-rate displays#34
arkroyal01 wants to merge 1 commit into
Sonic-DE:masterfrom
arkroyal01:mixed-refresh

Conversation

@arkroyal01
Copy link
Copy Markdown
Contributor

On mixed-refresh setups (e.g. a 60 Hz laptop panel alongside a 144 Hz external monitor) the X11 compositor previously always picked the lowest output's refresh rate to drive its single shared RenderLoop. This is the safe default — no output gets over-driven, no tearing — but it caps the higher-refresh display at 60 Hz for compositor-mediated updates, which is the wrong trade-off for many users.

Add a kwinrc setting [Compositing]CompositorRefreshRate (enum, 0 = Lowest / 1 = Highest), exposed as "Refresh rate on mixed displays" in the Compositor KCM. Default is Lowest, preserving the current safe behaviour. Switching to Highest selects the fastest output's rate at the cost of possible tearing or dropped frames on slower outputs.

The selection is backend-independent (GLX, EGL, Vulkan all share the single X11 RenderLoop) and applies on the next compositor reinit (KCM's reinit DBus signal is enough; no kwin_x11 --replace required).

The KWIN_X11_REFRESH_RATE env var and __GL_SYNC_DISPLAY_DEVICE remain higher-priority escape hatches for power users.

To make the choice observable, updateRefreshRate() now logs the applied rate and policy whenever the rate changes:

Compositor refresh rate set to 144 Hz (policy: Highest, outputs: 2)

Potential candidate for #30.

On mixed-refresh setups (e.g. a 60 Hz laptop panel alongside a 144 Hz
external monitor) the X11 compositor previously always picked the
lowest output's refresh rate to drive its single shared RenderLoop.
This is the safe default — no output gets over-driven, no tearing —
but it caps the higher-refresh display at 60 Hz for compositor-mediated
updates, which is the wrong trade-off for many users.

Add a kwinrc setting [Compositing]CompositorRefreshRate (enum, 0 =
Lowest / 1 = Highest), exposed as "Refresh rate on mixed displays" in
the Compositor KCM. Default is Lowest, preserving the current safe
behaviour. Switching to Highest selects the fastest output's rate at
the cost of possible tearing or dropped frames on slower outputs.

The selection is backend-independent (GLX, EGL, Vulkan all share the
single X11 RenderLoop) and applies on the next compositor reinit
(KCM's reinit DBus signal is enough; no kwin_x11 --replace required).

The KWIN_X11_REFRESH_RATE env var and __GL_SYNC_DISPLAY_DEVICE remain
higher-priority escape hatches for power users.

To make the choice observable, updateRefreshRate() now logs the
applied rate and policy whenever the rate changes:

  Compositor refresh rate set to 144 Hz (policy: Highest, outputs: 2)

Tested on a single-output system: log line confirms kwinrc is read,
policy field reflects the KCM toggle. End-to-end mixed-output
verification requires hardware not currently available.

Closes Sonic-DE#30.
@arkroyal01
Copy link
Copy Markdown
Contributor Author

arkroyal01 commented May 25, 2026

This is a tradeoff, let users make a choice, comes with big warning that slower of the 2 or however many outputs may misbehave (tearing, stutters, dropped frames). There's a better way to do it down the line, but let's not make users hunt for env variables.

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.

1 participant