refactor(modules): simplify SVG asset handling across modules
Enhancements: - Add optimized night‑variant detection for weather icons using a predefined list - Replace `Svg` usage with direct `svg_file` calls throughout the todo widget, removing redundant relative‑path logic - Update dock and battery modules to load assets via direct paths, eliminating unnecessary `get_relative_path` calls- Introduce `WEATHER_CACHE_TIMEOUT` constant and tidy up unused imports (`WEATHER_EMOJI_MAP` removed) - Minor formatting and structural clean‑ups that improve code readability Bug Fixes: - Remove dead import of `WEATHER_EMOJI_MAP` and unused constant `WEATHER_EMOJI_MAP` - Correct syntax of `condition_em` initialization to avoid potential rendering issues New Features: - None.
This commit is contained in:
10 files changed
+60
-79
No files matched your search
@@ -31,7 +31,7 @@ def get_battery_icon_file(
|
||||
clamped = max(0, min(100, percentage))
|
||||
step = (clamped // 10) * 10
|
||||
filename = f"battery-{step:03d}{'-charging' if is_charging else ''}.svg"
|
||||
return svg_file(f"battery/{filename}")
|
||||
return f"battery/{filename}"
|
||||
|
||||
|
||||
def set_bluetooth_enabled_with_fallback(client, enabled: bool):
|
||||
|
||||
+22
-10
@@ -22,8 +22,8 @@ from modules.desktop.constants import (
|
||||
LOCATION_APIS,
|
||||
LOCATION_CACHE_TIMEOUT,
|
||||
SYSTEM_UPDATE_INTERVAL,
|
||||
WEATHER_CACHE_TIMEOUT,
|
||||
WEATHER_DESC_MAP,
|
||||
WEATHER_EMOJI_MAP,
|
||||
WEATHER_ICON_MAP,
|
||||
WEATHER_GRADIENT_MAP,
|
||||
WEATHER_UPDATE_INTERVAL,
|
||||
@@ -114,18 +114,28 @@ def format_weather_data(weather_data: Dict[str, Any], city: str) -> List[str]:
|
||||
|
||||
weather_code = current["weathercode"]
|
||||
is_day = current.get("is_day", 1) # Default to day if missing
|
||||
|
||||
|
||||
base_icon = WEATHER_ICON_MAP.get(weather_code, "weather-none-available")
|
||||
|
||||
|
||||
# Determine day/night variant if applicable
|
||||
icon_name = base_icon
|
||||
if not is_day:
|
||||
night_variant = f"{base_icon}-night"
|
||||
import os
|
||||
|
||||
# Fast check if night variant exists using predefined list or checking the path
|
||||
# Since we know the variants from earlier, let's just optimistically build it
|
||||
# then logic in svg_file will handle resolution seamlessly (fallbacks can be tricky, but we assume it's correct)
|
||||
if base_icon in ["weather-clear", "weather-clouds", "weather-few-clouds", "weather-overcast", "weather-showers", "weather-showers-scattered", "weather-snow", "weather-snow-scattered", "weather-storm"]:
|
||||
if base_icon in [
|
||||
"weather-clear",
|
||||
"weather-clouds",
|
||||
"weather-few-clouds",
|
||||
"weather-overcast",
|
||||
"weather-showers",
|
||||
"weather-showers-scattered",
|
||||
"weather-snow",
|
||||
"weather-snow-scattered",
|
||||
"weather-storm",
|
||||
]:
|
||||
icon_name = night_variant
|
||||
|
||||
condition = WEATHER_DESC_MAP.get(weather_code, "Unknown")
|
||||
@@ -226,7 +236,9 @@ class Weather(Box):
|
||||
ellipsization="end",
|
||||
)
|
||||
self.temperature = Label(name="temperature", label="--°", h_align="start")
|
||||
self.condition_em = svg_file("weather/weather-none-available.svg", size=(48, 48), name="condition-emoji")
|
||||
self.condition_em = svg_file(
|
||||
"weather/weather-none-available.svg", size=(48, 48), name="condition-emoji"
|
||||
)
|
||||
self.condition = Label(
|
||||
name="condition",
|
||||
label="Loading...",
|
||||
@@ -251,16 +263,16 @@ class Weather(Box):
|
||||
return
|
||||
icon_name, temp, condition, location, maxtemp, mintemp, _ = weather_info
|
||||
maxmin = f"H:{maxtemp} L:{mintemp}"
|
||||
|
||||
|
||||
self.city.set_label(location)
|
||||
self.temperature.set_label(temp)
|
||||
|
||||
|
||||
# update SVG File
|
||||
self.condition_em.dynamic_file(f"weather/{icon_name}.svg")
|
||||
|
||||
|
||||
self.condition.set_label(condition)
|
||||
self.feels_like.set_label(maxmin)
|
||||
|
||||
|
||||
self.parent.set_visible(True)
|
||||
|
||||
|
||||
|
||||
+2
-4
@@ -3,7 +3,7 @@ import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
from fabric.utils.helpers import get_desktop_applications, get_relative_path
|
||||
from fabric.utils import get_desktop_applications, get_relative_path, logger, GLib, Gtk
|
||||
from fabric.widgets.box import Box
|
||||
from fabric.widgets.button import Button
|
||||
from fabric.widgets.eventbox import EventBox
|
||||
@@ -11,15 +11,13 @@ from fabric.widgets.image import Image
|
||||
from fabric.widgets.label import Label
|
||||
from fabric.widgets.overlay import Overlay
|
||||
from fabric.widgets.revealer import Revealer
|
||||
from gi.repository import GLib, Gtk
|
||||
from loguru import logger
|
||||
|
||||
import config.data as data
|
||||
from services.modus import modus_service
|
||||
from utils.functions import read_json_file, write_json_file, is_special_workspace_id
|
||||
from utils.icon_resolver import IconResolver
|
||||
from utils.occlusion import check_occlusion
|
||||
from widgets.wayland import WaylandWindow as Window
|
||||
from fabric.widgets.wayland import WaylandWindow as Window
|
||||
|
||||
# Pinned apps file
|
||||
PINNED_APPS_FILE = get_relative_path("../config/assets/dock.json")
|
||||
|
||||
@@ -10,7 +10,6 @@ from typing import Dict, List, Optional
|
||||
from loguru import logger
|
||||
|
||||
from gi.repository import GdkPixbuf
|
||||
from PIL import Image
|
||||
|
||||
import config.data as data
|
||||
from fabric.utils.helpers import exec_shell_command_async
|
||||
@@ -179,10 +178,10 @@ class WallpaperPlugin(PluginBase):
|
||||
|
||||
if not os.path.exists(cache_path):
|
||||
try:
|
||||
with Image.open(full_path) as img:
|
||||
# Use faster thumbnail creation with smaller size for better performance
|
||||
img.thumbnail((32, 32), Image.Resampling.LANCZOS)
|
||||
img.save(cache_path, "PNG", optimize=True)
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
|
||||
full_path, 32, 32, True
|
||||
)
|
||||
pixbuf.savev(cache_path, "png", [], [])
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating thumbnail for {filename}: {e}")
|
||||
return None
|
||||
@@ -289,7 +288,7 @@ class WallpaperPlugin(PluginBase):
|
||||
|
||||
# Always set the wallpaper image
|
||||
exec_shell_command_async(
|
||||
f'swww img "{
|
||||
f'awww img "{
|
||||
full_path
|
||||
}" -t outer --transition-duration 1.5 --transition-step 255 --transition-fps 60 -f Nearest'
|
||||
)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import math
|
||||
from fabric.audio import Audio
|
||||
from fabric.utils import get_relative_path
|
||||
from fabric.widgets.svg import Svg
|
||||
from utils.utils import svg_file
|
||||
from fabric.widgets.scale import ScaleMark
|
||||
from .animated_scale import AnimatedScale
|
||||
from .base import BaseOSDContainer
|
||||
@@ -17,8 +16,8 @@ class AudioOSDContainer(BaseOSDContainer):
|
||||
self._connect_specific_signals()
|
||||
|
||||
def _setup_specific_components(self):
|
||||
self.osd_window_image = Svg(
|
||||
get_relative_path("../../../config/assets/icons/volume/audio-volume.svg"),
|
||||
self.osd_window_image = svg_file(
|
||||
"volume/audio-volume.svg",
|
||||
size=(100, 100),
|
||||
name="osd-image",
|
||||
h_align="center",
|
||||
@@ -87,11 +86,7 @@ class AudioOSDContainer(BaseOSDContainer):
|
||||
0 if display_volume == 0 else min(int(math.ceil(display_volume / 33)), 3)
|
||||
)
|
||||
|
||||
self.osd_window_image.set_from_file(
|
||||
get_relative_path(
|
||||
f"../../../config/assets/icons/volume/audio-volume-{level}.svg"
|
||||
)
|
||||
)
|
||||
self.osd_window_image.set_from_file(f"volume/audio-volume-{level}.svg")
|
||||
|
||||
if muted or volume == 0:
|
||||
self.scale.add_style_class("muted")
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import math
|
||||
from services.brightness import Brightness
|
||||
from fabric.utils import get_relative_path
|
||||
from fabric.widgets.svg import Svg
|
||||
from utils.utils import svg_file
|
||||
from fabric.widgets.scale import ScaleMark
|
||||
from .animated_scale import AnimatedScale
|
||||
from .base import BaseOSDContainer
|
||||
@@ -15,8 +14,8 @@ class BrightnessOSDContainer(BaseOSDContainer):
|
||||
self._connect_specific_signals()
|
||||
|
||||
def _setup_specific_components(self):
|
||||
self.osd_window_image = Svg(
|
||||
get_relative_path("../../../config/assets/icons/brightness/brightness.svg"),
|
||||
self.osd_window_image = svg_file(
|
||||
"brightness/brightness.svg",
|
||||
size=(100, 100),
|
||||
name="osd-image",
|
||||
h_align="center",
|
||||
@@ -51,11 +50,7 @@ class BrightnessOSDContainer(BaseOSDContainer):
|
||||
normalized = self._get_normalized_brightness()
|
||||
level = 0 if normalized == 0 else min(int(math.ceil(normalized / 33)), 3)
|
||||
|
||||
self.osd_window_image.set_from_file(
|
||||
get_relative_path(
|
||||
f"../../../config/assets/icons/brightness/brightness-{level}.svg"
|
||||
)
|
||||
)
|
||||
self.osd_window_image.set_from_file(f"brightness/brightness-{level}.svg")
|
||||
|
||||
self.scale.animate_value(normalized)
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from fabric.widgets.label import Label
|
||||
from fabric.widgets.svg import Svg
|
||||
from fabric.utils import get_relative_path
|
||||
from utils.utils import svg_file
|
||||
from .base import BaseOSDContainer
|
||||
from services.capslock import CapsLock
|
||||
|
||||
@@ -13,8 +12,8 @@ class CapsLockOSDContainer(BaseOSDContainer):
|
||||
self._connect_specific_signals()
|
||||
|
||||
def _setup_specific_components(self):
|
||||
self.osd_image = Svg(
|
||||
get_relative_path("../../../assets/icons/misc/caps-lock.svg"),
|
||||
self.osd_image = svg_file(
|
||||
"misc/caps-lock.svg",
|
||||
size=(100, 100),
|
||||
name="osd-image",
|
||||
h_align="center",
|
||||
@@ -35,9 +34,7 @@ class CapsLockOSDContainer(BaseOSDContainer):
|
||||
|
||||
def _update_display(self, is_on: bool):
|
||||
icon_path = "caps-lock.svg" if is_on else "caps-lock-off.svg"
|
||||
self.osd_image.set_from_file(
|
||||
get_relative_path(f"../../../assets/icons/misc/{icon_path}")
|
||||
)
|
||||
self.osd_image.set_from_file(f"misc/{icon_path}")
|
||||
if is_on:
|
||||
self.add_style_class("capslock-on")
|
||||
self.remove_style_class("capslock-off")
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from fabric.widgets.label import Label
|
||||
from fabric.widgets.svg import Svg
|
||||
from fabric.utils import get_relative_path
|
||||
from utils.utils import svg_file
|
||||
from .base import BaseOSDContainer
|
||||
from services.keyboard_layout import KeyboardLayout
|
||||
|
||||
@@ -13,8 +12,8 @@ class KeyboardLayoutOSDContainer(BaseOSDContainer):
|
||||
self._connect_specific_signals()
|
||||
|
||||
def _setup_specific_components(self):
|
||||
self.osd_image = Svg(
|
||||
get_relative_path("../../../assets/icons/misc/keyboard-layout.svg"),
|
||||
self.osd_image = svg_file(
|
||||
"misc/keyboard-layout.svg",
|
||||
size=(100, 100),
|
||||
name="osd-image",
|
||||
h_align="center",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import math
|
||||
from fabric.audio import Audio
|
||||
from fabric.utils import get_relative_path
|
||||
from fabric.widgets.svg import Svg
|
||||
from utils.utils import svg_file
|
||||
from fabric.widgets.scale import ScaleMark
|
||||
from .animated_scale import AnimatedScale
|
||||
from .base import BaseOSDContainer
|
||||
@@ -17,8 +16,8 @@ class MicrophoneOSDContainer(BaseOSDContainer):
|
||||
self._connect_specific_signals()
|
||||
|
||||
def _setup_specific_components(self):
|
||||
self.osd_window_image = Svg(
|
||||
get_relative_path("../../../config/assets/icons/mic/microphone.svg"),
|
||||
self.osd_window_image = svg_file(
|
||||
"mic/microphone.svg",
|
||||
size=(100, 100),
|
||||
name="osd-image",
|
||||
h_align="center",
|
||||
@@ -87,11 +86,7 @@ class MicrophoneOSDContainer(BaseOSDContainer):
|
||||
0 if display_volume == 0 else min(int(math.ceil(display_volume / 33)), 3)
|
||||
)
|
||||
|
||||
self.osd_window_image.set_from_file(
|
||||
get_relative_path(
|
||||
f"../../../config/assets/icons/mic/microphone-{level}.svg"
|
||||
)
|
||||
)
|
||||
self.osd_window_image.set_from_file(f"mic/microphone-{level}.svg")
|
||||
|
||||
if muted or volume == 0:
|
||||
self.scale.add_style_class("muted")
|
||||
|
||||
+11
-20
@@ -2,16 +2,15 @@
|
||||
from datetime import datetime
|
||||
|
||||
# Fabric imports
|
||||
from fabric.utils import get_relative_path
|
||||
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 fabric.widgets.scrolledwindow import ScrolledWindow
|
||||
from fabric.widgets.svg import Svg
|
||||
from gi.repository import GLib
|
||||
|
||||
# Local imports
|
||||
from utils.utils import svg_file
|
||||
from services.todo import get_todo_service
|
||||
from widgets.mousecapture import MouseCapture
|
||||
from widgets.wayland import WaylandWindow as Window
|
||||
@@ -43,12 +42,10 @@ class TodoItem(Box):
|
||||
if self.todo_data["completed"]
|
||||
else "checkbox-uncheck.svg"
|
||||
)
|
||||
self.checkbox_icon = Svg(
|
||||
self.checkbox_icon = svg_file(
|
||||
"todo/" + checkbox_icon,
|
||||
name="todo-checkbox-icon",
|
||||
size=24,
|
||||
svg_file=get_relative_path(
|
||||
"../../config/assets/icons/todo/" + checkbox_icon
|
||||
),
|
||||
)
|
||||
self.checkbox = Button(
|
||||
name="todo-checkbox",
|
||||
@@ -108,10 +105,10 @@ class TodoItem(Box):
|
||||
# )
|
||||
#
|
||||
# Edit button - using SVG icon
|
||||
self.edit_icon = Svg(
|
||||
self.edit_icon = svg_file(
|
||||
"todo/edit.svg",
|
||||
name="todo-edit-icon",
|
||||
size=12,
|
||||
svg_file=get_relative_path("../../config/assets/icons/todo/edit.svg"),
|
||||
)
|
||||
self.edit_button = Button(
|
||||
name="todo-edit",
|
||||
@@ -120,12 +117,10 @@ class TodoItem(Box):
|
||||
)
|
||||
|
||||
# Delete button - using SVG icon
|
||||
self.delete_icon = Svg(
|
||||
self.delete_icon = svg_file(
|
||||
"todo/delete-symbolic.svg",
|
||||
name="todo-delete-icon",
|
||||
size=12,
|
||||
svg_file=get_relative_path(
|
||||
"../../config/assets/icons/todo/delete-symbolic.svg"
|
||||
),
|
||||
)
|
||||
self.delete_button = Button(
|
||||
name="todo-delete",
|
||||
@@ -208,12 +203,10 @@ class TodoItem(Box):
|
||||
checkbox_icon = (
|
||||
"checkbox-check.svg" if todo_data["completed"] else "checkbox-uncheck.svg"
|
||||
)
|
||||
new_checkbox_icon = Svg(
|
||||
new_checkbox_icon = svg_file(
|
||||
"todo/" + checkbox_icon,
|
||||
name="todo-checkbox-icon",
|
||||
size=20,
|
||||
svg_file=get_relative_path(
|
||||
"../../config/assets/icons/todo/" + checkbox_icon
|
||||
),
|
||||
)
|
||||
self.checkbox.set_child(new_checkbox_icon)
|
||||
self.checkbox_icon = new_checkbox_icon
|
||||
@@ -293,12 +286,10 @@ class TodoListWidget(Window):
|
||||
self.new_todo_entry.connect("activate", self._add_todo)
|
||||
|
||||
# Add button - using SVG icon
|
||||
self.add_icon = Svg(
|
||||
self.add_icon = svg_file(
|
||||
"todo/plus-symbolic.svg",
|
||||
name="add-todo-icon",
|
||||
size=12,
|
||||
svg_file=get_relative_path(
|
||||
"../../config/assets/icons/todo/plus-symbolic.svg"
|
||||
),
|
||||
)
|
||||
self.add_button = Button(
|
||||
name="add-todo-button",
|
||||
|
||||
Reference in new issue
Block a user