A lightweight Windows tool that makes the cursor cross between monitors at the same physical height, using real screen sizes instead of pixels
翻譯準備中
正在載入完整 README。
檢視完整 README ↗This release is unsigned, so Windows and/or Third-Party Antivirus Software (Bitdefender Web Protection flagged the file download for me) may show a warning that it is not safe to download or run. Download only from the official GitHub release and compare its SHA-256 with the value published alongside that release.
Windows lines your screens up by their pixels. If your screens differ in size, resolution or height on the desk, the cursor jumps up or down as it crosses from one to the next, or gets stuck where the pixel edges don't line up.
physmouse fixes that. You tell it where your screens actually sit on your desk, and it moves the cursor between them by real distance, so it leaves one screen and enters the next at the same physical spot.
physmouse stays out of the way in the background: about 0.1% CPU, around 8 MB of memory and no network traffic apart from an update check at startup, in Task Manager (measured on an AMD Ryzen 7 9850X3D, 32 GB DDR5-6000 CL36, Windows 11 26H2). It only steps in when the cursor crosses a screen edge.
The easiest way is the Microsoft Store, which installs and updates physmouse for you. Like the GitHub version, it only starts with Windows once you turn that on under General > Start with Windows. To install it from GitHub instead:
physmouse-v<version>-installer.exe from the latest release and run it. Releases are built by GitHub Actions from the tagged commit. To check that your download is that build, run gh attestation verify physmouse-v<version>-installer.exe -R lieberlenny/physmouse, or compare its SHA-256 with the one in the release notes.%LOCALAPPDATA%\Programs\physmouse. You can change the folder and choose whether it starts with Windows (off by default) and gets a desktop shortcut.physmouse runs in the notification area. Click its icon, or open it again from Start, to bring back the window.
To update, download the new physmouse.exe and run it. It offers to replace the installed version and keeps your settings and layout.
To uninstall, use Settings > Apps > Installed apps, or Uninstall on physmouse's About page. You can choose to keep your settings for a later reinstall.
If you'd rather not install anything, choose Run portable instead. physmouse then keeps its settings next to the exe and doesn't touch the Start menu or startup entries until you turn them on.
It needs Windows 10 or 11 and the .NET Framework 4.8, which is part of Windows.
Everything is stored in %APPDATA%\physmouse\settings.ini, a plain-text file that's easy to back up or copy to another PC. For a portable setup, put an empty settings.ini next to physmouse.exe and physmouse will use that instead.
The screen id is the EDID product code plus the port the screen is connected to. If a screen moves to another port or the graphics driver renumbers it, physmouse still matches it by product code, as long as you don't have two identical screens.
physmouse installs a low-level mouse hook on its own high-priority thread. When a mouse movement would take the cursor off its current screen, physmouse converts the exit point to millimetres on the desk, finds the screen across from it, and places the cursor at the matching point there. Movement within a screen passes straight through untouched.
The hook only sees input that Windows lets it see. Windows doesn't pass mouse input to a normal app's hook while an app running as administrator (such as Task Manager) is in front, so physmouse can't remap the cursor then. Windows' own pixel layout applies until you switch to another window.
Why there's no "run as administrator" option anymore. Up to 1.3.0, physmouse could start with administrator rights at sign-in through a Task Scheduler task. That task ran physmouse.exe from the per-user install folder, which any program running as you can write to without administrator rights. Malware could have replaced the exe and then been started with full rights at the next sign-in, without a UAC prompt. The option is gone, and an existing task is removed. When the task starts physmouse with administrator rights, physmouse deletes it silently and adds a normal startup entry instead. When it can't (for example on a standard user account), physmouse explains the task the next time you open it by hand and asks before Windows shows its administrator prompt; it never prompts when it starts at sign-in. A task named \physmouse that starts physmouse from Program Files was set up by an administrator on purpose and is left alone. If you need remapping over elevated windows for a while, quit physmouse and start it with Run as administrator; that copy runs until you quit it or sign out.
This section is for anyone reviewing physmouse before rolling it out, for example through Intune. To report a vulnerability, see SECURITY.md. What changed between versions is in CHANGELOG.md.
WH_MOUSE_LL). It acts only on cursor movement that leaves a screen. Clicks, the wheel and movement within a screen pass through untouched. Nothing is logged or stored.RegisterHotKey).settings.ini.HEAD request to github.com/lieberlenny/physmouse/releases/latest at startup, to see whether a newer release exists. It sends nothing except the app version in the User-Agent. The DisableUpdateCheck policy turns it off.DefaultSettings policy points to a network share (UNC path), Windows reads that file over SMB on the first start.| What | Where | When |
|---|---|---|
| Program | %LOCALAPPDATA%\Programs\physmouse\physmouse.exe (or the folder chosen during setup) | install |
| Apps & features entry | HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall\physmouse | install |
| Start menu shortcut, optional desktop shortcut | %APPDATA%\Microsoft\Windows\Start Menu\Programs\physmouse.lnk, Desktop\physmouse.lnk | install |
| Settings and layout | %APPDATA%\physmouse\settings.ini, or settings.ini next to the exe in portable mode (Store: the package's LocalCache\Roaming\physmouse) | first start, every change |
| Start with Windows | value physmouse under HKCU\Software\Microsoft\Windows\CurrentVersion\Run and ...\Explorer\StartupApproved\Run | only when turned on |
Nothing is written to HKLM or to Program Files, setup never needs administrator rights, and physmouse only asks for them to remove the task described next, after explaining it, and never when it starts at sign-in. Versions up to 1.3.0 could also register a Task Scheduler task \physmouse with highest privileges; current versions remove it (see How it works).
physmouse installs per user, so deploy it in the user context (Intune Win32 app: Install behavior: User).
| Action | Command | Exit code |
|---|---|---|
| Install or upgrade | physmouse.exe --install --quiet | 0 = success, 1 = failure, 2 = installed but the legacy elevated task from 1.3.0 or older remains |
| Same, and start with Windows | physmouse.exe --install --quiet --autostart | 0 / 1 / 2 |
| Remove the legacy elevated task (run as administrator or SYSTEM) | physmouse.exe --remove-legacy-task | 0 = removed or not there, 1 = failure |
Uninstall (keeps settings.ini) | "%LOCALAPPDATA%\Programs\physmouse\physmouse.exe" --uninstall --quiet (also registered as QuietUninstallString) | 0 = success, 1 = failure, 2 = no changes because the legacy task remains |
--autostart or set the ForceAutostart policy.Start-Process -Wait (which also waits for child processes) only returns once that copy exits; use (Start-Process ... -PassThru).WaitForExit() instead.ForceAutostart policy is set.schtasks /Delete /TN physmouse /F, or run physmouse.exe --remove-legacy-task from a trusted deployment package. Do not run the copy from the user's %LOCALAPPDATA% folder as SYSTEM because the user can replace it. --remove-legacy-task removes the task named \physmouse when it starts an exe outside Program Files and the Windows folder, which also covers tasks registered by a portable copy, and works the same when run as SYSTEM. The SYSTEM command only deletes the task; it cannot restore the signed-in user's startup entry. A user can start physmouse by hand and confirm its prompt to remove the task and restore normal start-with-Windows. An interactive update still installs when that prompt is declined, and says that the task remains.HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Uninstall\physmouse, value DisplayVersion, string comparison equals the deployed version (for example 1.4.2). Don't check the exe file instead: an uninstall deletes it a moment after the uninstaller has exited, so a file check right away can still find it.Values under HKEY_LOCAL_MACHINE\SOFTWARE\Policies\physmouse override what the user chooses. physmouse reads them when it starts. You can push them with Intune (for example a PowerShell script or the Registry settings in a configuration profile); no ADMX template is needed.
| Value | Type | Effect |
|---|---|---|
DisableUpdateCheck | DWORD 1 | No update check against GitHub. |
DisableAutostart | DWORD 1 | Start with Windows is off and can't be turned on. Wins over ForceAutostart. |
ForceAutostart | DWORD 1 | Start with Windows is on and the toggle is locked. Users can still disable the entry in Task Manager; physmouse turns it back on the next time it starts. |
DisableSelfInstaller | DWORD 1 | The downloaded exe no longer offers to install or update itself, and About no longer shows Uninstall. The command-line switches above keep working. |
DefaultSettings | String | Path to a settings.ini (environment variables allowed) that is used as the starting point for users who have no settings yet, for example a preset layout or options. Prefer a local path: if a network share can't be reached, the first start waits for Windows' network timeout (about 20 seconds). |
In the Store version, DisableAutostart and ForceAutostart turn the package's startup task off or on. Windows' own app policies still apply.
A flag is on when it is a REG_DWORD other than 0 or a string 1; any other type or value counts as off. Changes take effect the next time physmouse starts. DisableElevatedStartup from 1.3.0 is no longer needed, because the elevated startup option is gone; it's ignored.
build.cmd
The build uses the C# compiler that ships with Windows (%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\csc.exe) and the WinRT metadata in %WINDIR%\System32\WinMetadata, so no SDK or Visual Studio is needed. It produces bin\physmouse.exe and runs the tests in tests\Tests.cs.
physmouse has no account, ads or telemetry, and settings stay on your PC. The only network request is the update check against GitHub at startup (not in the Store version, and admins can turn it off). Full policy: https://lennartblees.de/physmouse-privacy.html
Free code signing provided by SignPath.io, certificate by SignPath Foundation. See the code signing policy.