Linux support: Unix socket transport (NEEDS TESTING on real Linux + Discord) - #1
Merged
Merged
Conversation
UNVERIFIED against a real Linux Discord client. Not released as a binary until someone confirms presence actually appears. See tests/ for what IS checked. The blocker was never packaging. Both endpoints this talks to are Unix domain sockets on Linux, and open() on a socket path fails with ENXIO, so the previous POSIX branches could not have worked - the transport was never written. UnixSocketStream wraps AF_UNIX behind read/write/close/fileno, which is the entire surface PipeReader, pump() and _send() use, so none of them needed a platform branch. bytes_available already had a select() branch that works on a socket via fileno(). open_ipc() picks the transport. discord_ipc_paths() also scans the Flatpak and Snap sandbox subdirectories. Scanning only XDG_RUNTIME_DIR is the usual reason a Linux presence tool looks like it does nothing on those installs. The shim now branches on uname for the two things that actually differ: the mpv binary name, and pipe-vs-socket for --input-ipc-server. install.sh writes ANI_CLI_PLAYER into the shell rc inside sentinel markers, so uninstall removes exactly what was added, and re-running repoints instead of stacking exports. tests/smoke_posix.py stands up a mock Discord and a mock mpv and asserts a real SET_ACTIVITY arrives with the right title and episode. That is the only automated evidence the socket transport works; CI runs it on real Linux and also builds the Linux binary, which PyInstaller cannot cross-compile. Windows is unaffected: discord_ipc_paths() still yields the same 10 named pipes, and the daemon was re-checked after the refactor. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Owner
Author
|
CI is green on the first run — all four jobs. The socket transport is verified at the protocol level on real Linux:
What this still does not cover, and why this PR stays open:
So: transport and framing are sound, integration is unproven. Still needs a human on Linux with Discord. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Status: needs a human with Linux and Discord
Everything here is written but has never run against a real Linux Discord client. It is deliberately not shipping as a release binary until someone confirms presence actually appears. If you are that person, testing this is the most useful thing you can do for the project right now — please comment with what you see.
Why Linux wasn't just a packaging job
The daemon's transport was Windows named pipes. On Linux both endpoints — mpv's
--input-ipc-serverand Discord's IPC socket — are Unix domain sockets, andopen()on a socket path fails withENXIO. The POSIX branches that were already in the file (lockfile singleton,select-basedbytes_available) showed intent, but the transport itself was never written, so it could not have worked.What changed
UnixSocketStreamwrapsAF_UNIXbehindread/write/close/fileno. That is the entire surfacePipeReader,pump()and_send()touch, so none of them needed a platform branch.bytes_availablealready had aselect()branch that works on a socket throughfileno().open_ipc(path)picksopen()on Windows, socket on POSIX.discord_ipc_paths()also scans the Flatpak and Snap sandbox subdirectories (app/com.discordapp.Discord/,snap.discord/). Scanning onlyXDG_RUNTIME_DIRis the usual reason a Linux presence tool appears to do nothing on those installs.unamefor the only two things that differ: the mpv binary name, and pipe-vs-socket for the IPC argument.install.shwritesANI_CLI_PLAYERinto the shell rc inside sentinel markers, so uninstall removes exactly what it added and re-running repoints rather than stacking duplicate exports. Same no-spaces-in-path check as Windows, for the same reason (ani-cli launches the player unquoted).What is actually verified
tests/smoke_posix.pystands up a mock Discord IPC socket and a mock mpv IPC socket, runs a real daemon against both, and asserts aSET_ACTIVITYarrives with the correct title and episode. CI runs it on real Linux, and also builds the Linux binary — PyInstaller cannot cross-compile, so that job is the only way the artifact exists at all.This proves the socket transport and framing. It does not prove presence renders in Discord. No mock can.
Windows is unaffected
discord_ipc_paths()still yields the same 10 named pipes, and the daemon was re-run after the refactor. v1.0.0 shipped frommainand is untouched by this branch.How to test
Please report your distro, how Discord is installed (native / Flatpak / Snap), and the log.