Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# -*- coding: utf-8 -*- 

2# This file is part of Xpra. 

3# Copyright (C) 2010-2020 Antoine Martin <antoine@xpra.org> 

4# Xpra is released under the terms of the GNU GPL v2, or, at your option, any 

5# later version. See the file COPYING for details. 

6 

7from xpra.util import typedict 

8from xpra.server.source.stub_source_mixin import StubSourceMixin 

9from xpra.log import Logger 

10 

11log = Logger("notify") 

12 

13 

14class NotificationMixin(StubSourceMixin): 

15 

16 @classmethod 

17 def is_needed(cls, caps : typedict) -> bool: 

18 return caps.boolget("notifications", False) 

19 

20 

21 def init_state(self): 

22 self.send_notifications = False 

23 self.send_notifications_actions = False 

24 self.notification_callbacks = {} 

25 

26 def parse_client_caps(self, c : typedict): 

27 self.send_notifications = c.boolget("notifications") 

28 self.send_notifications_actions = c.boolget("notifications.actions") 

29 log("notifications=%s, actions=%s", self.send_notifications, self.send_notifications_actions) 

30 

31 def get_info(self) -> dict: 

32 return { 

33 "notifications" : self.send_notifications, 

34 } 

35 

36 ###################################################################### 

37 # notifications: 

38 # Utility functions for mixins (makes notifications optional) 

39 def may_notify(self, nid=0, summary="", body="", actions=(), hints=None, expire_timeout=10*1000, 

40 icon_name=None, user_callback=None): 

41 try: 

42 from xpra.platform.paths import get_icon_filename 

43 from xpra.notifications.common import parse_image_path 

44 except ImportError as e: 

45 log("not sending notification: %s", e) 

46 else: 

47 icon_filename = get_icon_filename(icon_name) 

48 icon = parse_image_path(icon_filename) or "" 

49 self.notify("", nid, "Xpra", 0, "", 

50 summary, body, actions, hints or {}, 

51 expire_timeout, icon, user_callback) 

52 

53 def notify(self, dbus_id, nid, app_name, replaces_nid, app_icon, 

54 summary, body, actions, hints, expire_timeout, icon, user_callback=None): 

55 args = (dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, actions, hints, expire_timeout, icon) 

56 log("notify%s types=%s", args, tuple(type(x) for x in args)) 

57 if not self.send_notifications: 

58 log("client %s does not support notifications", self) 

59 return False 

60 #"suspended" belongs in the WindowsMixin: 

61 if getattr(self, "suspended", False): 

62 log("client %s is suspended, notification not sent", self) 

63 return False 

64 if user_callback: 

65 self.notification_callbacks[nid] = user_callback 

66 #this is one of the few places where we actually do care about character encoding: 

67 try: 

68 summary = summary.encode("utf8") 

69 except UnicodeEncodeError: 

70 summary = str(summary) 

71 try: 

72 body = body.encode("utf8") 

73 except UnicodeEncodeError: 

74 body = str(body) 

75 if self.hello_sent: 

76 #Warning: actions and hints are send last because they were added later (in version 2.3) 

77 self.send_async("notify_show", dbus_id, nid, app_name, replaces_nid, app_icon, 

78 summary, body, expire_timeout, icon, actions, hints) 

79 return True 

80 

81 def notify_close(self, nid : int): 

82 if not self.send_notifications or self.suspended or not self.hello_sent: 

83 return 

84 self.send_more("notify_close", nid)