Skip to content

Commit

Permalink
#1735: try to match the notification to the application tray that sen…
Browse files Browse the repository at this point in the history
…t it

git-svn-id: https://xpra.org/svn/Xpra/trunk@17997 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Jan 13, 2018
1 parent 139a700 commit c6a7e59
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 26 deletions.
5 changes: 3 additions & 2 deletions src/xpra/client/client_tray.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ class ClientTray(ClientWidgetBase):
DEFAULT_SIZE = [64, 64]
DEFAULT_GEOMETRY = DEFAULT_LOCATION + DEFAULT_SIZE

def __init__(self, client, wid, w, h, tray_widget, mmap_enabled, mmap_area):
def __init__(self, client, wid, w, h, title, tray_widget, mmap_enabled, mmap_area):
log("ClientTray%s", (client, wid, w, h, tray_widget, mmap_enabled, mmap_area))
ClientWidgetBase.__init__(self, client, 0, wid, True)
self.title = title
self.tray_widget = tray_widget
self._geometry = None
self._window_alpha = True
Expand Down Expand Up @@ -173,7 +174,7 @@ def destroy(self):
tw.cleanup()

def __repr__(self):
return "ClientTray(%s)" % self._id
return "ClientTray(%i:%s)" % (self._id, self.title)


class TrayBacking(WindowBackingBase):
Expand Down
2 changes: 1 addition & 1 deletion src/xpra/client/gtk3/gtk3_notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

class GTK3_Notifier(NotifierBase):

def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon):
def show_notify(self, dbus_id, tray, nid, app_id, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon):
if not self.dbus_check(dbus_id):
return
icon_string = self.get_icon_string(nid, app_icon, icon)
Expand Down
5 changes: 4 additions & 1 deletion src/xpra/client/tray_base.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is part of Xpra.
# Copyright (C) 2010 Nathaniel Smith <[email protected]>
# Copyright (C) 2011-2017 Antoine Martin <[email protected]>
# Copyright (C) 2011-2018 Antoine Martin <[email protected]>
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

