Last active
January 16, 2024 13:20
-
-
Save noamnotyou/afc7240d2d0b442ec8c624c988eac822 to your computer and use it in GitHub Desktop.
Custom function for DisplayFusion that will move your cursor to the same relative position in the next or previous monitor (e.g. center of monitor 1 to center of monitor 2). Works with any mix of monitors. Workaround for mouse cursor snagging on monitors with different resolutions or not moving to the right position.
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
using System; | |
using System.Drawing; | |
// Note: this won't work if "lock cursor to current monitor" is enabled, so if like me you don't like having the mouse go to next monitor when you're trying to | |
// click a corner or edge, you can align the monitors diagonally and only use hotkeys to move the mouse between monitors. | |
// Made by Noam Schvetz (noamnotyou) | |
public static class DisplayFusionFunction { | |
// If you have more than 2 monitors and so want a 'previous' hotkey as well, simply use this script twice and change the value of | |
// 'isForwardDirection' to 'false' in one of them which will make it go backwards. | |
static bool isForwardDirection = false; | |
public static void Run(IntPtr windowHandle) { | |
// Get current mouse coordinates | |
int mouseX = BFS.Input.GetMousePositionX(); | |
int mouseY = BFS.Input.GetMousePositionY(); | |
// Get monitor mouse is currently in and its bounds, get all available monitors' IDs | |
uint currentMonitorID = BFS.Monitor.GetMonitorIDByXY(mouseX, mouseY); | |
Rectangle currentMonitorBounds = BFS.Monitor.GetMonitorBoundsByID(currentMonitorID); | |
uint[] monitorIDs = BFS.Monitor.GetMonitorIDs(); | |
// Find next monitor from left to right and get its bounds | |
// There is no need to use loops for every case but we're going to, anyway, since it's going to work on any | |
// setup either way and this is easier to read. | |
int nextMonitorIndex = -1; | |
if (isForwardDirection) { | |
for (int i = 0; i < monitorIDs.Length; i++) { | |
if (currentMonitorID == monitorIDs[i]) { | |
if (i == monitorIDs.Length - 1) { nextMonitorIndex = 0; } | |
else { nextMonitorIndex = i + 1; } | |
break; | |
} | |
} | |
} else { | |
for (int i = monitorIDs.Length - 1; i >= 0; i--) { | |
if (currentMonitorID == monitorIDs[i]) { | |
if (i == 0) { nextMonitorIndex = monitorIDs.Length - 1; } | |
else { nextMonitorIndex = i - 1; } | |
break; | |
} | |
} | |
} | |
if (nextMonitorIndex < 0) { return; } | |
uint nextMonitorID = monitorIDs[nextMonitorIndex]; | |
Rectangle nextMonitorBounds = BFS.Monitor.GetMonitorBoundsByID(nextMonitorID); | |
// Calculate current position of cursor relative to monitor it's in (percentage of width and height of monitor) | |
int currentMonitorWidth = currentMonitorBounds.Width; | |
int currentMonitorHeight = currentMonitorBounds.Height; | |
int currentMonitorX = currentMonitorBounds.X; | |
int currentMonitorY = currentMonitorBounds.Y; | |
int currentMonitorAbsMouseX = mouseX - currentMonitorX; | |
int currentMonitorAbsMouseY = mouseY - currentMonitorY; | |
decimal mouseRelativeX = (decimal) currentMonitorAbsMouseX / (decimal) currentMonitorWidth; | |
decimal mouseRelativeY = (decimal) currentMonitorAbsMouseY / (decimal) currentMonitorHeight; | |
// Calculate coordinates in next monitor at the same relative position, e.g. center to center | |
int nextMonitorWidth = nextMonitorBounds.Width; | |
int nextMonitorHeight = nextMonitorBounds.Height; | |
int nextMonitorX = nextMonitorBounds.X; | |
int nextMonitorY = nextMonitorBounds.Y; | |
int nextMouseX = Convert.ToInt32(nextMonitorX + mouseRelativeX * nextMonitorWidth); | |
int nextMouseY = Convert.ToInt32(nextMonitorY + mouseRelativeY * nextMonitorHeight); | |
// Move mouse cursor to new relative position in next monitor. | |
// If called just once, results in weird behaviour and mouse moving to opposite edges and stuff | |
// however if called twice it works as expected. | |
BFS.Input.SetMousePosition(nextMouseX, nextMouseY); | |
BFS.Input.SetMousePosition(nextMouseX, nextMouseY); | |
// Debugging message | |
// BFS.Dialog.ShowMessageInfo("Mouse is at (" + mouseX + ", " + mouseY + ") or as fraction of monitor rectangle (" + mouseRelativeX + ", " + mouseRelativeY + | |
// ") of " + currentMonitorWidth + "x" + currentMonitorHeight | |
// + " calculated as:\n( ( mouseX [" + mouseX + "] - currentMonitorX [" + currentMonitorX + "] )" + " / currentMonitorWidth [" + currentMonitorWidth + "] )\n" | |
// + "( ( mouseY [" + mouseY + "] - currentMonitorY [" + currentMonitorY + "] )" + " / currentMonitorHeight [" + currentMonitorHeight + "] )\n" | |
// + " So I'll move the mouse to (" + nextMouseX + ", " + nextMouseY + ")"); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment