Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* add dbus and xpra control interface for sending notifications to the clients
* better debug logging

git-svn-id: https://xpra.org/svn/Xpra/trunk@13678 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Sep 13, 2016
1 parent d285285 commit 939d36e
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 12 deletions.
3 changes: 1 addition & 2 deletions src/xpra/client/gtk_base/gtk_tray_menu_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,7 @@ def notifications_toggled(*args):
def set_notifications_menuitem(*args):
log("set_notifications_menuitem%s enabled=%s", args, self.client.notifications_enabled)
self.notifications_menuitem.set_active(self.client.notifications_enabled)
c = self.client
can_notify = c.server_supports_notifications and c.client_supports_notifications
can_notify = self.client.client_supports_notifications
set_sensitive(self.notifications_menuitem, can_notify)
if can_notify:
self.notifications_menuitem.set_tooltip_text("Forward system notifications")
Expand Down
14 changes: 9 additions & 5 deletions src/xpra/client/ui_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
clipboardlog = Logger("clipboard")
scalinglog = Logger("scaling")
webcamlog = Logger("webcam")
notifylog = Logger("notify")


from xpra import __version__ as XPRA_VERSION
Expand Down Expand Up @@ -455,9 +456,10 @@ def show_tray(*args):
#show when the main loop is running:
self.idle_add(self.tray.show)

notifylog("client_supports_notifications=%s", self.client_supports_notifications)
if self.client_supports_notifications:
self.notifier = self.make_notifier()
traylog("using notifier=%s", self.notifier)
notifylog("using notifier=%s", self.notifier)
self.client_supports_notifications = self.notifier is not None

#audio tagging:
Expand Down Expand Up @@ -798,7 +800,7 @@ def make_clipboard_helper(self):

def make_notifier(self):
nc = self.get_notifier_classes()
traylog("make_notifier() notifier classes: %s", nc)
notifylog("make_notifier() notifier classes: %s", nc)
return self.make_instance(nc)

def get_notifier_classes(self):
Expand Down Expand Up @@ -1722,7 +1724,7 @@ def parse_server_capabilities(self):
self.server_window_decorations = c.boolget("window.decorations")
self.server_window_frame_extents = c.boolget("window.frame-extents")
self.server_supports_notifications = c.boolget("notifications")
self.notifications_enabled = self.server_supports_notifications and self.client_supports_notifications
self.notifications_enabled = self.client_supports_notifications
self.server_supports_cursors = c.boolget("cursors", True) #added in 0.5, default to True!
self.cursors_enabled = self.server_supports_cursors and self.client_supports_cursors
self.server_supports_bell = c.boolget("bell") #added in 0.5, default to True!
Expand Down Expand Up @@ -2573,7 +2575,6 @@ def _process_sound_data(self, packet):

def send_notify_enabled(self):
assert self.client_supports_notifications, "cannot toggle notifications: the feature is disabled by the client"
assert self.server_supports_notifications, "cannot toggle notifications: the feature is disabled by the server"
self.send("set-notify", self.notifications_enabled)

def send_bell_enabled(self):
Expand Down Expand Up @@ -3001,10 +3002,13 @@ def _process_bell(self, packet):

def _process_notify_show(self, packet):
if not self.notifications_enabled:
notifylog("process_notify_show: ignoring packet, notifications are disabled")
return
self._ui_event()
dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout = packet[1:9]
log("_process_notify_show(%s)", packet)
#note: if the server doesn't support notification forwarding,
#it can still send us the messages (via xpra control or the dbus interface)
notifylog("_process_notify_show(%s) notifier=%s, server_supports_notifications", packet, self.notifier, self.server_supports_notifications)
assert self.notifier
#TODO: choose more appropriate tray if we have more than one shown?
tray = self.tray
Expand Down
6 changes: 6 additions & 0 deletions src/xpra/server/dbus/dbus_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,12 @@ def DisableDebug(self, category):
disable_debug_for(c)


