From 27c693e4abac7b91b928938f171d205d23ddf00d Mon Sep 17 00:00:00 2001 From: "N0\\A" Date: Wed, 29 Oct 2025 10:02:46 +0100 Subject: [PATCH] app caching --- core/app_launcher.py | 16 ++++++++++++++-- main.py | 11 +++++++++++ windows/app_launcher.py | 22 +++++++++++++++++++++- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/core/app_launcher.py b/core/app_launcher.py index 81dcb7d..e9b0af2 100644 --- a/core/app_launcher.py +++ b/core/app_launcher.py @@ -1,6 +1,9 @@ from pathlib import Path import os import configparser +from typing import Optional + +_app_cache: Optional[list['App']] = None class App: def __init__(self, name: str, exec: str, icon: str = "", hidden: bool = False, generic_name: str = "", comment: str = "", command: str = ""): @@ -90,7 +93,12 @@ def is_user_dir(path: Path) -> bool: user_home = str(Path.home()) return path_str.startswith(user_home) -def list_apps() -> list[App]: +def list_apps(force_reload: bool = False) -> list[App]: + global _app_cache + + if _app_cache is not None and not force_reload: + return _app_cache + apps_dict = {} for desktop_dir in get_desktop_dirs(): @@ -109,7 +117,11 @@ def list_apps() -> list[App]: else: apps_dict[app.name] = (app, is_user) - return [app for app, _ in apps_dict.values()] + _app_cache = [app for app, _ in apps_dict.values()] + return _app_cache + +def reload_app_cache() -> list[App]: + return list_apps(force_reload=True) def launch(app: App): import subprocess diff --git a/main.py b/main.py index acfd5ed..d60e311 100644 --- a/main.py +++ b/main.py @@ -2,15 +2,22 @@ import sys, json from pathlib import Path from PySide6 import QtWidgets +import threading from core.discord_presence import presence from core.dukto import DuktoProtocol from core.updater import update_repository, is_update_available +from core.app_launcher import list_apps from windows.main_window import MainWindow STRINGS_PATH = Path(__file__).parent / "strings" / "personality_en.json" +def preload_apps(): + print("Preloading application list...") + list_apps() + print("Application list preloaded.") + def main(): app = QtWidgets.QApplication(sys.argv) @@ -38,6 +45,10 @@ def main(): if update_available: update_repository() + # Start preloading apps in the background + preload_thread = threading.Thread(target=preload_apps, daemon=True) + preload_thread.start() + dukto_handler = DuktoProtocol() pet = MainWindow(dukto_handler=dukto_handler, strings=strings, restart=restart, no_quit=no_quit, super_menu=super_menu) diff --git a/windows/app_launcher.py b/windows/app_launcher.py index ea10ae7..93d8758 100644 --- a/windows/app_launcher.py +++ b/windows/app_launcher.py @@ -1,6 +1,6 @@ from PySide6 import QtCore, QtGui, QtWidgets -from core.app_launcher import list_apps, launch +from core.app_launcher import list_apps, launch, reload_app_cache class AppLauncherDialog(QtWidgets.QDialog): def __init__(self, strings, parent=None): @@ -25,9 +25,17 @@ class AppLauncherDialog(QtWidgets.QDialog): # Buttons button_layout = QtWidgets.QHBoxLayout() + + refresh_button = QtWidgets.QPushButton() + refresh_icon = self.style().standardIcon(QtWidgets.QStyle.SP_BrowserReload) # type: ignore + refresh_button.setIcon(refresh_icon) + refresh_button.setToolTip("Reload application list") + refresh_button.clicked.connect(self.reload_apps) + close_button = QtWidgets.QPushButton(self.strings["close_button"]) close_button.clicked.connect(self.close) + button_layout.addWidget(refresh_button) button_layout.addStretch() button_layout.addWidget(close_button) layout.addLayout(button_layout) @@ -51,6 +59,18 @@ class AppLauncherDialog(QtWidgets.QDialog): finally: QtWidgets.QApplication.restoreOverrideCursor() + def reload_apps(self): + try: + QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) #type: ignore + self.apps = reload_app_cache() + self.apps.sort(key=lambda x: x.name.lower()) + # Reapply current filter + self.filter_apps(self.search_box.text()) + except Exception as e: + QtWidgets.QMessageBox.critical(self, self.strings["load_error_title"], self.strings["load_error_text"].format(e=e)) + finally: + QtWidgets.QApplication.restoreOverrideCursor() + def populate_list(self, apps): self.list_widget.clear() for app in apps: