From 38a7c606c8701ae156ce849ddfbcb06b163a20ce Mon Sep 17 00:00:00 2001 From: notiant <238434866+notiant@users.noreply.github.com> Date: Fri, 31 Oct 2025 15:54:50 +0100 Subject: [PATCH] Add airplane mode detection, improve NetworkService & add icons to notice toasts --- Assets/Translations/de.json | 8 +++ Assets/Translations/en.json | 8 +++ Assets/Translations/es.json | 8 +++ Assets/Translations/fr.json | 8 +++ Assets/Translations/pt.json | 8 +++ Assets/Translations/zh-CN.json | 8 +++ Modules/Settings/Tabs/AboutTab.qml | 2 +- Modules/Settings/Tabs/ColorSchemeTab.qml | 4 +- Modules/Settings/Tabs/DisplayTab.qml | 4 +- Modules/Toast/SimpleToast.qml | 23 +++++---- Modules/Toast/ToastScreen.qml | 9 ++-- Services/BatteryService.qml | 2 +- Services/BluetoothService.qml | 54 ++++++++++++++++--- Services/ColorSchemeService.qml | 4 +- Services/IdleInhibitorService.qml | 4 +- Services/NetworkService.qml | 66 ++++++++++++++++++++++-- Services/NightLightService.qml | 4 +- Services/NotificationService.qml | 2 +- Services/PowerProfileService.qml | 2 +- Services/ScreenRecorderService.qml | 4 +- Services/ToastService.qml | 12 ++--- 21 files changed, 197 insertions(+), 47 deletions(-) diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index 85d94e98d..45017ad82 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -1761,6 +1761,14 @@ "enabled": "Aktiviert", "disabled": "Deaktiviert" }, + "airplane-mode": { + "title": "Flugmodus", + "enabled": "Aktiviert", + "disabled": "Deaktiviert" + }, + "internet": { + "limited": "Verbunden ohne Internet" + }, "kofi": { "opened": "Ko-fi-Seite in Ihrem Browser geöffnet" }, diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index d8f16c14d..8edce966d 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -1721,6 +1721,14 @@ "enabled": "Enabled", "disabled": "Disabled" }, + "airplane-mode": { + "title": "Airplane mode", + "enabled": "Enabled", + "disabled": "Disabled" + }, + "internet": { + "limited": "Connected without internet" + }, "kofi": { "opened": "Ko-fi page opened in your browser" }, diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index 440166557..30f5c7a8b 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -1721,6 +1721,14 @@ "enabled": "Activado", "disabled": "Desactivado" }, + "airplane-mode": { + "title": "Modo avión", + "enabled": "Activado", + "disabled": "Desactivado" + }, + "internet": { + "limited": "Conectado sin Internet" + }, "kofi": { "opened": "Página de Ko-fi abierta en tu navegador" }, diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json index 783e94ec1..38968fee6 100644 --- a/Assets/Translations/fr.json +++ b/Assets/Translations/fr.json @@ -1721,6 +1721,14 @@ "enabled": "Activé", "disabled": "Désactivé" }, + "airplane-mode": { + "title": "Mode avion", + "enabled": "Activé", + "disabled": "Désactivé" + }, + "internet": { + "limited": "Connecté sans Internet" + }, "kofi": { "opened": "Page Ko-fi ouverte dans votre navigateur" }, diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index 7cb7c3cf0..43ef064f0 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -1721,6 +1721,14 @@ "enabled": "Ativado", "disabled": "Desativado" }, + "airplane-mode": { + "title": "Modo avião", + "enabled": "Ativado", + "disabled": "Desativado" + }, + "internet": { + "limited": "Conectado sem Internet" + }, "kofi": { "opened": "Página do Ko-fi aberta no seu navegador" }, diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json index fdf2893c7..33f37db66 100644 --- a/Assets/Translations/zh-CN.json +++ b/Assets/Translations/zh-CN.json @@ -1721,6 +1721,14 @@ "enabled": "已启用", "disabled": "已禁用" }, + "airplane-mode": { + "title": "飞行模式", + "enabled": "已启用", + "disabled": "已禁用" + }, + "internet": { + "limited": "已连接但无互联网" + }, "kofi": { "opened": "Ko-fi页面已在您的浏览器中打开" }, diff --git a/Modules/Settings/Tabs/AboutTab.qml b/Modules/Settings/Tabs/AboutTab.qml index 6892b1ce1..445b72876 100644 --- a/Modules/Settings/Tabs/AboutTab.qml +++ b/Modules/Settings/Tabs/AboutTab.qml @@ -127,7 +127,7 @@ ColumnLayout { cursorShape: Qt.PointingHandCursor onClicked: { Quickshell.execDetached(["xdg-open", "https://ko-fi.com/lysec"]) - ToastService.showNotice(I18n.tr("settings.about.support"), I18n.tr("toast.kofi.opened"), 3000) + ToastService.showNotice(I18n.tr("settings.about.support"), I18n.tr("toast.kofi.opened")) } } } diff --git a/Modules/Settings/Tabs/ColorSchemeTab.qml b/Modules/Settings/Tabs/ColorSchemeTab.qml index 99fdf580f..742e71d16 100644 --- a/Modules/Settings/Tabs/ColorSchemeTab.qml +++ b/Modules/Settings/Tabs/ColorSchemeTab.qml @@ -111,7 +111,7 @@ 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")) + ToastService.showNotice(I18n.tr("settings.color-scheme.color-source.use-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")) } @@ -248,7 +248,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")) + ToastService.showNotice(I18n.tr("settings.color-scheme.color-source.use-wallpaper-colors.label"), I18n.tr("toast.wallpaper-colors.disabled"), "settings-color-scheme") if (Settings.data.colorSchemes.predefinedScheme) { ColorSchemeService.applyScheme(Settings.data.colorSchemes.predefinedScheme) diff --git a/Modules/Settings/Tabs/DisplayTab.qml b/Modules/Settings/Tabs/DisplayTab.qml index f8bfb3ef9..b835b50de 100644 --- a/Modules/Settings/Tabs/DisplayTab.qml +++ b/Modules/Settings/Tabs/DisplayTab.qml @@ -38,7 +38,7 @@ ColumnLayout { if (exitCode === 0) { Settings.data.nightLight.enabled = true NightLightService.apply() - ToastService.showNotice(I18n.tr("settings.display.night-light.section.label"), I18n.tr("toast.night-light.enabled")) + ToastService.showNotice(I18n.tr("settings.display.night-light.section.label"), I18n.tr("toast.night-light.enabled"), "nightlight-on") } else { Settings.data.nightLight.enabled = false ToastService.showWarning(I18n.tr("settings.display.night-light.section.label"), I18n.tr("toast.night-light.not-installed")) @@ -194,7 +194,7 @@ ColumnLayout { Settings.data.nightLight.enabled = false Settings.data.nightLight.forced = false NightLightService.apply() - ToastService.showNotice(I18n.tr("settings.display.night-light.section.label"), I18n.tr("toast.night-light.disabled")) + ToastService.showNotice(I18n.tr("settings.display.night-light.section.label"), I18n.tr("toast.night-light.disabled"), "nightlight-off") } } } diff --git a/Modules/Toast/SimpleToast.qml b/Modules/Toast/SimpleToast.qml index 1575c4a42..2de83cccd 100644 --- a/Modules/Toast/SimpleToast.qml +++ b/Modules/Toast/SimpleToast.qml @@ -9,6 +9,7 @@ Rectangle { property string message: "" property string description: "" + property string icon: "" property string type: "notice" property int duration: 3000 readonly property real initialScale: 0.7 @@ -80,16 +81,15 @@ Rectangle { // Icon NIcon { id: icon - icon: { - switch (type) { - case "warning": - return "toast-warning" - case "error": - return "toast-error" - default: - return "toast-notice" - } - } + icon: if (root.icon !== "") { + return root.icon + } else if (type === "warning") { + return "toast-warning" + } else if (type === "error") { + return "toast-error" + } else { + return "toast-notice" + } color: { switch (type) { case "warning": @@ -139,13 +139,14 @@ Rectangle { cursorShape: Qt.PointingHandCursor } - function show(msg, desc, msgType, msgDuration) { + function show(msg, desc, msgIcon, msgType, msgDuration) { // Stop all timers first hideTimer.stop() hideAnimation.stop() message = msg description = desc || "" + icon = msgIcon || "" type = msgType || "notice" duration = msgDuration || 3000 diff --git a/Modules/Toast/ToastScreen.qml b/Modules/Toast/ToastScreen.qml index fafd9e040..0bd206936 100644 --- a/Modules/Toast/ToastScreen.qml +++ b/Modules/Toast/ToastScreen.qml @@ -22,10 +22,11 @@ Item { Connections { target: ToastService - function onNotify(message, description, type, duration) { + function onNotify(message, description, icon, type, duration) { root.enqueueToast({ "message": message, "description": description, + "icon": icon, "type": type, "duration": duration, "timestamp": Date.now() @@ -122,7 +123,7 @@ Item { onStatusChanged: { // When loader becomes ready, show the pending toast if (status === Loader.Ready && pendingToast !== null) { - item.showToast(pendingToast.message, pendingToast.description, pendingToast.type, pendingToast.duration) + item.showToast(pendingToast.message, pendingToast.description, pendingToast.icon, pendingToast.type, pendingToast.duration) pendingToast = null } } @@ -201,8 +202,8 @@ Item { WlrLayershell.keyboardFocus: WlrKeyboardFocus.None exclusionMode: PanelWindow.ExclusionMode.Ignore - function showToast(message, description, type, duration) { - toastItem.show(message, description, type, duration) + function showToast(message, description, icon, type, duration) { + toastItem.show(message, description, icon, type, duration) } function hideToast() { diff --git a/Services/BatteryService.qml b/Services/BatteryService.qml index 4977233cc..3f942403a 100644 --- a/Services/BatteryService.qml +++ b/Services/BatteryService.qml @@ -119,7 +119,7 @@ Singleton { } ToastService.showNotice(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.set-success-desc", { "percent": BatteryService.getThresholdValue(BatteryService.chargingMode) - })) + }), "battery") Settings.data.battery.chargingMode = BatteryService.chargingMode } else if (exitCode === 2) { ToastService.showWarning(I18n.tr("toast.battery-manager.title"), I18n.tr("toast.battery-manager.initial-setup")) diff --git a/Services/BluetoothService.qml b/Services/BluetoothService.qml index f6a427434..3ba38f4e2 100644 --- a/Services/BluetoothService.qml +++ b/Services/BluetoothService.qml @@ -3,14 +3,19 @@ pragma Singleton import QtQuick import Quickshell import Quickshell.Bluetooth +import Quickshell.Io import qs.Commons +import qs.Services Singleton { id: root + property bool airplaneModeToggled: false + property bool lastBluetoothBlocked: false readonly property BluetoothAdapter adapter: Bluetooth.defaultAdapter readonly property bool available: (adapter !== null) readonly property bool enabled: adapter?.enabled ?? false + readonly property bool blocked: (adapter?.state === BluetoothAdapterState.Blocked) readonly property bool discovering: (adapter && adapter.discovering) ?? false readonly property var devices: adapter ? adapter.devices : null readonly property var pairedDevices: { @@ -50,18 +55,25 @@ Singleton { Connections { target: adapter - function onEnabledChanged() { + function onStateChanged() { if (!adapter) { - Logger.w("Bluetooth", "onEnabledChanged", "No adapter available") + Logger.w("Bluetooth", "onStateChanged", "No adapter available") + return + } + if (adapter.state === BluetoothAdapterState.Enabling || adapter.state === BluetoothAdapterState.Disabling) { return } - Logger.d("Bluetooth", "onEnableChanged", adapter.enabled) - if (adapter.enabled) { - ToastService.showNotice(I18n.tr("bluetooth.panel.title"), I18n.tr("toast.bluetooth.enabled")) + Logger.d("Bluetooth", "onStateChanged", adapter.state) + const bluetoothBlockedToggled = (root.blocked !== lastBluetoothBlocked) + root.lastBluetoothBlocked = root.blocked + if (bluetoothBlockedToggled) { + checkWifiBlocked.running = true + } else if (adapter.enabled) { + ToastService.showNotice(I18n.tr("bluetooth.panel.title"), I18n.tr("toast.bluetooth.enabled"), "bluetooth") discoveryTimer.running = true } else { - ToastService.showNotice(I18n.tr("bluetooth.panel.title"), I18n.tr("toast.bluetooth.disabled")) + ToastService.showNotice(I18n.tr("bluetooth.panel.title"), I18n.tr("toast.bluetooth.disabled"), "bluetooth-off") } } } @@ -238,4 +250,34 @@ Singleton { Logger.i("Bluetooth", "SetBluetoothEnabled", state) adapter.enabled = state } + + Process { + id: checkWifiBlocked + running: false + command: ["rfkill", "list", "wifi"] + + stdout: StdioCollector { + onStreamFinished: { + const wifiBlocked = text && text.trim().includes("Soft blocked: yes") + Logger.d("Network", "Wi-Fi adapter was detected as blocked:", blocked) + + // Check if airplane mode has been toggled + if (wifiBlocked && wifiBlocked === root.blocked) { + root.airplaneModeToggled = true + NetworkService.setWifiEnabled(false) + ToastService.showNotice(I18n.tr("toast.airplane-mode.title"), I18n.tr("toast.airplane-mode.enabled"), "plane") + } else if (!wifiBlocked && wifiBlocked === root.blocked) { + root.airplaneModeToggled = true + NetworkService.setWifiEnabled(true) + ToastService.showNotice(I18n.tr("toast.airplane-mode.title"), I18n.tr("toast.airplane-mode.disabled"), "plane") + } else if (adapter.enabled) { + ToastService.showNotice(I18n.tr("bluetooth.panel.title"), I18n.tr("toast.bluetooth.enabled"), "bluetooth") + discoveryTimer.running = true + } else { + ToastService.showNotice(I18n.tr("bluetooth.panel.title"), I18n.tr("toast.bluetooth.disabled"), "bluetooth-off") + } + root.airplaneModeToggled = false + } + } + } } diff --git a/Services/ColorSchemeService.qml b/Services/ColorSchemeService.qml index ff271b695..8c6e71972 100644 --- a/Services/ColorSchemeService.qml +++ b/Services/ColorSchemeService.qml @@ -27,7 +27,7 @@ Singleton { const enabled = !!Settings.data.colorSchemes.darkMode const label = enabled ? "Dark mode" : "Light mode" const description = enabled ? "Enabled" : "Enabled" - ToastService.showNotice(label, description) + ToastService.showNotice(label, description, "dark-mode") } } @@ -109,7 +109,7 @@ Singleton { if (schemeExists) { Settings.data.colorSchemes.predefinedScheme = basename applyScheme(schemeName) - ToastService.showNotice("Color Scheme", `Set to ${basename}`) + ToastService.showNotice("Color Scheme", `Set to ${basename}`, "settings-color-scheme") } else { Logger.e("ColorScheme", "Scheme not found:", schemeName) ToastService.showError("Color Scheme", `Scheme '${basename}' not found!`) diff --git a/Services/IdleInhibitorService.qml b/Services/IdleInhibitorService.qml index ab20dd947..59c1266e7 100644 --- a/Services/IdleInhibitorService.qml +++ b/Services/IdleInhibitorService.qml @@ -156,12 +156,12 @@ Singleton { function manualToggle() { if (activeInhibitors.includes("manual")) { removeInhibitor("manual") - ToastService.showNotice(I18n.tr("tooltips.keep-awake"), I18n.tr("toast.keep-awake.disabled")) + ToastService.showNotice(I18n.tr("tooltips.keep-awake"), I18n.tr("toast.keep-awake.disabled"), "keep-awake-on") Logger.i("IdleInhibitor", "Manual inhibition disabled") return false } else { addInhibitor("manual", "Manually activated by user") - ToastService.showNotice(I18n.tr("tooltips.keep-awake"), I18n.tr("toast.keep-awake.enabled")) + ToastService.showNotice(I18n.tr("tooltips.keep-awake"), I18n.tr("toast.keep-awake.enabled"), "keep-awake-off") Logger.i("IdleInhibitor", "Manual inhibition enabled (will reset on next session)") return true } diff --git a/Services/NetworkService.qml b/Services/NetworkService.qml index 4e5d6dfb7..f5f90ec7f 100644 --- a/Services/NetworkService.qml +++ b/Services/NetworkService.qml @@ -4,6 +4,7 @@ import QtQuick import Quickshell import Quickshell.Io import qs.Commons +import qs.Services Singleton { id: root @@ -17,6 +18,7 @@ Singleton { property bool ethernetConnected: false property string disconnectingFrom: "" property string forgettingNetwork: "" + property string internetConnectivity: "unknown" property bool ignoreScanResults: false property bool scanPending: false @@ -48,9 +50,18 @@ Singleton { target: Settings.data.network function onWifiEnabledChanged() { if (Settings.data.network.wifiEnabled) { - ToastService.showNotice(I18n.tr("wifi.panel.title"), I18n.tr("toast.wifi.enabled")) + if (!BluetoothService.airplaneModeToggled) + ToastService.showNotice(I18n.tr("wifi.panel.title"), I18n.tr("toast.wifi.enabled"), "wifi") + + // Perform a scan to update the UI + delayedScanTimer.interval = 3000 + delayedScanTimer.restart() } else { - ToastService.showNotice(I18n.tr("wifi.panel.title"), I18n.tr("toast.wifi.disabled")) + if (!BluetoothService.airplaneModeToggled) + ToastService.showNotice(I18n.tr("wifi.panel.title"), I18n.tr("toast.wifi.disabled"), "wifi-off") + + // Clear networks so the widget icon changes + root.networks = ({}) } } } @@ -89,6 +100,16 @@ Singleton { onTriggered: ethernetStateProcess.running = true } + // Internet connectivity check timer + // Always running every 10s + Timer { + id: connectivityCheckTimer + interval: 10000 + running: true + repeat: true + onTriggered: connectivityCheckProcess.running = true + } + // Core functions function syncWifiState() { wifiStateProcess.running = true @@ -202,6 +223,8 @@ Singleton { // Helper functions function signalIcon(signal) { + if (root.internetConnectivity === "limited" || root.internetConnectivity === "portal") + return "world-off" if (signal >= 80) return "wifi" if (signal >= 50) @@ -276,6 +299,38 @@ Singleton { } } + // Process to check the internet connectivity + Process { + id: connectivityCheckProcess + running: false + command: ["nmcli", "networking", "connectivity"] + + stdout: StdioCollector { + onStreamFinished: { + const result = text.trim() + if (result && result !== root.internetConnectivity) { + root.internetConnectivity = result + Logger.i("Network", "Internet connectivity:", result) + + if (result === "limited" || result === "portal") { + ToastService.showWarning(I18n.tr("wifi.panel.title"), "toast.internet.limited") + } + else { + scan() + } + } + } + } + + stderr: StdioCollector { + onStreamFinished: { + if (text.trim()) { + Logger.w("Network", "Connectivity check error: " + text) + } + } + } + } + // Helper process to get existing profiles Process { id: profileCheckProcess @@ -462,6 +517,9 @@ Singleton { return cmd } } + environment: { + "LC_ALL": "C" + } stdout: StdioCollector { onStreamFinished: { @@ -494,7 +552,7 @@ Singleton { Logger.i("Network", `Connected to network: '${connectProcess.ssid}'`) ToastService.showNotice(I18n.tr("wifi.panel.title"), I18n.tr("toast.wifi.connected", { "ssid": connectProcess.ssid - })) + }), "wifi") // Still do a scan to get accurate signal and security info delayedScanTimer.interval = 5000 @@ -537,7 +595,7 @@ Singleton { Logger.i("Network", `Disconnected from network: '${disconnectProcess.ssid}'`) ToastService.showNotice(I18n.tr("wifi.panel.title"), I18n.tr("toast.wifi.disconnected", { "ssid": disconnectProcess.ssid - })) + }), "wifi-off") // Immediately update UI on successful disconnect root.updateNetworkStatus(disconnectProcess.ssid, false) diff --git a/Services/NightLightService.qml b/Services/NightLightService.qml index adf3704e0..234cfb02c 100644 --- a/Services/NightLightService.qml +++ b/Services/NightLightService.qml @@ -63,12 +63,12 @@ Singleton { apply() // Toast: night light toggled const enabled = !!Settings.data.nightLight.enabled - ToastService.showNotice(I18n.tr("settings.display.night-light.section.label"), enabled ? I18n.tr("toast.night-light.enabled") : I18n.tr("toast.night-light.disabled")) + ToastService.showNotice(I18n.tr("settings.display.night-light.section.label"), enabled ? I18n.tr("toast.night-light.enabled") : I18n.tr("toast.night-light.disabled"), enabled ? "nightlight-on" : "nightlight-off") } function onForcedChanged() { apply() if (Settings.data.nightLight.enabled) { - ToastService.showNotice(I18n.tr("settings.display.night-light.section.label"), Settings.data.nightLight.forced ? I18n.tr("toast.night-light.forced") : I18n.tr("toast.night-light.normal")) + ToastService.showNotice(I18n.tr("settings.display.night-light.section.label"), Settings.data.nightLight.forced ? I18n.tr("toast.night-light.forced") : I18n.tr("toast.night-light.normal"), forced ? "nightlight-forced" : "nightlight-on") } } function onNightTempChanged() { diff --git a/Services/NotificationService.qml b/Services/NotificationService.qml index 8a55af35b..72277372f 100644 --- a/Services/NotificationService.qml +++ b/Services/NotificationService.qml @@ -543,7 +543,7 @@ Singleton { target: Settings.data.notifications function onDoNotDisturbChanged() { const enabled = Settings.data.notifications.doNotDisturb - ToastService.showNotice(enabled ? I18n.tr("toast.do-not-disturb.enabled") : I18n.tr("toast.do-not-disturb.disabled"), enabled ? I18n.tr("toast.do-not-disturb.enabled-desc") : I18n.tr("toast.do-not-disturb.disabled-desc")) + ToastService.showNotice(enabled ? I18n.tr("toast.do-not-disturb.enabled") : I18n.tr("toast.do-not-disturb.disabled"), enabled ? I18n.tr("toast.do-not-disturb.enabled-desc") : I18n.tr("toast.do-not-disturb.disabled-desc"), enabled ? "bell-off" : "bell") } } } diff --git a/Services/PowerProfileService.qml b/Services/PowerProfileService.qml index 7a16b999e..2417b81ba 100644 --- a/Services/PowerProfileService.qml +++ b/Services/PowerProfileService.qml @@ -90,7 +90,7 @@ Singleton { if (profileName !== "Unknown") { ToastService.showNotice(I18n.tr("toast.power-profile.changed"), I18n.tr("toast.power-profile.profile-name", { "profile": profileName - })) + }), profileName.toLowerCase().replace(" ", "")) } } } diff --git a/Services/ScreenRecorderService.qml b/Services/ScreenRecorderService.qml index 333a433c9..15d416478 100644 --- a/Services/ScreenRecorderService.qml +++ b/Services/ScreenRecorderService.qml @@ -85,7 +85,7 @@ Singleton { return } - ToastService.showNotice(I18n.tr("toast.recording.stopping"), outputPath, 2000) + ToastService.showNotice(I18n.tr("toast.recording.stopping"), outputPath, 2000, "settings-screen-recorder") Quickshell.execDetached(["sh", "-c", "pkill -SIGINT -f 'gpu-screen-recorder' || pkill -SIGINT -f 'com.dec05eba.gpu_screen_recorder'"]) @@ -131,7 +131,7 @@ Singleton { monitorTimer.running = false // Consider successful save if exitCode == 0 if (exitCode === 0) { - ToastService.showNotice(I18n.tr("toast.recording.saved"), outputPath, 5000) + ToastService.showNotice(I18n.tr("toast.recording.saved"), outputPath, 5000, "settings-screen-recorder") } else { const err2 = String(recorderProcess.stderr.text || "").trim() if (err2.length > 0) diff --git a/Services/ToastService.qml b/Services/ToastService.qml index df4cc2511..ab9466dac 100644 --- a/Services/ToastService.qml +++ b/Services/ToastService.qml @@ -7,18 +7,18 @@ Singleton { id: root // Simple signal-based notification system - signal notify(string message, string description, string type, int duration) + signal notify(string message, string description, string icon, string type, int duration) // Convenience methods - function showNotice(message, description = "", duration = 3000) { - notify(message, description, "notice", duration) + function showNotice(message, description = "", icon = "", duration = 3000) { + notify(message, description, icon, "notice", duration) } function showWarning(message, description = "", duration = 4000) { - notify(message, description, "warning", duration) + notify(message, description, "", "warning", duration) } function showError(message, description = "", duration = 5000) { - notify(message, description, "error", duration) + notify(message, description, "", "error", duration) } -} +} \ No newline at end of file