[Linux] Read MPRIS PlaybackStatus without introspection - #741
Open
harisb2012 wants to merge 1 commit into
Open
Conversation
Chromium serves an empty Introspect document, so the metaobject QDBusInterface builds from it carries no properties and property() returns an invalid QVariant for a browser that is plainly playing. Ear detection then skipped it, leaving browsers running with a pod out.
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.
What goes wrong
With ear detection set to pause when one pod is removed, Spotify pauses correctly but a video playing in Chromium keeps going. It only stops when both pods come out, and that is not the pause path:
removeAudioOutputDevice()sets the card profile tooff, the sink disappears, and Chromium stops itself.Why
Chromium answers
Introspectwith an empty document:QDBusInterfacebuilds its metaobject from that document, so for Chromium it carries no properties andproperty("PlaybackStatus")returns an invalid QVariant while the player is plainly Playing.MediaController::pause(),MediaController::getPlayingMediaPlayers()andPlayerStatusWatcher::getCurrentPlaybackStatus()all read the status that way, so Chromium is skipped in the pause loop, and with Chromium as the only playergetCurrentMediaState()never returns Playing, sohandleEarDetection()does not even reachpause().Spotify ships a normal introspection document, which is why it was never affected.
Standalone reproduction, no AirPods needed:
repro.cpp
With a video playing in Chromium:
The fix
Read the property with a direct
org.freedesktop.DBus.Properties.Get, which needs no introspection, and route the three status reads through it. Method calls were never affected, becausecall("Pause")goes out as a message without consulting the metaobject, sopause()andplay()are otherwise unchanged.Worth noting the Rust rewrite on
linux/rustalready does exactly this inmedia_controller.rs, using thedbuscrate'sProperties::get. This brings the Qt tree in line with it.Relation to #424
#424 targets the same symptom and describes it as browsers that "don't register properly with DBus". That part is not quite right: Chromium registers fine and answers
Properties.Getcorrectly, it just serves an empty introspection document, which is a Qt metaobject problem rather than a registration problem. That PR fixes it by shelling out toplayerctlas a fallback and by removing theisActiveOutputDeviceAirPods()check. This one needs no new runtime dependency (playerctlis not installed on my machine, so that fallback would not have helped here) and keeps the active-device check intact.The MAC formatting issue @Jimoz77 raised on that PR is a separate bug and is not addressed here.
The same fix is up against the omapods fork of this daemon at thisisgm/omarchy-pods#22, where it is running on my machine.
What I ran
Arch Linux, Qt 6.11.1, PipeWire with WirePlumber, Chromium on Wayland, AirPods Pro 3 (A3047).
Before, unpatched daemon with debug logging, one pod removed while Chromium was playing:
No
Pausing playback for ear detectionand noPaused playback for. The video kept playing.After, same hardware and same gesture:
Resume on reinsert works now too, which it never did for Chromium, since nothing was being recorded in
pausedByAppServices.cmake --build buildonlinux/is clean, no new warnings.One question
The Linux bug report template marks the Qt version as not maintained. I sent this anyway because the tree is still what several downstreams build from, and it is a three line change with no new dependency. Happy to close it if you would rather not carry patches here.