Skip to content

Gok-tug/CrossMacro

Β 
Β 

CrossMacro

Build Status License Release

A modern mouse and keyboard macro recording and playback application for Linux (Wayland and X11), Windows, and macOS.

Screenshots

Recording Playback Text Expansion
Recording Playback Text Expansion
Shortcuts Scheduled Tasks Settings
Shortcuts Scheduled Tasks Settings

πŸ–₯️ Supported Platforms

  • Linux (X11 & Wayland) βœ“
  • Windows βœ“
  • macOS βœ“
About Mouse Position Tracking on Wayland

CrossMacro works on all Wayland compositors. However, due to Wayland's security model, how we track mouse position varies:

Absolute positioning β€” We can read the cursor position directly. Supported on:

  • Hyprland (via IPC)
  • KDE Plasma (via D-Bus)
  • GNOME (via Shell Extension)

Relative positioning (fallback) β€” For other compositors, the cursor resets to the top-left corner (0,0) at the start of every recording and playback session. This is needed because we can't read the current mouse position, so we use a known reference point to calculate movements.

Both modes work reliably for macro recording and playback.

🎯 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
    • Toggle mode: Press to start, press again to stop
    • Run while held: Runs while the key is pressed, stops on release
    • Loop support with customizable repeat count and delay
  • 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. Reboot your system for group changes to take effect.

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.

  1. 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
  2. Restart your computer (Important for group changes to take effect).
  3. 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.

  1. Open the .dmg file.
  2. Drag CrossMacro to your Applications folder.
  3. 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:

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

If something isn't working, checking the logs is the best place to start. Both the daemon and UI can provide useful information.

Daemon logs (debug level):

sudo systemctl kill -s USR1 crossmacro
journalctl -u crossmacro -f

Send the signal again to switch back to normal logging.

UI logs: Run the application from terminal to see output directly.

Look for permission errors, device detection issues, or any error messages that point to the problem.

Input Not Working (Keyboard or Mouse)

If your keyboard or mouse inputs aren't being captured, first check the daemon and UI logs (see Enable Debug Logging above).

One known cause is GPU Screen Recorder, which locks input devices exclusively. Stop it temporarily:

systemctl --user stop gpu-screen-recorder
pkill -9 -f gpu-screen-recorder

Restart after you're done:

systemctl --user start gpu-screen-recorder

About

A modern mouse and keyboard macro recording and playback application for Linux (Wayland and X11), Windows, and macOS

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • C# 95.0%
  • Shell 3.8%
  • Nix 1.2%