def parse_hints(self, h) -> dict: hints = {} for x in ("action-icons", "category", "desktop-entry", "resident", "transient", "x", "y", "urgency"): v = h.get(x) if v is not None: hints[x] = native_to_dbus(v) image_data = h.get("image-data") if image_data and bytestostr(image_data[0]) == "png": try: from xpra.codecs.pillow.decoder import open_only img_data = image_data[3] img = open_only(img_data, ("png", )) w, h = img.size channels = len(img.mode) rowstride = w * channels has_alpha = img.mode == "RGBA" pixel_data = bytearray(img.tobytes("raw", img.mode)) log.info("pixel_data=%s", type(pixel_data)) args = w, h, rowstride, has_alpha, 8, channels, pixel_data hints["image-data"] = tuple(native_to_dbus(x) for x in args) #hints["image-data"] = args except Exception as e: log("parse_hints(%s) error on image-data=%s", h, image_data, exc_info=True) log.error("Error parsing notification image:") log.error(" %s", e) log("parse_hints(%s)=%s", h, hints) #return dbus.types.Dictionary(hints, signature="sv") return hints
def NotifyError(self, dbus_error, *_args): try: if isinstance(dbus_error, dbus.exceptions.DBusException): message = dbus_error.get_dbus_message() dbus_error_name = dbus_error.get_dbus_name() if dbus_error_name != "org.freedesktop.DBus.Error.ServiceUnknown": log.error("unhandled dbus exception: %s, %s", message, dbus_error_name) return False if not self.may_retry: log.error("Error: cannot send notification via dbus,") log.error( " check that you notification service is operating properly" ) return False self.may_retry = False log.info("trying to re-connect to the notification service") #try to connect to the notification again (just once): self.setup_dbusnotify() #and retry: self.show_notify(*self.last_notification) except Exception: log("cannot filter error", exc_info=True) log.error("Error processing notification:") log.error(" %s", dbus_error) return False
def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout, icon): if not self.dbus_check(dbus_id): return self.may_retry = True try: icon_string = self.get_icon_string(nid, app_icon, icon) log("get_icon_string%s=%s", (nid, app_icon, ellipsizer(icon)), icon_string) try: app_str = self.app_name_format % app_name except TypeError: app_str = app_name or "Xpra" self.last_notification = (dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon) def NotifyReply(notification_id): log("NotifyReply(%s) for nid=%i", notification_id, nid) self.actual_notification_id[nid] = int(notification_id) dbus_hints = self.parse_hints(hints) self.dbusnotify.Notify(app_str, 0, icon_string, summary, body, actions, dbus_hints, expire_timeout, reply_handler=NotifyReply, error_handler=self.NotifyError) except Exception: log.error("Error: dbus notify failed", exc_info=True)