Skip to content

Commit

Permalink
Keep alive when i3bar hidden
Browse files Browse the repository at this point in the history
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 ultrabug#253
  • Loading branch information
tobes committed Apr 11, 2016
1 parent a762517 commit a344685
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
20 changes: 19 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 @@ -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):
"""
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions 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
from tempfile import NamedTemporaryFile
from threading import Thread
from time import time
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit a344685

Please sign in to comment.