Skip to content

setMode() does not change refresh rate on Windows #17

Description

@rodiaua

Description

On Windows, calling Monitor.setMode() with a DisplayMode that has a different
refresh rate changes nothing. ChangeDisplaySettingsEx returns DISP_CHANGE_SUCCESSFUL (0),
but the monitor keeps its previous frequency.

Steps to reproduce

import pymonctl as pmc

mon = pmc.getPrimary()
print("current:", mon.mode)
print("available:", mon.allModes)

# pick a mode with the same resolution but a different frequency
target = next(m for m in mon.allModes
              if (m.width, m.height) == (mon.mode.width, mon.mode.height)
              and m.frequency != mon.mode.frequency)
mon.setMode(target)
print("after:", mon.mode)   # frequency is unchanged

Expected: the refresh rate changes to target.frequency.
Actual: the resolution is applied (if different), but the refresh rate stays the same.

Environment

  • OS: Windows 11 Pro 25H2 / 26200.9457
  • Python: 3.14.5
  • PyMonCtl: 0.92
  • pywin32: 312

Cause

In src/pymonctl/_pymonctl_win.py, setMode() sets devmode.DisplayFrequency, but
devmode.Fields doesn't include DM_DISPLAYFREQUENCY. Windows only reads the DEVMODE
members whose flags are set in Fields, so the frequency is ignored.

Proposed fix

-            devmode.Fields = win32con.DM_PELSWIDTH | win32con.DM_PELSHEIGHT
+            devmode.Fields = win32con.DM_PELSWIDTH | win32con.DM_PELSHEIGHT | win32con.DM_DISPLAYFREQUENCY

I've tested this fix locally and will open a PR.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions