3
# This is a part of the Cairo-Dock plug-ins.
4
# Copyright : (C) 2011 by Fabrice Rey
5
# E-mail : fabounet@glx-dock.org
7
# This program is free software; you can redistribute it and/or
8
# modify it under the terms of the GNU General Public License
9
# as published by the Free Software Foundation; either version 3
10
# of the License, or (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
# http://www.gnu.org/licenses/licenses.html#GPL
18
# Developped as a part of Cairo-Dock, but usable as a stand-alone systray daemon.
19
# The code follows the same logic as the KDE watcher, to ensure a complete compatibility.
24
import dbus, dbus.service
25
from dbus.mainloop.glib import DBusGMainLoop
27
class SNWatcher(dbus.service.Object):
28
bus_name_str = 'org.kde.StatusNotifierWatcher'
29
bus_obj_str = '/StatusNotifierWatcher'
30
bus_iface_str = 'org.kde.StatusNotifierWatcher'
31
items_list = [] # array of service+path
32
hosts_list = [] # array of services
35
DBusGMainLoop(set_as_default=True)
37
self.bus = dbus.SessionBus()
38
bus_name = dbus.service.BusName (self.bus_name_str, self.bus)
39
print "registered a watcher:",bus_name
40
dbus.service.Object.__init__(self, bus_name, self.bus_obj_str)
41
except Exception, exception:
42
print 'Could not open dbus. Uncaught exception.'
45
bus_object = self.bus.get_object(dbus.BUS_DAEMON_NAME, dbus.BUS_DAEMON_PATH)
46
self.main = dbus.Interface(bus_object, dbus.BUS_DAEMON_IFACE)
47
self.main.connect_to_signal("NameOwnerChanged", self.on_name_owner_changed)
49
self.loop = gobject.MainLoop()
52
def on_name_owner_changed(self, service, prev_owner, new_owner):
53
print "name_owner_changed: %s; %s; %s" % (service, prev_owner, new_owner)
54
if (new_owner == '' and not service.startswith(':')): # a service has disappear from the bus, check if it was an item or a host.
55
# search amongst the items.
57
print " search for ",match
59
for it in self.items_list:
60
print " check for ",it
61
if (it.startswith(match)): # it[0:len(match)] == match
63
to_be_removed.append(it)
64
for it in to_be_removed:
65
self.items_list.remove (it)
66
self.StatusNotifierItemUnregistered(it)
68
# search amongst the hosts.
70
for it in self.hosts_list:
72
to_be_removed.append(it)
73
for it in to_be_removed:
74
self.hosts_list.remove (it)
75
self.StatusNotifierHostUnregistered()
79
@dbus.service.method(dbus_interface = bus_iface_str, in_signature = 's', out_signature = None)
80
def RegisterStatusNotifierHost(self, service):
81
if (self.hosts_list.count (service) == 0): # if not already listed
82
self.hosts_list.append (service)
83
self.StatusNotifierHostRegistered()
84
print 'hosts:',self.hosts_list
87
@dbus.service.method(dbus_interface = bus_iface_str, in_signature = 's', out_signature = None, sender_keyword='sender')
88
def RegisterStatusNotifierItem(self, serviceOrPath, sender=None):
89
# build the item id: service + path
90
if (serviceOrPath[0] == '/'):
94
service = serviceOrPath
95
path = "/StatusNotifierItem"
97
itemId = service + path
98
# keep track of this new item, and emit the 'new' signal.
99
if (self.items_list.count (itemId) == 0): # if not already listed
100
self.items_list.append (itemId)
101
self.StatusNotifierItemRegistered (itemId)
105
@dbus.service.method(dbus_interface = dbus.PROPERTIES_IFACE, in_signature = 'ss', out_signature = 'v')
106
def Get(self, interface, property):
107
if interface == 'org.kde.StatusNotifierWatcher':
108
if property == 'RegisteredStatusNotifierItems':
109
print "items: ",self.items_list
110
if (len (self.items_list) != 0):
111
return self.items_list
112
else: # too bad! dbus-python can't encode the GValue if 'items_list' is None or [].
113
return [''] # so we return a empty string; hopefuly the host will skip this invalid value.
114
elif property == 'HasStatusNotifierHostRegistered':
115
return (len (self.hosts_list) != 0)
116
elif property == 'ProtocolVersion':
121
@dbus.service.signal(dbus_interface=bus_name_str, signature='s')
122
def StatusNotifierItemRegistered(self, service):
123
print "%s registered" % (service)
126
@dbus.service.signal(dbus_interface=bus_name_str, signature='s')
127
def StatusNotifierItemUnregistered(self, service):
128
print "%s unregistered" % (service)
131
@dbus.service.signal(dbus_interface=bus_name_str, signature=None)
132
def StatusNotifierHostRegistered(self):
133
print "a host has been registered"
136
@dbus.service.signal(dbus_interface=bus_name_str, signature=None)
137
def StatusNotifierHostUnregistered(self):
138
print "a host has been unregistered"
142
if __name__ == '__main__':