Mate namespace for MediaKeys not supported by any application #7

Closed
cvtsi2sd opened this Issue May 29, 2012 · 14 comments

Projects

None yet

8 participants

@cvtsi2sd

(following from this Linux Mint forums thread)

In the fork mate-settings-daemon has been updated to provide all its interfaces under org.mate.SettingsDaemon instead of the old org.gnome.SettingsDaemon.

While this is correct to avoid conflicts and to completely separate MATE and Gnome, this gives us a compability problem with any application that continue to refers to the old org.gnome.SettingsDaemon, in particular multimedia applications that want to receive notifications about multimedia keys presses.

As a temporary workaround I wrote a little Python script that emulates the org.gnome.SettingsDaemon.MediaKeys object, pushing notifications when it receives them from org.mate.SettingsDaemon.MediaKeys; it works fine, but it seems to me just a weak workaround.

Since we don't know if MATE will ever gain enough momentum to make developers of most media players patch their programs to support also MATE explicitly, in my opinion the best fix would be to abandon the media-keys notification mechanism inherited from Gnome (that, at the moment, no media players that I know of support) and move to something more standard: for example, we could use MPRIS2 to communicate with any compatible media player.

AFAIK MPRIS2 works "backwards" compared to the current mechanism (mate-settings-daemon should enumerate the currently running media players and tell them what to do, instead of a plain "media key pressed" notification), but:

  • it's standard (endorsed by FreeDesktop.org);
  • it's quite widely supported;
  • the number of media players that support it out of the box is growing, since many widely used components use it to remote-control media players (e.g. Ubuntu sound indicator menu).
@cvtsi2sd

Simpler script that uses MPRIS2 instead of emulating gnome-settings-daemon.

@szesch
Member
szesch commented Jun 22, 2012

The problem with MPRIS2 is that it seems to assume you know which media player you want to interact with, or in other words, you know which media player is currently playing music/video and should be told what media key was pressed. This is obviously something of an issue.

gnome-settings-daemon essentially requires a media player to register with it via GrabMediaPlayerKeys. Whatever client was registered last gnome-settings-daemon assumes is the client that should be notified of the key press. From what I've seen of MPRIS2, it doesn't seem like there exists any functionality to achieve this.

I do agree that we need an alternative to having clients register with mate-settings-daemon, since I can't imagine VLC, Banshee, Clementine, etc. adding support for it any time soon. We just need to find a nice non-hack solution to determining which media player MPRIS2 needs to notify.

Thoughts?

@cvtsi2sd

I suppose we could just listen on D-Bus for messages of someone acquiring any name under org.mpris.MediaPlayer2 (I recall that there's some message for that that is sent globally), keep a "most recently started" queue of players and send the message only to the top element of the queue; in the improbable event that more than one player is already running before mate-settings-daemon is started we can just pick one random.

I don't know how demanding is this in terms of resources wasted, but even if we listened to every "new name registered under DBus" it shouldn't be a big deal, I never such incredible traffic of messages with dbus-monitor; still, an alternative would be polling, asking every e.g. 1 second the list of mpris-enabled players, but if you ask me it feels like a cheap hack (and it feels also more demanding on system resources).

... but isn't it a strange corner-case to have multiple media players opened in first place? And also the current method of giving the key signals just to the last opened player IMHO isn't perfect, it introduces some implicit "music player focus" that isn't so clear (although it has the big advantage that, if the user doesn't like the "focused" player it can intuitively close it and give the "music focus" to the previous one).

@brianjmurrell

I wonder how many other org.gnome interfaces are used by non-core gnome (i.e. applications not being covered in the MATE project) and will break because of the aggressive s/gnome/mate/g operation.

Certainly, going to MPRIS2 seems to be a standards based solution to this particular instance of the s/gnome/mate/g operation (and one might hope that GNOME will follow with the adoption of MPRIS2, if they are not already, rather than continuing to use their org.gnome.SettingsDaemon interface) but I wonder how many else are out there.

@szesch
Member
szesch commented Jul 27, 2012
@szesch szesch was assigned Aug 3, 2012
@thassan
Contributor
thassan commented Dec 15, 2012

@matteo-italia It isn't strange nor corner case to have multiple media players opened. For example, I could have banshee playing music, then pause it (and dock to systray), and open a video file/stream in VLC. Now, if I try to use media keys on keyboard, or an irda remote control, which of the players will get the media-key-press notification(s)?

@alirezaimi

