wx.TaskBarIcon not appearing in panel on startup

Hi all,

I've found the TaskBarIcon class not appearing in the panel system tray on
Gnome when you put the program in Startup Programs. It is then started on
login. Is this known? It seems the TaskBarIcon class detects if there is a
panel system tray available and if not it draws the icon on the root.
Apparently the panel hasn't started yet and so TaskBarIcon cannot detect the
panel.

I've got this simple code. If run manually it appears in the system tray. If
run at startup it appears on the desktop. On ubuntu startup programs is
managed through System - Preferences - Sessions.

Here's the code:
#!/usr/bin/python
import wx
import string
import sys, os, platform

···

##
# The IconBar class
# It just returns an icon on Get()

class IconBar:

  l= 1
  r = 1

  ##
  # \brief the constructor default left: red, default right: green
  #
  def
__init__(self,l_off=[128,0,0],l_on=[255,0,0],r_off=[0,128,0],r_on=[0,255,0]):
    self.s_line = "\xff\xff\xff"+"\0"*45
    self.s_border = "\xff\xff\xff\0\0\0"
    self.s_point = "\0"*3
    self.sl_off = string.join(map(chr,l_off),'')*6
    self.sl_on = string.join(map(chr,l_on),'')*6
    self.sr_off = string.join(map(chr,r_off),'')*6
    self.sr_on = string.join(map(chr,r_on),'')*6

  ##
  # \brief gets a new icon with 0 <= l,r <= 5
  #
  def Get(self,l,r):
    s=""+self.s_line
    for i in range(5):
      if i<(5-l):
        sl = self.sl_off
      else:
        sl = self.sl_on

      if i<(5-r):
        sr = self.sr_off
      else:
        sr = self.sr_on

      s+=self.s_border+sl+self.s_point+sr+self.s_point
      s+=self.s_border+sl+self.s_point+sr+self.s_point
      s+=self.s_line

    image = wx.EmptyImage(16,16)
    image.SetData(s)

    bmp = image.ConvertToBitmap()
    ##
    # This results in a freeze on Ubuntu
    #
    #bmp.SetMask(wx.Mask(bmp, wx.WHITE)) #sets the transparency colour to
white
    
    icon = wx.EmptyIcon()
    icon.CopyFromBitmap(bmp)

    return icon

class MyTaskBarIcon(wx.TaskBarIcon):

  ##
  # \brief the constructor
  #
  def __init__(self, frame):
    wx.TaskBarIcon.__init__(self)
    self.frame = frame
    self.IconBar = IconBar((127,127,0),(255,255,0),(0,127,127),(0,255,255))
    self.SetIconBar(2, 3)
    
    self.Bind(wx.EVT_MENU, self.frame.OnAbout, id=self.frame.RTDMENU_ABOUT)
    self.Bind(wx.EVT_MENU, self.frame.OnTaskBarClose,
id=self.frame.RTDMENU_CLOSE)

  def CreatePopupMenu(self):
    """
    This method is called by the base class when it needs to popup
    the menu for the default EVT_RIGHT_DOWN event. Just create
    the menu how you want it and return it from this function,
    the base class takes care of the rest.
    """
    menu = wx.Menu()
    menu.Append(self.frame.RTDMENU_ABOUT, "About")
    menu.AppendSeparator()
    menu.Append(self.frame.RTDMENU_CLOSE, "Exit")
    return menu

  ##
  # \brief sets the icon bar and a message
  #
  def SetIconBar(self,l,r, c=0):
    icon = self.IconBar.Get(l,r)
    self.SetIcon(icon, "Retyping Dante\nCharacters Typed:%d"% c )
  
