Exemple #1
0
    def activate(self, text=None):
        if self.use_terminal:
            try:
                import subprocess

                prog = subprocess.Popen(
                    self._name.split(" "),
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT)
                
                zenity = subprocess.Popen(
                    ["zenity", "--title="+self._name,
                        "--window-icon="+join(deskbar.ART_DATA_DIR, "generic.png"),
                        "--width=700",
                        "--height=500",
                        "--text-info"],
                    stdin=prog.stdout)
    
                # Reap the processes when they have done
                glib.child_watch_add(zenity.pid, lambda pid, code: None)
                glib.child_watch_add(prog.pid, lambda pid, code: None)
                return
            except:
                #No zenity, get out of the if, and launch without GUI
                pass
        
        spawn_async(self._name.split(" "))
Exemple #2
0
def spawn_child(argv, respawn=True, display=None):
    """
    Spawn argv in the mainloop and keeping it as a child process
    (it will be made sure to exit with the parent).

    @respawn: If True, respawn if child dies abnormally

    raises utils.SpawnError
    returns pid
    """
    flags = (glib.SPAWN_SEARCH_PATH | glib.SPAWN_DO_NOT_REAP_CHILD)
    kwargs = {}
    if display:
        # environment is passed as a sequence of strings
        envd = os.environ.copy()
        envd['DISPLAY'] = display
        kwargs['envp'] = ['='.join((k, v)) for k, v in envd.items()]

    try:
        pid, stdin_fd, stdout_fd, stderr_fd = \
            glib.spawn_async(argv, flags=flags,
                             child_setup=_try_register_pr_pdeathsig,
                             **kwargs)
    except glib.GError as exc:
        raise utils.SpawnError(unicode(exc))
    if pid:
        glib.child_watch_add(pid, _on_child_exit, (argv, respawn))
    return pid
Exemple #3
0
def spawn_child(argv, respawn=True, display=None):
    """
	Spawn argv in the mainloop and keeping it as a child process
	(it will be made sure to exit with the parent).

	@respawn: If True, respawn if child dies abnormally

	raises utils.SpawnError
	returns pid
	"""
    flags = (glib.SPAWN_SEARCH_PATH | glib.SPAWN_DO_NOT_REAP_CHILD)
    kwargs = {}
    if display:
        # environment is passed as a sequence of strings
        envd = os.environ.copy()
        envd['DISPLAY'] = display
        kwargs['envp'] = ['='.join((k, v)) for k, v in envd.items()]

    try:
        pid, stdin_fd, stdout_fd, stderr_fd = \
         glib.spawn_async(argv, flags=flags,
                          child_setup=_try_register_pr_pdeathsig,
                          **kwargs)
    except glib.GError as exc:
        raise utils.SpawnError(unicode(exc))
    if pid:
        glib.child_watch_add(pid, _on_child_exit, (argv, respawn))
    return pid
Exemple #4
0
    def __init__(self, argv, finish_callback, timeout_s, stdin=None, env=""):
        self.stdout = []
        self.stderr = []
        self.stdin = []
        self.timeout = False
        self.killed = False
        self.finished = False
        self.finish_callback = finish_callback

        argv = _argv_to_locale(argv)
        pretty.print_debug(__name__, "AsyncCommand:", argv)

        # get default environment var if not given
        env = env or ['='.join(kv) for kv in os.environ.iteritems()]

        flags = (glib.SPAWN_SEARCH_PATH | glib.SPAWN_DO_NOT_REAP_CHILD)
        pid, stdin_fd, stdout_fd, stderr_fd = \
             glib.spawn_async(argv, standard_output=True, standard_input=True,
                              standard_error=True, flags=flags, envp=env)

        if stdin:
            self.stdin[:] = self._split_string(stdin, self.max_input_buf)
            in_io_flags = glib.IO_OUT | glib.IO_ERR | glib.IO_HUP | glib.IO_NVAL
            glib.io_add_watch(stdin_fd, in_io_flags, self._in_io_callback,
                              self.stdin)
        else:
            os.close(stdin_fd)

        io_flags = glib.IO_IN | glib.IO_ERR | glib.IO_HUP | glib.IO_NVAL
        glib.io_add_watch(stdout_fd, io_flags, self._io_callback, self.stdout)
        glib.io_add_watch(stderr_fd, io_flags, self._io_callback, self.stderr)
        self.pid = pid
        glib.child_watch_add(pid, self._child_callback)
        if timeout_s is not None:
            glib.timeout_add_seconds(timeout_s, self._timeout_callback)
