From a344685c77b78b4a9f5772a652787b567ae3224d Mon Sep 17 00:00:00 2001 From: Toby Dacre Date: Sun, 10 Apr 2016 16:19:35 +0100 Subject: [PATCH] Keep alive when i3bar hidden By default i3bar sends a -SIGSTOP to a process sending it data. This causes some modules interacting with i3 ipc to be suspended, which lead to locking issues inside i3. This patch switches to using SIGUSR2 as the suspend signal. The async modules eg window_title_async were affected. see https://github.com/ultrabug/py3status/issues/253 --- py3status/core.py | 20 +++++++++++++++++++- py3status/i3status.py | 3 +++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/py3status/core.py b/py3status/core.py index 382828307a..db1f84dc86 100644 --- a/py3status/core.py +++ b/py3status/core.py @@ -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 @@ -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 = {} @@ -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() @@ -443,6 +452,12 @@ def create_output_modules(self): self.output_modules = output_modules + def i3bar_stop(self, signum, frame): + self.i3bar_running = False + + def i3bar_start(self, signum, frame): + self.i3bar_running = True + @profile def run(self): """ @@ -471,6 +486,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 diff --git a/py3status/i3status.py b/py3status/i3status.py index a8f9c8fa94..636c505e65 100644 --- a/py3status/i3status.py +++ b/py3status/i3status.py @@ -7,6 +7,7 @@ from subprocess import Popen from subprocess import PIPE from syslog import syslog, LOG_INFO +from signal import SIGUSR2 from tempfile import NamedTemporaryFile from threading import Thread from time import time @@ -540,6 +541,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: