Last active
November 26, 2025 10:07
-
-
Save dofy/f993333785e85f3e0e40d9017514a4d9 to your computer and use it in GitHub Desktop.
This is a raycast script that allows the mouse pointer to quickly jump between multiple screens using a keyboard shortcut. If you have three screens arranged side by side, you'll thank me.
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
| #!/usr/bin/swift | |
| // Required parameters: | |
| // @raycast.schemaVersion 1 | |
| // @raycast.title My mouse my mouse where will you go? | |
| // @raycast.mode silent | |
| // Optional parameters: | |
| // @raycast.icon 🐭 | |
| // Documentation: | |
| // @raycast.description Tell me where did you sleep last night. | |
| // @raycast.author Seven Yu | |
| // @raycast.authorURL https://phpz.xyz | |
| import CoreGraphics | |
| import Foundation | |
| var displayCount: UInt32 = 0 | |
| CGGetActiveDisplayList(0, nil, &displayCount) | |
| let allocated = Int(displayCount) | |
| var active = [CGDirectDisplayID](repeating: 0, count: allocated) | |
| CGGetActiveDisplayList(displayCount, &active, &displayCount) | |
| // Determine the current cursor location and move to the next or previous display based on left/right half | |
| guard let event = CGEvent(source: nil) else { exit(1) } | |
| let pos = event.location | |
| if active.isEmpty { exit(0) } | |
| // Build a left-to-right ordered list of displays | |
| let displaysWithRects: [(CGDirectDisplayID, CGRect)] = active.map { ($0, CGDisplayBounds($0)) } | |
| let sorted = displaysWithRects.sorted { | |
| if $0.1.minX == $1.1.minX { | |
| return $0.1.minY < $1.1.minY | |
| } | |
| return $0.1.minX < $1.1.minX | |
| } | |
| // Find current display in the sorted order | |
| var currentIndex = 0 | |
| var currentRect = CGRect.zero | |
| for (i, pair) in sorted.enumerated() { | |
| if pair.1.contains(pos) { | |
| currentIndex = i | |
| currentRect = pair.1 | |
| break | |
| } | |
| } | |
| // 1 display | |
| if sorted.count <= 1 { | |
| exit(0) | |
| } | |
| // 2 display | |
| if sorted.count == 2 { | |
| let targetIndex = (currentIndex == 0) ? 1 : 0 | |
| let targetRect = sorted[targetIndex].1 | |
| let directionMsg = (targetRect.minX > currentRect.minX) ? "Go Right" : "Go Left" | |
| print(directionMsg) | |
| let center = CGPoint(x: targetRect.midX, y: targetRect.midY) | |
| CGWarpMouseCursorPosition(center) | |
| CGAssociateMouseAndMouseCursorPosition(1) | |
| exit(0) | |
| } | |
| // 3 display | |
| let relX = (pos.x - currentRect.minX) / currentRect.width | |
| let region: String | |
| if relX < 1.0/3.0 { | |
| region = "left" | |
| } else if relX > 2.0/3.0 { | |
| region = "right" | |
| } else { | |
| region = "center" | |
| } | |
| // Decide target by explicit rules: | |
| let isLeftHalf = pos.x < currentRect.midX | |
| let isRightHalf = pos.x >= currentRect.midX | |
| var targetIndex = currentIndex | |
| if currentIndex == 0 { | |
| targetIndex = isLeftHalf ? 2 : 1 | |
| } else if currentIndex == 1 { | |
| targetIndex = isLeftHalf ? 0 : 2 | |
| } else { // currentIndex == 2 (or clamp) | |
| targetIndex = isRightHalf ? 0 : 1 | |
| } | |
| // Friendly direction-only output | |
| let targetRectPreview = sorted[targetIndex].1 | |
| let directionMsg = (targetRectPreview.minX > currentRect.minX) ? "Go Right" : "Go Left" | |
| print(directionMsg) | |
| // Warp to center of target display | |
| let targetRect = sorted[targetIndex].1 | |
| let center = CGPoint(x: targetRect.midX, y: targetRect.midY) | |
| CGWarpMouseCursorPosition(center) | |
| CGAssociateMouseAndMouseCursorPosition(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment