How the osu! Handler Works for Importing Beatmaps and Skins in osu-winello

TLDR: The osu! handler acts as a bridge between the Linux host and the Windows osu! client, registering MIME types and URL schemes on the host system while injecting Windows registry entries that map beatmap (.osz), skin (.osk), and replay (.osr) files to the Wine environment, then dispatching them via start.exe to the game executable.

The open-source tool osu-winello (nellokudo/osu-winello) streamlines running osu! on Linux through Wine. Central to its functionality is the osu! handler, which eliminates manual file copying by enabling direct import of beatmaps and skins from the Linux desktop into the Windows game client running under Wine.

Stage 1: Registering MIME Types and Windows Registry Entries

The setup process begins with the osuHandlerSetup() function defined in osu-winello.sh (lines 21-66). This function performs dual registration: it configures the Linux desktop environment and prepares the Wine prefix to recognize osu! file formats.

First, it creates two desktop entry files:

  • osuwinello-file-extensions-handler.desktop associates the MIME types application/x-osu-beatmap-archive and application/x-osu-skin-archive with the command osu-wine --osuhandler %f.
  • osuwinello-url-handler.desktop registers the osu:// URL scheme with the command osu-wine --osuhandler %u.

Second, it imports stuff/osu-handler.reg into the Wine registry using waitWine regedit /s stuff/osu-handler.reg. This registry file maps file extensions—including .osz, .osk, .osr, and .osz2—to specific ProgIDs (e.g., osustable.File.osz) that resolve to the executable path D:\osu!.exe.

Stage 2: Runtime Dispatch via osuHandlerHandle()

When a user opens a registered file or clicks an osu:// link, the desktop entry invokes osu-wine --osuhandler <argument>, triggering the osuHandlerHandle() function (lines 68-100) in osu-winello.sh.

This function inspects the incoming argument and branches accordingly:

  • For osu:// URLs: It passes the URL directly to Wine's start.exe, which forwards the deep-link to the running Windows client.
  • For local files: It resolves the absolute path, accounts for the Wine filesystem view using PRESSURE_VESSEL_FILESYSTEMS_RW, and executes start.exe /ProgIDOpen "osustable.File.<ext>" <full-path>. The ProgID lookup routes the request to D:\osu!.exe based on the registry entries created during setup.

Stage 3: Process Reuse and Wine Session Management

To optimize performance, osuHandlerHandle() checks for an existing osu! process before launching a new Wine session. If the game is already running (detected via PID), the function sets YAWL_VERBS=enter=$OSUPID to inject the operation into the current Wine process (lines 74-80). This avoids the overhead of initializing a new Wine prefix session. If no instance exists, the handler launches a fresh Wine session using the osm-handler-wine executable.

Practical Usage Examples

To activate or repair the handler associations, run the setup command:

./osu-winello.sh fixosuhandler

To import a beatmap or skin from the Linux filesystem:

osu-wine --osuhandler /home/user/Downloads/cool_song.osz
osu-wine --osuhandler /home/user/Downloads/new_skin.osk

To open an osu! direct link from a browser or terminal:

osu-wine --osuhandler "osu://s/123456"

These commands trigger the desktop entries created by osuHandlerSetup(), which ultimately invoke the dispatch logic in osuHandlerHandle().

Summary

  • Dual registration system: The handler creates Linux desktop entries for MIME types and URL schemes while simultaneously importing Windows registry entries via stuff/osu-handler.reg.
  • Path translation: osuHandlerHandle() converts Linux paths to Wine-compatible views using PRESSURE_VESSEL_FILESYSTEMS_RW before passing them to start.exe.
  • ProgID delegation: File associations rely on Windows ProgIDs (e.g., osustable.File.osz) mapped to D:\osu!.exe in the registry.
  • Process optimization: The handler reuses existing Wine processes via YAWL_VERBS=enter=$OSUPID to avoid redundant initialization.

Frequently Asked Questions

How do I repair or reinstall the osu! handler file associations?

Run ./osu-winello.sh fixosuhandler. This command triggers osuHandlerSetup() in osu-winello.sh, which regenerates the desktop entries in ~/.local/share/applications/ and re-imports stuff/osu-handler.reg into the Wine prefix.

Yes. Once osuHandlerSetup() has registered the URL scheme handler (osuwinello-url-handler.desktop), clicking an osu:// link in Firefox or Chrome launches osu-wine --osuhandler %u, which passes the URL directly to the Windows client via Wine's start.exe.

Why does the handler use start.exe instead of launching osu!.exe directly?

The Windows osu! client relies on registry-based file associations (ProgIDs) to handle different file types correctly. By using start.exe /ProgIDOpen, the handler delegates file type detection to the Windows registry entries defined in stuff/osu-handler.reg, ensuring .osz, .osk, and .osr files open with the correct in-game importers.

What file formats does the osu! handler support?

According to the registry entries in stuff/osu-handler.reg and the dispatch logic in osuHandlerHandle(), the handler supports .osz (beatmaps), .osk (skins), .osr (replays), and .osz2 (osu!lazer archives). Each extension maps to a specific ProgID that resolves to D:\osu!.exe.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →