/usr/share/pyshared/quodlibet/qltk/dbusmmkey.py is in exfalso 3.0.2-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | # -*- coding: utf-8 -*-
# Copyright 2007 Ronny Haryanto <ronny at haryan.to>
# 2011,2012 Christoph Reiter <christoph.reiter@gmx.at>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
import time
import dbus
from gi.repository import GObject
class DBusMMKey(GObject.GObject):
DBUS_NAME = "org.gnome.SettingsDaemon"
# Work around the gnome-settings-daemon dbus interface
# changing between 2.20 and 2.22 by connecting to both
# the old and new object.
DBUS_IFACES = [{"path": "/org/gnome/SettingsDaemon",
"interface": "org.gnome.SettingsDaemon"},
{"path": "/org/gnome/SettingsDaemon/MediaKeys",
"interface": "org.gnome.SettingsDaemon.MediaKeys"}]
__gsignals__ = {
'action': (GObject.SignalFlags.RUN_LAST, None, (str,)),
}
@classmethod
def is_active(cls):
"""If the gsd plugin is active atm"""
bus = dbus.Bus(dbus.Bus.TYPE_SESSION)
# FIXME: check if the media-keys plugin is active
return bus.name_has_owner(cls.DBUS_NAME)
def __init__(self, window, name):
super(DBusMMKey, self).__init__()
self.__interface = None
self.__watch = None
self.__grab_time = -1
self.__name = name
self.__key_pressed_sig = None
self.__grab()
self.__enable_watch()
self.__focus_sig = window.connect("notify::is-active",
self.__focus_event)
window.connect("destroy", self.__destroy)
def __destroy(self, window):
self.__disable_watch()
self.__release()
window.disconnect(self.__focus_sig)
def __update_interface(self):
"""If __interface is None, set a proxy interface object and connect
to the key pressed signal."""
if self.__interface:
return self.__interface
bus = dbus.Bus(dbus.Bus.TYPE_SESSION)
for desc in self.DBUS_IFACES:
try:
obj = bus.get_object(self.DBUS_NAME, desc["path"])
iface = dbus.Interface(obj, desc["interface"])
# try to call a method to test the interface
iface.ReleaseMediaPlayerKeys(self.__name)
except dbus.DBusException:
pass
else:
self.__key_pressed_sig = iface.connect_to_signal(
"MediaPlayerKeyPressed", self.__key_pressed)
self.__interface = iface
break
return self.__interface
def __enable_watch(self):
"""Enable events for dbus name owner change"""
if self.__watch:
return
bus = dbus.Bus(dbus.Bus.TYPE_SESSION)
# This also triggers for existing name owners
self.__watch = bus.watch_name_owner(self.DBUS_NAME,
self.__owner_changed)
def __disable_watch(self):
"""Disable name owner change events"""
if self.__watch:
self.__watch.cancel()
self.__watch = None
def __owner_changed(self, owner):
"""This gets called when the owner of the dbus name changes so we can
handle gnome-settings-daemon restarts."""
if not owner:
# owner gone, remove the signal matches/interface etc.
self.__release()
elif not self.__interface:
# new owner, get a new interface object and
# resend the last grab event
self.__grab(update=False)
def __key_pressed(self, application, action):
if application != self.__name:
return
self.emit("action", action)
def __grab(self, update=True):
"""Tells gsd that QL started or got the focus.
update: whether to send the current time or the last one"""
if update:
# so this breaks every 50 days.. ok..
t = int((time.time() * 1000)) & 0xFFFFFFFF
self.__grab_time = dbus.UInt32(t)
elif self.__grab_time < 0:
# can not send the last event if there was none
return
iface = self.__update_interface()
if not iface:
return
try:
iface.GrabMediaPlayerKeys(self.__name, self.__grab_time)
except dbus.DBusException:
pass
def __release(self):
"""Tells gsd that we don't want events anymore and
removes all signal matches"""
if self.__key_pressed_sig:
self.__key_pressed_sig.remove()
self.__key_pressed_sig = None
if self.__interface:
try:
self.__interface.ReleaseMediaPlayerKeys(self.__name)
except dbus.DBusException:
pass
self.__interface = None
def __focus_event(self, window, param):
if window.get_property(param.name):
self.__grab()
|