1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-07 14:05:38 -05:00

ipc wallpaper handler, fix high CPU usage

This commit is contained in:
bbedward
2025-07-14 14:36:08 -04:00
parent 58d711b3e9
commit 31f1360d1b
17 changed files with 186 additions and 90 deletions

View File

@@ -101,38 +101,6 @@ Singleton {
/* ──────────────── wallpaper change monitor ──────────────── */ /* ──────────────── wallpaper change monitor ──────────────── */
property string lastWallpaperTimestamp: "" property string lastWallpaperTimestamp: ""
Timer {
id: wallpaperMonitorTimer
interval: 1000 // Check every second
repeat: true
onTriggered: {
wallpaperNotifyMonitor.reload()
}
}
FileView {
id: wallpaperNotifyMonitor
path: "file://" + notifyPath
onLoaded: {
var timestamp = wallpaperNotifyMonitor.text()
if (timestamp && timestamp !== lastWallpaperTimestamp) {
console.log("Wallpaper change detected - updating dynamic theme")
lastWallpaperTimestamp = timestamp
// Only update if we're currently using dynamic theme
if (typeof Theme !== "undefined" && Theme.isDynamicTheme) {
console.log("Triggering color extraction due to wallpaper change")
extractColors()
}
}
}
onLoadFailed: {
// File doesn't exist yet, this is normal
}
}
/* ──────────────── public helper ──────────────── */ /* ──────────────── public helper ──────────────── */
function extractColors() { function extractColors() {

View File

@@ -34,6 +34,15 @@ Singleton {
Component.onCompleted: loadSettings() Component.onCompleted: loadSettings()
// Monitor system resources preference changes to control service monitoring
onShowSystemResourcesChanged: {
console.log("Prefs: System resources monitoring", showSystemResources ? "enabled" : "disabled")
// Control SystemMonitorService based on whether system monitor widgets are visible
if (typeof SystemMonitorService !== 'undefined') {
SystemMonitorService.enableTopBarMonitoring(showSystemResources)
}
}
FileView { FileView {
id: settingsFile id: settingsFile
path: StandardPaths.writableLocation(StandardPaths.ConfigLocation) + "/DankMaterialShell/settings.json" path: StandardPaths.writableLocation(StandardPaths.ConfigLocation) + "/DankMaterialShell/settings.json"

View File

@@ -16,6 +16,10 @@ Singleton {
property var audioSources: [] property var audioSources: []
property string currentAudioSource: "" property string currentAudioSource: ""
// Device scanning control
property bool deviceScanningEnabled: false
property bool initialScanComplete: false
// Real Audio Control // Real Audio Control
Process { Process {
id: volumeChecker id: volumeChecker
@@ -51,7 +55,7 @@ Singleton {
Process { Process {
id: audioSinkLister id: audioSinkLister
command: ["pactl", "list", "sinks"] command: ["pactl", "list", "sinks"]
running: true running: false
stdout: StdioCollector { stdout: StdioCollector {
onStreamFinished: { onStreamFinished: {
@@ -136,7 +140,7 @@ Singleton {
Process { Process {
id: audioSourceLister id: audioSourceLister
command: ["pactl", "list", "sources"] command: ["pactl", "list", "sources"]
running: true running: false
stdout: StdioCollector { stdout: StdioCollector {
onStreamFinished: { onStreamFinished: {
@@ -283,7 +287,9 @@ Singleton {
console.log("Audio sink changed successfully") console.log("Audio sink changed successfully")
// Refresh current sink and list // Refresh current sink and list
defaultSinkChecker.running = true defaultSinkChecker.running = true
audioSinkLister.running = true if (root.deviceScanningEnabled) {
audioSinkLister.running = true
}
} else { } else {
console.error("Failed to change audio sink") console.error("Failed to change audio sink")
} }
@@ -308,20 +314,51 @@ Singleton {
console.log("Audio source changed successfully") console.log("Audio source changed successfully")
// Refresh current source and list // Refresh current source and list
defaultSourceChecker.running = true defaultSourceChecker.running = true
audioSourceLister.running = true if (root.deviceScanningEnabled) {
audioSourceLister.running = true
}
} else { } else {
console.error("Failed to change audio source") console.error("Failed to change audio source")
} }
} }
} }
// Timer to refresh audio devices regularly (catches new Bluetooth devices)
Timer { Timer {
interval: 4000 // 4s refresh to catch new BT devices interval: 5000
running: true; repeat: true running: root.deviceScanningEnabled && root.initialScanComplete
repeat: true
onTriggered: { onTriggered: {
if (root.deviceScanningEnabled) {
audioSinkLister.running = true
audioSourceLister.running = true
}
}
}
Component.onCompleted: {
console.log("AudioService: Starting initialization...")
// Do initial device scan
audioSinkLister.running = true
audioSourceLister.running = true
initialScanComplete = true
console.log("AudioService: Initialization complete")
}
// Control functions for managing device scanning
function enableDeviceScanning(enabled) {
console.log("AudioService: Device scanning", enabled ? "enabled" : "disabled")
root.deviceScanningEnabled = enabled
if (enabled && root.initialScanComplete) {
// Immediately scan when enabled
audioSinkLister.running = true audioSinkLister.running = true
audioSourceLister.running = true audioSourceLister.running = true
} }
} }
// Manual refresh function for when user opens audio settings
function refreshDevices() {
console.log("AudioService: Manual device refresh triggered")
audioSinkLister.running = true
audioSourceLister.running = true
}
} }

View File

@@ -193,10 +193,10 @@ Singleton {
', root) ', root)
} }
// Timer to refresh adapter & device state
Timer { Timer {
interval: 3000 // 3s refresh for more responsive updates id: bluetoothMonitorTimer
running: true; repeat: true interval: 5000
running: false; repeat: true
onTriggered: { onTriggered: {
bluetoothStatusChecker.running = true bluetoothStatusChecker.running = true
if (root.bluetoothEnabled) { if (root.bluetoothEnabled) {
@@ -208,6 +208,14 @@ Singleton {
} }
} }
function enableMonitoring(enabled) {
bluetoothMonitorTimer.running = enabled
if (enabled) {
// Immediately update when enabled
bluetoothStatusChecker.running = true
}
}
property var discoveredDevices: [] property var discoveredDevices: []
// Handle discovered devices // Handle discovered devices

View File

@@ -12,10 +12,10 @@ Singleton {
property bool isLoading: false property bool isLoading: false
property string lastError: "" property string lastError: ""
// Periodic refresh timer (5 minutes) // Periodic refresh timer
Timer { Timer {
id: refreshTimer id: refreshTimer
interval: 300000 // 5 minutes interval: 60000
running: root.khalAvailable running: root.khalAvailable
repeat: true repeat: true
onTriggered: { onTriggered: {

View File

@@ -10,7 +10,10 @@ Singleton {
// Process list properties // Process list properties
property var processes: [] property var processes: []
property bool isUpdating: false property bool isUpdating: false
property int processUpdateInterval: 3000 property int processUpdateInterval: 1500
// Performance control - only run when process monitor is actually visible
property bool monitoringEnabled: false
// System information properties // System information properties
property int totalMemoryKB: 0 property int totalMemoryKB: 0
@@ -109,28 +112,41 @@ Singleton {
} }
} }
// System and process monitoring timer // System and process monitoring timer - now conditional
Timer { Timer {
id: processTimer id: processTimer
interval: root.processUpdateInterval interval: root.processUpdateInterval
running: true running: root.monitoringEnabled // Only run when monitoring is enabled
repeat: true repeat: true
onTriggered: { onTriggered: {
updateSystemInfo() if (root.monitoringEnabled) {
updateProcessList() updateSystemInfo()
updateProcessList()
}
} }
} }
// Public functions // Public functions
function updateSystemInfo() { function updateSystemInfo() {
if (!systemInfoProcess.running) { if (!systemInfoProcess.running && root.monitoringEnabled) {
systemInfoProcess.running = true systemInfoProcess.running = true
} }
} }
// Control functions for enabling/disabling monitoring
function enableMonitoring(enabled) {
console.log("ProcessMonitorService: Monitoring", enabled ? "enabled" : "disabled")
root.monitoringEnabled = enabled
if (enabled) {
// Immediately update when enabled
updateSystemInfo()
updateProcessList()
}
}
function updateProcessList() { function updateProcessList() {
if (!root.isUpdating) { if (!root.isUpdating && root.monitoringEnabled) {
root.isUpdating = true root.isUpdating = true
// Update sort command based on current sort option // Update sort command based on current sort option

View File

@@ -28,10 +28,13 @@ Singleton {
// Temperature properties // Temperature properties
property real cpuTemperature: 0.0 property real cpuTemperature: 0.0
// Update intervals property int cpuUpdateInterval: 3000
property int cpuUpdateInterval: 1000 property int memoryUpdateInterval: 5000
property int memoryUpdateInterval: 2000 property int temperatureUpdateInterval: 10000
property int temperatureUpdateInterval: 5000
// Performance control
property bool enabledForTopBar: true
property bool enabledForDetailedView: false
Component.onCompleted: { Component.onCompleted: {
console.log("SystemMonitorService: Starting initialization...") console.log("SystemMonitorService: Starting initialization...")
@@ -176,12 +179,14 @@ Singleton {
Timer { Timer {
id: cpuTimer id: cpuTimer
interval: root.cpuUpdateInterval interval: root.cpuUpdateInterval
running: true running: root.enabledForTopBar || root.enabledForDetailedView
repeat: true repeat: true
onTriggered: { onTriggered: {
cpuUsageProcess.running = true if (root.enabledForTopBar || root.enabledForDetailedView) {
cpuFrequencyProcess.running = true cpuUsageProcess.running = true
cpuFrequencyProcess.running = true
}
} }
} }
@@ -189,11 +194,13 @@ Singleton {
Timer { Timer {
id: memoryTimer id: memoryTimer
interval: root.memoryUpdateInterval interval: root.memoryUpdateInterval
running: true running: root.enabledForTopBar || root.enabledForDetailedView
repeat: true repeat: true
onTriggered: { onTriggered: {
memoryUsageProcess.running = true if (root.enabledForTopBar || root.enabledForDetailedView) {
memoryUsageProcess.running = true
}
} }
} }
@@ -201,11 +208,13 @@ Singleton {
Timer { Timer {
id: temperatureTimer id: temperatureTimer
interval: root.temperatureUpdateInterval interval: root.temperatureUpdateInterval
running: true running: root.enabledForDetailedView
repeat: true repeat: true
onTriggered: { onTriggered: {
temperatureProcess.running = true if (root.enabledForDetailedView) {
temperatureProcess.running = true
}
} }
} }
@@ -215,10 +224,22 @@ Singleton {
} }
function updateSystemStats() { function updateSystemStats() {
cpuUsageProcess.running = true if (root.enabledForTopBar || root.enabledForDetailedView) {
memoryUsageProcess.running = true cpuUsageProcess.running = true
cpuFrequencyProcess.running = true memoryUsageProcess.running = true
temperatureProcess.running = true cpuFrequencyProcess.running = true
if (root.enabledForDetailedView) {
temperatureProcess.running = true
}
}
}
function enableTopBarMonitoring(enabled) {
root.enabledForTopBar = enabled
}
function enableDetailedMonitoring(enabled) {
root.enabledForDetailedView = enabled
} }
function getCpuUsageColor() { function getCpuUsageColor() {

View File

@@ -47,14 +47,12 @@ PanelWindow {
onTriggered: updateFilteredModel() onTriggered: updateFilteredModel()
} }
// Periodic rescan while open
Timer { Timer {
id: periodicRescanTimer id: periodicRescanTimer
interval: 15000 // 15 seconds interval: 60000
repeat: true repeat: true
running: launcher.isVisible running: launcher.isVisible
onTriggered: { onTriggered: {
console.log("AppLauncher: Periodic rescan triggered")
if (DesktopEntries.rescan) { if (DesktopEntries.rescan) {
DesktopEntries.rescan() DesktopEntries.rescan()
} }

View File

@@ -107,7 +107,7 @@ PanelWindow {
radius: parent.radius radius: parent.radius
SequentialAnimation on opacity { SequentialAnimation on opacity {
running: true running: root.calendarVisible
loops: Animation.Infinite loops: Animation.Infinite
NumberAnimation { NumberAnimation {
to: 0.08 to: 0.08

View File

@@ -36,10 +36,10 @@ Rectangle {
return activePlayer && activePlayer.length > 0 ? currentPosition / activePlayer.length : 0 return activePlayer && activePlayer.length > 0 ? currentPosition / activePlayer.length : 0
} }
// Updates progress bar every second // Updates progress bar every 2 seconds when playing
Timer { Timer {
id: positionTimer id: positionTimer
interval: 1000 interval: 2000
running: activePlayer && activePlayer.playbackState === MprisPlaybackState.Playing && activePlayer.length > 0 && !progressMouseArea.isSeeking running: activePlayer && activePlayer.playbackState === MprisPlaybackState.Playing && activePlayer.length > 0 && !progressMouseArea.isSeeking
repeat: true repeat: true
onTriggered: { onTriggered: {

View File

@@ -17,6 +17,12 @@ PanelWindow {
visible: isVisible visible: isVisible
// Monitor process dropdown visibility to enable/disable process monitoring
onIsVisibleChanged: {
console.log("Process dropdown", isVisible ? "opened" : "closed")
ProcessMonitorService.enableMonitoring(isVisible)
}
implicitWidth: 600 implicitWidth: 600
implicitHeight: 600 implicitHeight: 600

View File

@@ -32,10 +32,9 @@ PanelWindow {
onTriggered: updateFilteredApps() onTriggered: updateFilteredApps()
} }
// Periodic rescan while open
Timer { Timer {
id: periodicRescanTimer id: periodicRescanTimer
interval: 15000 // 15 seconds interval: 60000
repeat: true repeat: true
running: spotlightOpen running: spotlightOpen
onTriggered: { onTriggered: {

View File

@@ -1,4 +1,5 @@
import QtQuick import QtQuick
import Quickshell
import "../../Common" import "../../Common"
Rectangle { Rectangle {
@@ -51,13 +52,14 @@ Rectangle {
} }
} }
Timer { SystemClock {
interval: 1000 id: systemClock
running: true precision: SystemClock.Seconds
repeat: true onDateChanged: root.currentDate = systemClock.date
onTriggered: { }
root.currentDate = new Date()
} Component.onCompleted: {
root.currentDate = systemClock.date
} }
MouseArea { MouseArea {

View File

@@ -121,7 +121,7 @@ PanelWindow {
radius: parent.radius radius: parent.radius
SequentialAnimation on opacity { SequentialAnimation on opacity {
running: true running: false
loops: Animation.Infinite loops: Animation.Infinite
NumberAnimation { NumberAnimation {
to: 0.08 to: 0.08

View File

@@ -10,6 +10,9 @@ mkdir -p "$QS_DIR"
LINK="$QS_DIR/current_wallpaper" LINK="$QS_DIR/current_wallpaper"
ln -sf -- "$img" "$LINK" ln -sf -- "$img" "$LINK"
# Kill existing swaybg processes before starting new one
pkill -f "swaybg.*$LINK" 2>/dev/null || true
swaybg -m fill -i "$LINK" & disown swaybg -m fill -i "$LINK" & disown
json="$(matugen image "$img" --json hex)" json="$(matugen image "$img" --json hex)"
@@ -79,7 +82,5 @@ echo " (use in ghostty: theme = $QS_DIR/generated_ghostty_colors.conf )"
niri msg action do-screen-transition --delay-ms 100 niri msg action do-screen-transition --delay-ms 100
# Notify running shell about wallpaper change (for dynamic theme updates) # Notify running shell about wallpaper change via IPC
NOTIFY_FILE="$QS_DIR/wallpaper_changed" qs -c "DankMaterialShell" ipc call wallpaper refresh 2>/dev/null && echo "→ Shell notified via IPC" || echo "→ Shell not running or IPC failed"
echo "$(date '+%s')" > "$NOTIFY_FILE"
echo "→ Shell notified: $NOTIFY_FILE"

View File

@@ -23,6 +23,11 @@ ShellRoot {
Component.onCompleted: { Component.onCompleted: {
// Make root accessible to Theme singleton for error handling // Make root accessible to Theme singleton for error handling
Theme.rootObj = root Theme.rootObj = root
// Initialize service monitoring states based on preferences
SystemMonitorService.enableTopBarMonitoring(Prefs.showSystemResources)
ProcessMonitorService.enableMonitoring(false) // Start disabled, enable when process dropdown is opened
AudioService.enableDeviceScanning(false) // Start disabled, enable when control center is opened
} }
property bool calendarVisible: false property bool calendarVisible: false
@@ -40,6 +45,17 @@ ShellRoot {
property MprisPlayer activePlayer: MprisController.activePlayer property MprisPlayer activePlayer: MprisController.activePlayer
property bool hasActiveMedia: activePlayer && (activePlayer.trackTitle || activePlayer.trackArtist) property bool hasActiveMedia: activePlayer && (activePlayer.trackTitle || activePlayer.trackArtist)
property bool controlCenterVisible: false property bool controlCenterVisible: false
// Monitor control center visibility to enable/disable audio device scanning
onControlCenterVisibleChanged: {
console.log("Control center", controlCenterVisible ? "opened" : "closed")
AudioService.enableDeviceScanning(controlCenterVisible)
BluetoothService.enableMonitoring(controlCenterVisible)
if (controlCenterVisible) {
// Immediately refresh devices when opening control center
AudioService.refreshDevices()
}
}
property bool batteryPopupVisible: false property bool batteryPopupVisible: false
property bool powerMenuVisible: false property bool powerMenuVisible: false
property bool powerConfirmVisible: false property bool powerConfirmVisible: false
@@ -165,14 +181,15 @@ ShellRoot {
// Weather configuration // Weather configuration
// WiFi Auto-refresh Timer
Timer { Timer {
id: wifiAutoRefreshTimer id: wifiAutoRefreshTimer
interval: 10000 // 10 seconds interval: 20000
running: root.wifiAutoRefreshEnabled && root.controlCenterVisible running: root.wifiAutoRefreshEnabled && root.controlCenterVisible
repeat: true repeat: true
onTriggered: { onTriggered: {
WifiService.scanWifi() if (root.wifiAutoRefreshEnabled && root.controlCenterVisible) {
WifiService.scanWifi()
}
} }
} }
@@ -375,4 +392,18 @@ ShellRoot {
ClipboardHistory { ClipboardHistory {
id: clipboardHistoryPopup id: clipboardHistoryPopup
} }
IpcHandler {
target: "wallpaper"
function refresh() {
console.log("Wallpaper IPC: refresh() called")
// Trigger color extraction if using dynamic theme
if (typeof Theme !== "undefined" && Theme.isDynamicTheme) {
console.log("Triggering color extraction due to wallpaper IPC")
Colors.extractColors()
}
return "WALLPAPER_REFRESH_SUCCESS"
}
}
} }