Skip to content

Commit

Permalink
Merge pull request #266 from tobes/SIGUSR2
Browse files Browse the repository at this point in the history
Keep alive when i3bar hidden by @tobes and @cornerman
  • Loading branch information
ultrabug committed Apr 13, 2016
2 parents 43bf69d + 2fc225c commit 09ec0aa
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
22 changes: 21 additions & 1 deletion py3status/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from json import dumps
from signal import signal
from signal import SIGTERM, SIGUSR1
from signal import SIGTERM, SIGUSR1, SIGUSR2, SIGCONT
from subprocess import Popen
from subprocess import call
from threading import Event
Expand Down Expand Up @@ -37,6 +37,7 @@ def __init__(self):
Useful variables we'll need.
"""
self.config = {}
self.i3bar_running = True
self.last_refresh_ts = time()
self.lock = Event()
self.modules = {}
Expand Down Expand Up @@ -235,6 +236,14 @@ def setup(self):
# set the Event lock
self.lock.set()

# SIGUSR2 will be recieced from i3bar indicating that all output should
# stop and we should consider py3status suspended. It is however
# important that any processes using i3 ipc should continue to recieve
# those events otherwise it can lead to a stall in i3.
signal(SIGUSR2, self.i3bar_stop)
# SIGCONT indicates output should be resumed.
signal(SIGCONT, self.i3bar_start)

# setup configuration
self.config = self.get_config()

Expand Down Expand Up @@ -473,6 +482,14 @@ def create_output_modules(self):

self.output_modules = output_modules

def i3bar_stop(self, signum, frame):
self.i3bar_running = False
# i3status should be stopped
self.i3status_thread.suspend_i3status()

def i3bar_start(self, signum, frame):
self.i3bar_running = True

@profile
def run(self):
"""
Expand Down Expand Up @@ -501,6 +518,9 @@ def run(self):

# main loop
while True:
while not self.i3bar_running:
sleep(0.1)

sec = int(time())

# only check everything is good each second
Expand Down
18 changes: 17 additions & 1 deletion py3status/i3status.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from subprocess import Popen
from subprocess import PIPE
from syslog import syslog, LOG_INFO
from signal import SIGUSR2, SIGSTOP, SIG_IGN, signal
from tempfile import NamedTemporaryFile
from threading import Thread
from time import time
Expand Down Expand Up @@ -49,6 +50,7 @@ class I3statusModule:
"""

def __init__(self, module_name, py3_wrapper):
self.i3status_pipe = None
self.module_name = module_name
self.i3status = py3_wrapper.i3status_thread
self.is_time_module = module_name.split()[0] in TIME_MODULES
Expand Down Expand Up @@ -504,6 +506,11 @@ def write_tmp_i3status_config(self, tmpfile):
self.write_in_tmpfile('}\n\n', tmpfile)
tmpfile.flush()

def suspend_i3status(self):
# Put i3status to sleep
if self.i3status_pipe:
self.i3status_pipe.send_signal(SIGSTOP)

@profile
def run(self):
"""
Expand All @@ -519,11 +526,17 @@ def run(self):
i3status_pipe = Popen(
['i3status', '-c', tmpfile.name],
stdout=PIPE,
stderr=PIPE, )
stderr=PIPE,
# Ignore the SIGUSR2 signal for this subprocess
preexec_fn=lambda: signal(SIGUSR2, SIG_IGN)
)
self.poller_inp = IOPoller(i3status_pipe.stdout)
self.poller_err = IOPoller(i3status_pipe.stderr)
self.tmpfile_path = tmpfile.name

# Store the pipe so we can signal it
self.i3status_pipe = i3status_pipe

try:
# loop on i3status output
while self.lock.is_set():
Expand All @@ -540,6 +553,8 @@ def run(self):
if 'version' in line:
header = loads(line)
header.update({'click_events': True})
# set custom stop signal
header['stop_signal'] = SIGUSR2
line = dumps(header)
print_line(line)
else:
Expand All @@ -564,6 +579,7 @@ def run(self):
# we cleanup the tmpfile ourselves so when the delete will occur
# it will usually raise an OSError: No such file or directory
pass
self.i3status_pipe = None

def cleanup_tmpfile(self):
"""
Expand Down

0 comments on commit 09ec0aa

Please sign in to comment.