Exemple #5
0
    def start_vim_hidden(self, extra_args=[], is_preload=False):
        """
        Open a new hidden Vim window

        Return (window, preload_id)
        """
        window = gtk.Window()
        window.set_default_size(*WINDOW_SIZE_NOTE)
        server_id = self.generate_vim_server_id()

        socket = gtk.Socket()
        window.realize()
        window.add(socket)
        socket.show()
        socket.connect("plug-added", self.on_socket_plug_added,
                       server_id, window, is_preload)


        argv = [VIM, '-g', '-f', '--socketid', '%s' % socket.get_id()]
        argv.extend(['--servername', server_id])
        argv.extend(VIM_EXTRA_FLAGS)
        argv.extend(['-c', 'so %s' % self.write_vimrc_file()])
        argv.extend(extra_args)

        log("Spawning", argv)
        pid, sin, sout, serr = \
                glib.spawn_async(argv, child_setup=self.on_spawn_child_setup,
                         flags=glib.SPAWN_SEARCH_PATH|glib.SPAWN_DO_NOT_REAP_CHILD)
        glib.child_watch_add(pid, self.on_vim_exit, window)
        return window
Exemple #6
0
    def activate(self, text=None):
        if self.use_terminal:
            try:
                import subprocess

                prog = subprocess.Popen(self._name.split(" "),
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.STDOUT)

                matedialog = subprocess.Popen([
                    "matedialog", "--title=" + self._name, "--window-icon=" +
                    join(deskbar.ART_DATA_DIR, "generic.png"), "--width=700",
                    "--height=500", "--text-info"
                ],
                                              stdin=prog.stdout)

                # Reap the processes when they have done
                glib.child_watch_add(matedialog.pid, lambda pid, code: None)
                glib.child_watch_add(prog.pid, lambda pid, code: None)
                return
            except:
                #No matedialog, get out of the if, and launch without GUI
                pass

        spawn_async(self._name.split(" "))
Exemple #7
0
	def __init__(self, argv, finish_callback, timeout_s, stdin=None):
		self.stdout = []
		self.stderr = []
		self.stdin = []
		self.timeout = False
		self.killed = False
		self.finished = False
		self.finish_callback = finish_callback

		argv = _argv_to_locale(argv)
		pretty.print_debug(__name__, "AsyncCommand:", argv)

		flags = (glib.SPAWN_SEARCH_PATH | glib.SPAWN_DO_NOT_REAP_CHILD)
		pid, stdin_fd, stdout_fd, stderr_fd = \
		     glib.spawn_async(argv, standard_output=True, standard_input=True,
		                      standard_error=True, flags=flags)

		if stdin:
			self.stdin[:] = self._split_string(stdin, self.max_input_buf)
			in_io_flags = glib.IO_OUT | glib.IO_ERR | glib.IO_HUP | glib.IO_NVAL
			glib.io_add_watch(stdin_fd, in_io_flags, self._in_io_callback,
			                  self.stdin)
		else:
			os.close(stdin_fd)

		io_flags = glib.IO_IN | glib.IO_ERR | glib.IO_HUP | glib.IO_NVAL
		glib.io_add_watch(stdout_fd, io_flags, self._io_callback, self.stdout)
		glib.io_add_watch(stderr_fd, io_flags, self._io_callback, self.stderr)
		self.pid = pid
		glib.child_watch_add(pid, self._child_callback)
		if timeout_s is not None:
			glib.timeout_add_seconds(timeout_s, self._timeout_callback)
 def testChildWatch(self):
     self.data = None
     self.loop = glib.MainLoop()
     argv = [sys.executable, '-c', 'import sys']
     pid, stdin, stdout, stderr = glib.spawn_async(
         argv, flags=glib.SPAWN_DO_NOT_REAP_CHILD)
     pid.close()
     glib.child_watch_add(pid, self._child_watch_cb, 12345)
     self.loop.run()
     self.assertEqual(self.data, 12345)
Exemple #9
0
 def testChildWatch(self):
     self.data = None
     self.loop = glib.MainLoop()
     argv = [sys.executable, '-c', 'import sys']
     pid, stdin, stdout, stderr = glib.spawn_async(
         argv, flags=glib.SPAWN_DO_NOT_REAP_CHILD)
     pid.close()
     glib.child_watch_add(pid, self._child_watch_cb, 12345)
     self.loop.run()
     self.assertEqual(self.data, 12345)
Exemple #10
0
    def _open_link(self, tag):
        """Open linked file in editor."""
        path = aeidon.util.shell_quote(tag.get_data("path"))
        command = string.Template(gaupol.conf.debug.text_editor)
        command = command.safe_substitute(LINENO=tag.get_data("lineno"),
                                          FILE=path)

        process = aeidon.util.start_process(command)
        glib.child_watch_add(process.pid, self._on_editor_exit, command)
        tag.props.foreground = "purple"
Exemple #11
0
    def __init__(self, handle):
        # Initialize the parent
        Activity.__init__(self, handle)
        hbox = gtk.HBox()
        self.set_canvas(hbox)
        self.show_all()
        options = ['tuxpaint', '--nolockfile', '--native', '--fullscreen', '--noprint']
        doc_path = self.get_documents_path()
        if doc_path is not None:
            options.extend(('--savedir', doc_path))
        proc = subprocess.Popen(options)

        # but get rid of that window if the child exits beforehand
        glib.child_watch_add(proc.pid, gtk.main_quit)
Exemple #12
0
    def __start_setup(self):
        if self.__setup_pid != None:
            try:
                # if setup dialog is running, bring the dialog to front by SIGUSR1
                os.kill(self.__setup_pid, signal.SIGUSR1)
                return
            except OSError:
                # seems the setup dialog is not running anymore
                self.__setup_pid.close()
                self.__setup_pid = None

        pid = glib.spawn_async(argv=[self.__setup_cmd, "ibus-setup"], flags=glib.SPAWN_DO_NOT_REAP_CHILD)[0]
        self.__setup_pid = pid
        glib.child_watch_add(self.__setup_pid, self.__child_watch_cb)
Exemple #13
0
    def __start_setup(self):
        if self.__setup_pid != None:
            try:
                # if setup dialog is running, bring the dialog to front by SIGUSR1
                os.kill(self.__setup_pid, signal.SIGUSR1)
                return
            except OSError:
                # seems the setup dialog is not running anymore
                self.__setup_pid.close()
                self.__setup_pid = None

        pid = glib.spawn_async(argv=[self.__setup_cmd, "ibus-setup"],
                               flags=glib.SPAWN_DO_NOT_REAP_CHILD)[0]
        self.__setup_pid = pid
        glib.child_watch_add(self.__setup_pid, self.__child_watch_cb)
Exemple #14
0
 def run(self):
     """Start the programm and retrieve the output."""
     flags = glib.SPAWN_SEARCH_PATH | glib.SPAWN_DO_NOT_REAP_CHILD
     log("spawn > start > " + repr(self.exe))
     try:
         data = glib.spawn_async(self.exe, [], self.pwd, flags, None, None, False, True, True)
         self.pid = data[0]
         glib.child_watch_add(self.pid, self.callback_end)
     except:
         return False
     out = os.fdopen(data[2], 'r')
     err = os.fdopen(data[3], 'r')
     self.wid[0] = glib.io_add_watch(data[2], glib.IO_IN|glib.IO_HUP, self.read_callback, out, 1)
     self.wid[1] = glib.io_add_watch(data[3], glib.IO_IN|glib.IO_HUP, self.read_callback, err, 2)
     self.isrunning = True
     return True
Exemple #15
0
    def new_vimdow_preloaded(self, name, filepath):
        if not self.preload_ids:
            raise RuntimeError("No Preloaded instances found!")
        preload_id, window = self.preload_ids.popitem()
        window.set_title(name)
        self.open_files[filepath] = window

        ## Note: Filename requires escaping (but our defaults are safe ones)
        preload_argv = [VIM, '-g', '-f', '--servername', preload_id,
                        '--remote-send', '<ESC>:e %s<CR><CR>' % filepath]

        log("Using preloaded", preload_argv)
        ## watch this process
        pid, sin, sout, serr = glib.spawn_async(preload_argv,
                      flags=glib.SPAWN_SEARCH_PATH|glib.SPAWN_DO_NOT_REAP_CHILD)
        glib.child_watch_add(pid, self.on_vim_remote_exit, preload_argv)
        self.position_window(window, filepath)
        window.present()
        self.emit("note-opened", filepath, window)
Exemple #16
0
    def testExceptionHandling(self):
        pipe_r, pipe_w = os.pipe()

        pid = os.fork()
        if pid == 0:
            os.close(pipe_w)
            select.select([pipe_r], [], [])
            os.close(pipe_r)
            os._exit(1)

        def child_died(pid, status, loop):
            loop.quit()
            raise Exception("deadbabe")

        loop = glib.MainLoop()
        glib.child_watch_add(pid, child_died, loop)

        os.close(pipe_r)
        os.write(pipe_w, _bytes("Y"))
        os.close(pipe_w)

        def excepthook(type, value, traceback):
            assert type is Exception
            assert value.args[0] == "deadbabe"
        sys.excepthook = excepthook

        got_exception = False
        try:
            loop.run()
        except:
            got_exception = True

        #
        # The exception should be handled (by printing it)
        # immediately on return from child_died() rather
        # than here. See bug #303573
        #
        sys.excepthook = sys.__excepthook__
        assert not got_exception
Exemple #17
0
def do_now_playing(data, server, witem):
    def on_result(pid, status):
        if not os.WIFEXITED(status):
            sys.stderr.write('child %d exited abnormally: status %d\n' % (
                pid, status))
            return
        stdout, stderr = proc.stdout.read(), proc.stderr.read()
        if os.WEXITSTATUS(status):
            irssi.prnt(stderr.rstrip())
        elif irssi.settings_get_bool('lastfm_use_action'):
            witem.command('me %s' % stdout.rstrip())
        else:
            witem.command('say %s' % stdout.rstrip())
    username = data or irssi.settings_get_str('lastfm_user')
    irssi_encoding = irssi.settings_get_str('term_charset')
    lastfm_strftime = irssi.settings_get_str('lastfm_strftime')
    lastfm_output = irssi.settings_get_str('lastfm_output')
    proc = subprocess.Popen([
            sys.executable, __file__, 
            username, irssi_encoding, lastfm_strftime, lastfm_output],
        stdin=open(os.devnull), stdout=subprocess.PIPE, stderr=subprocess.PIPE, 
        close_fds=True)
    glib.child_watch_add(proc.pid, on_result)
Exemple #18
0
    def refreshWaveForm(self, widget=None, data=None):
        self.builder.get_object("WaveFormImage").set_from_stock(gtk.STOCK_REFRESH, gtk.ICON_SIZE_LARGE_TOOLBAR)
        self.clearEvents()
        tmpname = tempfile.mkstemp()
	starttime = float(self.builder.get_object("txtStart").get_text())
	endtime = float(self.builder.get_object("txtEnd").get_text())

	msmode = True
	if self.cbTimeAxis.get_active() == 0:
	    starttime = starttime / 1000.0
	    endtime = endtime / 1000.0
	    msmode = False

	gle = GLE()
	if data == None or data["type"] == "preview":
	    gle.format = 'png' 

        pid = gle.waveform(tmpname[1], self.wavfile, self.framerate, msmode=msmode, minX=starttime, maxX=endtime)
        watch = child_watch_add(pid, self.updateWaveFormImage, data=tmpname[1])
        self.clearEvents()
