diff --git a/pyproject.toml b/pyproject.toml index 32dd791..b153d4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "modus" -version = "0.2.0" +version = "2.0.0" description = "Add your description here" readme = "README.md" requires-python = ">=3.13" @@ -34,9 +34,66 @@ packages = ["src/shared", "src/utils", "src/window", "src/services", "src/global [tool.hatch.build.targets.wheel.sources] "src" = "" +[tool.ruff] +target-version = "py313" +line-length = 88 + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +skip-magic-trailing-comma = false +line-ending = "auto" + +[tool.ruff.lint] +select = [ + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # pyflakes + "I", # isort + "UP", # pyupgrade + "B", # flake8-bugbear + "SIM", # flake8-simplify + "C4", # flake8-comprehensions + "RET", # flake8-return + "RUF", # ruff-specific rules + "PIE", # flake8-pie + "T20", # flake8-print + "PT", # flake8-pytest-style + "TCH", # flake8-type-checking + "FLY", # flynt (f-string conversion) +] +ignore = [ + "T201", # allow print() (used for CLI output) + "RET504", # allow unnecessary assignment before return + "SIM108", # allow ternary operator (readability) + "B008", # allow function calls in default args (common in GTK) + "UP007", # allow X | Y union syntax (keep Optional for compatibility) + "UP045", # allow Optional[X] annotation style + "UP006", # allow typing.List etc (keep for readability) + "UP035", # allow deprecated typing imports + "RUF012", # allow mutable class attributes (common in GTK widgets) + "TC001", # allow runtime imports that happen to be type-only + "E501", # line length handled by formatter + "RET505", # allow superfluous else after return + "B027", # allow empty method bodies (common in ABCs) + "B007", # allow unused loop variables + "SIM102", # allow collapsible if + "SIM105", # allow suppressible exception (contextlib.suppress) + "B023", # allow function uses loop variable (closures) + "RUF002", # allow ambiguous unicode in docstrings + "RUF003", # allow ambiguous unicode in comments + "SIM115", # allow open without context handler + "SIM116", # allow if-else instead of dict lookup + "B018", # allow useless expression (standalone identifiers) +] + +[tool.ruff.lint.isort] +known-first-party = ["services", "utils", "shared", "window", "globalmenu"] + [tool.ruff.lint.per-file-ignores] "src/main.py" = ["E402"] "src/window/switcher/main.py" = ["E402"] +"examples/**" = ["INP001", "D101", "D102", "D103"] [tool.uv.sources] fabric = { git = "https://github.com/Fabric-Development/fabric.git" } diff --git a/src/globalmenu/dbusmenu.py b/src/globalmenu/dbusmenu.py index 135c247..ed97a0a 100644 --- a/src/globalmenu/dbusmenu.py +++ b/src/globalmenu/dbusmenu.py @@ -28,18 +28,18 @@ def _get_bus() -> Gio.DBusConnection: class DBusMenuItem: __slots__ = ( - "id", - "label", - "enabled", - "visible", - "type", - "shortcut", - "icon_name", - "has_submenu", - "children", "action_name", "action_target", + "children", + "enabled", + "has_submenu", + "icon_name", + "id", + "label", "parent_id", + "shortcut", + "type", + "visible", ) def __init__( @@ -65,7 +65,7 @@ class DBusMenuItem: self.shortcut = shortcut self.icon_name = icon_name self.has_submenu = has_submenu - self.children: List["DBusMenuItem"] = children if children is not None else [] + self.children: List[DBusMenuItem] = children if children is not None else [] self.action_name = action_name self.action_target = action_target self.parent_id = parent_id @@ -73,18 +73,18 @@ class DBusMenuItem: class DBusMenuClient: __slots__ = ( - "service_name", - "object_path", "_cache", "_cache_valid", + "_fetching", "_hash_cache", "_lock", - "_fetching", + "_on_item_activated_cb", + "_on_items_updated_cb", + "_on_layout_updated_cb", "_revision", "_signal_ids", - "_on_layout_updated_cb", - "_on_items_updated_cb", - "_on_item_activated_cb", + "object_path", + "service_name", ) def __init__(self, service_name: str, object_path: str): diff --git a/src/globalmenu/gtkmenu.py b/src/globalmenu/gtkmenu.py index 34cd555..f892f47 100644 --- a/src/globalmenu/gtkmenu.py +++ b/src/globalmenu/gtkmenu.py @@ -115,11 +115,11 @@ class _ActionInfo: class GtkMenuClient: __slots__ = ( - "service_name", - "object_path", + "_action_cache", "_action_path", "_cached_items", - "_action_cache", + "object_path", + "service_name", ) def __init__(self, service_name: str, object_path: str): @@ -342,9 +342,7 @@ class GtkMenuClient: action_info = self._describe_action(action_name) use_change_state = False if action_info and action_info.state is not None: - if action_info.state_type == "b": - use_change_state = True - elif action_info.parameter_type: + if action_info.state_type == "b" or action_info.parameter_type: use_change_state = True try: @@ -416,12 +414,12 @@ class GtkMenuClient: class ActionMenuClient: __slots__ = ( - "service_name", - "object_path", + "_action_cache", + "_action_map", "_action_path", "_cached_items", - "_action_map", - "_action_cache", + "object_path", + "service_name", ) def __init__(self, service_name: str, object_path: str): @@ -684,9 +682,7 @@ class ActionMenuClient: action_info = self._describe_action(action_name) use_change_state = False if action_info and action_info.state is not None: - if action_info.state_type == "b": - use_change_state = True - elif action_info.parameter_type: + if action_info.state_type == "b" or action_info.parameter_type: use_change_state = True try: diff --git a/src/globalmenu/service.py b/src/globalmenu/service.py index ea527df..4706626 100644 --- a/src/globalmenu/service.py +++ b/src/globalmenu/service.py @@ -708,7 +708,7 @@ class GlobalMenuService(Service): _safe_cap = _safe_cls.capitalize() if _safe_cls else "" dynamic_bases = self._build_dynamic_bases(svc, _safe_cls, _safe_cap) - fallback_paths, seen_fallback = self._introspect_paths( + fallback_paths, _seen_fallback = self._introspect_paths( bus, svc, dynamic_bases ) @@ -772,7 +772,7 @@ class GlobalMenuService(Service): action_candidates.extend( [f"/org/{cls_lower}/{_safe_cap}", f"/org/{cls_lower}"] ) - for ns in _DE_NAMESPACES + [cls_lower]: + for ns in [*_DE_NAMESPACES, cls_lower]: for app_part in (_safe_cap, _safe_cls): p = f"/org/{ns}/{app_part}" if GLib.Variant.is_object_path(p): @@ -833,7 +833,7 @@ class GlobalMenuService(Service): if _safe_cls: cls_lower = _safe_cls.lower() - for ns in _DE_NAMESPACES + [cls_lower]: + for ns in [*_DE_NAMESPACES, cls_lower]: for app_part in (_safe_cap, _safe_cls): for suffix in ("menus/menubar", "menus/appmenu", "menus"): p = f"/org/{ns}/{app_part}/{suffix}" diff --git a/src/main.py b/src/main.py index 8918279..9d1e56c 100644 --- a/src/main.py +++ b/src/main.py @@ -36,26 +36,9 @@ from window.notification.notification import ModusNoti from window.osd.main import OSDWindow from window.panel.main import Panel from window.screencapture import ScreenCaptureWindow +from window.spotlight.main import SpotlightWindow from window.switcher import ApplicationSwitcher -# class LazyLauncher: -# def __init__(self): -# self._instance = None -# -# def _get_instance(self): -# if self._instance is None: -# from window.launcher.main import Launcher -# -# self._instance = Launcher() -# import __main__ -# -# if hasattr(__main__, "app") and __main__.app: -# __main__.app.add_window(self._instance) -# return self._instance -# -# def __getattr__(self, name): -# return getattr(self._get_instance(), name) - def main(): @@ -74,7 +57,7 @@ def main(): switcher = ApplicationSwitcher() panel = Panel() modusnoti = ModusNoti() - # launcher = LazyLauncher() + spotlight = SpotlightWindow() deskwidget = Deskwidgets() dock = Dock() osd = OSDWindow() @@ -97,6 +80,7 @@ def main(): switcher, dock, screencapture, + spotlight, ) def set_css(): @@ -123,7 +107,7 @@ def main(): __main__.switcher = switcher __main__.panel = panel __main__.modusnoti = modusnoti - # __main__.launcher = launcher + __main__.spotlight = spotlight __main__.deskwidget = deskwidget __main__.dock = dock __main__.osd = osd diff --git a/src/services/__init__.py b/src/services/__init__.py index b64ed5e..310bf3a 100644 --- a/src/services/__init__.py +++ b/src/services/__init__.py @@ -1,12 +1,15 @@ from fabric.audio import Audio # noqa: F401 + from .battery import Battery # noqa: F401 from .brightness import Brightness # noqa: F401 from .capslock import CapsLock # noqa: F401 -from .numlock import NumLock # noqa: F401 +from .config import ConfigService, on_config_change, start_config_service # noqa: F401 from .keyboard_layout import KeyboardLayout # noqa: F401 -from .network import NetworkClient, Wifi, Ethernet # noqa: F401 -from .mpris import PlayerService, PlayerManager # noqa: F401 -from .mpris import PlayerService as MprisPlayer, PlayerManager as MprisPlayerManager # noqa: F401 from .modus import ModusService # noqa: F401 +from .mpris import PlayerManager, PlayerService # noqa: F401 +from .mpris import PlayerManager as MprisPlayerManager # noqa: F401 +from .mpris import PlayerService as MprisPlayer # noqa: F401 +from .network import Ethernet, NetworkClient, Wifi # noqa: F401 +from .numlock import NumLock # noqa: F401 from .todo import TodoService # noqa: F401 -from .config import on_config_change, start_config_service, ConfigService # noqa: F401 +from .wallpaper import WallpaperService, create_thumbnail # noqa: F401 diff --git a/src/services/brightness.py b/src/services/brightness.py index 5f9cf15..3293373 100644 --- a/src/services/brightness.py +++ b/src/services/brightness.py @@ -179,6 +179,7 @@ class Brightness(Service): return int(f.readline().strip()) except Exception: return None + return None def _update_brightness_cache(self): """Update brightness cache with current value.""" @@ -246,6 +247,7 @@ class Brightness(Service): logger.error(f"Error executing ddcutil async: {e}") return self._last_raw if self._last_raw != -1 else 0 + return None @screen_brightness.setter def screen_brightness(self, value: int): diff --git a/src/services/config.py b/src/services/config.py index 5f4013c..4717cdf 100644 --- a/src/services/config.py +++ b/src/services/config.py @@ -7,15 +7,13 @@ changes. It is implemented as a singleton and intended to be reused by any module that needs dynamic configuration. """ -from __future__ import annotations - from typing import Any, Callable, Dict, List, Optional from fabric.utils import Gio, GLib, logger, os from tomlkit import document as toml_document from tomlkit import dump as toml_dump from tomlkit import load as toml_load -from tomlkit.items import Integer, String, Bool, Array +from tomlkit.items import Array, Bool, Integer, String from utils.utils import toml_file @@ -97,7 +95,7 @@ class ConfigService: def _load_config(self) -> None: try: if os.path.exists(self._config_file): - with open(self._config_file, "r") as f: + with open(self._config_file) as f: self._config = toml_load(f) else: try: diff --git a/src/services/custom_notification.py b/src/services/custom_notification.py index 020a469..223de0b 100644 --- a/src/services/custom_notification.py +++ b/src/services/custom_notification.py @@ -184,17 +184,14 @@ class CachedNotifications(Notifications): @Signal def clear_all(self) -> None: """Signal emitted when notifications are emptied.""" - pass @Signal def cached_notification_added(self, notification: CachedNotification) -> None: """Signal emitted when a notification is cached.""" - pass @Signal def cached_notification_removed(self, notification: CachedNotification) -> None: """Signal emitted when a notification is removed from cache.""" - pass @Property(List[CachedNotification], "readable") def cached_notifications(self) -> List[CachedNotification]: @@ -269,7 +266,7 @@ class CachedNotifications(Notifications): def load_cached_notifications(self) -> dict[int, CachedNotification]: """Load cached notifications from a JSON file (deserialization).""" try: - with open(NOTIFICATION_CACHE_FILE, "r") as file: + with open(NOTIFICATION_CACHE_FILE) as file: data = json.load(file) # Load list of serialized notifications except (FileNotFoundError, json.JSONDecodeError): # If file doesn't exist or is corrupted, start with empty list diff --git a/src/services/gamemode.py b/src/services/gamemode.py index 6cdbfe7..4020b28 100644 --- a/src/services/gamemode.py +++ b/src/services/gamemode.py @@ -21,7 +21,7 @@ STATE_FILE = Path("/tmp/hyprland_gamemode.toml") def run_hyprctl(command: str) -> str: """Run a hyprctl command and return the output (raises on error).""" - result = run_command(["hyprctl"] + command.split(), timeout=5) + result = run_command(["hyprctl", *command.split()], timeout=5) if result.returncode != 0: raise RuntimeError(f"hyprctl failed: {result.stderr}") return result.stdout.strip() @@ -31,7 +31,7 @@ def _read_state() -> dict: if not STATE_FILE.exists(): return {} try: - with open(STATE_FILE, "r") as f: + with open(STATE_FILE) as f: data = tomlkit.load(f) return dict(data) if data else {} except Exception: diff --git a/src/services/google_lens.py b/src/services/google_lens.py index 2a70dd9..8e7cbe2 100644 --- a/src/services/google_lens.py +++ b/src/services/google_lens.py @@ -61,7 +61,7 @@ class GoogleLens(Service): raise RuntimeError(f"Failed to capture region: {capture_result.stderr}") except Exception as e: - raise RuntimeError(f"Failed to capture region: {e}") + raise RuntimeError(f"Failed to capture region: {e}") from e def upload_file(self, uploader_url, file_path): url_resp = None diff --git a/src/services/keyboard_layout.py b/src/services/keyboard_layout.py index 931a146..b046065 100644 --- a/src/services/keyboard_layout.py +++ b/src/services/keyboard_layout.py @@ -66,7 +66,7 @@ class KeyboardLayout(Service): if not self.layout_state_file.exists(): return None try: - with open(self.layout_state_file, "r") as f: + with open(self.layout_state_file) as f: data = tomlkit.load(f) return dict(data) if data else None except Exception as e: diff --git a/src/services/modus.py b/src/services/modus.py index 6ae5981..3bfa5b7 100644 --- a/src/services/modus.py +++ b/src/services/modus.py @@ -50,7 +50,7 @@ def __getattr__(name): def get_notification_service(): import sys - return getattr(sys.modules[__name__], "notification_service") + return sys.modules[__name__].notification_service class ModusService(Service): diff --git a/src/services/network.py b/src/services/network.py index a0c5ac8..8561b0b 100644 --- a/src/services/network.py +++ b/src/services/network.py @@ -254,7 +254,7 @@ class Ethernet(Service): ): self._device.connect(f"notify::{pn}", lambda *_: self.notifier(pn)) - self._device.connect("notify::speed", lambda *_: print(_)) + self._device.connect("notify::speed", lambda *_: self.notifier("speed")) def notifier(self, pn): self.notify(pn) diff --git a/src/services/todo.py b/src/services/todo.py index ff31dbe..612bf82 100644 --- a/src/services/todo.py +++ b/src/services/todo.py @@ -6,6 +6,7 @@ from pathlib import Path # Fabric imports from fabric.core.service import Property, Service +from fabric.utils import logger # Local imports import shared.data as data @@ -36,7 +37,7 @@ class TodoService(Service): try: callback(event_type, data) except Exception as e: - print(f"Error in todo callback: {e}") + logger.error(f"Error in todo callback: {e}") def _get_todos_file_path(self): """Returns the path to the todos JSON file""" @@ -48,12 +49,12 @@ class TodoService(Service): """Load todos from JSON file""" try: if self._file_path.exists(): - with open(self._file_path, "r", encoding="utf-8") as f: + with open(self._file_path, encoding="utf-8") as f: self._todos = json.load(f) else: self._todos = [] except Exception as e: - print(f"Error loading todos: {e}") + logger.error(f"Error loading todos: {e}") self._todos = [] def _save_todos(self): @@ -62,7 +63,7 @@ class TodoService(Service): with open(self._file_path, "w", encoding="utf-8") as f: json.dump(self._todos, f, indent=2, ensure_ascii=False) except Exception as e: - print(f"Error saving todos: {e}") + logger.error(f"Error saving todos: {e}") @Property(list, "readable") def todos(self): diff --git a/src/shared/data.py b/src/shared/data.py index 75d5184..438152a 100644 --- a/src/shared/data.py +++ b/src/shared/data.py @@ -1,20 +1,28 @@ -from fabric.utils import logger - -from fabric.utils import GLib, get_relative_path, os +from fabric.utils import GLib, get_relative_path, logger, os from utils.functions import parse_timeout_string from utils.utils import toml_file +HOME_DIR = GLib.get_home_dir() APP_NAME = "modus1" CACHE_DIR = str(GLib.get_user_cache_dir()) + f"/{APP_NAME}" CONFIG_DIR = os.path.expanduser(f"~/.config/{APP_NAME}") +SYSTEM_CACHE_DIR = GLib.get_user_cache_dir() +WALLPAPER_PATH = f"{HOME_DIR}/Pictures/Wallpapers" +WALLPAPER_THUMBS_PATH = f"{WALLPAPER_PATH}/.thumbnails" +WALLPAPERS_THUMBNAILS_SIZE = 200 WALLPAPERS_DIR_DEFAULT = get_relative_path("../assets/wallpapers_example/") + CONFIG_FILE = toml_file("config.toml") +CLIPBOARD_THUMBS_DIR = f"{GLib.get_user_cache_dir()}/{APP_NAME}/clipboard_thumbs" +CLIPBOARD_DB_PATH = f"{GLib.get_user_cache_dir()}/cliphist/db" + + def load_config(): """Load the configuration from config.toml""" try: @@ -30,7 +38,7 @@ def load_config(): try: import tomlkit - with open(CONFIG_FILE, "r") as f: + with open(CONFIG_FILE) as f: config = dict(tomlkit.load(f)) except Exception as e: logger.error(f"Error loading config: {e}") diff --git a/src/shared/dialogs/about.py b/src/shared/dialogs/about.py index aae1a39..96426b3 100644 --- a/src/shared/dialogs/about.py +++ b/src/shared/dialogs/about.py @@ -138,7 +138,7 @@ def get_app_info(wmclass): continue try: full_path = os.path.join(path, f) - with open(full_path, "r", encoding="utf-8") as df: + with open(full_path, encoding="utf-8") as df: content = df.read() if ( f"StartupWMClass={wmclass}" in content @@ -151,7 +151,7 @@ def get_app_info(wmclass): if desktop_file: try: - with open(desktop_file, "r", encoding="utf-8") as f: + with open(desktop_file, encoding="utf-8") as f: content = f.read() name = wmclass.title() @@ -178,9 +178,7 @@ def get_app_info(wmclass): name = value elif key == "Version": version = value - elif key == "Comment": - comment = value - elif key == "GenericName" and not comment: + elif key == "Comment" or (key == "GenericName" and not comment): comment = value elif key == "Icon": icon = value diff --git a/src/shared/widgets/animator.py b/src/shared/widgets/animator.py index 03709ce..91e3beb 100644 --- a/src/shared/widgets/animator.py +++ b/src/shared/widgets/animator.py @@ -93,7 +93,6 @@ class Animator(Service): self._timing_function = lambda progress=0.0, **_: cubic_bezier( *value, progress=progress ) - return @Property(TimingFunctionCallback, "read-write") def timing_function(self) -> TimingFunctionCallback: @@ -102,7 +101,6 @@ class Animator(Service): @timing_function.setter def timing_function(self, value: TimingFunctionCallback): self._timing_function = value - return @Property(float, "read-write") def duration(self): @@ -114,7 +112,6 @@ class Animator(Service): raise ValueError("duration can't be smaller than or equal to 0.0") self._duration = value - return @Property(float, "read-write") def value(self): @@ -123,7 +120,6 @@ class Animator(Service): @value.setter def value(self, value: float): self._value = value - return @Property(float, "read-write") def max_value(self): @@ -132,7 +128,6 @@ class Animator(Service): @max_value.setter def max_value(self, value: float): self._max_value = value - return @Property(float, "read-write") def min_value(self): @@ -141,7 +136,6 @@ class Animator(Service): @min_value.setter def min_value(self, value: float): self._min_value = value - return @Property(bool, "read-write", default_value=False) def playing(self): @@ -150,7 +144,6 @@ class Animator(Service): @playing.setter def playing(self, value: bool): # this setter is intended for internal usage only self._playing = value - return @Property(bool, "read-write", default_value=False) def repeat(self): @@ -159,7 +152,6 @@ class Animator(Service): @repeat.setter def repeat(self, value: bool): self._repeat = value - return def __init__( self, @@ -203,7 +195,7 @@ class Animator(Service): if not self._playing: return - elapsed_time = delta_time - cast(float, self._start_time) + elapsed_time = delta_time - cast("float", self._start_time) self._timeline_pos = min(1.0, elapsed_time / self._duration) @@ -225,7 +217,6 @@ class Animator(Service): self._start_time = delta_time self._timeline_pos = 0.0 - return def do_handle_tick(self, *_): current_time = self.do_get_time_now() @@ -241,7 +232,6 @@ class Animator(Service): else: GLib.source_remove(self._tick_handler) self._tick_handler = None - return def play(self): if self._playing: @@ -270,5 +260,5 @@ class Animator(Service): if not self._tick_handler: self._timeline_pos = 0 self.playing = False - return + return None return self.do_remove_tick_handlers() diff --git a/src/shared/widgets/circle_image.py b/src/shared/widgets/circle_image.py index 1dee90b..e2c0dad 100644 --- a/src/shared/widgets/circle_image.py +++ b/src/shared/widgets/circle_image.py @@ -1,6 +1,7 @@ from typing import Literal + from fabric.core.service import Property -from fabric.utils import Gdk, GdkPixbuf, Gtk, cairo, math # noqa: E402 +from fabric.utils import Gdk, GdkPixbuf, Gtk, cairo, math from fabric.widgets.widget import Widget diff --git a/src/shared/widgets/clipping_box.py b/src/shared/widgets/clipping_box.py index da1d757..cf16d68 100644 --- a/src/shared/widgets/clipping_box.py +++ b/src/shared/widgets/clipping_box.py @@ -32,7 +32,7 @@ class ClippingBox(Box): self.get_allocated_width(), self.get_allocated_height(), cast( - int, + "int", self.get_style_context().get_property( "border-radius", self.get_state_flags() ), diff --git a/src/shared/widgets/custom_image.py b/src/shared/widgets/custom_image.py index 5cee888..4475a7c 100644 --- a/src/shared/widgets/custom_image.py +++ b/src/shared/widgets/custom_image.py @@ -1,8 +1,7 @@ import math from typing import cast -from fabric.utils import cairo, Gtk - +from fabric.utils import Gtk, cairo from fabric.widgets.image import Image @@ -30,7 +29,7 @@ class CustomImage(Image): cr, width, height, - cast(int, context.get_property("border-radius", Gtk.StateFlags.NORMAL)), + cast("int", context.get_property("border-radius", Gtk.StateFlags.NORMAL)), ) cr.clip() Image.do_draw(self, cr) diff --git a/src/shared/widgets/customrevealer.py b/src/shared/widgets/customrevealer.py index 07d0174..a56626c 100644 --- a/src/shared/widgets/customrevealer.py +++ b/src/shared/widgets/customrevealer.py @@ -113,7 +113,7 @@ class SlideRevealer(Gtk.Overlay): x, y = self._get_position_at_progress_cached(progress) # Round to nearest pixel for actual positioning - pixel_x, pixel_y = int(round(x)), int(round(y)) + pixel_x, pixel_y = round(x), round(y) self._fixed.move(self.child, pixel_x, pixel_y) self.queue_draw() diff --git a/src/shared/widgets/flat_scale.py b/src/shared/widgets/flat_scale.py index 4df4711..3f64183 100644 --- a/src/shared/widgets/flat_scale.py +++ b/src/shared/widgets/flat_scale.py @@ -4,7 +4,7 @@ from typing import Callable, Iterable, Literal, TypedDict from fabric.utils import Gdk, GObject, Gtk, cairo from fabric.utils.helpers import clamp from fabric.widgets.widget import Widget -from gi.repository import Pango, PangoCairo # noqa: E402 +from gi.repository import Pango, PangoCairo from shared.widgets.animator import Animator, ease_in, ease_in_out, ease_out diff --git a/src/shared/window/animated_scrollwindow.py b/src/shared/window/animated_scrollwindow.py index 5dd844b..6d1c95d 100644 --- a/src/shared/window/animated_scrollwindow.py +++ b/src/shared/window/animated_scrollwindow.py @@ -63,7 +63,7 @@ class AnimatedScrollable(ScrolledWindow): def animate_size(self, height: int = -1): if not self.animate: idle_add(lambda: self.snap_to_size(height)) - return + return None self._last_req = height current_val = self.height_animator.value return self.do_animate(current_val, height) diff --git a/src/shared/window/applet_window.py b/src/shared/window/applet_window.py index 0e9b5e0..422a76c 100644 --- a/src/shared/window/applet_window.py +++ b/src/shared/window/applet_window.py @@ -1,9 +1,8 @@ -from fabric.utils import logger -from fabric.utils import GLib -from fabric.widgets.eventbox import EventBox # noqa: E402 -from fabric.widgets.wayland import WaylandWindow as Window # noqa: E402 +from fabric.utils import GLib, logger +from fabric.widgets.eventbox import EventBox +from fabric.widgets.wayland import WaylandWindow as Window -from shared.window.popup_win import PopupWindow # noqa: E402 +from shared.window.popup_win import PopupWindow class DismissLayer(Window): diff --git a/src/shared/window/battery_widget.py b/src/shared/window/battery_widget.py index 39ee17b..6cdf10a 100644 --- a/src/shared/window/battery_widget.py +++ b/src/shared/window/battery_widget.py @@ -1,14 +1,13 @@ -from fabric.utils import logger -from fabric.utils import GLib +from fabric.utils import GLib, logger from fabric.widgets.box import Box from fabric.widgets.button import Button from fabric.widgets.centerbox import CenterBox from fabric.widgets.image import Image from fabric.widgets.label import Label from fabric.widgets.separator import Separator -from services.gamemode import check_gamemode, toggle_gamemode from services.battery import Battery +from services.gamemode import check_gamemode, toggle_gamemode from utils.functions import clear_children, format_duration from utils.utils import svg_file diff --git a/src/shared/window/popup_win.py b/src/shared/window/popup_win.py index d9eb957..17c360a 100644 --- a/src/shared/window/popup_win.py +++ b/src/shared/window/popup_win.py @@ -89,7 +89,7 @@ class PopupWindow(WaylandWindow): def do_handle_size_allocate(self, *_): if not self.get_visible(): - return + return None return self.do_reposition(self.do_calculate_edges()) def do_calculate_edges(self): @@ -142,7 +142,7 @@ class PopupWindow(WaylandWindow): height = self.get_allocated_height() width = self.get_allocated_width() - monitor_x, monitor_width = _get_monitor_geometry(parent_window) + _monitor_x, monitor_width = _get_monitor_geometry(parent_window) if self._pointing_widget: coords = self.get_coords_for_widget(self._pointing_widget) @@ -176,7 +176,8 @@ class PopupWindow(WaylandWindow): position_margins = (clamped, 0, 0, 0) new_margin = tuple( - a + b for a, b in zip(position_margins, self._base_margin.values()) + a + b + for a, b in zip(position_margins, self._base_margin.values(), strict=False) ) new_margin = ( max(0, new_margin[0]), diff --git a/src/utils/app_name_resolver.py b/src/utils/app_name_resolver.py index c372ca5..cb4046e 100644 --- a/src/utils/app_name_resolver.py +++ b/src/utils/app_name_resolver.py @@ -16,7 +16,7 @@ class AppName: return None desktop_app_name = wmclass - with open(os.path.join(self.path, desktop_file), "r") as f: + with open(os.path.join(self.path, desktop_file)) as f: lines = f.readlines() for line in lines: if line.startswith("Name="): diff --git a/src/utils/conversion.py b/src/utils/conversion.py index deb616b..9978328 100644 --- a/src/utils/conversion.py +++ b/src/utils/conversion.py @@ -1,10 +1,10 @@ -from fabric.utils import logger import threading import time from concurrent.futures import ThreadPoolExecutor from typing import Dict, Optional, Tuple import httpx +from fabric.utils import logger class CurrencyCache: @@ -102,7 +102,7 @@ class CurrencyCache: except Exception as je: logger.error(f"Failed to parse JSON for {from_code}: {je}") else: - print( + logger.warning( f"Background fetch for {from_code} returned status { response.status_code }" diff --git a/src/utils/icon_resolver.py b/src/utils/icon_resolver.py index cdcf345..cd6b521 100644 --- a/src/utils/icon_resolver.py +++ b/src/utils/icon_resolver.py @@ -12,7 +12,7 @@ if not os.path.exists(data.CACHE_DIR): class IconResolver: def __init__( - self, default_applicaiton_icon: str = "application-x-executable-symbolic" + self, default_application_icon: str = "application-x-executable-symbolic" ): if os.path.exists(ICON_CACHE_FILE): with open(ICON_CACHE_FILE) as f: @@ -25,7 +25,7 @@ class IconResolver: self._icon_dict = {} self._icon_dict_order: list[str] = [] - self.default_applicaiton_icon = default_applicaiton_icon + self.default_application_icon = default_application_icon def get_icon_name(self, app_id: str): if app_id in self._icon_dict: @@ -50,11 +50,11 @@ class IconResolver: try: # Fallback to the default application icon. return icon_theme.load_icon( - self.default_applicaiton_icon, size, Gtk.IconLookupFlags.FORCE_SIZE + self.default_application_icon, size, Gtk.IconLookupFlags.FORCE_SIZE ) except GLib.Error as fallback_error: logger.error( - f"Error: Fallback icon '{self.default_applicaiton_icon}' also not found. Error: {fallback_error}" + f"Error: Fallback icon '{self.default_application_icon}' also not found. Error: {fallback_error}" ) return None @@ -84,7 +84,7 @@ class IconResolver: except Exception as e: logger.error(f"[ICONS] Error reading desktop file {desktop_file_path}: {e}") - return self.default_applicaiton_icon + return self.default_application_icon def _get_desktop_file(self, app_id: str) -> str | None: if not app_id: @@ -131,7 +131,7 @@ class IconResolver: continue path = os.path.join(data_dir, f) try: - with open(path, "r", errors="ignore") as file: + with open(path, errors="ignore") as file: for line in file: line = line.strip() if line.startswith("StartupWMClass="): @@ -149,7 +149,7 @@ class IconResolver: def _compositor_find_icon(self, app_id: str): if not app_id: - return self.default_applicaiton_icon + return self.default_application_icon icon_theme = Gtk.IconTheme.get_default() @@ -169,4 +169,4 @@ class IconResolver: if icon and icon_theme.has_icon(icon): return icon - return self.default_applicaiton_icon + return self.default_application_icon diff --git a/src/utils/inhibit.py b/src/utils/inhibit.py index 3e511b8..ed9eaf6 100644 --- a/src/utils/inhibit.py +++ b/src/utils/inhibit.py @@ -1,7 +1,5 @@ -from fabric.utils import logger # From https://github.com/stwa/wayland-idle-inhibitor # License: WTFPL Version 2 - import argparse import os import subprocess @@ -9,6 +7,8 @@ import sys from dataclasses import dataclass from pathlib import Path +from fabric.utils import logger + # Add the project root to sys.path to allow absolute imports from 'utils' sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) @@ -47,10 +47,10 @@ def parse_duration(duration_str: str) -> int: return int(float(duration_str[:-1])) else: return int(duration_str) - except ValueError: + except ValueError as err: raise ValueError( "Invalid duration format. Use '1h', '30m', '45s', 'on', 'off', etc." - ) + ) from err def kill_existing_inhibit_processes(): @@ -183,7 +183,7 @@ def main() -> None: shutdown() except Exception as e: - logger.error(f"Error: {str(e)}") + logger.error(f"Error: {e!s}") logger.error("Make sure you're running this under a Wayland session.") sys.exit(1) diff --git a/src/utils/roam.py b/src/utils/roam.py index 1d1c7b5..f35bf98 100644 --- a/src/utils/roam.py +++ b/src/utils/roam.py @@ -4,7 +4,7 @@ _services_mod = None def _mod(): global _services_mod if _services_mod is None: - import services.modus as _services_mod # noqa: F811 + import services.modus as _services_mod return _services_mod diff --git a/src/window/controlcenter/expanded_player.py b/src/window/controlcenter/expanded_player.py index 0bc632d..5cf5bd6 100644 --- a/src/window/controlcenter/expanded_player.py +++ b/src/window/controlcenter/expanded_player.py @@ -13,9 +13,9 @@ from fabric.widgets.wayland import WaylandWindow as Window from services.mpris import PlayerManager, PlayerService from utils.utils import svg_file from window.controlcenter.player import ( + PLAYER_FALLBACK_ART, apply_player_art, get_shared_mpris_manager, - PLAYER_FALLBACK_ART, ) @@ -667,9 +667,10 @@ class PlayerBox(Box): self.play_pause_icon.dynamic_file(icon_file) else: # Fallback if play_pause_icon isn't available - from utils.utils import get_relative_path import os + from utils.utils import get_relative_path + self.play_pause_button.get_child().set_from_file( os.path.join(get_relative_path("assets/icons/"), icon_file) ) diff --git a/src/window/controlcenter/per_app_volume.py b/src/window/controlcenter/per_app_volume.py index 3b016d0..7cf38cd 100644 --- a/src/window/controlcenter/per_app_volume.py +++ b/src/window/controlcenter/per_app_volume.py @@ -3,10 +3,11 @@ from fabric.widgets.box import Box from fabric.widgets.button import Button from fabric.widgets.image import Image from fabric.widgets.label import Label -from shared.widgets.flat_scale import FlatScale from fabric.widgets.scrolledwindow import ScrolledWindow from fabric.widgets.separator import Separator +from shared.widgets.flat_scale import FlatScale + # Local imports from utils.roam import audio_service @@ -208,9 +209,10 @@ class PerAppVolumeControl(Box): for i, app in enumerate(applications): if hasattr(app, "name") and hasattr(app, "volume"): app_widget = self._create_app_control(app) - self.apps_container.children = list( - self.apps_container.children - ) + [app_widget] + self.apps_container.children = [ + *list(self.apps_container.children), + app_widget, + ] # Add separator between apps (except for last one) if i < len(applications) - 1: @@ -218,9 +220,10 @@ class PerAppVolumeControl(Box): orientation="horizontal", style_classes="app-volume-separator", ) - self.apps_container.children = list( - self.apps_container.children - ) + [separator] + self.apps_container.children = [ + *list(self.apps_container.children), + separator, + ] self._app_widgets[app.name] = (app_widget, app) else: diff --git a/src/window/desktop/widget.py b/src/window/desktop/widget.py index 8a84c0a..8d2dbd6 100644 --- a/src/window/desktop/widget.py +++ b/src/window/desktop/widget.py @@ -77,7 +77,7 @@ def get_location() -> str: if city: return city - print("All location APIs failed") + logger.warning("All location APIs failed") return "" @@ -201,6 +201,7 @@ def get_weather(callback): GLib.idle_add(callback, formatted_data) else: GLib.idle_add(callback, None) + return None executor.submit(fetch_weather) diff --git a/src/window/dock/animator.py b/src/window/dock/animator.py index a4f066a..d574065 100644 --- a/src/window/dock/animator.py +++ b/src/window/dock/animator.py @@ -1,15 +1,11 @@ -from __future__ import annotations - -from typing import TYPE_CHECKING, Optional +from typing import Optional from fabric.utils import GLib +from .canvas import DockCanvas from .constants import ANIM_INTERVAL_MS, IDLE_THRESHOLD, LERP_FACTOR from .layout import DockLayout -if TYPE_CHECKING: - from .canvas import DockCanvas - class DockAnimator: def __init__(self, canvas: DockCanvas): diff --git a/src/window/dock/canvas.py b/src/window/dock/canvas.py index 75d4c3f..5ebb682 100644 --- a/src/window/dock/canvas.py +++ b/src/window/dock/canvas.py @@ -1,5 +1,3 @@ -from __future__ import annotations - import math from dataclasses import dataclass from typing import Dict, List, Optional, Tuple @@ -810,9 +808,9 @@ class DockCanvas(Gtk.DrawingArea): if item.is_pinned and not item.is_running: self._handle_pinned_click(event, item) - elif item.is_running and not item.is_pinned: - self._handle_instance_click(event, item) - elif item.is_pinned and item.is_running: + elif (item.is_running and not item.is_pinned) or ( + item.is_pinned and item.is_running + ): self._handle_instance_click(event, item) return True @@ -894,7 +892,7 @@ class DockCanvas(Gtk.DrawingArea): def _read_pinned_apps(self) -> list: try: if os.path.exists(PINNED_APPS_FILE): - with open(PINNED_APPS_FILE, "r") as f: + with open(PINNED_APPS_FILE) as f: data = tomlkit.load(f) return list(data.get("pinned", [])) except Exception as e: diff --git a/src/window/dock/constants.py b/src/window/dock/constants.py index 30e489a..bd96f89 100644 --- a/src/window/dock/constants.py +++ b/src/window/dock/constants.py @@ -1,5 +1,3 @@ -from __future__ import annotations - from utils.utils import toml_file PINNED_APPS_FILE = toml_file("dock.toml") diff --git a/src/window/dock/layout.py b/src/window/dock/layout.py index 963e185..9f4e101 100644 --- a/src/window/dock/layout.py +++ b/src/window/dock/layout.py @@ -1,8 +1,7 @@ -from __future__ import annotations - import math -from typing import TYPE_CHECKING, List, Tuple +from typing import List, Tuple +from .canvas import DockItem from .constants import ( BG_PADDING_H, BG_PADDING_V, @@ -13,9 +12,6 @@ from .constants import ( SIGMA_FACTOR, ) -if TYPE_CHECKING: - from .canvas import DockItem - class DockLayout: @staticmethod diff --git a/src/window/dock/main.py b/src/window/dock/main.py index f15c205..8d415a1 100644 --- a/src/window/dock/main.py +++ b/src/window/dock/main.py @@ -1,5 +1,3 @@ -from __future__ import annotations - from fabric.utils import GLib, logger, random from fabric.widgets.box import Box from fabric.widgets.eventbox import EventBox diff --git a/src/window/notification/notification.py b/src/window/notification/notification.py index 408dbe6..4c0d200 100644 --- a/src/window/notification/notification.py +++ b/src/window/notification/notification.py @@ -1263,10 +1263,7 @@ class ModusNoti(Window): app_name = getattr(notification, "app_name", "") # Check if app name is in ignored list - if app_name in ignored_apps: - return True - - return False + return app_name in ignored_apps except Exception as e: logger.warning(f"Failed to check if notification should be ignored: {e}") return False diff --git a/src/window/notification/unified_cache.py b/src/window/notification/unified_cache.py index dec5982..62b7694 100644 --- a/src/window/notification/unified_cache.py +++ b/src/window/notification/unified_cache.py @@ -3,7 +3,7 @@ import time import uuid from collections import OrderedDict -from fabric.utils import GdkPixbuf, get_relative_path, Gtk, logger, os +from fabric.utils import GdkPixbuf, Gtk, get_relative_path, logger, os import shared.data as data diff --git a/src/window/osd/__init__.py b/src/window/osd/__init__.py index fbc6378..9b1b70c 100644 --- a/src/window/osd/__init__.py +++ b/src/window/osd/__init__.py @@ -1,5 +1,5 @@ -from .main import OSDWindow # noqa: F401 from .components import ( # noqa: F401 AudioOSDContainer, BrightnessOSDContainer, ) +from .main import OSDWindow # noqa: F401 diff --git a/src/window/osd/components/audio.py b/src/window/osd/components/audio.py index 658006d..8473ccc 100644 --- a/src/window/osd/components/audio.py +++ b/src/window/osd/components/audio.py @@ -1,8 +1,11 @@ -from fabric.utils import logger import math + from fabric.audio import Audio -from utils.utils import svg_file +from fabric.utils import logger from fabric.widgets.scale import ScaleMark + +from utils.utils import svg_file + from .animated_scale import AnimatedScale from .base import BaseOSDContainer @@ -88,9 +91,7 @@ class AudioOSDContainer(BaseOSDContainer): ) display_volume = 0 if (volume == 0 or muted) else volume - level = ( - 0 if display_volume == 0 else min(int(math.ceil(display_volume / 33)), 3) - ) + level = 0 if display_volume == 0 else min(math.ceil(display_volume / 33), 3) self.osd_window_image.set_from_file(f"volume/audio-volume-{level}.svg") diff --git a/src/window/osd/components/base.py b/src/window/osd/components/base.py index 190556d..aef08fe 100644 --- a/src/window/osd/components/base.py +++ b/src/window/osd/components/base.py @@ -1,5 +1,6 @@ from abc import abstractmethod -from fabric.utils import Gdk, GLib, invoke_repeater, remove_handler, time, logger + +from fabric.utils import Gdk, GLib, invoke_repeater, logger, remove_handler, time from fabric.widgets.box import Box from fabric.widgets.wayland import WaylandWindow as Window diff --git a/src/window/osd/components/brightness.py b/src/window/osd/components/brightness.py index 07ec57e..c0ce79c 100644 --- a/src/window/osd/components/brightness.py +++ b/src/window/osd/components/brightness.py @@ -1,8 +1,11 @@ -from fabric.utils import logger import math + +from fabric.utils import logger +from fabric.widgets.scale import ScaleMark + from services.brightness import Brightness from utils.utils import svg_file -from fabric.widgets.scale import ScaleMark + from .animated_scale import AnimatedScale from .base import BaseOSDContainer @@ -49,7 +52,7 @@ class BrightnessOSDContainer(BaseOSDContainer): def _update_display(self): normalized = self._get_normalized_brightness() - level = 0 if normalized == 0 else min(int(math.ceil(normalized / 33)), 3) + level = 0 if normalized == 0 else min(math.ceil(normalized / 33), 3) self.osd_window_image.set_from_file(f"brightness/brightness-{level}.svg") diff --git a/src/window/panel/components/custom_mods.py b/src/window/panel/components/custom_mods.py index 21f559a..4439662 100644 --- a/src/window/panel/components/custom_mods.py +++ b/src/window/panel/components/custom_mods.py @@ -1,8 +1,7 @@ from pathlib import Path import tomlkit - -from fabric.utils import GLib, Gio, logger +from fabric.utils import Gio, GLib, logger from fabric.widgets.box import Box from fabric.widgets.button import Button from fabric.widgets.label import Label diff --git a/src/window/panel/components/enhanced_system_tray.py b/src/window/panel/components/enhanced_system_tray.py index f542e39..c5f3a3e 100644 --- a/src/window/panel/components/enhanced_system_tray.py +++ b/src/window/panel/components/enhanced_system_tray.py @@ -1,5 +1,5 @@ -from pathlib import Path import weakref +from pathlib import Path from fabric.system_tray.widgets import SystemTrayItem from fabric.utils import GdkPixbuf, GLib, logger diff --git a/src/window/panel/components/globalmenu.py b/src/window/panel/components/globalmenu.py index fe06993..bba9169 100644 --- a/src/window/panel/components/globalmenu.py +++ b/src/window/panel/components/globalmenu.py @@ -5,9 +5,9 @@ from fabric.widgets.button import Button from fabric.widgets.centerbox import CenterBox from fabric.widgets.label import Label +from globalmenu.service import get_global_menu_service from shared.dialogs.about import AboutApp, get_about_window from shared.window.dropdown import ModusDropdown, dropdown_divider, dropdowns -from globalmenu.service import get_global_menu_service from utils.app_name_resolver import format_window from utils.roam import modus_service from utils.utils import setup_cursor_hover diff --git a/src/window/panel/components/indicators.py b/src/window/panel/components/indicators.py index 8b0d151..28e2d35 100644 --- a/src/window/panel/components/indicators.py +++ b/src/window/panel/components/indicators.py @@ -435,7 +435,7 @@ class BatteryIndicator(Box): def update_state(self): if not self._is_present(): - print("[Battery] No battery detected, hiding indicator") + logger.warning("No battery detected, hiding indicator") self.hide() return else: diff --git a/src/window/panel/components/todo.py b/src/window/panel/components/todo.py index b0db585..09ac7af 100644 --- a/src/window/panel/components/todo.py +++ b/src/window/panel/components/todo.py @@ -5,9 +5,9 @@ from fabric.widgets.box import Box from fabric.widgets.button import Button from fabric.widgets.entry import Entry from fabric.widgets.label import Label -from shared.window.animated_scrollwindow import AnimatedScrollable -from services.todo import get_todo_service +from services.todo import get_todo_service +from shared.window.animated_scrollwindow import AnimatedScrollable from shared.window.applet_window import AppletWindow from utils.utils import svg_file @@ -364,11 +364,11 @@ class TodoListWidget(AppletWindow): def _on_todo_event(self, event_type, data=None): """Handle todo service events via callback""" - if event_type == "todos-changed": - GLib.idle_add(self._refresh_todos) - elif event_type == "todo-added": - GLib.idle_add(self._refresh_todos) - elif event_type == "todo-deleted": + if ( + event_type == "todos-changed" + or event_type == "todo-added" + or event_type == "todo-deleted" + ): GLib.idle_add(self._refresh_todos) elif event_type in ["todo-toggled", "todo-edited", "todo-priority-changed"]: if data and data["id"] in self.todo_items: diff --git a/src/window/panel/main.py b/src/window/panel/main.py index f12b448..f469f2c 100644 --- a/src/window/panel/main.py +++ b/src/window/panel/main.py @@ -43,7 +43,7 @@ class Panel(Window): self.imac = Button( name="panel-button", child=svg_file("misc/logo.svg", size=18), - on_clicked=lambda *_: self.globalmenu.show_system_dropdown((self.imac)), + on_clicked=lambda *_: self.globalmenu.show_system_dropdown(self.imac), ) setup_cursor_hover(self.imac, "pointer") self.globalmenu.set_imac_button(self.imac) @@ -313,7 +313,7 @@ class Panel(Window): self.queue_resize() def _on_config_changed(self, new_config, old_config): - print("[Panel] Config changed, checking keys...") + logger.debug("Config changed, checking keys...") keys = { "imac_button", "global_menu", @@ -330,7 +330,7 @@ class Panel(Window): } changed_keys = [k for k in keys if new_config.get(k) != old_config.get(k)] if changed_keys: - print(f"[Panel] Rebuilding due to changes in: {changed_keys}") + logger.debug(f"Rebuilding due to changes in: {changed_keys}") self._rebuild_layout_from_config(new_config) self._update_tray_visibility() diff --git a/src/window/panel/notch/__init__.py b/src/window/panel/notch/__init__.py index dc4f686..1efcb27 100644 --- a/src/window/panel/notch/__init__.py +++ b/src/window/panel/notch/__init__.py @@ -1,8 +1,8 @@ -from window.panel.notch.notch import Notch from window.panel.notch.indicators import ( CapsLockIndicator, KeyboardLayoutIndicator, NumLockIndicator, ) +from window.panel.notch.notch import Notch -__all__ = ["Notch", "CapsLockIndicator", "KeyboardLayoutIndicator", "NumLockIndicator"] +__all__ = ["CapsLockIndicator", "KeyboardLayoutIndicator", "Notch", "NumLockIndicator"] diff --git a/src/window/panel/notch/notch.py b/src/window/panel/notch/notch.py index a58d06f..4e27c46 100644 --- a/src/window/panel/notch/notch.py +++ b/src/window/panel/notch/notch.py @@ -1,19 +1,20 @@ -from fabric.utils import Gdk, Gtk, GLib +from fabric.utils import Gdk, GLib, Gtk from fabric.widgets.box import Box from fabric.widgets.centerbox import CenterBox from fabric.widgets.shapes import Corner from fabric.widgets.stack import Stack + from services.screencapture import screen_capture_service -from window.panel.notch.recording import RecordingIndicator -from window.panel.notch.player import NotchPlayer +from window.controlcenter.player import get_shared_mpris_manager from window.panel.notch.indicators import ( CapsLockIndicator, + ChargingIndicator, KeyboardLayoutIndicator, MicrophoneIndicator, NumLockIndicator, - ChargingIndicator, ) -from window.controlcenter.player import get_shared_mpris_manager +from window.panel.notch.player import NotchPlayer +from window.panel.notch.recording import RecordingIndicator class Notch(Box): diff --git a/src/window/panel/notch/player.py b/src/window/panel/notch/player.py index 62e39ce..7596073 100644 --- a/src/window/panel/notch/player.py +++ b/src/window/panel/notch/player.py @@ -2,7 +2,7 @@ import math import os import time -from fabric.utils import GLib, Gtk, GdkPixbuf +from fabric.utils import GdkPixbuf, GLib, Gtk from fabric.widgets.box import Box from fabric.widgets.centerbox import CenterBox diff --git a/src/window/screencapture/main.py b/src/window/screencapture/main.py index fe22978..b001ea5 100644 --- a/src/window/screencapture/main.py +++ b/src/window/screencapture/main.py @@ -219,11 +219,7 @@ class ScreenCaptureWindow(Window): screen_capture_service.record( "active", use_audio=use_audio, show_cursor=show_cursor ) - elif tool == "record-window": - screen_capture_service.record( - "selection", use_audio=use_audio, show_cursor=show_cursor - ) - elif tool == "record-region": + elif tool == "record-window" or tool == "record-region": screen_capture_service.record( "selection", use_audio=use_audio, show_cursor=show_cursor ) @@ -289,7 +285,7 @@ class ScreenCaptureWindow(Window): ) ctx.remove_class("recording") - def toggle(self, ss: str = None, sr: str = None): + def toggle(self, ss: str | None = None, sr: str | None = None): """ Toggle the window, or trigger a direct action via CLI. :param ss: screenshot mode (e.g. 'region', 'fullscreen', 'selectwindow') diff --git a/src/window/screencapture/options_menu.py b/src/window/screencapture/options_menu.py index 54924f5..9438964 100644 --- a/src/window/screencapture/options_menu.py +++ b/src/window/screencapture/options_menu.py @@ -1,4 +1,5 @@ from fabric.utils import Gdk, Gtk + from shared.widgets.smooth_switch import SmoothSwitch diff --git a/src/window/screencapture/tool_button.py b/src/window/screencapture/tool_button.py index c3a3d62..f9d8a37 100644 --- a/src/window/screencapture/tool_button.py +++ b/src/window/screencapture/tool_button.py @@ -1,4 +1,5 @@ from fabric.widgets.button import Button + from utils.utils import svg_file diff --git a/src/window/settings/main.py b/src/window/settings/main.py index 4831fe4..660a66b 100644 --- a/src/window/settings/main.py +++ b/src/window/settings/main.py @@ -13,7 +13,9 @@ from utils.utils import setup_cursor_hover, svg_file class SettingsRow(CenterBox): - def __init__(self, label: str, child=None, description: str = None, **kwargs): + def __init__( + self, label: str, child=None, description: str | None = None, **kwargs + ): label_widget = Label(label=label, name="settings-row-label", h_align="start") start_children = [label_widget] diff --git a/src/window/switcher/main.py b/src/window/switcher/main.py index c4aaeb7..b393d99 100644 --- a/src/window/switcher/main.py +++ b/src/window/switcher/main.py @@ -28,16 +28,16 @@ from utils.icon_resolver import IconResolver class _SwitcherItem: __slots__ = ( - "button", - "item_box", - "header_box", + "address", "app_icon", - "name_label", - "preview_image", - "overlay", "badge_box", "badge_label", - "address", + "button", + "header_box", + "item_box", + "name_label", + "overlay", + "preview_image", ) def __init__(