Skip to content

fix(mpris): send actions in the phone's spelling and seek phones with SetPosition - #49

Merged
bethropolis merged 3 commits into
bethropolis:mainfrom
Rishabh672003:fix/mpris-actions-seek
Oct 4, 2026
Merged

bethropolis merged 3 commits into
bethropolis:mainfrom
Rishabh672003:fix/mpris-actions-seek

Conversation

@Rishabh672003

@Rishabh672003 Rishabh672003 commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Two MPRIS commands return ok but do nothing on an Android phone.

Action names. The docs list lowercase actions (playpause, next), but Android only matches PlayPause, Next, etc. Known actions are now mapped to the phone's spelling.

Seek. Android has no Seek handler, only SetPosition, so kcd mpris seek +30s does nothing (checked on kcd 1.22.0). A relative seek is now sent as SetPosition from the tracked position, and the documented setPosition field now works.

Docs updated to match.

Testing: new unit tests and the full suite pass. Checked on a phone: with this branch, setPosition moves playback.

Not changed: protocol Seek is in µs, but kcd uses ms. The fallback (no tracked position) and incoming Seek in playerctl.go still mix the two.

AI assisted

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
@bethropolis

Copy link
Copy Markdown
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
bethropolis merged commit 5dba20e into bethropolis:main Oct 4, 2026
9 checks passed
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.
@Rishabh672003
Rishabh672003 deleted the fix/mpris-actions-seek branch October 5, 2026 07:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants