From 168bf54f4143c06f8c5ef2087b7f8ca78e4eff79 Mon Sep 17 00:00:00 2001 From: ItsLemmy Date: Sat, 8 Nov 2025 19:29:02 -0500 Subject: [PATCH] Fixing app templating after refactor --- Assets/Translations/de.json | 9 +++-- Assets/Translations/en.json | 10 +++-- Assets/Translations/es.json | 9 +++-- Assets/Translations/fr.json | 9 +++-- Assets/Translations/pt.json | 9 +++-- Assets/Translations/tr.json | 9 +++-- Assets/Translations/uk-UA.json | 9 +++-- Assets/Translations/zh-CN.json | 9 +++-- Assets/settings-default.json | 12 +++--- CLAUDE.md | 4 +- Commons/Settings.qml | 13 +++--- Modules/Background/Background.qml | 4 +- Modules/Bar/Widgets/ScreenRecorder.qml | 2 +- Modules/MainScreen/AllScreens.qml | 6 ++- Modules/MainScreen/MainScreen.qml | 17 +------- Modules/Panels/Launcher/Launcher.qml | 4 +- .../Panels/Settings/Tabs/ColorSchemeTab.qml | 10 ++--- Services/Location/NightLightService.qml | 1 + Services/Media/ScreenRecorderService.qml | 12 +++--- Services/System/ProgramCheckerService.qml | 2 +- .../AppThemeService.qml | 7 ++-- .../ColorPaletteGenerator.qml | 0 .../ColorSchemeService.qml | 1 + .../TemplateProcessor.qml | 40 ++++++++++++------- .../TemplateRegistry.qml | 0 Services/UI/PanelService.qml | 2 +- Services/UI/ToastService.qml | 2 +- shell.qml | 2 +- 28 files changed, 113 insertions(+), 101 deletions(-) rename Services/{DynamicTheming => Theming}/AppThemeService.qml (91%) rename Services/{DynamicTheming => Theming}/ColorPaletteGenerator.qml (100%) rename Services/{DynamicTheming => Theming}/ColorSchemeService.qml (99%) rename Services/{DynamicTheming => Theming}/TemplateProcessor.qml (92%) rename Services/{DynamicTheming => Theming}/TemplateRegistry.qml (100%) diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index 7b336459..f17e667c 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -1719,10 +1719,6 @@ "kofi": { "opened": "Ko-fi-Seite in Ihrem Browser geöffnet" }, - "matugen": { - "failed": "Matugen-Verarbeitung fehlgeschlagen", - "failed-general": "Matugen ist beim Verarbeiten der Vorlagen auf einen Fehler gestoßen" - }, "missing-control-center": { "description": "Das Kontrollzentrum-Widget wurde aus der Leiste entfernt. Um es erneut über die Leiste zu öffnen, fügen Sie das Widget wieder hinzu. Sie können es auch durch Rechtsklick auf die Leiste öffnen.", "label": "Letztes Kontrollzentrum-Widget entfernt" @@ -1755,6 +1751,11 @@ "started": "Aufnahme gestartet", "stopping": "Aufnahme wird gestoppt…" }, + "theming-processor-failed": { + "desc-generic": "Beim Verarbeiten von Vorlagen ist ein Fehler aufgetreten.", + "title-matugen": "Matugen-Templating-Verarbeitung fehlgeschlagen", + "title-predefined": "Die Verarbeitung des vordefinierten Farbschemas ist fehlgeschlagen." + }, "wallpaper-colors": { "disabled": "Hintergrundbild-Farben deaktiviert", "enabled": "Hintergrundbild-Farben aktiviert", diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index 518eefb9..5a00ad0c 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -1719,10 +1719,6 @@ "kofi": { "opened": "Ko-fi page opened in your browser" }, - "matugen": { - "failed": "Matugen processing failed", - "failed-general": "Matugen encountered an error while processing templates" - }, "missing-control-center": { "description": "The Control Center widget has been removed from the bar. To access it from the bar again, you will need to re-add the widget. You can open it with right clicking on the bar too.", "label": "Last Control Center widget removed" @@ -1755,7 +1751,13 @@ "started": "Recording started", "stopping": "Stopping recording…" }, + "theming-processor-failed": { + "desc-generic": "Encountered an error while processing templates", + "title-matugen": "Matugen templating processing failed", + "title-predefined": "Predefined color cheme processing failed" + }, "wallpaper-colors": { + "label": "Wallpaper colors generation", "disabled": "Wallpaper colors disabled", "enabled": "Wallpaper colors enabled", "not-installed": "Matugen not installed - required for wallpaper color extraction" diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index 9399c515..91ffaa57 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -1719,10 +1719,6 @@ "kofi": { "opened": "Página de Ko-fi abierta en tu navegador" }, - "matugen": { - "failed": "Error en el procesamiento de Matugen", - "failed-general": "Matugen encontró un error al procesar las plantillas" - }, "missing-control-center": { "description": "El widget del Centro de control se eliminó de la barra. Para acceder a él nuevamente desde la barra, debes volver a añadir el widget. También puedes abrirlo haciendo clic derecho en la barra.", "label": "Se eliminó el último widget del Centro de control" @@ -1755,6 +1751,11 @@ "started": "Grabación iniciada", "stopping": "Deteniendo grabación..." }, + "theming-processor-failed": { + "desc-generic": "Se encontró un error al procesar las plantillas.", + "title-matugen": "Falló el procesamiento de la plantilla Matugen.", + "title-predefined": "Falló el procesamiento del esquema de color predefinido." + }, "wallpaper-colors": { "disabled": "Colores del fondo de pantalla desactivados", "enabled": "Colores del fondo de pantalla activados", diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json index 1eff9cdc..0ce5ef9d 100644 --- a/Assets/Translations/fr.json +++ b/Assets/Translations/fr.json @@ -1719,10 +1719,6 @@ "kofi": { "opened": "Page Ko-fi ouverte dans votre navigateur" }, - "matugen": { - "failed": "Échec du traitement Matugen", - "failed-general": "Matugen a rencontré une erreur lors du traitement des modèles" - }, "missing-control-center": { "description": "Le widget du Centre de contrôle a été retiré de la barre. Pour y accéder à nouveau depuis la barre, veuillez ré‑ajouter le widget. Vous pouvez aussi l'ouvrir en cliquant avec le bouton droit sur la barre.", "label": "Dernier widget du Centre de contrôle supprimé" @@ -1755,6 +1751,11 @@ "started": "Enregistrement démarré", "stopping": "Arrêt de l'enregistrement..." }, + "theming-processor-failed": { + "desc-generic": "Une erreur s'est produite lors du traitement des modèles.", + "title-matugen": "Le traitement du modèle Matugen a échoué.", + "title-predefined": "Le traitement du schéma de couleurs prédéfini a échoué." + }, "wallpaper-colors": { "disabled": "Couleurs du fond d'écran désactivées", "enabled": "Couleurs du fond d'écran activées", diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index 5fbcd5c5..c3baf25e 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -1719,10 +1719,6 @@ "kofi": { "opened": "Página do Ko-fi aberta no seu navegador" }, - "matugen": { - "failed": "Falha no processamento do Matugen", - "failed-general": "Matugen encontrou um erro ao processar os modelos" - }, "missing-control-center": { "description": "O widget da Central de Controle foi removido da barra. Para acessá-lo novamente pela barra, adicione o widget novamente. Você também pode abri-lo clicando com o botão direito na barra.", "label": "Último widget da Central de Controle removido" @@ -1755,6 +1751,11 @@ "started": "Gravação iniciada", "stopping": "Parando gravação…" }, + "theming-processor-failed": { + "desc-generic": "Ocorreu um erro ao processar os templates.", + "title-matugen": "Falha no processamento do template Matugen", + "title-predefined": "O processamento do esquema de cores predefinido falhou." + }, "wallpaper-colors": { "disabled": "Cores do papel de parede desativadas", "enabled": "Cores do papel de parede ativadas", diff --git a/Assets/Translations/tr.json b/Assets/Translations/tr.json index 7f3dd309..43e038ce 100644 --- a/Assets/Translations/tr.json +++ b/Assets/Translations/tr.json @@ -1719,10 +1719,6 @@ "kofi": { "opened": "Ko-fi sayfası tarayıcınızda açıldı" }, - "matugen": { - "failed": "Matugen işlemi başarısız oldu", - "failed-general": "Matugen şablonları işlerken bir hata ile karşılaştı" - }, "missing-control-center": { "description": "Kontrol Merkezi widget'ı çubuktan kaldırıldı. Çubuktan tekrar erişmek için widget'ı yeniden eklemeniz gerekecek. Çubuğa sağ tıklayarak da açabilirsiniz.", "label": "Son Kontrol Merkezi widget'ı kaldırıldı" @@ -1755,6 +1751,11 @@ "started": "Kayıt başladı", "stopping": "Kayıt durduruluyor..." }, + "theming-processor-failed": { + "desc-generic": "Şablonlar işlenirken bir hatayla karşılaşıldı.", + "title-matugen": "Matugen şablon işleme başarısız oldu.", + "title-predefined": "Önceden tanımlanmış renk şeması işleme başarısız oldu." + }, "wallpaper-colors": { "disabled": "Duvar kağıdı renkleri devre dışı", "enabled": "Duvar kağıdı renkleri etkin", diff --git a/Assets/Translations/uk-UA.json b/Assets/Translations/uk-UA.json index 8f5e9163..3969ea44 100644 --- a/Assets/Translations/uk-UA.json +++ b/Assets/Translations/uk-UA.json @@ -1719,10 +1719,6 @@ "kofi": { "opened": "Сторінка Ko-fi відкрита у вашому браузері" }, - "matugen": { - "failed": "Помилка обробки Matugen", - "failed-general": "Matugen зіткнувся з помилкою під час обробки шаблонів" - }, "missing-control-center": { "description": "Віджет Центру керування видалено з панелі. Щоб знову отримати до нього доступ з панелі, вам потрібно повторно додати віджет. Ви також можете відкрити його, клацнувши правою кнопкою миші на панелі.", "label": "Останній віджет Центру керування видалено" @@ -1755,6 +1751,11 @@ "started": "Запис розпочато", "stopping": "Зупинка запису…" }, + "theming-processor-failed": { + "desc-generic": "Виникла помилка під час обробки шаблонів.", + "title-matugen": "Помилка обробки шаблонів Matugen", + "title-predefined": "Помилка обробки попередньо визначеної колірної схеми" + }, "wallpaper-colors": { "disabled": "Кольори шпалер вимкнено", "enabled": "Кольори шпалер увімкнено", diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json index 6ab2bbef..371faa55 100644 --- a/Assets/Translations/zh-CN.json +++ b/Assets/Translations/zh-CN.json @@ -1719,10 +1719,6 @@ "kofi": { "opened": "Ko-fi页面已在您的浏览器中打开" }, - "matugen": { - "failed": "Matugen 处理失败", - "failed-general": "Matugen 在处理模板时遇到错误" - }, "missing-control-center": { "description": "控制中心小部件已从状态栏中移除。要再次从状态栏访问它,您需要重新添加小部件。您也可以通过右键点击状态栏来打开它。", "label": "最后一个控制中心小部件已移除" @@ -1755,6 +1751,11 @@ "started": "录制已开始", "stopping": "正在停止录制…" }, + "theming-processor-failed": { + "desc-generic": "处理模板时遇到错误", + "title-matugen": "Matugen模板处理失败", + "title-predefined": "预定义的颜色方案处理失败" + }, "wallpaper-colors": { "disabled": "壁纸颜色已禁用", "enabled": "壁纸颜色已启用", diff --git a/Assets/settings-default.json b/Assets/settings-default.json index fabf4225..ed319e04 100644 --- a/Assets/settings-default.json +++ b/Assets/settings-default.json @@ -257,17 +257,17 @@ "wezterm": false, "fuzzel": false, "discord": false, + "pywalfox": false, + "vicinae": false, + "walker": false, + "code": false, + "enableUserTemplates": false, "discord_vesktop": false, "discord_webcord": false, "discord_armcord": false, "discord_equibop": false, "discord_lightcord": false, - "discord_dorion": false, - "pywalfox": false, - "vicinae": false, - "walker": false, - "code": false, - "enableUserTemplates": false + "discord_dorion": false }, "nightLight": { "enabled": false, diff --git a/CLAUDE.md b/CLAUDE.md index 82ccb76b..bfa699f9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -327,7 +327,7 @@ BarWidgetRegistry and ControlCenterWidgetRegistry: Services in Quickshell use the `pragma Singleton` directive: - Add `pragma Singleton` at the top of the QML file (before imports) - No qmldir needed - Quickshell handles singleton resolution automatically -- Import with standard path: `import qs.Services` or `import qs.Services.DynamicTheming` +- Import with standard path: `import qs.Services` or `import qs.Services.Theming` - Access via singleton name: `AppThemeService.generate()` Example: @@ -346,7 +346,7 @@ Singleton { } ``` -### DynamicTheming Architecture +### Theming Architecture The theming system was refactored (Jan 2025) into 4 focused services in `Services/`: **AppThemeService.qml** (~60 lines) - Main facade diff --git a/Commons/Settings.qml b/Commons/Settings.qml index 6e2147f5..404e7897 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -402,17 +402,18 @@ Singleton { property bool wezterm: false property bool fuzzel: false property bool discord: false - property bool discord_vesktop: false - property bool discord_webcord: false - property bool discord_armcord: false - property bool discord_equibop: false - property bool discord_lightcord: false - property bool discord_dorion: false property bool pywalfox: false property bool vicinae: false property bool walker: false property bool code: false property bool enableUserTemplates: false + + property bool discord_vesktop: false // To be deleted soon + property bool discord_webcord: false // To be deleted soon + property bool discord_armcord: false // To be deleted soon + property bool discord_equibop: false // To be deleted soon + property bool discord_lightcord: false // To be deleted soon + property bool discord_dorion: false // To be deleted soon } // night light diff --git a/Modules/Background/Background.qml b/Modules/Background/Background.qml index f6b97bdd..abea1806 100644 --- a/Modules/Background/Background.qml +++ b/Modules/Background/Background.qml @@ -332,10 +332,10 @@ Variants { var dim = Qt.size(0, 0) if (screenWidth >= screenHeight) { const w = Math.min(screenWidth, wpWidth) - dim = Qt.size(w, w / imageAspectRatio) + dim = Qt.size(Math.round(w), Math.round(w / imageAspectRatio)) } else { const h = Math.min(screenHeight, wpHeight) - dim = Qt.size(h * imageAspectRatio, h) + dim = Qt.size(Math.round(h * imageAspectRatio), Math.round(h)) } Logger.d("Background", `Wallpaper resized on ${modelData.name} ${screenWidth}x${screenHeight} @ ${compositorScale}x`, "src:", wpWidth, wpHeight, "dst:", dim.width, dim.height) diff --git a/Modules/Bar/Widgets/ScreenRecorder.qml b/Modules/Bar/Widgets/ScreenRecorder.qml index 8683f583..085db1e3 100644 --- a/Modules/Bar/Widgets/ScreenRecorder.qml +++ b/Modules/Bar/Widgets/ScreenRecorder.qml @@ -24,7 +24,7 @@ NIconButton { function handleClick() { if (!ScreenRecorderService.isAvailable) { - ToastService.showError(I18n.tr("toast.recording.not-installed"), I18n.tr("toast.recording.not-installed-desc"), 7000) + ToastService.showError(I18n.tr("toast.recording.not-installed"), I18n.tr("toast.recording.not-installed-desc")) return } ScreenRecorderService.toggleRecording() diff --git a/Modules/MainScreen/AllScreens.qml b/Modules/MainScreen/AllScreens.qml index dc929b57..9758790d 100644 --- a/Modules/MainScreen/AllScreens.qml +++ b/Modules/MainScreen/AllScreens.qml @@ -15,8 +15,10 @@ Variants { required property ShellScreen modelData property bool shouldBeActive: { - if (!modelData || !modelData.name) - Logger.d("Shell", "MainScreen activated for", modelData?.name) + if (!modelData || !modelData.name) { + return false + } + Logger.d("Shell", "MainScreen activated for", modelData?.name) return true } diff --git a/Modules/MainScreen/MainScreen.qml b/Modules/MainScreen/MainScreen.qml index 0edbe4d8..1d6fa665 100644 --- a/Modules/MainScreen/MainScreen.qml +++ b/Modules/MainScreen/MainScreen.qml @@ -163,7 +163,6 @@ PanelWindow { Component.onCompleted: { objectName = "audioPanel-" + (screen?.name || "unknown") PanelService.registerPanel(audioPanel) - Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -175,7 +174,6 @@ PanelWindow { Component.onCompleted: { objectName = "batteryPanel-" + (screen?.name || "unknown") PanelService.registerPanel(batteryPanel) - Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -187,7 +185,6 @@ PanelWindow { Component.onCompleted: { objectName = "bluetoothPanel-" + (screen?.name || "unknown") PanelService.registerPanel(bluetoothPanel) - Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -199,7 +196,6 @@ PanelWindow { Component.onCompleted: { objectName = "controlCenterPanel-" + (screen?.name || "unknown") PanelService.registerPanel(controlCenterPanel) - Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -211,7 +207,6 @@ PanelWindow { Component.onCompleted: { objectName = "calendarPanel-" + (screen?.name || "unknown") PanelService.registerPanel(calendarPanel) - Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -223,7 +218,6 @@ PanelWindow { Component.onCompleted: { objectName = "launcherPanel-" + (screen?.name || "unknown") PanelService.registerPanel(launcherPanel) - Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -235,7 +229,6 @@ PanelWindow { Component.onCompleted: { objectName = "notificationHistoryPanel-" + (screen?.name || "unknown") PanelService.registerPanel(notificationHistoryPanel) - Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -247,7 +240,6 @@ PanelWindow { Component.onCompleted: { objectName = "sessionMenuPanel-" + (screen?.name || "unknown") PanelService.registerPanel(sessionMenuPanel) - Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -259,7 +251,6 @@ PanelWindow { Component.onCompleted: { objectName = "settingsPanel-" + (screen?.name || "unknown") PanelService.registerPanel(settingsPanel) - Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -271,7 +262,6 @@ PanelWindow { Component.onCompleted: { objectName = "setupWizardPanel-" + (screen?.name || "unknown") PanelService.registerPanel(setupWizardPanel) - Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -283,7 +273,6 @@ PanelWindow { Component.onCompleted: { objectName = "trayDrawerPanel-" + (screen?.name || "unknown") PanelService.registerPanel(trayDrawerPanel) - Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -295,7 +284,6 @@ PanelWindow { Component.onCompleted: { objectName = "trayMenuPanel-" + (screen?.name || "unknown") PanelService.registerPanel(trayMenuPanel) - Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -307,7 +295,6 @@ PanelWindow { Component.onCompleted: { objectName = "wallpaperPanel-" + (screen?.name || "unknown") PanelService.registerPanel(wallpaperPanel) - Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -319,7 +306,6 @@ PanelWindow { Component.onCompleted: { objectName = "wifiPanel-" + (screen?.name || "unknown") PanelService.registerPanel(wifiPanel) - Logger.d("MainScreen", "Panel registered:", objectName, "on screen:", screen?.name) } } @@ -338,9 +324,8 @@ PanelWindow { property ShellScreen screen: root.screen onLoaded: { - Logger.d("MainScreen", "Bar loaded:", item !== null) if (item) { - Logger.d("MainScreen", "Bar screen", item.screen?.name, "size:", item.width, "x", item.height) + Logger.d("MainScreen", "Bar loaded with screen", item.screen?.name) // Bind screen to bar component (use binding for reactivity) item.screen = Qt.binding(function () { return barLoader.screen diff --git a/Modules/Panels/Launcher/Launcher.qml b/Modules/Panels/Launcher/Launcher.qml index d26f1b0b..7cc1248a 100644 --- a/Modules/Panels/Launcher/Launcher.qml +++ b/Modules/Panels/Launcher/Launcher.qml @@ -4,8 +4,10 @@ import QtQuick.Layouts import Quickshell import Quickshell.Widgets import qs.Commons -import qs.Widgets import qs.Modules.MainScreen +import qs.Services.Keyboard +import qs.Widgets + import "Plugins" SmartPanel { diff --git a/Modules/Panels/Settings/Tabs/ColorSchemeTab.qml b/Modules/Panels/Settings/Tabs/ColorSchemeTab.qml index c4570b8b..b4059379 100644 --- a/Modules/Panels/Settings/Tabs/ColorSchemeTab.qml +++ b/Modules/Panels/Settings/Tabs/ColorSchemeTab.qml @@ -4,7 +4,7 @@ import QtQuick.Layouts import Quickshell import Quickshell.Io import qs.Commons -import qs.Services.DynamicTheming +import qs.Services.Theming import qs.Services.System import qs.Services.UI import qs.Widgets @@ -113,9 +113,9 @@ ColumnLayout { if (exitCode === 0) { Settings.data.colorSchemes.useWallpaperColors = true AppThemeService.generate() - ToastService.showNotice(I18n.tr("settings.color-scheme.color-source.use-wallpaper-colors.label"), I18n.tr("toast.wallpaper-colors.enabled"), "settings-color-scheme") + ToastService.showNotice(I18n.tr("toast.wallpaper-colors.label"), I18n.tr("toast.wallpaper-colors.enabled"), "settings-color-scheme") } else { - ToastService.showWarning(I18n.tr("settings.color-scheme.color-source.use-wallpaper-colors.label"), I18n.tr("toast.wallpaper-colors.not-installed")) + ToastService.showWarning(I18n.tr("oast.wallpaper-colors.label"), I18n.tr("toast.wallpaper-colors.not-installed")) } } @@ -130,7 +130,6 @@ ColumnLayout { Repeater { model: ColorSchemeService.schemes - delegate: Item { FileView { path: modelData @@ -250,7 +249,7 @@ ColumnLayout { matugenCheck.running = true } else { Settings.data.colorSchemes.useWallpaperColors = false - ToastService.showNotice(I18n.tr("settings.color-scheme.color-source.use-wallpaper-colors.label"), I18n.tr("toast.wallpaper-colors.disabled"), "settings-color-scheme") + ToastService.showNotice(I18n.tr("toast.wallpaper-colors.label"), I18n.tr("toast.wallpaper-colors.disabled"), "settings-color-scheme") if (Settings.data.colorSchemes.predefinedScheme) { ColorSchemeService.applyScheme(Settings.data.colorSchemes.predefinedScheme) @@ -470,6 +469,7 @@ ColumnLayout { ColumnLayout { Layout.fillWidth: true spacing: Style.marginL + visible: Settings.data.colorSchemes.useWallpaperColors || Settings.data.colorSchemes.generateTemplatesForPredefined NHeader { label: I18n.tr("settings.color-scheme.templates.section.label") diff --git a/Services/Location/NightLightService.qml b/Services/Location/NightLightService.qml index 8160c9e9..e25c828a 100644 --- a/Services/Location/NightLightService.qml +++ b/Services/Location/NightLightService.qml @@ -4,6 +4,7 @@ import QtQuick import Quickshell import Quickshell.Io import qs.Commons +import qs.Services.UI Singleton { id: root diff --git a/Services/Media/ScreenRecorderService.qml b/Services/Media/ScreenRecorderService.qml index 8b4d9f98..22b8f649 100644 --- a/Services/Media/ScreenRecorderService.qml +++ b/Services/Media/ScreenRecorderService.qml @@ -113,7 +113,7 @@ Singleton { // Check if gpu-screen-recorder is not installed const stdout = String(recorderProcess.stdout.text || "").trim() if (stdout === "GPU_SCREEN_RECORDER_NOT_INSTALLED") { - ToastService.showError(I18n.tr("toast.recording.not-installed"), I18n.tr("toast.recording.not-installed-desc"), 7000) + ToastService.showError(I18n.tr("toast.recording.not-installed"), I18n.tr("toast.recording.not-installed-desc")) return } @@ -121,9 +121,9 @@ Singleton { if (exitCode !== 0) { const err = String(recorderProcess.stderr.text || "").trim() if (err.length > 0) - ToastService.showError(I18n.tr("toast.recording.failed-start"), err, 7000) + ToastService.showError(I18n.tr("toast.recording.failed-start"), err) else - ToastService.showError(I18n.tr("toast.recording.failed-start"), I18n.tr("toast.recording.failed-gpu"), 7000) + ToastService.showError(I18n.tr("toast.recording.failed-start"), I18n.tr("toast.recording.failed-gpu")) } } else if (isRecording) { // Process ended normally while recording @@ -135,9 +135,9 @@ Singleton { } else { const err2 = String(recorderProcess.stderr.text || "").trim() if (err2.length > 0) - ToastService.showError(I18n.tr("toast.recording.failed-start"), err2, 7000) + ToastService.showError(I18n.tr("toast.recording.failed-start"), err2) else - ToastService.showError(I18n.tr("toast.recording.failed-start"), I18n.tr("toast.recording.failed-general"), 7000) + ToastService.showError(I18n.tr("toast.recording.failed-start"), I18n.tr("toast.recording.failed-general")) } } } @@ -153,7 +153,7 @@ Singleton { } else { isPending = false hasActiveRecording = false - ToastService.showError(I18n.tr("toast.recording.no-portals"), I18n.tr("toast.recording.no-portals-desc"), 8000) + ToastService.showError(I18n.tr("toast.recording.no-portals"), I18n.tr("toast.recording.no-portals-desc")) } } } diff --git a/Services/System/ProgramCheckerService.qml b/Services/System/ProgramCheckerService.qml index e569ce1e..13b2bc34 100644 --- a/Services/System/ProgramCheckerService.qml +++ b/Services/System/ProgramCheckerService.qml @@ -4,7 +4,7 @@ import QtQuick import Quickshell import Quickshell.Io import qs.Commons -import qs.Services.DynamicTheming +import qs.Services.Theming // Service to check if various programs are available on the system Singleton { diff --git a/Services/DynamicTheming/AppThemeService.qml b/Services/Theming/AppThemeService.qml similarity index 91% rename from Services/DynamicTheming/AppThemeService.qml rename to Services/Theming/AppThemeService.qml index 167309da..74c95099 100644 --- a/Services/DynamicTheming/AppThemeService.qml +++ b/Services/Theming/AppThemeService.qml @@ -8,15 +8,15 @@ import qs.Services.UI Singleton { id: root - // PUBLIC API - maintain compatibility with existing code readonly property string colorsApplyScript: Quickshell.shellDir + '/Bin/colors-apply.sh' - // Connections to trigger regeneration Connections { target: WallpaperService + + // When the wallpaper changes, regenerate with Matugen if necessary function onWallpaperChanged(screenName, path) { if (screenName === Screen.name && Settings.data.colorSchemes.useWallpaperColors) { - generate() + generateFromWallpaper() } } } @@ -39,6 +39,7 @@ Singleton { generateFromWallpaper() } else { ColorSchemeService.applyScheme(Settings.data.colorSchemes.predefinedScheme) + generateFromPredefinedScheme() } } diff --git a/Services/DynamicTheming/ColorPaletteGenerator.qml b/Services/Theming/ColorPaletteGenerator.qml similarity index 100% rename from Services/DynamicTheming/ColorPaletteGenerator.qml rename to Services/Theming/ColorPaletteGenerator.qml diff --git a/Services/DynamicTheming/ColorSchemeService.qml b/Services/Theming/ColorSchemeService.qml similarity index 99% rename from Services/DynamicTheming/ColorSchemeService.qml rename to Services/Theming/ColorSchemeService.qml index 734d8bd9..a853e651 100644 --- a/Services/DynamicTheming/ColorSchemeService.qml +++ b/Services/Theming/ColorSchemeService.qml @@ -5,6 +5,7 @@ import Qt.labs.folderlistmodel import Quickshell import Quickshell.Io import qs.Commons +import qs.Services.UI Singleton { id: root diff --git a/Services/DynamicTheming/TemplateProcessor.qml b/Services/Theming/TemplateProcessor.qml similarity index 92% rename from Services/DynamicTheming/TemplateProcessor.qml rename to Services/Theming/TemplateProcessor.qml index b436967c..86f2c3bb 100644 --- a/Services/DynamicTheming/TemplateProcessor.qml +++ b/Services/Theming/TemplateProcessor.qml @@ -29,7 +29,7 @@ Singleton { /** * Process wallpaper colors using matugen CLI - * Requirement #4: Dual-path architecture (wallpaper uses matugen CLI) + * Dual-path architecture (wallpaper uses matugen CLI) */ function processWallpaperColors(wallpaperPath, mode) { const content = buildMatugenConfig() @@ -39,6 +39,7 @@ Singleton { const wp = wallpaperPath.replace(/'/g, "'\\''") const script = buildMatugenScript(content, wp, mode) + generateProcess.generator = "matugen" generateProcess.command = ["bash", "-lc", script] generateProcess.running = true } @@ -46,7 +47,7 @@ Singleton { /** * Process predefined color scheme using sed scripts - * Requirement #4: Dual-path architecture (predefined uses sed scripts) + * Dual-path architecture (predefined uses sed scripts) */ function processPredefinedScheme(schemeData, mode) { handleTerminalThemes(mode) @@ -57,6 +58,7 @@ Singleton { // Add user templates if enabled (requirement #1) script += buildUserTemplateCommandForPredefined(schemeData, mode) + generateProcess.generator = "predefined" generateProcess.command = ["bash", "-lc", script] generateProcess.running = true } @@ -167,7 +169,6 @@ Singleton { } } }) - return script } @@ -184,6 +185,7 @@ Singleton { const outputDir = outputPath.substring(0, outputPath.lastIndexOf('/')) const baseConfigDir = outputDir.replace("/themes", "") + script += `\n` script += `if [ -d "${baseConfigDir}" ]; then\n` script += ` mkdir -p ${outputDir}\n` script += ` cp '${templatePath}' '${outputPath}'\n` @@ -205,9 +207,11 @@ Singleton { const outputPath = output.path.replace("~", homeDir) const outputDir = outputPath.substring(0, outputPath.lastIndexOf('/')) + script += `\n` script += `mkdir -p ${outputDir}\n` script += `cp '${templatePath}' '${outputPath}'\n` script += replaceColorsInFile(outputPath, palette) + script += `\n` }) if (app.postProcess) { @@ -269,7 +273,7 @@ Singleton { } // ================================================================================ - // USER TEMPLATES + // USER TEMPLATES, advanced usage // ================================================================================ function buildUserTemplateCommand(input, mode) { if (!Settings.data.templates.enableUserTemplates) @@ -320,17 +324,21 @@ Singleton { workingDirectory: Quickshell.shellDir running: false + // Error reporting helpers + property string generator: "" + function showError() { + const description = (stderr.text && stderr.text.trim() !== "") ? stderr.text.trim() : ((stdout.text && stdout.text.trim() !== "") ? stdout.text.trim() : I18n.tr("toast.theming-processor-failed.desc-generic")) + const title = I18n.tr(`toast.theming-processor-failed.title-${generator}`) + + // Give a bit more time to the user to read, as it can contains important information for debugging user's templates. + ToastService.showError(title, description, 8000) + return description + } + onExited: function (exitCode) { if (exitCode !== 0) { - const errorMsg = (stderr.text && stderr.text.trim() !== "") ? stderr.text.trim() : ((stdout.text && stdout.text.trim() !== "") ? stdout.text.trim() : I18n.tr("toast.matugen.failed-general")) - Logger.e("TemplateProcessor", "Process failed with exit code:", exitCode) - if (stderr.text && stderr.text.trim() !== "") { - Logger.e("TemplateProcessor", "stderr:", stderr.text) - } - if (stdout.text && stdout.text.trim() !== "") { - Logger.e("TemplateProcessor", "stdout:", stdout.text) - } - ToastService.showError(I18n.tr("toast.matugen.failed"), errorMsg, 6000) + const description = generateProcess.showError() + Logger.e("TemplateProcessor", "Process failed with exit code", exitCode, description) } } @@ -342,8 +350,10 @@ Singleton { } stderr: StdioCollector { onStreamFinished: { - if (this.text) - Logger.d("TemplateProcessor", "stderr:", this.text) + if (this.text) { + const description = generateProcess.showError() + Logger.e("TemplateProcessor", "Process failed with exit code", exitCode, description) + } } } } diff --git a/Services/DynamicTheming/TemplateRegistry.qml b/Services/Theming/TemplateRegistry.qml similarity index 100% rename from Services/DynamicTheming/TemplateRegistry.qml rename to Services/Theming/TemplateRegistry.qml diff --git a/Services/UI/PanelService.qml b/Services/UI/PanelService.qml index e7519cca..d22fc575 100644 --- a/Services/UI/PanelService.qml +++ b/Services/UI/PanelService.qml @@ -25,7 +25,7 @@ Singleton { // Register this panel (called after panel is loaded) function registerPanel(panel) { registeredPanels[panel.objectName] = panel - Logger.i("PanelService", "Registered panel:", panel.objectName) + Logger.d("PanelService", "Registered panel:", panel.objectName) } // Returns a panel (loads it on-demand if not yet loaded) diff --git a/Services/UI/ToastService.qml b/Services/UI/ToastService.qml index fd39e6ba..5a5a0929 100644 --- a/Services/UI/ToastService.qml +++ b/Services/UI/ToastService.qml @@ -18,7 +18,7 @@ Singleton { notify(message, description, "", "warning", duration) } - function showError(message, description = "", duration = 5000) { + function showError(message, description = "", duration = 6000) { notify(message, description, "", "error", duration) } } diff --git a/shell.qml b/shell.qml index af944e62..646a3c5d 100644 --- a/shell.qml +++ b/shell.qml @@ -13,7 +13,7 @@ import Quickshell // Commons & Services import qs.Commons import qs.Services.Control -import qs.Services.DynamicTheming +import qs.Services.Theming import qs.Services.Hardware import qs.Services.Location import qs.Services.Networking