From 77f9db0edf5d4aab941fa697d8a12b2748c454d3 Mon Sep 17 00:00:00 2001 From: aristocratos Date: Sun, 27 Sep 2020 21:45:51 +0200 Subject: [PATCH] Fixes for clock and battery placement and sizing --- bpytop.py | 60 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/bpytop.py b/bpytop.py index fac678a..ed48b02 100755 --- a/bpytop.py +++ b/bpytop.py @@ -1204,7 +1204,7 @@ class Theme: '''Load a bashtop formatted theme file and return a dict''' new_theme: Dict[str, str] = {} try: - with open(path) as f: + with open(path, "r") as f: for line in f: if not line.startswith("theme["): continue key = line[6:line.find("]")] @@ -1509,6 +1509,7 @@ class Box: buffers: List[str] = [] clock_on: bool = False clock: str = "" + clock_len: int = 0 resized: bool = False clock_custom_format: Dict[str, Any] = { "/host" : os.uname()[1], @@ -1535,23 +1536,28 @@ class Box: if now and not Menu.active: Draw.clear("update_ms") if CONFIG.show_battery and hasattr(psutil, "sensors_battery") and psutil.sensors_battery(): - CpuBox.redraw = True - CpuBox._draw_fg() - Draw.out("cpu") + Draw.out("battery") @classmethod def draw_clock(cls, force: bool = False): + out: str = "" if force: pass elif not cls.clock_on or Term.resized or strftime(CONFIG.draw_clock) == cls.clock: return clock_string = cls.clock = strftime(CONFIG.draw_clock) for custom in cls.clock_custom_format: if custom in clock_string: clock_string = clock_string.replace(custom, cls.clock_custom_format[custom]) - clock_len = len(clock_string[:(CpuBox.width-58)]) + clock_len = len(clock_string[:(CpuBox.width-56)]) + if cls.clock_len != clock_len and not CpuBox.resized: + out = f'{Mv.to(CpuBox.y, ((CpuBox.width)//2)-(cls.clock_len//2))}{Fx.ub}{THEME.cpu_box}{Symbol.h_line * cls.clock_len}' + cls.clock_len = clock_len now: bool = False if Menu.active else not force - Draw.buffer("clock", (f'{Mv.to(CpuBox.y, ((CpuBox.width-2)//2)-(clock_len//2)-3)}{Fx.ub}{THEME.cpu_box}{Symbol.h_line * 4}' - f'{Symbol.title_left}{Fx.b}{THEME.title(clock_string[:clock_len])}{Fx.ub}{THEME.cpu_box}{Symbol.title_right}{Symbol.h_line * 4}{Term.fg}'), - z=1, now=now, once=not force, only_save=Menu.active) + out += (f'{Mv.to(CpuBox.y, ((CpuBox.width)//2)-(clock_len//2))}{Fx.ub}{THEME.cpu_box}' + f'{Symbol.title_left}{Fx.b}{THEME.title(clock_string[:clock_len])}{Fx.ub}{THEME.cpu_box}{Symbol.title_right}{Term.fg}') + Draw.buffer("clock", out, z=1, now=now, once=not force, only_save=Menu.active) + if now and not Menu.active: + if CONFIG.show_battery and hasattr(psutil, "sensors_battery") and psutil.sensors_battery(): + Draw.out("battery") @classmethod def draw_bg(cls, now: bool = True): @@ -1582,6 +1588,7 @@ class CpuBox(Box, SubBox): battery_status: str = "Unknown" old_battery_pos = 0 old_battery_len = 0 + battery_path: Union[str, None] = "" clock_block: bool = True Box.buffers.append(buffer) @@ -1629,6 +1636,14 @@ class CpuBox(Box, SubBox): if not hasattr(psutil, "sensors_battery") or psutil.sensors_battery() == None: return False + if cls.battery_path == "": + for directory in os.listdir("/sys/class/power_supply"): + if directory.startswith('BAT') or 'battery' in directory.lower(): + cls.battery_path = f'/sys/class/power_supply/{directory}/' + break + else: + cls.battery_path = None + return_true: bool = False percent: int = ceil(getattr(psutil.sensors_battery(), "percent", 0)) if percent != cls.battery_percent: @@ -1641,12 +1656,8 @@ class CpuBox(Box, SubBox): return_true = True status: str = "not_set" - if os.path.isfile("/sys/class/power_supply/BAT0/status"): - try: - with open("/sys/class/power_supply/BAT0/status", "r") as file: - status = file.read().strip() - except: - pass + if cls.battery_path: + status = readfile(cls.battery_path + "status", default="not_set") if status == "not_set" and getattr(psutil.sensors_battery(), "power_plugged", None) == True: status = "Charging" if cls.battery_percent < 100 else "Full" elif status == "not_set" and getattr(psutil.sensors_battery(), "power_plugged", None) == False: @@ -1657,7 +1668,7 @@ class CpuBox(Box, SubBox): cls.battery_status = status return_true = True - if return_true or cls.resized or cls.redraw: + if return_true or cls.resized or cls.redraw or Menu.active: return True else: return False @@ -1691,6 +1702,7 @@ class CpuBox(Box, SubBox): Draw.buffer("cpu_misc", out_misc, only_save=True) if CONFIG.show_battery and cls.battery_activity(): + bat_out: str = "" if cls.battery_secs > 0: battery_time: str = f' {cls.battery_secs // 3600:02}:{(cls.battery_secs % 3600) // 60:02}' else: @@ -1708,11 +1720,12 @@ class CpuBox(Box, SubBox): battery_len: int = len(f'{CONFIG.update_ms}') + (11 if cls.width >= 100 else 0) + len(battery_time) + len(f'{cls.battery_percent}') battery_pos = cls.width - battery_len - 17 if battery_pos != cls.old_battery_pos and cls.old_battery_pos > 0 and not cls.resized: - out += f'{Mv.to(y-1, cls.old_battery_pos)}{THEME.cpu_box(Symbol.h_line*cls.old_battery_len)}' + bat_out += f'{Mv.to(y-1, cls.old_battery_pos)}{THEME.cpu_box(Symbol.h_line*cls.old_battery_len)}' cls.old_battery_pos, cls.old_battery_len = battery_pos, battery_len - out += (f'{Mv.to(y-1, battery_pos)}{THEME.cpu_box(Symbol.title_left)}{Fx.b}{THEME.title}BAT{battery_symbol} {cls.battery_percent}%'+ + bat_out += (f'{Mv.to(y-1, battery_pos)}{THEME.cpu_box(Symbol.title_left)}{Fx.b}{THEME.title}BAT{battery_symbol} {cls.battery_percent}%'+ ("" if cls.width < 100 else f' {Fx.ub}{Meters.battery(cls.battery_percent)}{Fx.b}') + f'{THEME.title}{battery_time}{Fx.ub}{THEME.cpu_box(Symbol.title_right)}') + Draw.buffer("battery", f'{bat_out}{Term.fg}', only_save=Menu.active) cx = cy = cc = 0 ccw = (bw + 1) // cls.box_columns @@ -4073,7 +4086,6 @@ class Menu: input_val += key elif isinstance(getattr(CONFIG, selected), int) and key.isdigit(): input_val += key - elif key == "q": clean_quit() elif key in ["escape", "o", "M", "f2"]: @@ -4108,6 +4120,8 @@ class Menu: if selected == "theme_background": Term.bg = THEME.main_bg if CONFIG.theme_background else "\033[49m" Draw.now(Term.bg) + if selected == "show_battery": + Draw.clear("battery", saved=True) Term.refresh(force=True) cls.resized = False elif key in ["left", "right"] and selected == "color_theme" and len(Theme.themes) > 1: @@ -4529,6 +4543,16 @@ def units_to_bytes(value: str) -> int: def min_max(value: int, min_value: int=0, max_value: int=100) -> int: return max(min_value, min(value, max_value)) +def readfile(file: str, default: str = "") -> str: + out: Union[str, None] = None + if os.path.isfile(file): + try: + with open(file, "r") as f: + out = f.read().strip() + except: + pass + return default if out is None else out + def process_keys(): mouse_pos: Tuple[int, int] = (0, 0) filtered: bool = False