|
In v26.8 I have been doing a fairly deep overhaul of the monitor-profile handling code because of reports of docks and Shelves occasionally ending up in the wrong place after startup or after resuming from sleep/hibernation.
The first step was to harden the existing display-change handling itself.
Windows can generate a lot of display-related activity during startup, resume, monitor connection/disconnection, DPI changes and resolution changes. Several notifications can arrive in rapid succession while the display subsystem is still settling, so I tightened the code to make the whole process much more resistant to re-entrancy, overlapping timers and partially processed display changes.
The display-change path now serializes processing more carefully, avoids entering the same logic again while a previous change is still being handled, debounces successive notifications, and performs an additional validation pass afterwards in case Windows changed the monitor configuration again while the first pass was still being processed.
The idea was to make sure that each monitor transition is handled as one coherent operation rather than several overlapping ones fighting with each other.
That significantly reduced the number of possible race conditions, and an issue that occasionally also happened here when returning from sleep never happened again, but it still left one uncomfortable possibility: during startup or resume and depending on hardware, Windows can briefly expose an intermediate monitor configuration, resolution or DPI before finally settling on the real one. WorkShelf may correctly end up with the final monitor configuration in memory, yet a dock or Shelf may already have been repositioned while the temporary configuration was active and the final monitor profile may, for whatever timing reason, never have been re-applied.
At that point there is nothing obviously wrong with the monitor collection itself - WorkShelf and Windows agree on the current monitor configuration - but the objects on screen may still be carrying geometry inherited from an earlier transient state.
That is why I just added a delayed monitor-profile reconciliation check.
About 30 seconds after startup, and again after resuming from sleep or hibernation, WorkShelf performs a one-shot sanity check after Windows has had plenty of time to settle.
The reconciliation first compares the monitor configuration Windows is actually reporting at that moment with the configuration currently stored internally by WorkShelf. If those differ, WorkShelf treats it as a missed or incomplete display change and sends it back through the normal WM_DISPLAYCHANGE processing path.
If the monitor configurations already agree, the reconciler can then check whether the appropriate monitor profile still needs to be re-applied.
A user today reported that two floating Shelves were not only being moved after reboot, but also being shrunk. That exposed a separate omission in the monitor-profile format: although Shelf positions were being saved, the user-defined Shelf length was not.
That meant that if Windows temporarily reported a smaller desktop and WorkShelf shortened a floating Shelf so that it would fit, restoring the monitor profile could put the Shelf back in the correct position but would not restore its original size.
Monitor profiles now also save the Shelf size. Older profiles remain fully compatible - if the new Size entry does not exist, it is simply ignored.
The reconciliation itself also had to be made conservative.
A monitor profile is not necessarily an exact frozen copy of the current desktop at every instant. Legitimate things can move docked objects slightly. For example, stopping NextSTART removes its reserved taskbar area and can move bottom-docked objects by 40 pixels or more even though nothing is wrong with the monitor configuration.
So reconciliation does not treat every one-pixel difference as a failure. Position and Shelf-size changes must exceed a threshold of 148 pixels before they are considered suspicious enough to justify restoring the profile, as this will move all objects back the position and size they were when the profile was saved. Changes to actual object state, such as docking mode or orientation, remain significant immediately.
The threshold is intentionally large because the failures this mechanism is intended to catch are usually visually obvious - objects being shifted because Windows briefly reported a fallback resolution, another monitor arrangement or another DPI state. Those errors normally produce differences of hundreds or thousands of pixels, not a few dozen.
There are also a couple of safety conditions around the delayed check. If the user interacts with a dock or Shelf before the timer fires, the reconciliation is cancelled, because an explicit user change takes priority over the saved startup/resume state. Likewise, if a fullscreen game is already running when the check fires, reconciliation is skipped because the game itself may have changed the display mode.
If reconciliation actually restores a WorkShelf monitor profile, the desktop modules are also repositioned from the same profile and then validated against the current monitor layout. This prevents the docks and Shelves from being corrected while desktop modules remain at coordinates inherited from a temporary display state.
While tracing all of this I also found a separate, much older monitor-profile problem.
Nexus, Nexus Ultimate and WorkShelf were all generating the same profile filename for the same monitor configuration. The filename depended on monitor geometry and DPI, but not on which Winstep application had created it.
That meant Nexus could inherit a profile last written by WorkShelf, Ultimate could subsequently overwrite it with its own dock list, and so on. Unique dock and shelf ID names prevented this from turning into an outright disaster, but the applications clearly should not have been sharing the same object profile.
Monitor-profile filenames are therefore now application-aware as well:
NX...ini - Nexus UT...ini - Nexus Ultimate WX...ini - WorkShelf / Winstep Xtreme
Backward compatibility is handled automatically. If a new application-specific profile does not yet exist, Winstep first looks for the previous DPI-aware shared profile and, failing that, the much older non-DPI-aware profile. If one exists, the complete INI is copied to the new application-specific filename.
Copying the complete file is important because these profiles can contain more than just dock and Shelf coordinates. WorkShelf profiles can also contain theme-specific desktop-module positions and other settings which must not be lost during migration.
The old shared profile is left untouched, while each application subsequently updates its own independent NX, UT or WX copy.
During this work I also found that the old compatibility check itself had a bug: some existence checks were being made against the profile filename alone instead of the full ...\Profiles\ path. Depending on the current working directory, that meant legacy-profile fallback could silently fail. That has now been corrected too.
If this doesn't finally put an end to these issues, I sincerely don't know what more I can do.
_________________ Jorge Coelho Winstep Xtreme - Xtreme Power! https://www.winstep.net - Winstep Software Technologies
|