CrossMacro

A modern mouse and keyboard macro recording and playback application for Linux (Wayland and X11), Windows, and macOS.
Screenshots
| Recording | Playback | Text Expansion |
|---|
 |  |  |
| Shortcuts | Scheduled Tasks | Settings |
 |  |  |
š„ļø Supported Platforms
Full Support (Absolute Positioning)
- Linux
- Hyprland (Wayland) ā
- KDE Plasma (Wayland & X11) ā
- GNOME (Wayland & X11) ā
- X11 (All other desktop environments) ā
- Windows ā
- macOS ā
Partial Support (Relative Positioning)
- Linux
- Other Wayland compositors (fallback mode)
What is the difference?
Relative positioning works flawlessly for reproducing input. However, in Fallback Mode, the cursor must reset to the top-left corner (0,0) at the start of every recording and playback session.
This is required because standard Wayland security protocols prevent applications from reading the current mouse position on these compositors, so the app must force a known reference point (0,0) to calculate relative movements correctly.
šÆ Features
- Mouse Event Recording: Record mouse clicks and movements
- Keyboard Event Recording: Record keyboard key presses
- Text Expansion: Create text shortcuts for quick insertions (e.g. :mail -> email@example.com)
- Shortcuts: Assign macros to keyboard keys, mouse buttons, or combinations for instant execution
- Scheduling: Run macros automatically at specific times or intervals
- Macro Editor: Powerful built-in editor with undo/redo, smart coordinate capture, and action reordering to fine-tune your macros
- Playback: Replay recorded macros with pause/resume support
- Loop Mode: Continuously repeat macros with customizable repeat count and delay
- Speed Control: Adjust playback speed from 0.1x to 10.0x
- File Operations: Save/load macros in .macro format (you choose where to save)
- Themes: Customize the look with Classic, Latte, Mocha, Dracula, and Nord themes
- System Tray Icon: Minimize to tray and control macros from system tray (optional)
- Global Hotkeys: Customizable global hotkey support
- F8: Start/Stop recording
- F9: Start/Stop playback
- F10: Pause/Resume playback
š„ Installation
Debian / Ubuntu (.deb)
# Download from GitHub Releases, then:
sudo apt install ./crossmacro-*_amd64.deb
# Add yourself to the crossmacro group (required for daemon communication)
sudo usermod -aG crossmacro $USER
# Enable and start the background service (important for daemon functionality)
sudo systemctl enable --now crossmacro.service
# Reboot your system for group changes to take effect, then start the app
Fedora / RHEL (.rpm)
# Download from GitHub Releases, then:
sudo dnf install ./crossmacro-*.x86_64.rpm
# Add yourself to the crossmacro group (required for daemon communication)
sudo usermod -aG crossmacro $USER
# Enable and start the background service (important for daemon functionality)
sudo systemctl enable --now crossmacro.service
# Reboot your system for group changes to take effect, then start the app
Arch Linux
Available on the AUR:
# Using yay
yay -S crossmacro
# Using paru
paru -S crossmacro
# Enable and start the background service (important for daemon functionality)
sudo systemctl enable --now crossmacro.service
# After installation, add yourself to the group
sudo usermod -aG crossmacro $USER
# Reboot your system for group changes to take effect, then start the app
NixOS
Run directly:
nix run github:alper-han/CrossMacro
> Note: nix run does not install the background daemon. For it to work, you must manually configure permissions (add yourself to input group and set up udev rules) as described in the AppImage section below.
Add to your configuration:
Add this to your flake.nix inputs:
inputs.crossmacro.url = "github:alper-han/CrossMacro";
Then in your NixOS configuration:
{ inputs, ... }: {
imports = [ inputs.crossmacro.nixosModules.default ];
programs.crossmacro = {
enable = true;
users = [ "yourusername" ]; # Add users who should access CrossMacro
};
}
> Note: The NixOS module automatically sets up the daemon service, user, groups, and adds specified users to the crossmacro group.
AppImage (Portable)
This method allows you to run the app without installing anything extra.
Since AppImages run on FUSE, we recommend configuring User Group Permissions for the best experience.
> ā ļø Security Warning: Adding your user to the input group grants your user account direct access to all input devices (keystrokes, mouse moves). This bypasses the secure daemon isolation typically recommended for Linux/Wayland, but is required for the AppImage to function without a system service.
Setup Instructions (Required) š ļø
This allows you to run the app normally (just double-click) without needing sudo.
- One-time setup (Run in terminal):
# Add udev rule for uinput access
echo 'KERNEL=="uinput", GROUP="input", MODE="0660", OPTIONS+="static_node=uinput"' | sudo tee /etc/udev/rules.d/99-crossmacro.rules
# Reload rules
sudo udevadm control --reload-rules && sudo udevadm trigger
# Add your user to input group
sudo usermod -aG input $USER
- Restart your computer (Important for group changes to take effect).
- Run the App:
chmod +x CrossMacro-*.AppImage
./CrossMacro-*.AppImage
Windows
Download the .exe file from GitHub Releases and run it directly.
Alternative (Winget):
winget install -e --id AlperHan.CrossMacro
> Note: No installation required. The executable is self-contained and doesn't require .NET to be installed.
macOS
Download the .dmg file from GitHub Releases.
- Open the
.dmg file.
- Drag CrossMacro to your Applications folder.
- Keep the app open in Applications folder. (Double check security settings if it doesn't open).
> Note: Requires Accessibility Permissions to record and play macros. You will be prompted to grant these permissions on first run.
> ā ļø "App is damaged" Error:
> If macOS prevents opening the app, run this command in Terminal to bypass Gatekeeper quarantine:
> bash > xattr -cr /Applications/CrossMacro.app >
Manual Build (Development)
Requirements: .NET 10 SDK
# Clone the repository
git clone https://github.com/alper-han/CrossMacro.git
cd CrossMacro
# Install daemon (Linux only)
sudo ./scripts/daemon/install.sh
# Run the application
dotnet run --project src/CrossMacro.UI/
āļø How It Works
Linux (Wayland)
CrossMacro uses a secure daemon architecture on Wayland:
āāāāāāāāāāāāāāāāāāā IPC Socket āāāāāāāāāāāāāāāāāāāāāāāā
ā CrossMacro UI ā āāāāāāāāāāāāāāāāāāāŗ ā CrossMacro Daemon ā
ā (Your User) ā ā (System Service) ā
āāāāāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāāāāāāāāāā
ā
ā¼
/dev/input/* (read)
/dev/uinput (write)
- Daemon runs as a system service with
input group privileges
- UI runs as your normal user, communicates via Unix socket
- Security: Wayland's strict security model prevents direct input access, so a privileged daemon handles input capture/simulation
- Position: Mouse position is obtained via compositor-specific protocols (Hyprland IPC, KDE D-Bus, GNOME Shell Extension)
Linux (X11)
CrossMacro uses native X11 APIs for direct input handling on X11:
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā CrossMacro UI ā
ā (Single Process Architecture) ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā
ā¼
X11 Server (Xlib)
āā XTest Extension (simulation)
ā āā XTestFakeKeyEvent()
ā āā XTestFakeButtonEvent()
ā āā XTestFakeMotionEvent()
ā
āā XInput2 Extension (capture)
āā XI_RawKeyPress/Release
āā XI_RawButtonPress/Release
āā XI_RawMotion
- Single Process: No separate daemon required (but daemon is still supported for unified experience)
- XTest: Simulates keyboard, mouse, and scroll events directly to X server
- XInput2: Captures raw input events from all master devices
- Position:
XQueryPointer() provides accurate cursor position
- Permissions: Runs with normal user privileges through X protocol
Windows
CrossMacro uses Windows API hooks for input handling:
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā CrossMacro UI ā
ā (Single Process Architecture) ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā
ā¼
Windows API (User32.dll)
āā SendInput() (simulation)
āā SetWindowsHookEx() (capture)
- Single Process: No separate daemon required
- API Hooks: Uses low-level keyboard and mouse hooks
- Permissions: Runs with normal user privileges
macOS
CrossMacro uses CGEvent Taps (Core Graphics) for input handling:
āāāāāāāāāāāāāāāāāāā
ā CrossMacro UI ā
āāāāāāāāāāāāāāāāāāā
ā
ā¼
Core Graphics (CGEvent)
āā CGEventCreate() (simulation)
āā CGEventTapCreate() (capture)
- Native Integration: Uses native macOS APIs for high performance.
- Permissions: Requires Accessibility API access (System Settings > Privacy & Security > Accessibility).
š ļø Troubleshooting
GNOME: Extension Required
CrossMacro requires a GNOME Shell extension to read mouse position on Wayland. The extension is automatically installed and enabled when you first run CrossMacro.
> Note: You need to log out and log back in for the extension to take effect after the first installation.
> Note: When using AppImage (without the system daemon), this extension is still required for recording mouse positions. The app will handle input simulation directly via the permissions granted.
CrossMacro will show a warning if the extension is not active.
Daemon Not Running
Check daemon status:
systemctl status crossmacro.service
If not running:
sudo systemctl start crossmacro.service
sudo systemctl enable crossmacro.service # Auto-start on boot
Permission Denied Errors
Ensure you're in the crossmacro group:
groups | grep crossmacro
If not, add yourself:
sudo usermod -aG crossmacro $USER
# Reboot your system for group changes to take effect!
Polkit Not Available (Minimal/Embedded Systems)
The daemon requires polkit for authorization. If your system doesn't have polkit installed (some minimal or embedded distributions), the daemon will reject all connections.
Check if polkit is installed:
which pkcheck
# or
pkcheck --version
If polkit is not available:
- The daemon won't work without polkit
- Use the AppImage instead with
input group permissions (see AppImage section above)
> Note: Most desktop Linux distributions (Fedora, Ubuntu, Arch, etc.) include polkit by default. This is typically only an issue on minimal server installations or embedded systems.
Enable Debug Logging
To enable debug logging for troubleshooting:
sudo systemctl kill -s USR1 crossmacro
journalctl -u crossmacro -f
Send the signal again to switch back to normal logging.
Keyboard Events Not Recording (Mouse Works)
Some applications lock input devices to prevent them from being used by other programs. One such application is GPU Screen Recorder.
To temporarily stop the conflicting service and record your macros:
systemctl --user stop gpu-screen-recorder
pkill -9 -f gpu-screen-recorder
After you're done recording, you can restart the service with:
systemctl --user start gpu-screen-recorder