Exemple #19
0
def run():
    # Internationalisation
    gettext.bindtextdomain('redshift', defs.LOCALEDIR)
    gettext.textdomain('redshift')
    _ = gettext.gettext

    # Start redshift with arguments from the command line
    args = sys.argv[1:]
    args.insert(0, os.path.join(defs.BINDIR, 'redshift'))
    process = subprocess.Popen(args)

    try:
        if appindicator:
            # Create indicator
            indicator = appindicator.Indicator(
                'redshift', 'redshift-status-on',
                appindicator.CATEGORY_APPLICATION_STATUS)
            indicator.set_status(appindicator.STATUS_ACTIVE)
        else:
            # Create status icon
            status_icon = gtk.StatusIcon()
            status_icon.set_from_icon_name('redshift-status-on')
            status_icon.set_tooltip('Redshift')

        def is_enabled():
            if appindicator:
                return indicator.get_icon() == 'redshift-status-on'
            else:
                return status_icon.get_icon_name() == 'redshift-status-on'

        def remove_suspend_timer():
            global SUSPEND_TIMER
            if SUSPEND_TIMER is not None:
                glib.source_remove(SUSPEND_TIMER)
                SUSPEND_TIMER = None

        def toggle_cb(widget, data=None):
            # If the user toggles redshift, we forget about the suspend timer.
            # Only then widget is not None.
            if widget:
                remove_suspend_timer()

            process.send_signal(signal.SIGUSR1)
            if appindicator:
                if indicator.get_icon() == 'redshift-status-on':
                    indicator.set_icon('redshift-status-off')
                else:
                    indicator.set_icon('redshift-status-on')
            else:
                if status_icon.get_icon_name() == 'redshift-status-on':
                    status_icon.set_from_icon_name('redshift-status-off')
                else:
                    status_icon.set_from_icon_name('redshift-status-on')

        def enable_cb():
            if is_enabled():
                return
            # Enable redshift
            toggle_cb(None)

        def suspend_cb(widget, minutes):
            if is_enabled():
                # Disable redshift
                toggle_cb(None)
            # If "suspend" is clicked while redshift is disabled, we reenable
            # it after the last selected timespan is over.
            remove_suspend_timer()
            # If redshift was already disabled we reenable it nonetheless.
            global SUSPEND_TIMER
            SUSPEND_TIMER = glib.timeout_add_seconds(minutes * 60, enable_cb)

        def autostart_cb(widget, data=None):
            utils.set_autostart(widget.get_active())

        def destroy_cb(widget, data=None):
            if not appindicator:
                status_icon.set_visible(False)
            gtk.main_quit()
            return False

        # Create popup menu
        status_menu = gtk.Menu()

        toggle_item = gtk.MenuItem(_('Toggle'))
        toggle_item.connect('activate', toggle_cb)
        status_menu.append(toggle_item)

        suspend_menu_item = gtk.MenuItem(_('Suspend for'))
        suspend_menu = gtk.Menu()
        for minutes, label in [(30, _('30 minutes')), (60, _('1 hour')),
                               (120, _('2 hours'))]:
            suspend_item = gtk.MenuItem(label)
            suspend_item.connect('activate', suspend_cb, minutes)
            suspend_menu.append(suspend_item)
        suspend_menu_item.set_submenu(suspend_menu)
        status_menu.append(suspend_menu_item)

        autostart_item = gtk.CheckMenuItem(_('Autostart'))
        try:
            autostart_item.set_active(utils.get_autostart())
        except IOError as strerror:
            print strerror
            autostart_item.set_property('sensitive', False)
        else:
            autostart_item.connect('activate', autostart_cb)
        finally:
            status_menu.append(autostart_item)

        quit_item = gtk.ImageMenuItem(gtk.STOCK_QUIT)
        quit_item.connect('activate', destroy_cb)
        status_menu.append(quit_item)

        if appindicator:
            status_menu.show_all()

            # Set the menu
            indicator.set_menu(status_menu)
        else:

            def popup_menu_cb(widget, button, time, data=None):
                status_menu.show_all()
                status_menu.popup(None, None, gtk.status_icon_position_menu,
                                  button, time, status_icon)

            # Connect signals for status icon and show
            status_icon.connect('activate', toggle_cb)
            status_icon.connect('popup-menu', popup_menu_cb)
            status_icon.set_visible(True)

        def child_cb(pid, cond, data=None):
            sys.exit(-1)

        # Add watch on child process
        glib.child_watch_add(process.pid, child_cb)

        # Run main loop
        gtk.main()

    except KeyboardInterrupt:
        # Ignore user interruption
        pass

    finally:
        # Always terminate redshift
        process.terminate()
        process.wait()
