feat: register ed2k:// and magnet: URL schemes cross-platform - #324
Conversation
|
I'm thinking that maybe we should allow users to configure the two protocols separately. The magnet protocol is used in BitTorrent applications, and it's common for some users to have both a BitTorrent client and Amule installed at the same time. BitTorrent is more popular, so users will likely want to associate magnet with BitTorrent and ed2k with aMule. Update: I think I didn't explain myself clearly. Amule should be registered as an application that supports both protocols, but it shouldn't be set as the default application for both protocols at the same time. |
|
Yes it’s already a separate checkbox in the preferences. But I’ll have to make the same for the Windows installer, there it’s a single checkbox to bind to both protocols atm. |
|
Update: I think I didn't explain myself clearly. Amule should be registered as an application that supports both protocols, but it shouldn't be set as the default application for both protocols at the same time. |
6e18e24 to
93b70b9
Compare
|
Update: refined the default state to be less aggressive about the magnet scheme, since aMule only handles the eD2k-compatible subset and would otherwise silently steal BitTorrent magnet clicks from a user's BT client.
Also fired a `workflow_dispatch` on the fork's Packaging workflow to validate the AppImage, Flatpak, macOS Universal2, and Windows installer builds against the branch: https://github.com/got3nks/amule/actions/runs/28816136839 |
93b70b9 to
a289959
Compare
ebc0d6a to
0cb0ca9
Compare
) * feat(AppImage): install amulegui launcher + shell shortcuts, fix em-dashes Two related integration gaps + one string-encoding cleanup in the same change: 1. amulegui first-class integration Previously the first-launch AppImage integration prompt only wrote org.amule.aMule.desktop (the monolithic amule variant). Users who invoked the AppImage via a `amulegui`-named symlink got amulegui running fine (AppRun's argv[0]-dispatch handled it), but no dedicated menu entry and no icon binding. Extended to also install org.amule.aMule.gui.desktop with Exec= pointing at ~/.local/bin/amulegui (the symlink from point 2 below), so AppRun's basename dispatch picks amulegui rather than the default amule. This also fixes the "amulegui registered as ed2k scheme handler opens amule" bug surfaced by #324: ProtocolHandlerManager writes the correct .desktop id to mimeapps.list, but xdg-mime couldn't find the .gui .desktop and silently fell back to amule. 2. Shell command shortcuts New InstallCommandSymlinks() iterates the AppRun-recognized names (amule, amuled, amulegui, amulecmd, amuleweb, amuleapi, ed2k, cas, wxcas, alc, alcc) and creates ~/.local/bin/<name> symlinks for each one the AppImage actually bundles. Users can now `amulecmd`, `amuled`, etc. straight from a terminal without knowing the AppImage path. Skips names that are pre-existing regular files (protects a user's distro-packaged binary if they somehow ended up under ~/.local/bin); replaces existing symlinks so a re-run with a newer AppImage refreshes the target. 3. Fix two user-visible em-dashes that mojibake on Windows Same class of bug as #326: - src/AppImageIntegration.cpp:222 (the integration prompt itself, reported by @got3nks during Ubuntu AppImage testing) - src/webapi/App.cpp:342 (amuleapi startup error when bound to a non-loopback address with no password set) Replaced the em-dashes with hyphens - identical rendering on Linux and macOS, no mojibake on Windows. The integration prompt string is also expanded to mention ~/.local/bin so users know what's being touched. Related: #324 (URL scheme handler PR that surfaced the amulegui gap). * po: regenerate catalogs after AppImageIntegration text changes Picks up the two revised msgids from the feat commit above: * the integration-prompt body (now mentions shell shortcuts and ~/.local/bin, and the em-dash was replaced with a hyphen) * the amuleapi startup-error message (em-dash → hyphen) * the log line summarising integration outcome (new %d counter for installed shell shortcuts) Required by the App-catalogs-in-sync CI check per scripts/update-po.sh.
69883a4 to
7ce63fc
Compare
7ce63fc to
59d23d2
Compare
Wraps OS-level scheme registration behind a cross-platform ProtocolHandlerManager (mirroring AutostartManager from amule-project#744) so a browser click on ed2k:// or magnet: reaches aMule directly — no more .reg imports, mimeapps.list hand-edits, or LaunchServices incantations. Backends: Windows HKCU\Software\Classes\<scheme> (per-user URL Protocol keys) Linux $XDG_CONFIG_HOME/mimeapps.list [Default Applications] macOS LSSetDefaultHandlerForURLScheme + CFBundleURLTypes plist decl Four surfaces expose the toggle, all going through the same manager: * Preferences → General: two checkboxes below the autostart toggle, live OS state on open, with an "Another app is currently the default handler for these links, replace with aMule?" confirm dialog before overwriting a third-party registration. * First-run wizard: new Integrations page between Bootstrap and Folders. Folds in the existing autostart toggle plus the two URL-scheme toggles. Strings shared verbatim with Preferences so translators only see them once. * --configure-protocols on|off CLI: one-shot, no prompt, mirrors --configure-autostart. Invoked by the Windows installer. * Windows installer: new SecProtocols section, default checked. Uninstall symmetry only wipes registry keys if they still point inside \$INSTDIR (protects a user's hand-set third-party registration from being clobbered). Identity is per-binary (basename on Windows/Linux, bundle id on macOS), so amule.exe and amulegui.exe each track their own registration state. The Preferences checkbox in amulegui correctly reads unchecked when amule.exe holds the registration, and toggling on prompts before replacing it. macOS specifics: * Info.plist gets CFBundleURLTypes for both schemes via a plutil post-build step (both aMule.app and aMuleGUI.app). * Runtime scheme delivery uses a kAEGetURL Apple Event handler registered in __attribute__((constructor)) at dylib-load time — required because macOS dispatches cold-launch scheme URLs between applicationWillFinishLaunching: and applicationDidFinishLaunching:, before any wxApp OnInit runs. * On amulegui, CamuleRemoteGuiApp::Startup() drains ED2KLinks explicitly after the poll timer starts so a URL queued pre-EC- connect reaches the daemon immediately post-connect rather than waiting ~1s for the first poll tick. * LaunchServices has no "clear default handler" call, so Disable() is a no-op on macOS — the Prefs checkbox is hidden while we're the current handler (Linux/Windows Disable works, boxes stay visible there). Magnet handling stays scoped to eD2k-compatible magnets (existing CMagnetED2KConverter contract). BitTorrent-only magnets are ignored. SelfHealOnStartup rewrites the registered path if it drifted (user moved AppImage / .app / install dir) — only when we're already the current handler, never when a third-party handler owns the scheme. Mirrors AutostartManager::SelfHealOnStartup. Closes amule-project#793.
Picks up the msgids added by the feature commit above (Preferences + Wizard checkbox labels, tooltips, magnet-specific confirm dialog text, wizard BitTorrent-limitation hint, and the two new installer section names / descriptions from the ed2k / magnet split). Required by the App-catalogs-in-sync CI check per scripts/update-po.sh.
59d23d2 to
e60fa19
Compare



Summary
Wraps OS-level scheme registration behind a cross-platform
ProtocolHandlerManager(mirroringAutostartManagerfrom #744) so a browser click oned2k://ormagnet:reaches aMule directly - no more.regimports,mimeapps.listhand-edits, orLaunchServicesincantations.Closes amule-project#793.
Related: #233 - complementary; this PR fixes the OS-level side, #233's browser-extension route addresses Chromium's active blocking of
ed2k://clicks that this PR cannot solve at the registration layer.Backends
HKCU\Software\Classes\<scheme>(URL Protocol keys)$XDG_CONFIG_HOME/mimeapps.list[Default Applications]xdg-mime-compatible ini write, no dep onxdg-utilsLSSetDefaultHandlerForURLScheme+CFBundleURLTypesinInfo.plistSurfaces
Four consistent entry points, all routing through the same manager:
--configure-protocols on|offCLI: one-shot, no prompt, mirrors--configure-autostart. Invoked by the Windows installer.SecProtocolssection, default checked, description mentions the BitTorrent limitation. Uninstall symmetry only wipes registry keys if they still point inside$INSTDIR(protects a user's hand-set third-party registration from being clobbered).Per-binary identity:
amule.exeandamulegui.exe(or.appon macOS,.desktopid on Linux) each track their own registration state. The Preferences checkbox in amulegui correctly reads unchecked whenamule.exeholds the registration, and toggling on prompts before replacing it.macOS specifics
Info.plistgetsCFBundleURLTypesfor both schemes via aplutilpost-build step (bothaMule.appandaMuleGUI.app).kAEGetURLApple Event handler registered in__attribute__((constructor))at dylib-load time - this is required because macOS dispatches cold-launch scheme URLs betweenapplicationWillFinishLaunching:andapplicationDidFinishLaunching:, before any wxAppOnInitruns.CamuleRemoteGuiApp::Startup()drainsED2KLinksexplicitly after the poll timer starts so a URL queued pre-EC-connect reaches the daemon immediately post-connect rather than waiting ~1s for the first poll tick.LaunchServiceshas no "clear default handler" call, soDisable()is a no-op on macOS - the Prefs checkbox is hidden while we're the current handler (Linux/Windows Disable works, boxes stay visible there).Magnet handling
Kept scoped to eD2k-compatible magnets (existing
CMagnetED2KConvertercontract). BitTorrent-only magnets are ignored - and every surface where the toggle can be enabled now spells out that limitation to the user (installer description, prefs tooltip, wizard hint, confirm-dialog magnet-specific text).SelfHeal
SelfHealOnStartup()rewrites the registered path if it drifted (user moved AppImage / .app / install dir) - only when we're already the current handler, never when a third-party handler owns the scheme. MirrorsAutostartManager::SelfHealOnStartup.Test plan
Verified end-to-end on:
aMule.app+aMuleGUI.app): cold-launch click, warm-launch click, prefs toggle, confirm dialog for third-party overrides.amule-dev-vm, source install):.desktopMimeType=advertises both schemes,xdg-mimepicks aMule automatically,mimeapps.listruntime toggle works.amule-dev-windows, portable install):HKCU\Software\Classes\{ed2k,magnet}populated by Prefs toggle; Firefox/Edge click delivery verified.Not yet exercised
SecProtocolsdefault-checked section + uninstall symmetry (only tested the portable build's runtime path).mimeapps.listsemantics.%uExec substitution.Leaving as draft until those three packaging paths are verified.
Known limitation
Chrome on Windows blocks
ed2k://clicks withabout:blank#blockedregardless of registration - Chromium'sExternalProtocolHandlerdoesn't allow-listed2k:.magnet:works because it's on the allow-list. Firefox works. See #233 for background; the practical mitigation is the Chrome extension route.Commits
feat: register ed2k:// and magnet: URL schemes cross-platform- the feature.po: regenerate catalogs after ProtocolHandlerManager string additions- required by the App-catalogs-in-sync CI check perscripts/update-po.sh.