Will this work on OSX and *nix

What I want is a daemon that will have a GUI to interact with it (If
and only if the display is available)

This works great on windows (Which always has the Display available),
but I want to make sure it works on OSX and *nix as well and I dont
have either to test on

###### Example daemon code ##########

import os
import threading
import thread
import time

import wx
import wx.lib.pubsub

Publisher = wx.lib.pubsub.Publisher()

class Deamon(threading.Thread):
    def __init__(self):
        Publisher.subscribe(self.command, "daemon.command")
        threading.Thread.__init__(self)
        self.running = False
        self.GUI = False

    def start(self):
        self.running = True
        self.run()

    def stop(self):
        self.running = False
        self.GUI = False

    def run(self):
        while self.running:
            if wx.App.IsDisplayAvailable() and not self.GUI:
                thread.start_new_thread(StartGUI, ())
                self.GUI = True
            elif not wx.App.IsDisplayAvailable():
                #This makes sure the GUI element gets set back to
False if the Display become unavaliable
                self.GUI = False
            time.sleep(1)

    def command(self, message):
        print message.data

def StartGUI():
    app = BlankApp(0)
    app.MainLoop()

class BlankFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="Deamon Interaction Tester")

        self.taskbar = wx.TaskBarIcon()
        self.taskbar.SetIcon(wx.Icon("d20.gif", wx.BITMAP_TYPE_GIF))
        self.taskbar.Bind(wx.EVT_TASKBAR_LEFT_DCLICK, self.Toggle)
        self.taskbar.Bind(wx.EVT_TASKBAR_RIGHT_DOWN, self.TaskMenu)

        self.txt1 = wx.TextCtrl(self, wx.ID_ANY, "")

        self.txt1.Bind(wx.EVT_CHAR, self.onChar)
        self.Bind(wx.EVT_CLOSE, self.onClose)

        #Do Sizer Stuff
        self.basesizer = wx.BoxSizer(wx.VERTICAL)
        self.basesizer.Add(self.txt1, 0, wx.EXPAND)
        self.SetSizer(self.basesizer)
        self.SetAutoLayout(True)
        self.Fit()

    def onChar(self, event):
        if event.KeyCode == wx.WXK_RETURN:
            Publisher.sendMessage("daemon.command", self.txt1.GetValue())
            self.txt1.SetValue('')

        event.Skip()

    def onClose(self, event):
        #This Should allow someonoe to log out of their GUI and still
have the daemon running
        _daemon.GUI = False
        event.Skip()

    def Toggle(self, event):
        if self.IsShown():
            self.Hide()
        else:
            self.Show()

    def TaskMenu(self, event):
        menu = wx.Menu()

        item = wx.MenuItem(menu, wx.ID_ANY, "Exit", "Exit The Application")
        self.taskbar.Bind(wx.EVT_MENU, self.OnM_Exit, item)
        menu.AppendItem(item)

        self.taskbar.PopupMenu(menu)

    def OnM_Exit(self, event):
        if _daemon.running:
            _daemon.stop()
        self.Destroy()

class BlankApp(wx.App):
    def OnInit(self):
        wx.InitAllImageHandlers()
        self.frame = BlankFrame()
        self.SetTopWindow(self.frame)
        return True

def main():
    _daemon.setDaemon(True)
    _daemon.start()

if __name__ == "__main__":
    _daemon = Deamon()
    if wx.Platform != '__WXMSW__':
        pid = os.fork ()
        if pid == 0: # if pid is child...
            os.setsid() # Create new session and sets process group.
            pid = os.fork () # Will have INIT (pid 1) as parent process...
            if pid == 0: # if pid is child...
                main ()
    else:
        main()

daemon.py (3.16 KB)