Exemple #20
0
def run():
    # Internationalisation
    gettext.bindtextdomain('redshift', defs.LOCALEDIR)
    gettext.textdomain('redshift')
    _ = gettext.gettext

    # Start redshift with arguments from the command line
    args = sys.argv[1:]
    args.insert(0, os.path.join(defs.BINDIR, 'redshift'))
    process = subprocess.Popen(args)

    try:
        if appindicator:
            # Create indicator
            indicator = appindicator.Indicator('redshift',
                                               'redshift-status-on',
                                               appindicator.CATEGORY_APPLICATION_STATUS)
            indicator.set_status(appindicator.STATUS_ACTIVE)
        else:
            # Create status icon
            status_icon = gtk.StatusIcon()
            status_icon.set_from_icon_name('redshift-status-on')
            status_icon.set_tooltip('Redshift')

        def toggle_cb(widget, data=None):
            process.send_signal(signal.SIGUSR1)
            if appindicator:
                if indicator.get_icon() == 'redshift-status-on':
                    indicator.set_icon('redshift-status-off')
                else:
                    indicator.set_icon('redshift-status-on')
            else:
	            if status_icon.get_icon_name() == 'redshift-status-on':
                        status_icon.set_from_icon_name('redshift-status-off')
	            else:
                        status_icon.set_from_icon_name('redshift-status-on')

        def autostart_cb(widget, data=None):
            utils.set_autostart(widget.get_active())

        def destroy_cb(widget, data=None):
            if not appindicator:
                status_icon.set_visible(False)
            gtk.main_quit()
            return False

        # Create popup menu
        status_menu = gtk.Menu()

        toggle_item = gtk.MenuItem(_('Toggle'))
        toggle_item.connect('activate', toggle_cb)
        status_menu.append(toggle_item)

        autostart_item = gtk.CheckMenuItem(_('Autostart'))
        try:
            autostart_item.set_active(utils.get_autostart())
        except IOError as strerror:
            print strerror
            autostart_item.set_property('sensitive', False)
        else:
            autostart_item.connect('activate', autostart_cb)
        finally:
            status_menu.append(autostart_item)

        quit_item = gtk.ImageMenuItem(gtk.STOCK_QUIT)
        quit_item.connect('activate', destroy_cb)
        status_menu.append(quit_item)

        if appindicator:
            status_menu.show_all()

            # Set the menu
            indicator.set_menu(status_menu)
        else:
            def popup_menu_cb(widget, button, time, data=None):
                status_menu.show_all()
                status_menu.popup(None, None, gtk.status_icon_position_menu,
                                  button, time, status_icon)

            # Connect signals for status icon and show
            status_icon.connect('activate', toggle_cb)
            status_icon.connect('popup-menu', popup_menu_cb)
            status_icon.set_visible(True)

        def child_cb(pid, cond, data=None):
            sys.exit(-1)

        # Add watch on child process
        glib.child_watch_add(process.pid, child_cb)

        # Run main loop
        gtk.main()

    except KeyboardInterrupt:
        # Ignore user interruption
        pass

    finally:
        # Always terminate redshift
        process.terminate()
        process.wait()
