From cad04b67d0792921d7a3ff2789cda8e1be2ac9c5 Mon Sep 17 00:00:00 2001 From: elParaguayo Date: Sat, 11 Nov 2023 17:45:49 +0000 Subject: [PATCH] Try to fix visualiser CPU issue This adds more stringent checks to prevent multiple calls to draw which result in constantly increasing CPU usage. --- CHANGELOG | 1 + qtile_extras/widget/visualiser.py | 25 +++++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 1a8fd5dc..642cc5f0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +2023-11-12: [BUGFIX] (Trying to) fix increasing CPU with `Visualiser` widget 2023-11-11: [DOCS] Update installation instructions 2023-11-10: [FEATURE] Add custom hooks to certain widgets (refer to docs for more) 2023-10-16: [FEATURE] Updated `Bluetooth` widget to add context menu diff --git a/qtile_extras/widget/visualiser.py b/qtile_extras/widget/visualiser.py index 2d4adcde..c59a2609 100644 --- a/qtile_extras/widget/visualiser.py +++ b/qtile_extras/widget/visualiser.py @@ -23,6 +23,7 @@ import signal import sys import tempfile +import time from contextlib import contextmanager from multiprocessing import shared_memory from pathlib import Path @@ -61,6 +62,15 @@ class Visualiser(base._Widget): cava is configured through the widget. Currently, you can set the number of bars and the framerate. + + .. warning:: + + Rendering the visualiser directly in qtile's bar is almost certainly not an efficient way + to have a visualiser in your setup. You should therefore be aware that this widget uses + more processing power than other widgets so you may see CPU usage increase when using this. + However, if the CPU usage continues to increase the longer you use the widget then that is + likely to be a bug and should be reported! + """ _experimental = True @@ -93,6 +103,7 @@ def __init__(self, **config): self._draw_count = 0 self._toggling = False self._starting = False + self._last_time = time.time() def _configure(self, qtile, bar): if self.cava_path is None: @@ -215,9 +226,16 @@ def draw(self): self.drawer.draw(offsetx=self.offsetx, offsety=self.offsety, width=self.length) return - self._draw_count += 1 - if self._draw_count == 1: - self._draw() + # We need to filter out calls that happen before the next interval + # If we don't do this, CPU usage increases horrifically + # Feels like there should be a better way though! + t = time.time() + diff = t - self._last_time + if diff < self._interval: + return + self._last_time = t + + self._draw() def _draw(self): with self._take_lock(): @@ -233,7 +251,6 @@ def _draw(self): self.drawer.ctx.paint() self.drawer.draw(offsetx=self.offsetx, offsety=self.offsety, width=self.length) - self._draw_count = 0 self._timer = self.timeout_add(self._interval, self.draw) def finalize(self):