~ubuntu-branches/ubuntu/saucy/cairo-dock-plug-ins/saucy

« back to all changes in this revision

Viewing changes to Status-Notifier/watcher/status-notifier-watcher.py.in

Tags: upstream-3.0.0.0beta1
ImportĀ upstreamĀ versionĀ 3.0.0.0beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!@PYTHON_EXECUTABLE@
 
2
#
 
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
 
6
#
 
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.
 
11
#
 
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
 
17
#
 
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.
 
20
 
 
21
import sys
 
22
import glib
 
23
import gobject
 
24
import dbus, dbus.service
 
25
from dbus.mainloop.glib import DBusGMainLoop
 
26
 
 
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
 
33
        
 
34
        def __init__(self):
 
35
                DBusGMainLoop(set_as_default=True)
 
36
                try: 
 
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.'
 
43
                        return
 
44
                
 
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)
 
48
                
 
49
                self.loop = gobject.MainLoop()
 
50
                self.loop.run()
 
51
        
 
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.
 
56
                        match = service+'/'
 
57
                        print "  search for ",match
 
58
                        to_be_removed=[]
 
59
                        for it in self.items_list:
 
60
                                print "  check for ",it
 
61
                                if (it.startswith(match)):  # it[0:len(match)] == match
 
62
                                        print "    match!"
 
63
                                        to_be_removed.append(it)
 
64
                        for it in to_be_removed:
 
65
                                self.items_list.remove (it)
 
66
                                self.StatusNotifierItemUnregistered(it)
 
67
 
 
68
                        # search amongst the hosts.
 
69
                        to_be_removed=[]
 
70
                        for it in self.hosts_list:
 
71
                                if (it == service):
 
72
                                        to_be_removed.append(it)
 
73
                        for it in to_be_removed:
 
74
                                self.hosts_list.remove (it)
 
75
                                self.StatusNotifierHostUnregistered()
 
76
                
 
77
        ### methods ###
 
78
        
 
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
 
85
                sys.stdout.flush()
 
86
        
 
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] == '/'):
 
91
                        service = sender
 
92
                        path = serviceOrPath
 
93
                else:
 
94
                        service = serviceOrPath
 
95
                        path = "/StatusNotifierItem"
 
96
                
 
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)
 
102
        
 
103
        ### Properties ###
 
104
        
 
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':
 
117
                                return 0
 
118
        
 
119
        ### Signals ###
 
120
        
 
121
        @dbus.service.signal(dbus_interface=bus_name_str, signature='s')
 
122
        def StatusNotifierItemRegistered(self, service):
 
123
                print "%s registered" % (service)
 
124
                sys.stdout.flush()
 
125
        
 
126
        @dbus.service.signal(dbus_interface=bus_name_str, signature='s')
 
127
        def StatusNotifierItemUnregistered(self, service):
 
128
                print "%s unregistered" % (service)
 
129
                sys.stdout.flush()
 
130
        
 
131
        @dbus.service.signal(dbus_interface=bus_name_str, signature=None)
 
132
        def StatusNotifierHostRegistered(self):
 
133
                print "a host has been registered"
 
134
                sys.stdout.flush()
 
135
        
 
136
        @dbus.service.signal(dbus_interface=bus_name_str, signature=None)
 
137
        def StatusNotifierHostUnregistered(self):
 
138
                print "a host has been unregistered"
 
139
                sys.stdout.flush()
 
140
        
 
141
        
 
142
if __name__ == '__main__':
 
143
        SNWatcher()