[core] Update only affected widgets on input event
When receiving an input event, only update affected widgets, identified by their instance ID. see #353
This commit is contained in:
parent
44a50c0b36
commit
3d9279c444
4 changed files with 49 additions and 5 deletions
|
@ -71,7 +71,7 @@ class Module(object):
|
|||
return widget
|
||||
|
||||
def errorWidget(self):
|
||||
msg = self.error
|
||||
msg = self.error or "n/a"
|
||||
if len(msg) > 10:
|
||||
msg = "{}...".format(msg[0:7])
|
||||
return bumblebee.output.Widget(full_text="error: {}".format(msg))
|
||||
|
@ -264,14 +264,32 @@ class Engine(object):
|
|||
def run(self):
|
||||
"""Start the event loop"""
|
||||
self._output.start()
|
||||
event = None
|
||||
while self.running():
|
||||
self.write_output()
|
||||
if event:
|
||||
self.patch_output(event)
|
||||
else:
|
||||
self.write_output()
|
||||
if self.running():
|
||||
self.input.wait(float(self._config.get("interval", 1)))
|
||||
event = self.input.wait(float(self._config.get("interval", 1)))
|
||||
|
||||
self._output.stop()
|
||||
self.input.stop()
|
||||
|
||||
def patch_output(self, event):
|
||||
for module in self._modules:
|
||||
widget = module.widget_by_id(event["instance"])
|
||||
if not widget: continue
|
||||
# this widget was affected by the event -> update
|
||||
module.update_wrapper(module.widgets())
|
||||
widget = module.errorWidget()
|
||||
if module.error is None:
|
||||
widget = module.widget_by_id(event["instance"])
|
||||
widget.link_module(module)
|
||||
self._output.replace(event, module, widget)
|
||||
self._output.flush()
|
||||
self._output.end()
|
||||
|
||||
def write_output(self):
|
||||
self._output.begin()
|
||||
for module in self._modules:
|
||||
|
|
|
@ -45,6 +45,7 @@ def read_input(inp):
|
|||
try:
|
||||
event = json.loads(line)
|
||||
if "instance" in event:
|
||||
inp.event = event
|
||||
inp.callback(event)
|
||||
inp.redraw()
|
||||
else:
|
||||
|
@ -66,6 +67,7 @@ class I3BarInput(object):
|
|||
self.global_id = str(uuid.uuid4())
|
||||
self.need_event = False
|
||||
self.has_event = False
|
||||
self.event = None
|
||||
self._condition = threading.Condition()
|
||||
|
||||
def start(self):
|
||||
|
@ -87,6 +89,9 @@ class I3BarInput(object):
|
|||
|
||||
def wait(self, timeout):
|
||||
self._condition.wait(timeout)
|
||||
rv = self.event if self.has_event else None
|
||||
self.has_event = False
|
||||
return rv
|
||||
|
||||
def _wait(self):
|
||||
while not self.has_event:
|
||||
|
|
|
@ -105,6 +105,29 @@ class I3BarOutput(object):
|
|||
self._started = False
|
||||
self._config = config
|
||||
|
||||
def replace(self, event, module, new_widget):
|
||||
full_text = new_widget.full_text()
|
||||
padding = self._theme.padding(new_widget)
|
||||
prefix = self._theme.prefix(new_widget, padding)
|
||||
suffix = self._theme.suffix(new_widget, padding)
|
||||
if prefix:
|
||||
full_text = u"{}{}".format(prefix, full_text)
|
||||
if suffix:
|
||||
full_text = u"{}{}".format(full_text, suffix)
|
||||
separator = self._theme.separator(new_widget)
|
||||
widget_data = {
|
||||
u"full_text": full_text,
|
||||
"color": self._theme.fg(new_widget),
|
||||
"background": self._theme.bg(new_widget),
|
||||
"separator_block_width": self._theme.separator_block_width(new_widget),
|
||||
"separator": True if separator is None else False,
|
||||
"min_width": None,
|
||||
"align": self._theme.align(new_widget),
|
||||
"instance": new_widget.id,
|
||||
"name": module.id,
|
||||
}
|
||||
self._widgets = [w if not "instance" in w or w["instance"] != event["instance"] else widget_data for w in self._widgets]
|
||||
|
||||
def started(self):
|
||||
return self._started
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ def asbool(val):
|
|||
return val in ("t", "true", "y", "yes", "on", "1")
|
||||
|
||||
def execute(cmd, wait=True):
|
||||
logging.info("executing command '{}'".format(cmd))
|
||||
args = shlex.split(cmd)
|
||||
proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
rv = None
|
||||
|
@ -35,7 +34,6 @@ def execute(cmd, wait=True):
|
|||
else:
|
||||
rv = out
|
||||
|
||||
logging.info(u"command returned '{}'".format("" if not rv else rv))
|
||||
return rv
|
||||
|
||||
def bytefmt(num):
|
||||
|
|
Loading…
Reference in a new issue