Mouse Cursor Management for Multi-Display macOS
MousePortal is a macOS utility for managing mouse cursor movement and window placement across multiple displays. It provides three core features:
- Hotkey Jump - Global keyboard shortcuts to instantly teleport the cursor to specific displays
- Portals - Custom edge-to-edge teleportation zones that warp the cursor when crossing defined screen boundaries
- Window Layouts - Save, preview, and restore application window positions for each display arrangement
- Configure custom global shortcuts for each display
- Support for any key + modifier combinations
- Support for mapping via display layout name or ID
- Define custom teleportation zones on display edges
- Support for bidirectional portals (from one display edge to another)
- Two trigger modes:
- Automatic - Always active
- Key-held - Requires holding a modifier key (default: Option)
- Visual editor for easy creation and adjustment of portal zones
- Save multiple named window layouts for each display arrangement
- Capture an automatic Before Lock layout before sleep or screen lock
- Preview saved windows directly on the display canvas
- Apply, rename, delete, or promote an automatic layout to a manual layout
- Control global window recovery independently from sleep/lock capture and automatic wake restoration
- Search for applications and exclude them from future snapshots
- Restore standard, non-minimized, non-full-screen windows; Split View, Stage Manager groups, and Spaces are not restored
Available in 20 languages: English, Simplified Chinese, Traditional Chinese, Japanese, Korean, German, French, Spanish, Portuguese (Brazil), Russian, Italian, Dutch, Polish, Turkish, Arabic, Hindi, Thai, Vietnamese, Indonesian, Malay.
- Launch at login
- Menu bar quick access
- Configuration profile management (for different setups)
- Display layout visualization
- System, Light, and Dark app themes
| English · Dark | English · Light |
|---|---|
![]() |
![]() |
| 简体中文 · 深色 | 简体中文 · 浅色 |
|---|---|
![]() |
![]() |
- macOS 13.0 or later
- Accessibility Permission required (System Settings > Privacy & Security > Accessibility)
- Download the latest
.zipfile from Releases - Extract and drag
MousePortal.appto/Applicationsfolder - On first launch, grant Accessibility permission in System Settings
# Clone the repository
git clone https://github.com/ai-eks/MousePortal.git
cd MousePortal
# Build
swift build -c release
# Run
swift run- Launch MousePortal
- Open System Settings > Privacy & Security > Accessibility
- Add MousePortal and ensure the toggle is enabled
- Return to MousePortal main window
- Open MousePortal main window
- Select Hotkeys in the left sidebar
- Click the hotkey input field and press your desired shortcut
- Select the display layout for this hotkey
- Click Save
- Select Portal Editor in the left sidebar
- Click + New Portal
- Select source and target displays
- Choose an edge (top/bottom/left/right)
- Adjust the portal zone start and end positions
- Select trigger mode (automatic or key-held)
- Name and save your portal
- Define your display arrangement in Display Layouts
- Assign a name to each layout (e.g., "Dual Display", "Triple Display")
- Specify relative positions of each display
- Open Settings > Window Recovery and turn on Enable Window Recovery
- Optionally enable Remember windows before sleep or lock and automatic restoration after displays wake
- Use the ignored-app search to exclude applications that should not be captured
- Return to Display Layouts, enable Show Window Layout, then click Save Window Layout
- Manage layouts below the matching display arrangement: apply, rename, delete, or promote an automatic layout to manual
| Service | Description |
|---|---|
PortalService |
Monitors mouse movement, detects when cursor crosses portal lines, warps cursor using CGWarpMouseCursorPosition |
HotkeyService |
Listens for global keyboard shortcuts via CGEvent |
PermissionService |
Handles macOS Accessibility permission |
DisplayService |
Fetches display info via CGGetActiveDisplayList/CGDisplayBounds |
WindowLayoutService |
Captures, previews, and restores application window layouts |
LanguageService |
Handles dynamic language switching |
LaunchAtLoginService |
Manages launch at login |
PortalPair- TwoPortalLineobjects defining a bidirectional warp zoneHotkeyConfig- Maps a key+modifiers combo to a display layoutConfigProfile- Named configuration snapshots for different setupsWindowLayoutSnapshot- A manual or automatic snapshot of windows for one display topology
- macOS 13+
- Swift 5.9+
- Xcode 15+
# Open in Xcode
open Package.swift
# Run tests
swift test
# Build release version
swift build -c releaseMousePortal/
├── MousePortal/ # Main application
│ ├── Models/ # Data models
│ ├── Views/ # SwiftUI views
│ ├── Services/ # Core services
│ ├── Utils/ # Utilities
│ ├── Protocols/ # Protocol definitions
│ └── Resources/ # Resources and localization
├── MousePortalTests/ # Unit tests
│ ├── Models/
│ ├── Services/
│ ├── Utils/
│ └── Mocks/
└── docs/ # Documentation
MousePortal is a focused utility and is mainly maintained by the project owner.
Bug reports and small focused fixes are welcome. Larger feature ideas may be discussed in issues first.
See PRIVACY.md for the privacy note.
This project is licensed under the Apache 2.0 License - see the LICENSE file for details.
A: MousePortal needs to listen for global keyboard events and monitor mouse position, which requires macOS Accessibility permission.
A: Please ensure:
- Accessibility permission is granted
- The portal is enabled
- If using key-held mode, make sure you're holding the modifier key




