lemonbar: Replace queue with Condition object in DateTime module

This commit is contained in:
kuben
2019-12-29 23:43:12 +01:00
committed by Jakub Fojt
parent 5195ae47bc
commit c4e760d5e7

View File

@@ -2,7 +2,6 @@ import threading
import subprocess
import contextlib
import time, os, signal, getpass
import queue
import i3_lemonbar_config as config
import i3_lemonbar_common as common
@@ -87,46 +86,62 @@ def format_load(data, module, alert):
class DateTimeModule(LemonModule):
def __init__(self):
self.show_secs = False
super().__init__()
def _start_module(self):
class DateTimeThread(threading.Thread):
def __init__(self, secs_mode = False):
self.secs_mode = secs_mode
self.last_out = ''
self.w_condition = threading.Condition()
self.out_queue = queue.Queue()
self.out_queue.readline = self.out_queue.get
self.readline = self.__readline_first
self.output = ''
lock = threading.Lock()
self.output_ready = threading.Condition(lock)
self.clock_tick = threading.Condition(lock) # Needed, because sleep may be interrupted when user
# changes H:M to H:M:S
super().__init__()
def __readline_first(self):
# Should return instantly the first time
self.readline = self.__readline_blocking
return self.output
def __readline_blocking(self):
self.output_ready.acquire()
self.output_ready.wait()
self.output_ready.release()
return self.output
def run(self):
while True:
fmt = "%a %d %b %H:%M:%S" if self.secs_mode else "%a %d %b %H:%M"
timestr = time.strftime(fmt, time.localtime())
if timestr != self.last_out:
self.last_out = timestr
self.out_queue.put('{}\n'.format(timestr))
if timestr != self.output:
self.output = timestr
self.output_ready.acquire()
self.output_ready.notify()
self.output_ready.release()
self.sleep_until_change()
def sleep_until_change(self):
# Sleep for an appropriate amount of time (depending on if showing seconds or not)
# with the possibility of being woken early
if self.secs_mode:
rem = 0.1
rem = 0.1 # TODO fiddle with this, benchmarking it
else:
rem = time.time() % 5.0 # 5 seconds, 60 is unnecessarily long
self.w_condition.acquire()
self.w_condition.wait(rem)
self.clock_tick.acquire()
self.clock_tick.wait(rem)
self.clock_tick.release()
def wake(self):
self.w_condition.acquire()
self.w_condition.notify()
self.w_condition.release()
self.clock_tick.acquire()
self.clock_tick.notify()
self.clock_tick.release()
self.dt_thread = DateTimeThread()
self.dt_thread.start()
self.status_handle = self.dt_thread.out_queue
self.status_handle = self.dt_thread # Only readline() is used
self.date = parser.IconTextUnit('date', action='date', order=40)
self.time = parser.IconTextUnit('time', action='toggle_secs', order=41