feat(cache): implement icon theme aware caching for notification icons and cleanup on theme change

This commit is contained in:
sankalp committed 2026-07-12 02:44:56 +05:45
1 parent 4b039c1ff3
commit ccfd1aecc1
2 files changed
+80 -3

No files matched your search

+79 -2
View File
@@ -3,7 +3,7 @@ import time
import uuid
from collections import OrderedDict
from fabric.utils import GdkPixbuf, get_relative_path, logger, os
from fabric.utils import GdkPixbuf, get_relative_path, Gtk, logger, os
import shared.data as data
@@ -14,6 +14,28 @@ _MEMORY_PIXBUF_CACHE: OrderedDict[str, GdkPixbuf.Pixbuf] = OrderedDict()
_MEMORY_CACHE_MAX = 64
def _get_icon_theme_name():
"""Get the current GTK icon theme name for cache invalidation"""
try:
settings = Gtk.Settings.get_default()
if settings:
return getattr(settings, "gtk_icon_theme_name", "") or ""
except Exception:
pass
# Fallback: read from settings.ini
try:
settings_path = os.path.expanduser("~/.config/gtk-3.0/settings.ini")
if os.path.exists(settings_path):
with open(settings_path) as f:
for line in f:
line = line.strip()
if line.startswith("gtk-icon-theme-name="):
return line.split("=", 1)[1].strip()
except Exception:
pass
return ""
def ensure_cache_dir():
"""Ensure unified notification cache directory exists"""
os.makedirs(UNIFIED_NOTIFICATION_CACHE_DIR, exist_ok=True)
@@ -36,10 +58,14 @@ def get_unified_cache_key(source_data, size=None, app_name=None):
if source_data.startswith("file://"):
source_data = source_data[7:]
# Create hash from file path and size
# Create hash from file path, size, and icon theme
hash_input = source_data
if size:
hash_input += f"_{size[0]}x{size[1]}"
# Include icon theme so cache invalidates on theme change
theme = _get_icon_theme_name()
if theme:
hash_input += f"|{theme}"
return hashlib.md5(hash_input.encode()).hexdigest()[:8]
else:
@@ -194,7 +220,58 @@ def get_fallback_icon(size=(48, 48)):
return None
# Theme tracking for cache invalidation
_CURRENT_THEME_FILE = os.path.join(data.CACHE_DIR, ".current_icon_theme")
def _get_stored_theme():
"""Get the previously stored icon theme name"""
try:
if os.path.exists(_CURRENT_THEME_FILE):
with open(_CURRENT_THEME_FILE) as f:
return f.read().strip()
except Exception:
pass
return ""
def _store_theme(name):
"""Store the current icon theme name"""
try:
os.makedirs(os.path.dirname(_CURRENT_THEME_FILE), exist_ok=True)
with open(_CURRENT_THEME_FILE, "w") as f:
f.write(name)
except Exception:
pass
def cleanup_theme_changed_caches():
"""Clear notification pixbuf caches if icon theme changed since last run"""
current_theme = _get_icon_theme_name()
stored_theme = _get_stored_theme()
if current_theme and stored_theme and current_theme != stored_theme:
logger.info(
f"[Cache] Icon theme changed: {stored_theme} -> {current_theme}, clearing notification caches"
)
cleanup_cache() # clear all pixbuf caches
# Also clear the icon resolver cache since icon names may map differently
try:
from utils.icon_resolver import ICON_CACHE_FILE
if os.path.exists(ICON_CACHE_FILE):
os.unlink(ICON_CACHE_FILE)
logger.info("[Cache] Cleared icon resolver cache")
except Exception:
pass
# Store current theme for next run
if current_theme:
_store_theme(current_theme)
# Initialize cache on module load
ensure_cache_dir()
cleanup_old_cache_files()
cleanup_theme_changed_caches()
verify_cache_persistence()
+1 -1
View File
@@ -7,7 +7,7 @@ from fabric.widgets.label import Label
from shared.dialogs.about import AboutApp, get_about_window
from shared.window.dropdown import ModusDropdown, dropdown_divider, dropdowns
from services.globalmenu import get_global_menu_service
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