Ticket #1735: notifications-actions.patch
File notifications-actions.patch, 15.4 KB (added by , 3 years ago) |
---|
-
xpra/client/gtk3/gtk3_notifier.py
14 14 15 15 class GTK3_Notifier(NotifierBase): 16 16 17 def show_notify(self, dbus_id, tray, nid, app_id, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon):17 def show_notify(self, dbus_id, tray, nid, app_id, app_name, replaces_nid, app_icon, summary, body, action, hints, expire_timeout, icon): 18 18 if not self.dbus_check(dbus_id): 19 19 return 20 20 icon_string = self.get_icon_string(nid, app_icon, icon) -
xpra/client/gtk_base/gtk_notifier.py
104 104 def get_origin_y(self): 105 105 return self.y 106 106 107 def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon):107 def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout, icon): 108 108 self.new_popup(summary, body, icon) 109 109 110 110 def new_popup(self, summary, body, icon): -
xpra/client/notifications/dbus_notifier.py
5 5 6 6 import os 7 7 8 from xpra.util import repr_ellipsized 8 from xpra.util import repr_ellipsized, csv 9 9 from xpra.client.notifications.notifier_base import NotifierBase, log 10 10 try: 11 11 #new recommended way of using the glib main loop: … … 46 46 self.org_fd_notifications = self.dbus_session.get_object(FD_NOTIFICATIONS, '/org/freedesktop/Notifications') 47 47 self.dbusnotify = dbus.Interface(self.org_fd_notifications, FD_NOTIFICATIONS) 48 48 log("using dbusnotify: %s(%s)", type(self.dbusnotify), FD_NOTIFICATIONS) 49 log("capabilities=%s", csv(str(x) for x in self.dbusnotify.GetCapabilities())) 49 50 50 def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon):51 def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout, icon): 51 52 if not self.dbus_check(dbus_id): 52 53 return 53 54 self.may_retry = True … … 64 65 except: 65 66 app_str = app_name or "Xpra" 66 67 self.last_notification = (dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon) 67 self.dbusnotify.Notify(app_str, 0, icon_string, summary, body, [], [], expire_timeout,68 self.dbusnotify.Notify(app_str, 0, icon_string, summary, body, actions, hints, expire_timeout, 68 69 reply_handler = self.cbReply, 69 70 error_handler = self.cbError) 70 71 except: -
xpra/client/notifications/notifier_base.py
25 25 for nid in self.temp_files.keys(): 26 26 self.clean_notification(nid) 27 27 28 def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon):28 def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout, icon): 29 29 pass 30 30 31 31 def get_icon_string(self, nid, app_icon, icon): -
xpra/client/notifications/pynotify_notifier.py
10 10 11 11 class PyNotify_Notifier(NotifierBase): 12 12 13 def show_notify(self, dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon):13 def show_notify(self, dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout, icon): 14 14 if not self.dbus_check(dbus_id): 15 15 return 16 16 icon_string = self.get_icon_string(nid, app_icon, icon) … … 23 23 n = pynotify.Notification(summary, body, icon_string) 24 24 n.set_urgency(pynotify.URGENCY_LOW) 25 25 n.set_timeout(expire_timeout) 26 if actions and False: 27 while len(actions)>=2: 28 26 29 n.show() 27 30 31 def add_action(self, n, action_id, action_label): 32 #n.add_action("foo", "Foo!", foo_action) 33 def callback(*args): 34 pass 35 n.add_action(action_id, action_label, callback) 36 28 37 def close_notify(self, nid): 29 38 pass 30 39 … … 34 43 import gtk 35 44 def show(): 36 45 n = PyNotify_Notifier() 37 n.show_notify("", 0, "Test", 0, "", "Summary", "Body...", 0)46 n.show_notify("", 0, "Test", 0, "", "Summary", "Body...", [], {}, 0, "") 38 47 return False 39 48 glib.idle_add(show) 40 49 glib.timeout_add(20000, gtk.main_quit) -
xpra/client/ui_client_base.py
3430 3430 return 3431 3431 self._ui_event() 3432 3432 dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout = packet[1:9] 3433 icon, actions, hints = None, [], {} 3433 3434 if len(packet)>=10: 3434 3435 icon = packet[9] 3435 else:3436 icon = None3436 if len(packet)>=12: 3437 actions, hints = packet[10], packet[11] 3437 3438 #note: if the server doesn't support notification forwarding, 3438 3439 #it can still send us the messages (via xpra control or the dbus interface) 3439 3440 notifylog("_process_notify_show(%s) notifier=%s, server_notifications=%s", repr_ellipsized(str(packet)), self.notifier, self.server_notifications) 3441 notifylog.info("actions=%s, hints=%s", actions, hints) 3440 3442 assert self.notifier 3441 #TODO: choose more appropriate tray if we have more than one shown?3442 3443 #this one of the few places where we actually do care about character encoding: 3443 3444 try: 3444 3445 summary = summary.decode("utf8") … … 3449 3450 except: 3450 3451 body = bytestostr(body) 3451 3452 app_name = bytestostr(app_name) 3452 tray = self.get_tray_window(app_name )3453 tray = self.get_tray_window(app_name, hints) 3453 3454 traylog("get_tray_window(%s)=%s", app_name, tray) 3454 self.notifier.show_notify(dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon)3455 self.notifier.show_notify(dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout, icon) 3455 3456 3456 3457 def _process_notify_close(self, packet): 3457 3458 if not self.notifications_enabled: … … 3461 3462 log("_process_notify_close(%s)", nid) 3462 3463 self.notifier.close_notify(nid) 3463 3464 3464 def get_tray_window(self, app_name ):3465 def get_tray_window(self, app_name, hints): 3465 3466 #try to identify the application tray that generated this notification, 3466 3467 #so we can show it as coming from the correct systray icon 3467 3468 #on platforms that support it (ie: win32) 3469 try: 3470 pid = int(hints.get("pid") or 0) 3471 except (TypeError, ValueError): 3472 pass 3473 else: 3474 #TODO: try to find a tray with this pid? 3475 if pid: 3476 notifylog("tray window: match pid=%i", pid) 3468 3477 if app_name and app_name.lower()!="xpra": 3469 3478 #exact match: 3470 3479 for window in self._id_to_window.values(): -
xpra/dbus/notifications_forwarder.py
4 4 # later version. See the file COPYING for details. 5 5 6 6 import os 7 import gtk8 7 import dbus.service 9 8 9 from xpra.dbus.helper import dbus_to_native 10 10 from xpra.log import Logger 11 11 log = Logger("dbus", "notify") 12 12 … … 44 44 nid = replaces_nid 45 45 log("Notify%s counter=%i, callback=%s", (app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout), self.counter, self.notify_callback) 46 46 if self.notify_callback: 47 self.notify_callback(self.dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout) 47 try: 48 actions = tuple(str(x) for x in actions) 49 hints = dbus_to_native(hints) 50 args = self.dbus_id, int(nid), str(app_name), int(replaces_nid), str(app_icon), str(summary), str(body), actions, hints, int(expire_timeout) 51 except Exception as e: 52 log.error("Error: failed to parse Notify arguments:") 53 log.error(" %s", e) 54 try: 55 self.notify_callback(*args) 56 except Exception as e: 57 log.error("Error calling notification handler", exc_info=True) 48 58 log("Notify returning %s", nid) 49 59 return nid 50 60 … … 88 98 89 99 def main(): 90 100 register() 101 import gtk 91 102 gtk.main() 92 103 93 104 if __name__ == "__main__": -
xpra/platform/darwin/gui.py
110 110 self.notification_center = NSUserNotificationCenter.defaultUserNotificationCenter() 111 111 assert self.notification_center 112 112 113 def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon):113 def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout, icon): 114 114 notification = NSUserNotification.alloc().init() 115 115 notification.setTitle_(summary) 116 116 notification.setInformativeText_(body) … … 133 133 134 134 135 135 class OSX_Subprocess_Notifier(NotifierBase): 136 def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon):136 def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout, icon): 137 137 from xpra.platform.darwin import osx_notifier 138 138 osx_notifier_file = osx_notifier.__file__ 139 139 if osx_notifier_file.endswith("pyc"): -
xpra/platform/win32/win32_notifier.py
8 8 9 9 class Win32_Notifier(NotifierBase): 10 10 11 def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon):11 def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout, icon): 12 12 if tray is None: 13 13 log.warn("Warning: no system tray - cannot show notification!") 14 14 return -
xpra/server/server_base.py
1115 1115 def idle_grace_timeout_cb(self, source): 1116 1116 log("idle_grace_timeout_cb(%s)", source) 1117 1117 timeout_nid = 2**16 + 2**8 + 1 1118 source.notify(0, timeout_nid, "xpra", 0, "", "This Xpra session will timeout soon", "Activate one of the windows to avoid this timeout", 10)1118 source.notify(0, timeout_nid, "xpra", 0, "", "This Xpra session will timeout soon", "Activate one of the windows to avoid this timeout", [], {}, 10, "") 1119 1119 source.go_idle() 1120 1120 1121 1121 def _log_disconnect(self, proto, *args): … … 1784 1784 notifylog("control_command_send_notification(%i, %s, %s, %s) will send to sources %s (matching %s)", nid, title, message, client_uuids, sources, client_uuids) 1785 1785 count = 0 1786 1786 for source in sources: 1787 if source.notify(0, nid, "control channel", 0, "", title, message, 10, ()):1787 if source.notify(0, nid, "control channel", 0, "", title, message, [], {}, 10, ""): 1788 1788 count += 1 1789 1789 msg = "notification id %i: message sent to %i clients" % (nid, count) 1790 1790 notifylog(msg) … … 2615 2615 if self._clipboard_client: 2616 2616 self._clipboard_client.send_clipboard(parts) 2617 2617 2618 def notify_callback(self, dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout):2618 def notify_callback(self, dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout): 2619 2619 try: 2620 2620 assert self.notifications_forwarder and self.notifications 2621 2621 icon = self.get_notification_icon(str(app_icon)) 2622 2622 if os.path.isabs(str(app_icon)): 2623 2623 app_icon = "" 2624 notifylog("notify_callback%s icon=%s", (dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout), repr_ellipsized(str(icon)))2624 notifylog("notify_callback%s icon=%s", (dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout), repr_ellipsized(str(icon))) 2625 2625 for ss in self._server_sources.values(): 2626 ss.notify(dbus_id, int(nid), str(app_name), int(replaces_nid), str(app_icon), str(summary), str(body), int(expire_timeout), icon)2626 ss.notify(dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout, icon) 2627 2627 except Exception as e: 2628 2628 notifylog("notify_callback failed", exc_info=True) 2629 2629 notifylog.error("Error processing notification:") -
xpra/server/source.py
1962 1962 return 1963 1963 self.send_async("bell", wid, device, percent, pitch, duration, bell_class, bell_id, bell_name) 1964 1964 1965 def notify(self, dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon):1966 args = (dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon)1965 def notify(self, dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout, icon): 1966 args = (dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout, icon) 1967 1967 notifylog("notify%s types=%s", args, tuple(type(x) for x in args)) 1968 1968 if not self.send_notifications: 1969 1969 notifylog("client %s does not support notifications", self) … … 1981 1981 except: 1982 1982 body = str(body) 1983 1983 if self.hello_sent: 1984 self.send_async("notify_show", dbus_id, int(nid), str(app_name), int(replaces_nid), str(app_icon), summary, body, int(expire_timeout), icon) 1984 #Warning: actions and hints are send last because they were added later (in version 2.3) 1985 self.send_async("notify_show", dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon, actions, hints) 1985 1986 return True 1986 1987 1987 1988 def notify_close(self, nid):