##
# The task bar application
#
class TaskBarApp(wx.Frame):
  RTDMENU_ABOUT = wx.NewId()
  RTDMENU_CLOSE = wx.NewId()

  ##
  # \brief the constructor
  #
  def __init__(self, parent, id, title):
    wx.Frame.__init__(self, parent, -1, title, size = (1, 1),
      style=wx.FRAME_NO_TASKBAR|wx.NO_FULL_REPAINT_ON_RESIZE)
    
    #create Taskbar and Icon
    self.tbicon = MyTaskBarIcon(self)
    
    self.Show(True)

  def OnAbout(self, event):
    info = wx.AboutDialogInfo()
    info.Name = "Retyping Dante Test Client"
    info.Version = "0.0.178"
    info.Copyright = "(C) 2008 Stichting z25.org"
    info.Description = "Characters Typed: %i:"% 99
    #info.Description = wx.lib.wordwrap(
    #"This is an example application that shows how to create "
    #"different kinds of About Boxes using wxPython!",
    #350, wx.ClientDC(self.panel))
    info.WebSite = ("http://test.com", "Current Stats")
    info.AddArtist("Jelle van der Ster")
    info.AddArtist("Arnaud Loonstra")
    info.AddArtist("Matthew Groen")
    info.AddArtist("Femke van der Ster")
    info.AddArtist("Elmer Zwolsman")
    info.AddArtist("Cindy van Rooijen")
    info.Developers = ["Arnaud Loonstra"]
    #info.License = wordwrap("Completely and totally open source!", 500,
    # wx.ClientDC(self.panel))
    # Show the wx.AboutBox
    wx.AboutBox(info)
    
  def OnTaskBarClose(self, event):
    self.tbicon.Destroy()
    wx.CallAfter(self.Close)

##
# The main application wx.App class
#
class MyApp(wx.App):
  def OnInit(self):
    self.frame = TaskBarApp(None, -1, ' ')
    self.frame.Center(wx.BOTH)
    self.frame.Show(False)
    return True

def main(argv=None):
  if argv is None:
    argv = sys.argv

  app = MyApp(0)
  app.MainLoop()

if __name__ == '__main__':
  print "python version:", platform.python_version()
  print "wxPython version:", wx.version()
  main()

--
View this message in context: http://www.nabble.com/wx.TaskBarIcon-not-appearing-in-panel-on-startup-tp20032108p20032108.html
Sent from the wxPython-users mailing list archive at Nabble.com.

sphaero wrote:

Hi all,

I've found the TaskBarIcon class not appearing in the panel system tray on
Gnome when you put the program in Startup Programs. It is then started on
login. Is this known? It seems the TaskBarIcon class detects if there is a
panel system tray available and if not it draws the icon on the root.
Apparently the panel hasn't started yet and so TaskBarIcon cannot detect the
panel.

In 2.9 there will be a IsAvailable static method that can be used to tell if taskbar icons are supported. I haven't looked that the implementation yet but that may be useful in this case if it is checking if there is a panel implementation running. You could set a timer and periodically check for it and create the taskbar icon later if/when panel support is available.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn wrote:

sphaero wrote:

Hi all,

I've found the TaskBarIcon class not appearing in the panel system tray
on
Gnome when you put the program in Startup Programs. It is then started on
login. Is this known? It seems the TaskBarIcon class detects if there is
a
panel system tray available and if not it draws the icon on the root.
Apparently the panel hasn't started yet and so TaskBarIcon cannot detect
the
panel.

In 2.9 there will be a IsAvailable static method that can be used to
tell if taskbar icons are supported. I haven't looked that the
implementation yet but that may be useful in this case if it is checking
if there is a panel implementation running. You could set a timer and
periodically check for it and create the taskbar icon later if/when
panel support is available.

So this issue is known? It makes me figure why it does work with the gtk
api. It starts at the same time. I do think this is a bug although it could
be worked around the way you suggest.

Arnaud

···

--
View this message in context: http://www.nabble.com/wx.TaskBarIcon-not-appearing-in-panel-on-startup-tp20032108p20067843.html
Sent from the wxPython-users mailing list archive at Nabble.com.

sphaero wrote:

Robin Dunn wrote:

sphaero wrote:

Hi all,

I've found the TaskBarIcon class not appearing in the panel system tray
on
Gnome when you put the program in Startup Programs. It is then started on
login. Is this known? It seems the TaskBarIcon class detects if there is
a
panel system tray available and if not it draws the icon on the root.
Apparently the panel hasn't started yet and so TaskBarIcon cannot detect
the
panel.

In 2.9 there will be a IsAvailable static method that can be used to tell if taskbar icons are supported. I haven't looked that the implementation yet but that may be useful in this case if it is checking if there is a panel implementation running. You could set a timer and periodically check for it and create the taskbar icon later if/when panel support is available.

So this issue is known?

I don't know if it is a known issue or not, this is the first I've heard of it. But it is not surprising that it behaves this way.

It makes me figure why it does work with the gtk
api. It starts at the same time.

There may be a way to get an event or something from GTK when the Panel is ready that wx is not doing. Please create a ticket about this, maybe somebody knows a better way to deal with this. wxTrac has been migrated to GitHub Issues - wxWidgets

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!