Merge lp:~larsu/gwibber/libmessaging-menu-port into lp:gwibber

Proposed by Lars Karlitski
Status: Merged
Merged at revision: 1375
Proposed branch: lp:~larsu/gwibber/libmessaging-menu-port
Merge into: lp:gwibber
Diff against target: 249 lines (+37/-120)
2 files modified
data/gwibber.desktop.in.in (+6/-0)
gwibber/microblog/dispatcher.py (+31/-120)
To merge this branch: bzr merge lp:~larsu/gwibber/libmessaging-menu-port
Reviewer Review Type Date Requested Status
Ken VanDine Approve
Review via email: mp+120961@code.launchpad.net
To post a comment you must log in.
1376. By Lars Karlitski

Add "Update Status" shortcut to the messaging menu

Revision history for this message
Ken VanDine (ken-vandine) wrote :

I am inclined to approve this, it looks fine however I am seeing some strange behavior. Perhaps it's a just a bug in libmessaging-menu. Should remove_source on the count remove the menu item or make it insensitive? Here's a simple example script:

from gi.repository import MessagingMenu
from gi.repository import GObject
from gi.repository import Gio
from gettext import lgettext as _

def activated (mmapp, source):
    print "%s has been activated" % source
    mmapp.set_source_count(source, 0)
    mmapp.remove_source(source)

if __name__ == "__main__":
    MESSAGES = _("Messages")
    REPLIES = _("Replies")
    PRIVATE = _("Private")
    mmapp = MessagingMenu.App.new ("gwibber.desktop")
    mmapp.register ()
    mmapp.append_source_with_count ("messages", None, MESSAGES, 0)
    mmapp.append_source_with_count ("replies", None, REPLIES, 0)
    mmapp.append_source_with_count ("private", None, PRIVATE, 0)
    mmapp.set_source_count ("messages", 123)
    mmapp.draw_attention ("replies")
    mmapp.connect("activate-source", activated)
    GObject.MainLoop().run()

Revision history for this message
Lars Karlitski (larsu) wrote :

What you're seeing is indeed a bug in libmessaging-menu. Gio's g_menu_get_item_attribute doesn't allow '&' in the variant format string anymore. Fix is coming.

By the way, I changed gwibber to not always show all streams in the messaging menu, but only the ones that have new messages. The "old" way of showing all streams all the time doesn't work anymore because libmessaging-menu removes sources as soon as they are activated. Thus, the activate callback calling the mmapp.remove_source in your example is redundant. Sorry that this isn't documented very well yet.

Revision history for this message
Ken VanDine (ken-vandine) wrote :

Oh, well is it also a bug that the count isn't getting removed? Is that the same bug that you mentioned?

Revision history for this message
Ken VanDine (ken-vandine) wrote :