@dbus.service.method(INTERFACE, in_signature='sss')
def SendNotification(self, title, message, uuids):
self.log(".SendNotification%s", (title, message, uuids))
self.server.control_command_send_notification(ns(title), ns(message), ns(uuids))


@dbus.service.method(INTERFACE, in_signature='', out_signature='a{ss}')
def ListClients(self):
d = {}
Expand Down
15 changes: 14 additions & 1 deletion src/xpra/server/server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
rpclog = Logger("rpc")
dbuslog = Logger("dbus")
webcamlog = Logger("webcam")
notifylog = Logger("notify")

from xpra.keyboard.mask import DEFAULT_MODIFIER_MEANINGS
from xpra.server.server_core import ServerCore, get_thread_info
Expand Down Expand Up @@ -784,7 +785,8 @@ def parse_4intlist(v):
ArgsControlCommand("start-child", "executes the command arguments in the server context, as a 'child' (honouring exit-with-children)", min_args=1),
#network and transfers:
ArgsControlCommand("print", "sends the file to the client(s) for printing", min_args=3),
ArgsControlCommand("send-file", "sends the file to the client(s)", min_args=3),
ArgsControlCommand("send-file", "sends the file to the client(s)", min_args=3, ),
ArgsControlCommand("send-notification", "sends a notification to the client(s)", min_args=3, max_args=4),
ArgsControlCommand("compression", "sets the packet compressor", min_args=1, max_args=1),
ArgsControlCommand("encoder", "sets the packet encoder", min_args=1, max_args=1),
ArgsControlCommand("clipboard-direction", "restrict clipboard transfers", min_args=1, max_args=1),
Expand Down Expand Up @@ -1499,6 +1501,17 @@ def _control_get_sources(self, client_uuids_str, attr=None):
commandlog.warn("client connection not found for uuid(s): %s", notfound)
return sources

def control_command_send_notification(self, title, message, client_uuids):
sources = self._control_get_sources(client_uuids)
notifylog("control_command_send_notification(%s, %s, %s) will send to %s", title, message, client_uuids, sources)
count = 0
for source in sources:
if source.notify(0, 0, "control channel", 0, "", title, message, 10):
count += 1
msg = "notification message send to %i clients" % count
notifylog(msg)
return msg

def control_command_send_file(self, filename, openit, client_uuids, maxbitrate=0):
openit = str(openit).lower() in ("open", "true", "1")
return self.do_control_file_command("send file", client_uuids, filename, "file_tranfer", (False, openit))
Expand Down
14 changes: 10 additions & 4 deletions src/xpra/server/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
mmaplog = Logger("mmap")
dbuslog = Logger("dbus")
statslog = Logger("stats")
notifylog = Logger("notify")


from xpra.server.source_stats import GlobalPerformanceStatistics
Expand Down Expand Up @@ -353,8 +354,8 @@ def __init__(self, protocol, disconnect_cb, idle_add, timeout_add, source_remove
dbuslog.error("Error setting up the source's DBUS server:")
dbuslog.error(" %s", e)

def __str__(self):
return "%s(%s)" % (type(self).__name__, self.protocol)
def __repr__(self):
return "%s(%i : %s)" % (type(self).__name__, self.counter, self.protocol)

def init_vars(self):
self.encoding = None #the default encoding for all windows
Expand Down Expand Up @@ -1687,9 +1688,14 @@ def bell(self, wid, device, percent, pitch, duration, bell_class, bell_id, bell_
self.send("bell", wid, device, percent, pitch, duration, bell_class, bell_id, bell_name)

def notify(self, dbus_id, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout):
if not self.send_notifications or self.suspended:
return
if not self.send_notifications:
notifylog("client %s does not support notifications", self)
return False
if self.suspended:
notifylog("client %s is suspended, notification not sent", self)
return False
self.send("notify_show", dbus_id, int(nid), str(app_name), int(replaces_nid), str(app_icon), str(summary), str(body), int(expire_timeout))
return True

def notify_close(self, nid):
if not self.send_notifications or self.suspended:
Expand Down

0 comments on commit 939d36e

Please sign in to comment.