Hi
in fedora 18 not worked ,
Traceback (most recent call last):
File "/usr/lib/python2.7/site-packages/dbus/connection.py", line 230, in maybe_handle_message
self._handler(_args, *_kwargs)
File "mmkeys-mate2mpris2.py", line 39, in onMediaKeyPress
sb.get_object(n, '/org/mpris/MediaPlayer2').getattr(ActionMappings[action])()
File "/usr/lib/python2.7/site-packages/dbus/proxies.py", line 70, in call
return self._proxy_method(_args, *_keywords)
File "/usr/lib/python2.7/site-packages/dbus/proxies.py", line 145, in call
**keywords)
File "/usr/lib/python2.7/site-packages/dbus/connection.py", line 651, in call_blocking
message, timeout)
DBusException: org.freedesktop.DBus.Error.UnknownMethod: No such interface `(null)' on object at path /org/mpris/MediaPlayer2

@brianjmurrell

@alirezaimi,

I had the same problem and contacted matteo-italia. Nothing resulted as of it though. I use this script now.

#!/usr/bin/env python

import dbus
import dbus.mainloop.glib
import gobject

app_name = 'mmkeys-mate2mpris2'
Version=0.1

MediaKeysObjName = 'org.mate.SettingsDaemon'
MediaKeysObjectPath = '/org/mate/SettingsDaemon/MediaKeys'
MediaKeysInterface = 'org.mate.SettingsDaemon.MediaKeys'

MPRIS2Prefix = 'org.mpris.MediaPlayer2'

ActionMappings = {
        'Play': 'PlayPause',
        'Pause': 'Pause',
        'Stop': 'Stop',
        'Next': 'Next',
        'Previous': 'Previous'}


def onMediaKeyPress(app_name, action):
    sb = dbus.SessionBus()
    # Get the compatible players
    players = [n for n in sb.list_names() if n.startswith(MPRIS2Prefix + ".") ]

    # Send them the command
    for n in players:
        targetObject = sb.get_object(n, '/org/mpris/MediaPlayer2')
        mpris = dbus.Interface(targetObject, dbus_interface='org.mpris.MediaPlayer2.Player')
        properties = dbus.Interface(targetObject, dbus_interface='org.freedesktop.DBus.Properties')

        mpris.__getattr__(ActionMappings[action])()

if __name__ == '__main__':

    # DBUS boilerplate
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
    sb = dbus.SessionBus()

    # Get the media keys notificator object
    mediaKeysObj = sb.get_object(MediaKeysObjName, MediaKeysObjectPath)

    # Register to receive media keys notifications
    mediaKeysObj.GrabMediaPlayerKeys(app_name, 0, dbus_interface=MediaKeysInterface)
    mediaKeysObj.connect_to_signal('MediaPlayerKeyPressed', onMediaKeyPress)

    # Start the main loop
    mainLoop = gobject.MainLoop()
    mainLoop.run()
@cvtsi2sd

@brianjmurrell I'm sorry, I didn't have much time to debug the issue at the time, and it would have been mostly blind tries, I don't grock much DBus; also, I moved to KDE on my main machine, so I would have to set up a VM just to try to fix it. Still, glad you solved! :)

@brianjmurrell

@matteo-italia,

No worries. Made me learn a bit about dbus anyway. :-)

@alirezaimi

@brianjmurrell Thanks a lot, problem solved.

@stefano-k stefano-k was assigned Mar 21, 2013
@stefano-k
Member

Implemented as plugin
9384398

@stefano-k stefano-k closed this Mar 22, 2013
@xtknight
xtknight commented May 9, 2013

There's a slight problem with the fix in the original post. This fixes it and makes (at least) Totem work properly.

What happen is that Totem reregisters itself every time it gets focus, thereby adding 'Totem' to the self.__apps list multiple times. Then, multiple events get sent, so it instantly plays/pauses, skipping a frame each time. Make the change to this area of the code.

@dbus.service.method(dbus_interface=Gnome_DbusInterface, in_signature='sd', out_signature='')
def GrabMediaPlayerKeys(self, app_name, time):
    if not (app_name in self.__apps): ## HERE
        self.__apps.append(app_name) ## HERE

@dbus.service.method(dbus_interface=Gnome_DbusInterface, in_signature='s', out_signature='')
def ReleaseMediaPlayerKeys(self, app_name):
    if app_name in self.__apps: ## HERE
        self.__apps.remove(app_name) ## HERE
@michaxm
michaxm commented Jan 13, 2016

With 1.8.1-0+qiana multimedia keys still do not work for me and totem on at least 3 different machines. What does "as a plugin" mean? Am I supposed to activate it somehow? Could not find anything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment