Skip to content

Commit

Permalink
add common system tray methods, mostly implemented everywhere:
Browse files Browse the repository at this point in the history
* set_tooltip: changes the hover text (not on osx)
* set_blinking: obvious (not on win32 yet, on osx the dock does not bounce when we use INFO_REQUEST, maybe we should use CRITICAL_REQUEST?)
* set_icon: obvious, works on all

Also use the occasion for cleaning up win32NotifyIcon

Note: ubuntu's appindicator also needs a bit of work - presumably someone who cares about that can go through the pain of supporting it?

git-svn-id: https://xpra.org/svn/Xpra/trunk@2848 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Feb 28, 2013
1 parent ab12081 commit ff0d547
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ def add_to_PATH(bindir):
('', ['xpra.README']),
('', ['win32/website.url']),
('', ['etc/xpra/client-only/xpra.conf']),
('icons', glob.glob('win32\\*.ico')),
('icons', glob.glob('icons\\*.*')),
('Microsoft.VC90.CRT', glob.glob('%s\\Microsoft.VC90.CRT\\*.*' % C_DLLs)),
('Microsoft.VC90.MFC', glob.glob('%s\\Microsoft.VC90.MFC\\*.*' % C_DLLs)),
Expand Down
29 changes: 28 additions & 1 deletion src/xpra/darwin/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
from wimpiggy.log import Logger
log = Logger()

#for attention_request:
CRITICAL_REQUEST = 0
INFO_REQUEST = 10

macapp = None
def get_OSXApplication():
global macapp
Expand Down Expand Up @@ -51,6 +55,7 @@ class ClientExtras(ClientExtrasBase):
def __init__(self, client, opts, conn):
self.menu_bar = None
self.macapp = None
self.last_attention_request_id = -1
ClientExtrasBase.__init__(self, client, opts, conn)
self.locate_icon_filename(opts.tray_icon)
self.setup_macdock()
Expand All @@ -62,7 +67,7 @@ def locate_icon_filename(self, opts_tray_icon):
self.icon_filename = opts_tray_icon
else:
#try to find the default icon:
x = os.path.join(self.get_data_dir(), "icons", "xpra.png")
x = os.path.join(self.get_data_dir(), "xpra", "icons", "xpra.png")
if os.path.exists(x):
self.icon_filename = x
log("darwin client extras using icon_filename=%s", self.icon_filename)
Expand All @@ -84,6 +89,28 @@ def remove_all_menus(self):
if self.macapp:
self.macapp.sync_menubar()

def set_tooltip(self, text=None):
pass #label cannot be set on the dock icon?

def set_blinking(self, on):
if on:
if self.last_attention_request_id<0:
self.last_attention_request_id = self.macapp.attention_request(INFO_REQUEST)
else:
if self.last_attention_request_id>=0:
self.macapp.cancel_attention_request(self.last_attention_request_id)
self.last_attention_request_id = -1

def set_icon(self, basefilename):
if not self.macapp:
return
filename = os.path.join(self.get_data_dir(), "xpra", "icons", "%s.png" % basefilename)
if not os.path.exists(filename):
log.error("could not find icon %s", filename)
return
pixbuf = gtk.gdk.pixbuf_new_from_file(filename)
self.macapp.set_dock_icon_pixbuf(pixbuf)

def setup_macdock(self):
log.debug("setup_macdock()")
self.macapp = get_OSXApplication()
Expand Down
2 changes: 2 additions & 0 deletions src/xpra/gtk_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ def get_icon_from_file(filename):
def set_tooltip_text(widget, text):
if hasattr(widget, "set_tooltip_text"):
widget.set_tooltip_text(text)
return True
return False


def add_close_accel(window, callback):
Expand Down
17 changes: 17 additions & 0 deletions src/xpra/win32/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@ def show_notify(self, dbus_id, nid, app_name, replaces_id, app_icon, summary, bo
self.notify(self.tray.getHWND(), summary, body, expire_timeout)


def set_tooltip(self, text=None):
if self.tray:
self.tray.set_tooltip(text or self.get_tray_tooltip())

def set_blinking(self, on):
if self.tray:
self.tray.set_blinking(on)

def set_icon(self, basefilename):
if not self.tray:
return
filename = os.path.join(self.get_data_dir(), "icons", "%s.ico" % basefilename)
if not os.path.exists(filename):
log.error("could not find icon %s", filename)
return
self.tray.set_icon(filename)

def setup_tray(self, no_tray, notifications, tray_icon_filename):
self.tray = None
self.notify = None
Expand Down
37 changes: 23 additions & 14 deletions src/xpra/win32/win32_NotifyIcon.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,18 @@
log = Logger()

class win32NotifyIcon:
def __init__(self, application_name, notify_callback, exit_callback, command_callback=None, iconPathName=None):
self.application_name = application_name
def __init__(self, title, notify_callback, exit_callback, command_callback=None, iconPathName=None):
self.title = title[:127]
self.notify_callback = notify_callback
self.exit_callback = exit_callback
self.command_callback = command_callback
self.current_icon = None
self.closed = False
self._message_id = win32con.WM_USER+20 #a message id we choose
message_map = {
win32con.WM_DESTROY: self.OnDestroy,
win32con.WM_COMMAND: self.OnCommand,
win32con.WM_USER+20: self.OnTaskbarNotify,
win32con.WM_DESTROY : self.OnDestroy,
win32con.WM_COMMAND : self.OnCommand,
self._message_id : self.OnTaskbarNotify,
}
# Register the Window class.
wc = WNDCLASS()
Expand All @@ -42,20 +44,27 @@ def __init__(self, application_name, notify_callback, exit_callback, command_cal
classAtom = RegisterClass(wc)
# Create the Window.
style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU
self.hwnd = CreateWindow(classAtom, self.application_name+" StatusIcon Window", style, \
self.hwnd = CreateWindow(classAtom, self.title+" StatusIcon Window", style, \
0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, \
0, 0, self.hinst, None)
UpdateWindow(self.hwnd)
hicon = self.win32LoadIcon(iconPathName)
flags = NIF_ICON | NIF_MESSAGE | NIF_TIP
nid = (self.hwnd, 0, flags, win32con.WM_USER+20, hicon, self.application_name)
Shell_NotifyIcon(NIM_ADD, nid)
self.current_icon = self.win32LoadIcon(iconPathName)
Shell_NotifyIcon(NIM_ADD, self.make_nid(NIF_ICON | NIF_MESSAGE | NIF_TIP))

def make_nid(self, flags):
return (self.hwnd, 0, flags, self._message_id, self.current_icon, self.title)

def set_blinking(self, on):
#FIXME: implement blinking on win32 using a timer
pass

def set_tooltip(self, name):
self.title = name[:127]
Shell_NotifyIcon(NIM_MODIFY, self.make_nid(NIF_ICON | NIF_MESSAGE | NIF_TIP))

def set_icon(self, iconPathName):
new_icon = self.win32LoadIcon(iconPathName)
flags = NIF_ICON | NIF_MESSAGE | NIF_TIP
nid = (self.hwnd, 0, flags, win32con.WM_USER+20, new_icon, self.application_name)
Shell_NotifyIcon(NIM_MODIFY, nid)
self.current_icon = self.win32LoadIcon(iconPathName)
Shell_NotifyIcon(NIM_MODIFY, self.make_nid(NIF_ICON))

def win32LoadIcon(self, iconPathName):
icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE
Expand Down
12 changes: 12 additions & 0 deletions src/xpra/win32/win32_tray.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ def close(self):
self.tray_widget.close()
self.tray_widget = None

def set_tooltip(self, name):
if self.tray_widget:
self.tray_widget.set_tooltip(name)

def set_icon(self, iconPathName):
if self.tray_widget:
self.tray_widget.set_icon(iconPathName)

def set_blinking(self, on):
if self.tray_widget:
self.tray_widget.set_blinking(on)


#****************************************************************
# Events detection (screensaver / login / logout)
Expand Down
36 changes: 31 additions & 5 deletions src/xpra/xposix/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,36 @@ def get_tray_icon_filename(self, cmdlineoverride):
return f
return None

def set_tooltip(self, text=None):
""" sets the tray tooltip, pass an empty string to use the default """
tooltip = text or self.get_tray_tooltip()
if hasattr(self.tray_widget, "set_label"):
self.tray_widget.set_label(tooltip)
else:
set_tooltip_text(self.tray_widget, tooltip)

def set_blinking(self, on):
if hasattr(self.tray_widget, "set_blinking"):
self.tray_widget.set_blinking(on)

def set_icon(self, basefilename):
filename = os.path.join(self.get_icons_dir(), "%s.png" % basefilename)
self.set_icon_from_file(filename)

def set_icon_from_file(self, filename):
if not self.tray_widget:
return
if not os.path.exists(filename):
log.error("could not find icon %s", filename)
return
if hasattr(self.tray_widget, "set_from_file"):
self.tray_widget.set_from_file(filename)
elif hasattr(self.tray_widget, "set_icon_from_file"):
self.tray_widget.set_icon_from_file(filename)
else:
pixbuf = gdk.pixbuf_new_from_file(filename)
self.tray_widget.set_from_pixbuf(pixbuf)

def setup_statusicon(self, delay_tray, tray_icon_filename):
self.tray_widget = None
try:
Expand All @@ -105,11 +135,7 @@ def show_tray(*args):
self.tray_widget.connect('activate', self.activate_menu)
filename = self.get_tray_icon_filename(tray_icon_filename)
if filename:
if hasattr(self.tray_widget, "set_from_file"):
self.tray_widget.set_from_file(filename)
else:
pixbuf = gdk.pixbuf_new_from_file(filename)
self.tray_widget.set_from_pixbuf(pixbuf)
self.set_icon_from_file(filename)
if delay_tray:
self.client.connect("first-ui-received", show_tray)
return True
Expand Down

0 comments on commit ff0d547

Please sign in to comment.