Processing Ajax...

Title

Message

Confirm

Confirm

Confirm

Confirm

Are you sure you want to delete this item?

Confirm

Are you sure you want to delete this item?

User Image
Derek Ziemba
4 discussion posts
I can't recall this being an issue prior to DisplayFusion Pro 11.0 Beta, but it's been a problem for multiple betas now.

The function "Cycle Left to Unoccupied Position" is a function I submitted some time ago & have been running for years. It splits horizontal monitors to 4 quadrants & vertical monitors to top and bottom quadrants. When choosing the next quadrant to cycle to it first checks if there's already an instance of the same program occupying that area, and if so, move on to the next.

My monitor configuration and quadrants is like so:
https://i.imgur.com/pj19zyZ.png


It has recently, I believe with the beta, become problematic.

As far as I can tell & what I believe is happening, is some change made things slow. SO now when it's rapidly called to move a window serveral positions, it's being invoked before the prior invocation has exited, & they end up fighting.
The action was once instantaneous so I would rarely, if ever, experience this issue. With that no longer the case, an attempt to cycle a window across all 4 monitors causes the window to throw an epileptic fit. To move a window furthest monitor left to furthest right requires 3 invocations if maximized, otherwise takes 5-9 invocations. However because the function has wrap around, a variant to cycle the opposite direction, and cycles maximized windows by monitor instead of quadrant, typically only 2-4 invocations are needed to position windows where needed.

Either whatever slowed down needs fixing, or a guard preventing concurrent invocations of a function on the same window.

Screen capture of the issue:
https://i.imgur.com/UPBaNEV.gif

Same thing except mp4 & uploaded to you guys instead of imgur:
https://www.displayfusion.com/Discussions/Download/?ID=018f8128-d65e-7662-bc33-1617cb2e7275


Also FYI, often I'll find 1 or two instances of the function in the system tray that are stuck running. Not sure what condition would cause them to continuously run. These stuck "running" instances don't appear to effect anything.
• Attachment: GuardAgainstMultpleInvocations1.mp4 [3,885,290 bytes]
May 16, 2024 (modified May 16, 2024)  • #1
Owen Muhlethaler (BFS)'s profile on WallpaperFusion.com
I was able to reproduce that here so I've added it to our list to look into.

Thanks!
May 17, 2024  • #2
User Image
Derek Ziemba
4 discussion posts
I didn't originally realize I could have state between calls. Thought the scripts were actually scripts & invoked in a sandbox or something.

In the meantime, since learning the static variables are stateful, I've added a queue + some caching to fix it.

Code

private static bool isBusy = false;
private static Queue<IntPtr> pendingHandles = new Queue<IntPtr>();

public static void Run(IntPtr windowHandle) {
    pendingHandles.Enqueue(windowHandle);
    if (isBusy) { return; }

    isBusy = true;

    if (Cache == null || Cache.MonitorCount != BFS.Monitor.GetMonitorCountEnabled()) {
        ResetCache();
    }

    while (pendingHandles.TryDequeue(out nint handle)) {
        try {
            ExecAction(handle);
        }
        catch (Exception e)
        {
            BFS.Audio.PlayWAV("U:\\Sounds\\notifications-wav\\Windows - Default Beep.wav");
            ResetCache();
        }
    }
    isBusy = false;
}

record CachedData(int MonitorCount, Rectangle PrimaryArea, Rectangle[] WorkAreas, Rectangle[][] SubAreas, Rectangle[] SubDivisions);

private static CachedData Cache = null;

private static void ResetCache() {
    int count = BFS.Monitor.GetMonitorCountEnabled();
    var primary = BFS.Monitor.GetPrimaryMonitorWorkArea();
    var workAreas = BFS.Monitor.GetMonitorWorkAreas();
    if (CycleLeft) { Array.Reverse(workAreas); }
    var subareas = workAreas.Select(static x => x.GetSubdivisions()).ToArray();
    var subdivs = subareas.SelectMany(static x => x).ToArray();
    Cache = new CachedData(count, primary, workAreas, subareas, subdivs);
}

It's made it painfully obvious how slow something has gotten though.
Takes almost a second (probably closer to 750ms) or so to move one spot.
May 24, 2024 (modified May 24, 2024)  • #3
Owen Muhlethaler (BFS)'s profile on WallpaperFusion.com
I spoke with our developers about this. We've adjusted the way DisplayFusion handles functions, and they run much faster now which is why it's overlapping, so this is working as it's supposed to.

Adding a delay like you did should help, and this might as well: https://www.displayfusion.com/ScriptedFunctions/Help/#bfsGeneralCountRunningFunctions. You can check to see if that function is running, and if it's greater then 1, then close it.
Jun 26, 2024  • #4
Subscribe to this discussion topic using RSS
Was this helpful?  Login to Vote(-)  Login to Vote(-)