Expand Down Expand Up @@ -32,6 +32,9 @@ def __init__(self, _client, app_id, menu, tooltip, icon_filename, size_changed_c
self.tray_event_locations = deque(maxlen=512)
self.default_icon_extension = "png"

def __repr__(self):
return "Tray(%i:%s)" % (self.app_id, self.tooltip)

def cleanup(self):
if self.tray_widget:
self.hide()
Expand Down
37 changes: 27 additions & 10 deletions src/xpra/client/ui_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,10 +460,11 @@ def setup_xpra_tray(*args):
if ICON_OVERLAY>0 and ICON_OVERLAY<=100:
icon_filename = get_icon_filename("xpra")
try:
from PIL import Image
from PIL import Image #@UnresolvedImport
self.overlay_image = Image.open(icon_filename)
except Exception as e:
log("init_ui failed to load overlay icon '%s': %s", icon_filename, e)
log.warn("Warning: failed to load overlay icon '%s':", icon_filename)
log.warn(" %s", e)

notifylog("client_supports_notifications=%s", self.client_supports_notifications)
if self.client_supports_notifications:
Expand Down Expand Up @@ -922,7 +923,7 @@ def get_tray_title(self):
traylog("get_tray_title()=%s (items=%s)", nonl(v), t)
return v

def setup_system_tray(self, client, wid, w, h, title):
def setup_system_tray(self, client, app_id, wid, w, h, title):
tray_widget = None
#this is a tray forwarded for a remote application
def tray_click(button, pressed, time=0):
Expand Down Expand Up @@ -964,14 +965,11 @@ def tray_geometry(*args):
self.idle_add(do_tray_geometry, *args)
def tray_exit(*args):
traylog("tray_exit(%s)", args)
#TODO: use the pid instead?
app_id = wid
tray_widget = self.make_system_tray(app_id, None, title, None, tray_geometry, tray_click, tray_mouseover, tray_exit)
traylog("setup_system_tray%s tray_widget=%s", (client, wid, w, h, title), tray_widget)
traylog("setup_system_tray%s tray_widget=%s", (client, app_id, wid, w, h, title), tray_widget)
assert tray_widget, "could not instantiate a system tray for tray id %s" % wid
tray_widget.show()
return ClientTray(client, wid, w, h, tray_widget, self.mmap_enabled, self.mmap)

return ClientTray(client, wid, w, h, title, tray_widget, self.mmap_enabled, self.mmap)

def desktops_changed(self, *args):
workspacelog("desktops_changed%s", args)
Expand Down Expand Up @@ -3268,11 +3266,13 @@ def _process_new_tray(self, packet):
if len(packet)>=5:
metadata = self.cook_metadata(True, packet[4])
assert wid not in self._id_to_window, "we already have a window %s" % wid
tray = self.setup_system_tray(self, wid, w, h, metadata.get("title", ""))
app_id = wid
tray = self.setup_system_tray(self, app_id, wid, w, h, metadata.strget("title", ""))
traylog("process_new_tray(%s) tray=%s", packet, tray)
self._id_to_window[wid] = tray
self._window_to_id[tray] = wid


def _process_window_move_resize(self, packet):
wid, x, y, w, h = packet[1:6]
ax = self.sx(x)
Expand Down Expand Up @@ -3445,7 +3445,9 @@ def _process_notify_show(self, packet):
body = body.decode("utf8")
except:
body = bytestostr(body)
tray = self.tray
app_name = bytestostr(app_name)
tray = self.get_tray_window(app_name)
traylog("get_tray_window(%s)=%s", app_name, tray)
self.notifier.show_notify(dbus_id, tray, nid, app_name, replaces_nid, app_icon, summary, body, expire_timeout, icon)

def _process_notify_close(self, packet):
Expand All @@ -3456,6 +3458,21 @@ def _process_notify_close(self, packet):
log("_process_notify_close(%s)", nid)
self.notifier.close_notify(nid)

def get_tray_window(self, app_name):
#try to identify the application tray that generated this notification,
#so we can show it as coming from the correct systray icon
#on platforms that support it (ie: win32)
if app_name and app_name.lower()!="xpra":
#exact match:
for window in self._id_to_window.values():
#traylog("window %s: is_tray=%s, title=%s", window, window.is_tray(), getattr(window, "title", None))
if window.is_tray() and window.title==app_name:
return window.tray_widget
for window in self._id_to_window.values():
if window.is_tray() and window.title.find(app_name)>=0:
return window.tray_widget
return self.tray


def _process_raise_window(self, packet):
#only implemented in gtk2 for now
Expand Down
12 changes: 5 additions & 7 deletions src/xpra/platform/win32/win32_NotifyIcon.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# This file is part of Xpra.
# Copyright (C) 2011-2017 Antoine Martin <[email protected]>
# Copyright (C) 2011-2018 Antoine Martin <[email protected]>
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

Expand Down Expand Up @@ -317,18 +317,16 @@ def make_nid(self, flags):
sprintf(byref(nid,NOTIFYICONDATA.szTip.offset), title)
nid.dwState = 0
nid.dwStateMask = 0
nid.guidItem = XPRA_GUID
nid.uID = self.app_id
flags |= NIF_GUID
#balloon notification bits:
#szInfo
#uTimeout
#szInfoTitle
#dwInfoFlags
#hBalloonIcon
#flags |= NIF_SHOWTIP
if self.app_id==XPRA_APP_ID:
nid.guidItem = XPRA_GUID
flags |= NIF_GUID
else:
nid.uID = self.app_id
nid.uVersion = 4
nid.uFlags = flags
log("make_nid(..)=%s tooltip='%s', app_id=%i, actual flags=%s", nid, nonl(title), self.app_id, csv([v for k,v in NIF_FLAGS.items() if k&flags]))
Expand Down Expand Up @@ -541,7 +539,7 @@ def command_callback(hwnd, cid):
icon = None
else:
pass
notify(hwnd, "hello", "world", timeout=1000, icon=icon)
notify(hwnd, 0, "hello", "world", timeout=1000, icon=icon)
elif cid == 1025:
print("Goodbye")
DestroyWindow(hwnd)
Expand Down
3 changes: 2 additions & 1 deletion src/xpra/platform/win32/win32_balloon.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,10 @@ def __setattr__(self, name, value):
self.__dict__[name] = value


def notify(hwnd, title, message, timeout=5000, icon=None):
def notify(hwnd, app_id, title, message, timeout=5000, icon=None):
nid = PyNOTIFYICONDATA()
nid.hWnd = hwnd
nid.uID = app_id
nid.uFlags = NIF_INFO
nid.guidItem = XPRA_GUID_BYTES
nid.szInfo = chop_string(message, 255, False) #prevent overflow
Expand Down
3 changes: 2 additions & 1 deletion src/xpra/platform/win32/win32_notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ def show_notify(self, dbus_id, tray, nid, app_name, replaces_nid, app_icon, summ
log.warn(" the system tray class %s does not support hwnd", type(tray))
return
hwnd = tray.getHWND()
notify(hwnd, summary, body, expire_timeout, icon)
app_id = tray.app_id
notify(hwnd, app_id, summary, body, expire_timeout, icon)

def close_notify(self, nid):
pass
6 changes: 3 additions & 3 deletions src/xpra/platform/win32/win32_tray.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# This file is part of Xpra.
# Copyright (C) 2011-2017 Antoine Martin <[email protected]>
# Copyright (C) 2011-2018 Antoine Martin <[email protected]>
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

Expand Down Expand Up @@ -50,8 +50,8 @@ def get_size(self):

def getHWND(self):
if self.tray_widget is None:
return None
return self.tray_widget.hwnd
return None
return self.tray_widget.hwnd

def cleanup(self):
log("Win32Tray.cleanup() tray_widget=%s", self.tray_widget)
Expand Down

0 comments on commit c6a7e59

Please sign in to comment.