fix(mpris): send actions in the phone's spelling and seek phones with SetPosition - #49
Merged
bethropolis merged 3 commits intoOct 4, 2026
Merged
Conversation
The docs list lowercase actions ("playpause", "next", ...) but the
daemon forwarded them verbatim and KDE Connect Android matches only
Play, Pause, PlayPause, Next, Previous and Stop, so documented requests
returned ok and the phone ignored them. Normalise known names
case-insensitively; anything else passes through unchanged.
AI assisted
KDE Connect Android's MprisReceiverPlugin implements SetPosition but never reads Seek, so seeking a phone (mpris_action "seek", and kcd mpris seek) did nothing. A relative seek is now sent as an absolute SetPosition computed from the tracked position, and mpris_action now honours the documented setPosition field for absolute seeks. Only one of the two is ever sent, since a desktop peer would apply both. AI assisted
Actions are matched case-insensitively, volume uses the volume field (there is no setVolume in the IPC payload), and a relative seek is sent to phones as an absolute position. AI assisted
Owner
|
Thank you for this. this is a great write up, also great work on solving the seek issue I'll review this and merge in the next release |
bethropolis
added a commit
that referenced
this pull request
Oct 4, 2026
Issue #50: `kcd mpris seek -10s` was rejected as an unknown flag. The offset parser was always right about "-10s"; urfave/cli never handed it the string, because it reads any argument starting with "-" as a flag. `-- -10s` worked around it, so the help text was advertising a form that did not parse. `kcd mpris seek` now sets SkipFlagParsing and recovers --device/--player itself. A "-" followed by a digit is the offset, which is unambiguous here because neither flag takes a numeric value. Anything else starting with "-" stays an error, so a typo like "--vol 5" cannot seek the wrong device by being silently ignored. SkipFlagParsing also stops urfave/cli handling -h, so that is recognised and routed to the subcommand help. Second fix, same plugin. A relative seek is sent to the phone as an absolute SetPosition, since phones implement SetPosition but ignore Seek. That conversion needs the tracked playback position, and when there was none the old code fell through and sent nothing at all -- a no-op that still reported success, which is the failure mode #49 set out to fix. It now returns an error naming the cause. An absolute setPosition or bare number needs no cached state and is unaffected. While here: SendAction's doc comment had drifted onto the canonicalActions var two declarations above it, so the function that sends on two packet types documented none of it. Verified against a paired phone with a track playing: -10s, -20s, +30s, +20s and the absolute 1m30s all move the position, `-- -15s` still works, and clamping holds at both ends of the track. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
bethropolis
added a commit
that referenced
this pull request
Oct 4, 2026
Issue #50: `kcd mpris seek -10s` was rejected as an unknown flag. The offset parser was always right about "-10s"; urfave/cli never handed it the string, because it reads any argument starting with "-" as a flag. `-- -10s` worked around it, so the help text was advertising a form that did not parse. `kcd mpris seek` now sets SkipFlagParsing and recovers --device/--player itself. A "-" followed by a digit is the offset, which is unambiguous here because neither flag takes a numeric value. Anything else starting with "-" stays an error, so a typo like "--vol 5" cannot seek the wrong device by being silently ignored. SkipFlagParsing also stops urfave/cli handling -h, so that is recognised and routed to the subcommand help. Second fix, same plugin. A relative seek is sent to the phone as an absolute SetPosition, since phones implement SetPosition but ignore Seek. That conversion needs the tracked playback position, and when there was none the old code fell through and sent nothing at all -- a no-op that still reported success, which is the failure mode #49 set out to fix. It now returns an error naming the cause. An absolute setPosition or bare number needs no cached state and is unaffected. While here: SendAction's doc comment had drifted onto the canonicalActions var two declarations above it, so the function that sends on two packet types documented none of it. Verified against a paired phone with a track playing: -10s, -20s, +30s, +20s and the absolute 1m30s all move the position, `-- -15s` still works, and clamping holds at both ends of the track.
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.
Two MPRIS commands return
okbut do nothing on an Android phone.Action names. The docs list lowercase actions (
playpause,next), but Android only matchesPlayPause,Next, etc. Known actions are now mapped to the phone's spelling.Seek. Android has no
Seekhandler, onlySetPosition, sokcd mpris seek +30sdoes nothing (checked on kcd 1.22.0). A relative seek is now sent asSetPositionfrom the tracked position, and the documentedsetPositionfield now works.Docs updated to match.
Testing: new unit tests and the full suite pass. Checked on a phone: with this branch,
setPositionmoves playback.Not changed: protocol
Seekis in µs, but kcd uses ms. The fallback (no tracked position) and incomingSeekinplayerctl.gostill mix the two.AI assisted