def run():
    # Internationalisation
    gettext.bindtextdomain('redshift', defs.LOCALEDIR)
    gettext.textdomain('redshift')
    _ = gettext.gettext

    # Start redshift with arguments from the command line
    args = sys.argv[1:]
    args.insert(0, os.path.join(defs.BINDIR, 'redshift'))
    process = subprocess.Popen(args)

    try:
        if appindicator:
            # Create indicator
            indicator = appindicator.Indicator('redshift',
                                               'redshift-status-on',
                                               appindicator.CATEGORY_APPLICATION_STATUS)
            indicator.set_status(appindicator.STATUS_ACTIVE)
        else:
            # Create status icon
            status_icon = gtk.StatusIcon()
            status_icon.set_from_icon_name('redshift-status-on')
            status_icon.set_tooltip('Redshift')

        def is_enabled():
            if appindicator:
                return indicator.get_icon() == 'redshift-status-on'
            else:
                return status_icon.get_icon_name() == 'redshift-status-on'

        def remove_suspend_timer():
            global SUSPEND_TIMER
            if SUSPEND_TIMER is not None:
                glib.source_remove(SUSPEND_TIMER)
                SUSPEND_TIMER = None

        def toggle_cb(widget, data=None):
            # If the user toggles redshift, we forget about the suspend timer.
            # Only then widget is not None.
            if widget:
                remove_suspend_timer()

            process.send_signal(signal.SIGUSR1)
            if appindicator:
                if indicator.get_icon() == 'redshift-status-on':
                    indicator.set_icon('redshift-status-off')
                else:
                    indicator.set_icon('redshift-status-on')
            else:
	            if status_icon.get_icon_name() == 'redshift-status-on':
                        status_icon.set_from_icon_name('redshift-status-off')
	            else:
                        status_icon.set_from_icon_name('redshift-status-on')

        def enable_cb():
            if is_enabled():
                return
            # Enable redshift
            toggle_cb(None)

        def suspend_cb(widget, minutes):
            if is_enabled():
                # Disable redshift
                toggle_cb(None)
            # If "suspend" is clicked while redshift is disabled, we reenable
            # it after the last selected timespan is over.
            remove_suspend_timer()
            # If redshift was already disabled we reenable it nonetheless.
            global SUSPEND_TIMER
            SUSPEND_TIMER = glib.timeout_add_seconds(minutes * 60, enable_cb)

        def autostart_cb(widget, data=None):
            utils.set_autostart(widget.get_active())

        def destroy_cb(widget, data=None):
            if not appindicator:
                status_icon.set_visible(False)
            gtk.main_quit()
            return False

        # Create popup menu
        status_menu = gtk.Menu()

        toggle_item = gtk.MenuItem(_('Toggle'))
        toggle_item.connect('activate', toggle_cb)
        status_menu.append(toggle_item)

        suspend_menu_item = gtk.MenuItem(_('Suspend for'))
        suspend_menu = gtk.Menu()
        for minutes, label in [(30, _('30 minutes')), (60, _('1 hour')),
                               (120, _('2 hours'))]:
            suspend_item = gtk.MenuItem(label)
            suspend_item.connect('activate', suspend_cb, minutes)
            suspend_menu.append(suspend_item)
        suspend_menu_item.set_submenu(suspend_menu)
        status_menu.append(suspend_menu_item)

        autostart_item = gtk.CheckMenuItem(_('Autostart'))
        try:
            autostart_item.set_active(utils.get_autostart())
        except IOError as strerror:
            print strerror
            autostart_item.set_property('sensitive', False)
        else:
            autostart_item.connect('activate', autostart_cb)
        finally:
            status_menu.append(autostart_item)

        quit_item = gtk.ImageMenuItem(gtk.STOCK_QUIT)
        quit_item.connect('activate', destroy_cb)
        status_menu.append(quit_item)

        if appindicator:
            status_menu.show_all()

            # Set the menu
            indicator.set_menu(status_menu)
        else:
            def popup_menu_cb(widget, button, time, data=None):
                status_menu.show_all()
                status_menu.popup(None, None, gtk.status_icon_position_menu,
                                  button, time, status_icon)

            # Connect signals for status icon and show
            status_icon.connect('activate', toggle_cb)
            status_icon.connect('popup-menu', popup_menu_cb)
            status_icon.set_visible(True)

        def child_cb(pid, cond, data=None):
            sys.exit(-1)

        # Add watch on child process
        glib.child_watch_add(process.pid, child_cb)

        # Run main loop
        gtk.main()

    except KeyboardInterrupt:
        # Ignore user interruption
        pass

    finally:
        # Always terminate redshift
        process.terminate()
        process.wait()