Looks like all the remaining issues are really bugs in libmessaging-menu, so aprroved. Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'data/gwibber.desktop.in.in'
2--- data/gwibber.desktop.in.in 2011-09-26 18:39:07 +0000
3+++ data/gwibber.desktop.in.in 2012-08-23 11:01:38 +0000
4@@ -9,3 +9,9 @@
5 Categories=GTK;GNOME;Network;
6 X-GNOME-Gettext-Domain=gwibber
7 X-Ayatana-Appmenu-Show-Stubs=False
8+Actions=UpdateStatus
9+
10+[Desktop Action UpdateStatus]
11+Name=Update Status
12+Exec=gwibber-poster
13+OnlyShowIn=Messaging Menu;
14
15=== modified file 'gwibber/microblog/dispatcher.py'
16--- gwibber/microblog/dispatcher.py 2012-06-22 17:36:27 +0000
17+++ gwibber/microblog/dispatcher.py 2012-08-23 11:01:38 +0000
18@@ -35,9 +35,9 @@
19 pass
20
21 try:
22- from gi.repository import Indicate as indicate
23+ from gi.repository import MessagingMenu
24 except:
25- indicate = None
26+ MessagingMenu = None
27
28 GLib.threads_init()
29
30@@ -328,41 +328,23 @@
31 self.connection_monitor.connect_to_signal("ConnectionOnline", self.on_connection_online)
32 self.connection_monitor.connect_to_signal("ConnectionOffline", self.on_connection_offline)
33
34- self.indicator_items = {}
35+ self.stream_names = { 'messages': _('Messages'), 'replies': _('Replies'), 'private': _('Private') }
36 self.notified_items = []
37 self.notified_errors = {}
38- self.messages_indicator = None
39- self.replies_indicator = None
40- self.private_indicator = None
41 self.unseen_counts = {}
42 for s in "messages", "replies", "private":
43 self.unseen_counts[s] = 0
44
45- self.indicate = None
46+ self.mmapp = None
47 self.launcher = None
48
49 self.job_list = []
50
51- if indicate and util.resources.get_desktop_file():
52- self.indicate = indicate.Server.ref_default ()
53- self.indicate.set_type("message.gwibber")
54- self.indicate.set_desktop_file(util.resources.get_desktop_file())
55- if Dbusmenu and self.indicate:
56- post_menu = Dbusmenu.Menuitem.new ()
57- post_menu.property_set (Dbusmenu.MENUITEM_PROP_LABEL, _("Update Status"))
58- post_menu.property_set_bool (Dbusmenu.MENUITEM_PROP_VISIBLE, True)
59- post_menu.connect("item-activated", self.show_poster)
60-
61- menu_server = Dbusmenu.Server.new("/messaging/commands")
62- root = Dbusmenu.Menuitem.new ()
63- root.child_append (post_menu)
64- menu_server.set_root(root)
65- self.indicate.set_menu (menu_server)
66- self.indicate.connect("server-display", self.on_indicator_server_activate)
67- self.indicate.connect("interest-added", self.on_indicator_interest_added)
68- self.indicate.connect("interest-removed", self.on_indicator_interest_removed)
69- self.update_indicators(self.unseen_counts)
70- self.indicate.show()
71+ if MessagingMenu:
72+ self.mmapp = MessagingMenu.App(desktop_id='gwibber.desktop')
73+ self.mmapp.register()
74+ self.mmapp.connect('activate-source', self.on_messaging_menu_source_activated)
75+ self.update_message_sources(self.unseen_counts)
76
77 if Unity and Dbusmenu:
78 self.launcher = Unity.LauncherEntry.get_for_desktop_id ("gwibber.desktop")
79@@ -565,7 +547,7 @@
80 service = dbus.Interface(obj, "com.Gwibber.Service")
81 service.UpdateIndicators("stream")
82 """
83- self.handle_indicator_counts(stream)
84+ self.handle_message_source_counts(stream)
85
86 @dbus.service.method("com.Gwibber.Service", in_signature="s")
87 def SendMessage(self, message):
88@@ -702,28 +684,6 @@
89 logger.info("Gwibber Service is being shutdown")
90 self.mainloop.quit()
91
92- @dbus.service.method("com.Gwibber.Service", out_signature="b")
93- def IndicatorInterestCheck(self):
94- """
95- Check for interest from the messaging menu indicator
96- Returns a boolean
97- example:
98- import dbus
99- obj = dbus.SessionBus().get_object("com.Gwibber.Service", "/com/gwibber/Service")
100- service = dbus.Interface(obj, "com.Gwibber.Service")
101- res = service.IndicatorInterestCheck()
102- """
103- if indicate and self.indicate:
104- return self.indicate.check_interest(indicate.INTEREST_SERVER_DISPLAY)
105- else:
106- return False
107-
108- @dbus.service.signal("com.Gwibber.Service")
109- def IndicatorInterestAdded(self): pass
110-
111- @dbus.service.signal("com.Gwibber.Service")
112- def IndicatorInterestRemoved(self): pass
113-
114 @dbus.service.signal("com.Gwibber.Service", signature="s")
115 def Error(self, error): pass
116
117@@ -803,7 +763,7 @@
118 ",".join(self.messages.columns),
119 ",".join("?" * len(self.messages.columns))), items)
120
121- GLib.idle_add (self.update_indicators, self.unseen_counts)
122+ GLib.idle_add (self.update_message_sources, self.unseen_counts)
123 query = """
124 SELECT * FROM messages WHERE rowid > {0} AND
125 ((operation == "receive" AND to_me = 0) OR
126@@ -831,44 +791,18 @@
127 self.LoadingComplete()
128 logger.info("Loading complete: %s - %s", self.refresh_count, output.rowcount if output.rowcount > 0 else 0)
129
130- def update_indicators(self, counts):
131+ def update_message_sources(self, counts):
132 total_unseen = 0
133- if indicate:
134- if counts.has_key("messages"):
135- if not self.messages_indicator:
136- self.messages_indicator = indicate.Indicator() if hasattr(indicate, "Indicator") else indicate.IndicatorMessage()
137- self.messages_indicator.connect("user-display", self.on_indicator_activate)
138- self.messages_indicator.set_property("name", _("Messages"))
139- self.messages_indicator.set_property("stream", "messages")
140- self.messages_indicator.show()
141- self.messages_indicator.set_property("count", str(counts["messages"]))
142- total_unseen += counts["messages"]
143- if self.messages_indicator not in self.indicator_items:
144- self.indicator_items["messages"] = self.messages_indicator
145- if counts.has_key("replies"):
146- if not self.replies_indicator:
147- self.replies_indicator = indicate.Indicator() if hasattr(indicate, "Indicator") else indicate.IndicatorMessage()
148- self.replies_indicator.connect("user-display", self.on_indicator_activate)
149- self.replies_indicator.set_property("name", _("Replies"))
150- self.replies_indicator.set_property("stream", "replies")
151- self.replies_indicator.show()
152- self.replies_indicator.set_property("count", str(counts["replies"]))
153- total_unseen += counts["replies"]
154- if self.replies_indicator not in self.indicator_items:
155- self.indicator_items["replies"] = self.replies_indicator
156- if counts.has_key("private"):
157- if not self.private_indicator:
158- self.private_indicator = indicate.Indicator() if hasattr(indicate, "Indicator") else indicate.IndicatorMessage()
159- self.private_indicator.connect("user-display", self.on_indicator_activate)
160- self.private_indicator.set_property("name", _("Private"))
161- self.private_indicator.set_property("stream", "private")
162- self.private_indicator.show()
163- self.private_indicator.set_property("count", str(counts["private"]))
164- total_unseen += counts["private"]
165- if counts["private"] > 0:
166- self.private_indicator.set_property_bool("draw-attention", True)
167- if self.private_indicator not in self.indicator_items:
168- self.indicator_items["private"] = self.private_indicator
169+ pos = 0
170+ if self.mmapp:
171+ for source, name in self.stream_names.iteritems():
172+ if counts.has_key(source) and counts[source] > 0:
173+ if self.mmapp.has_source(source):
174+ self.mmapp.set_source_count(source, counts[source])
175+ else:
176+ self.mmapp.insert_source_with_count(pos, source, None, name, counts[source])
177+ total_unseen += counts[source]
178+ pos += 1
179 if Unity and self.launcher:
180 self.launcher.set_property("count", total_unseen)
181 if total_unseen < 1:
182@@ -877,28 +811,10 @@
183 self.launcher.set_property("count_visible", True)
184 return False
185
186- def on_indicator_interest_added(self, server, interest):
187- self.IndicatorInterestAdded()
188-
189- def on_indicator_interest_removed(self, server, interest):
190- self.IndicatorInterestRemoved()
191-
192- def on_indicator_server_activate(self, indicator, timestamp=None):
193- dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
194- client_bus = dbus.SessionBus()
195- logger.debug("Raising gwibber client")
196- try:
197- self.handle_indicator_counts()
198- except:
199- pass
200- self.show_client()
201-
202- def on_indicator_activate(self, indicator, timestamp=None):
203- if not indicate: return
204- stream = indicator.get_property("stream")
205+ def on_messaging_menu_source_activated(self, mmapp, stream):
206 logger.debug("Raising gwibber client, focusing %s stream", stream)
207 try:
208- self.handle_indicator_counts(stream)
209+ self.handle_message_source_counts(stream)
210 except:
211 pass
212 self.show_client(stream=stream)
213@@ -909,29 +825,24 @@
214 def handle_focus_error(self, *args):
215 logger.error("Failed to raise client %s", args)
216
217- def handle_indicator_counts(self, stream=None):
218- if indicate:
219+ def handle_message_source_counts(self, stream=None):
220+ if self.mmapp:
221 if not stream or stream == "home":
222- for s in self.indicator_items.keys():
223- self.indicator_items[s].set_property("count", str(0))
224- self.unseen_counts[s] = 0
225- if s == "private":
226- self.private_indicator.set_property_bool("draw-attention", False)
227+ for s in self.stream_names.keys():
228+ self.mmapp.remove_source(s)
229 if self.launcher:
230 self.launcher.set_property("count", 0)
231 self.launcher.set_property("count_visible", False)
232 return
233- if self.indicator_items.has_key(stream):
234- self.indicator_items[stream].set_property("count", str(0))
235- if stream == "private":
236- self.private_indicator.set_property_bool("draw-attention", False)
237+ else:
238+ self.mmapp.remove_source(stream)
239
240 self.unseen_counts[stream] = 0
241 if Unity:
242 total_unseen = 0
243 for s in self.unseen_counts.keys():
244 total_unseen += self.unseen_counts[s]
245- logger.debug ("handle_indicator_counts total_unseen is %d", total_unseen)
246+ logger.debug ("handle_message_source_counts total_unseen is %d", total_unseen)
247 if self.launcher:
248 self.launcher.set_property("count", total_unseen)
249 if total_unseen < 1: