From 18e54bec1e5333b9b60575a8dc3a882cc9b89f8a Mon Sep 17 00:00:00 2001 From: jx11r Date: Tue, 25 Jul 2023 18:42:25 -0600 Subject: [PATCH] refactor(bar): improve structure and organization --- core/__init__.py | 2 +- core/bar/__init__.py | 7 +-- core/bar/base.py | 75 ++++++++++++++++++++++++++++ core/bar/{decorated.py => shapes.py} | 41 ++++++++------- core/bar/theme.py | 17 ------- core/bar/utils.py | 41 --------------- core/groups.py | 21 ++++---- core/hooks.py | 20 +++++--- core/screens.py | 5 +- utils/config.py | 43 +++++++++------- 10 files changed, 147 insertions(+), 125 deletions(-) create mode 100644 core/bar/base.py rename core/bar/{decorated.py => shapes.py} (86%) delete mode 100644 core/bar/theme.py delete mode 100644 core/bar/utils.py diff --git a/core/__init__.py b/core/__init__.py index 09d6e67..6266a5a 100644 --- a/core/__init__.py +++ b/core/__init__.py @@ -1,5 +1,5 @@ from core import hooks -from core.bar.utils import defaults +from core.bar.base import defaults from core.groups import groups from core.keys import keys from core.layouts import floating_layout, layouts diff --git a/core/bar/__init__.py b/core/bar/__init__.py index 8e45b11..3d186c3 100644 --- a/core/bar/__init__.py +++ b/core/bar/__init__.py @@ -1,8 +1,5 @@ -from core.bar import theme - -bar, tags = theme.bar +from core.bar.base import Bar __all__ = [ - "bar", - "tags", + "Bar", ] diff --git a/core/bar/base.py b/core/bar/base.py new file mode 100644 index 0000000..1d95a2f --- /dev/null +++ b/core/bar/base.py @@ -0,0 +1,75 @@ +from importlib import import_module +from os import listdir +from os.path import isfile, join + +from libqtile import bar + +from extras import PowerLineDecoration, RectDecoration +from utils.config import cfg + +defaults = { + "font": "SauceCodePro Nerd Font Medium", + "fontsize": 10, + "padding": None, +} + + +class Bar: + def __init__(self, theme: str) -> None: + self.theme = theme + + @property + def themes(self) -> set[str]: + path = join(cfg.path(), "core", "bar") + excluded_files = {"__init__.py", "base.py"} + return { + file.removesuffix(".py") + for file in listdir(path) + if isfile(join(path, file)) and file not in excluded_files + } + + @property + def config(self) -> dict | None: + if self.theme not in self.themes: + return None + module = import_module(f"core.bar.{self.theme}") + return {"widgets": module.widgets(), **module.bar} + + def create(self) -> bar.BarType | None: + if not self.config: + return None + return bar.Bar(**self.config) + + +def base(bg: str | None, fg: str) -> dict: + return { + "background": bg, + "foreground": fg, + } + + +def icon_font(size=15) -> dict: + font = "SauceCodePro Nerd Font" + return {"font": font, "fontsize": size} + + +def powerline(path: str | list[tuple], size=9) -> dict: + return { "decorations": [ + PowerLineDecoration( + path=path, + size=size, + ) + ]} # fmt: skip + + +def rectangle(side: str = "") -> dict: + return { "decorations": [ + RectDecoration( + filled = True, + radius = { + "left": [8, 0, 0, 8], + "right": [0, 8, 8, 0] + }.get(side, 8), + use_widget_background = True, + ) + ]} # fmt: skip diff --git a/core/bar/decorated.py b/core/bar/shapes.py similarity index 86% rename from core/bar/decorated.py rename to core/bar/shapes.py index d13c454..6559ab3 100644 --- a/core/bar/decorated.py +++ b/core/bar/shapes.py @@ -1,7 +1,7 @@ from libqtile.bar import CALCULATED from libqtile.lazy import lazy -from core.bar.utils import base, icon_font, powerline, rectangle +from core.bar.base import base, icon_font, powerline, rectangle from extras import Clock, GroupBox, TextBox, modify, widget from utils.palette import palette @@ -14,8 +14,6 @@ "size": 18, } -tags = ["", "", "", "󰈹", "󰇮", ""] - def sep(fg, offset=0, padding=8) -> TextBox: return TextBox( @@ -200,21 +198,22 @@ def clock(bg, fg) -> list: ] -widgets = [ - widget.Spacer(length=2), - logo(palette.blue, palette.base), - sep(palette.surface2, offset=-8), - groups(None), - sep(palette.surface2, offset=4, padding=4), - *volume(palette.pink, palette.base), - *updates(palette.red, palette.base), - widget.Spacer(), - window_name(None, palette.text), - widget.Spacer(), - *cpu(palette.green, palette.base), - *ram(palette.yellow, palette.base), - *disk(palette.teal, palette.base), - sep(palette.surface2), - *clock(palette.pink, palette.base), - widget.Spacer(length=2), -] +def widgets(): + return [ + widget.Spacer(length=2), + logo(palette.blue, palette.base), + sep(palette.surface2, offset=-8), + groups(None), + sep(palette.surface2, offset=4, padding=4), + *volume(palette.pink, palette.base), + *updates(palette.red, palette.base), + widget.Spacer(), + window_name(None, palette.text), + widget.Spacer(), + *cpu(palette.green, palette.base), + *ram(palette.yellow, palette.base), + *disk(palette.teal, palette.base), + sep(palette.surface2), + *clock(palette.pink, palette.base), + widget.Spacer(length=2), + ] diff --git a/core/bar/theme.py b/core/bar/theme.py deleted file mode 100644 index c060885..0000000 --- a/core/bar/theme.py +++ /dev/null @@ -1,17 +0,0 @@ -from importlib import import_module - -from libqtile.bar import Bar - -from utils.config import cfg - -themes = ["decorated"] - -if cfg.bar in themes: - module = import_module(f"core.bar.{cfg.bar}") - module.bar.update({"widgets": module.widgets}) - bar: tuple[Bar | None, list] = ( - Bar(**module.bar), - module.tags, - ) -else: - bar = (None, [None] * 10) diff --git a/core/bar/utils.py b/core/bar/utils.py deleted file mode 100644 index 687f680..0000000 --- a/core/bar/utils.py +++ /dev/null @@ -1,41 +0,0 @@ -from extras import PowerLineDecoration, RectDecoration - -defaults = { - "font": "SauceCodePro Nerd Font Medium", - "fontsize": 10, - "padding": None, -} - - -def base(bg: str | None, fg: str) -> dict: - return { - "background": bg, - "foreground": fg, - } - - -def icon_font(size=15) -> dict: - font = "SauceCodePro Nerd Font" - return {"font": font, "fontsize": size} - - -def powerline(path: str | list, size=9) -> dict: - return { "decorations": [ - PowerLineDecoration( - path=path, - size=size, - ) - ]} # fmt: skip - - -def rectangle(side: str = "") -> dict: - return { "decorations": [ - RectDecoration( - filled = True, - radius = { - "left": [8, 0, 0, 8], - "right": [0, 8, 8, 0] - }.get(side, 8), - use_widget_background = True, - ) - ]} # fmt: skip diff --git a/core/groups.py b/core/groups.py index 1ea1843..cf3708c 100644 --- a/core/groups.py +++ b/core/groups.py @@ -1,21 +1,20 @@ from libqtile.config import Group, Key from libqtile.lazy import lazy -from core import bar from core.keys import keys, mod from utils.match import wm_class -groups, tag = [], bar.tags +groups: list[Group] = [] -for i, (key, layout, matches) in enumerate([ - ("1", None, wm_class("wezterm")), - ("2", "max", wm_class("code")), - ("3", None, wm_class("insomnia", "obs", "evince")), - ("q", "max", wm_class("brave-browser", "firefox")), - ("w", "max", wm_class("discord", "telegram-desktop")), - ("e", "max", wm_class("spotify", "vlc")), -]): # fmt: skip - groups.append(Group(key, matches, layout=layout, label=tag[i])) +for key, label, layout, matches in [ + ("1", "", None, wm_class("wezterm")), + ("2", "", "max", wm_class("code")), + ("3", "", None, wm_class("insomnia", "obs", "evince")), + ("q", "󰈹", "max", wm_class("brave-browser", "firefox")), + ("w", "󰇮", "max", wm_class("discord", "telegram-desktop")), + ("e", "", "max", wm_class("spotify", "vlc")), +]: + groups.append(Group(key, matches, label=label, layout=layout)) keys.extend([ # mod1 + letter of group = switch to group diff --git a/core/hooks.py b/core/hooks.py index b0d8b9b..2951db0 100644 --- a/core/hooks.py +++ b/core/hooks.py @@ -2,18 +2,22 @@ from libqtile import hook -from core.bar import bar +from core.screens import screens + +bars = [screen.top for screen in screens] +margins = [sum(bar.margin) if bar else -1 for bar in bars] # type: ignore @hook.subscribe.startup def startup(): - if bar and not sum(bar.margin): - bar.window.window.set_property( - name="WM_NAME", - value="QTILE_BAR", - type="STRING", - format=8, - ) + for bar, margin in zip(bars, margins): + if not margin: + bar.window.window.set_property( + name="WM_NAME", + value="QTILE_BAR", + type="STRING", + format=8, + ) @hook.subscribe.client_new diff --git a/core/screens.py b/core/screens.py index 6c1db80..8b3803b 100644 --- a/core/screens.py +++ b/core/screens.py @@ -1,16 +1,17 @@ from libqtile.config import Screen -from core.bar import bar +from core.bar import Bar from utils.config import cfg screens = [ Screen( wallpaper=cfg.wallpaper, wallpaper_mode="fill", - top=bar, + top=Bar(cfg.bar).create(), ), Screen( wallpaper=cfg.wallpaper, wallpaper_mode="fill", + top=Bar(cfg.bar2).create(), ), ] diff --git a/utils/config.py b/utils/config.py index 059ab69..1517ab0 100644 --- a/utils/config.py +++ b/utils/config.py @@ -1,33 +1,38 @@ import json -import os from dataclasses import asdict, dataclass -from os import path +from os import getcwd +from os.path import exists, expanduser, join @dataclass class Config: - bar: str | None = "decorated" + bar: str = "shapes" + bar2: str = "" browser: str = "" term: str | None = "" - term2: str | None = "" + term2: str = "" wallpaper: str = "" + @staticmethod + def path() -> str: + xdg = expanduser("~/.config/qtile") + return xdg if exists(xdg) else getcwd() -def get_directory(): - XDG = path.expanduser("~/.config/qtile") - if path.exists(XDG): - return XDG - return os.getcwd() + @classmethod + def load(cls) -> "Config": + file = join(cls.path(), "cfg.json") + if not exists(file): + cls.generate(file) + return cls() + with open(file, "r") as f: + content = json.load(f) + return cls(**content) + @classmethod + def generate(cls, file: str) -> None: + with open(file, "w") as f: + content = asdict(cls()) + f.write(json.dumps(content, indent=2)) -file = f"{get_directory()}/cfg.json" -if not path.exists(file): - cfg = Config() - with open(file, "w") as f: - content = asdict(cfg) - f.write(json.dumps(content, indent=2)) -else: - with open(file, "r") as f: - content = json.load(f) - cfg = Config(**content) +cfg = Config.load()