lemonbar: Replace queue with Condition object in DateTime module
This commit is contained in:
@@ -2,7 +2,6 @@ import threading
|
|||||||
import subprocess
|
import subprocess
|
||||||
import contextlib
|
import contextlib
|
||||||
import time, os, signal, getpass
|
import time, os, signal, getpass
|
||||||
import queue
|
|
||||||
|
|
||||||
import i3_lemonbar_config as config
|
import i3_lemonbar_config as config
|
||||||
import i3_lemonbar_common as common
|
import i3_lemonbar_common as common
|
||||||
@@ -87,46 +86,62 @@ def format_load(data, module, alert):
|
|||||||
|
|
||||||
class DateTimeModule(LemonModule):
|
class DateTimeModule(LemonModule):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.show_secs = False
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
def _start_module(self):
|
def _start_module(self):
|
||||||
class DateTimeThread(threading.Thread):
|
class DateTimeThread(threading.Thread):
|
||||||
def __init__(self, secs_mode = False):
|
def __init__(self, secs_mode = False):
|
||||||
self.secs_mode = secs_mode
|
self.secs_mode = secs_mode
|
||||||
self.last_out = ''
|
self.readline = self.__readline_first
|
||||||
self.w_condition = threading.Condition()
|
self.output = ''
|
||||||
self.out_queue = queue.Queue()
|
|
||||||
self.out_queue.readline = self.out_queue.get
|
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__()
|
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):
|
def run(self):
|
||||||
while True:
|
while True:
|
||||||
fmt = "%a %d %b %H:%M:%S" if self.secs_mode else "%a %d %b %H:%M"
|
fmt = "%a %d %b %H:%M:%S" if self.secs_mode else "%a %d %b %H:%M"
|
||||||
timestr = time.strftime(fmt, time.localtime())
|
timestr = time.strftime(fmt, time.localtime())
|
||||||
if timestr != self.last_out:
|
if timestr != self.output:
|
||||||
self.last_out = timestr
|
self.output = timestr
|
||||||
self.out_queue.put('{}\n'.format(timestr))
|
self.output_ready.acquire()
|
||||||
|
self.output_ready.notify()
|
||||||
|
self.output_ready.release()
|
||||||
self.sleep_until_change()
|
self.sleep_until_change()
|
||||||
|
|
||||||
def sleep_until_change(self):
|
def sleep_until_change(self):
|
||||||
# Sleep for an appropriate amount of time (depending on if showing seconds or not)
|
# Sleep for an appropriate amount of time (depending on if showing seconds or not)
|
||||||
# with the possibility of being woken early
|
# with the possibility of being woken early
|
||||||
if self.secs_mode:
|
if self.secs_mode:
|
||||||
rem = 0.1
|
rem = 0.1 # TODO fiddle with this, benchmarking it
|
||||||
else:
|
else:
|
||||||
rem = time.time() % 5.0 # 5 seconds, 60 is unnecessarily long
|
rem = time.time() % 5.0 # 5 seconds, 60 is unnecessarily long
|
||||||
self.w_condition.acquire()
|
self.clock_tick.acquire()
|
||||||
self.w_condition.wait(rem)
|
self.clock_tick.wait(rem)
|
||||||
|
self.clock_tick.release()
|
||||||
|
|
||||||
def wake(self):
|
def wake(self):
|
||||||
self.w_condition.acquire()
|
self.clock_tick.acquire()
|
||||||
self.w_condition.notify()
|
self.clock_tick.notify()
|
||||||
self.w_condition.release()
|
self.clock_tick.release()
|
||||||
|
|
||||||
self.dt_thread = DateTimeThread()
|
self.dt_thread = DateTimeThread()
|
||||||
self.dt_thread.start()
|
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.date = parser.IconTextUnit('date', action='date', order=40)
|
||||||
self.time = parser.IconTextUnit('time', action='toggle_secs', order=41
|
self.time = parser.IconTextUnit('time', action='toggle_secs', order=41
|
||||||
|
|||||||
Reference in New Issue
Block a user