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 ──────────────── */
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 ──────────────── */
function extractColors() {

View File

@@ -34,6 +34,15 @@ Singleton {
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 {
id: settingsFile
path: StandardPaths.writableLocation(StandardPaths.ConfigLocation) + "/DankMaterialShell/settings.json"

View File

@@ -16,6 +16,10 @@ Singleton {
property var audioSources: []
property string currentAudioSource: ""
// Device scanning control
property bool deviceScanningEnabled: false
property bool initialScanComplete: false
// Real Audio Control
Process {
id: volumeChecker
@@ -51,7 +55,7 @@ Singleton {
Process {
id: audioSinkLister
command: ["pactl", "list", "sinks"]
running: true
running: false
stdout: StdioCollector {
onStreamFinished: {
@@ -136,7 +140,7 @@ Singleton {
Process {
id: audioSourceLister
command: ["pactl", "list", "sources"]
running: true
running: false
stdout: StdioCollector {
onStreamFinished: {
@@ -283,7 +287,9 @@ Singleton {
console.log("Audio sink changed successfully")
// Refresh current sink and list
defaultSinkChecker.running = true
if (root.deviceScanningEnabled) {
audioSinkLister.running = true
}
} else {
console.error("Failed to change audio sink")
}
@@ -308,20 +314,51 @@ Singleton {
console.log("Audio source changed successfully")
// Refresh current source and list
defaultSourceChecker.running = true
if (root.deviceScanningEnabled) {
audioSourceLister.running = true
}
} else {
console.error("Failed to change audio source")
}
}
}
// Timer to refresh audio devices regularly (catches new Bluetooth devices)
Timer {
interval: 4000 // 4s refresh to catch new BT devices
running: true; repeat: true
interval: 5000
running: root.deviceScanningEnabled && root.initialScanComplete
repeat: true
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
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)
}
// Timer to refresh adapter & device state
Timer {
interval: 3000 // 3s refresh for more responsive updates
running: true; repeat: true
id: bluetoothMonitorTimer
interval: 5000
running: false; repeat: true
onTriggered: {
bluetoothStatusChecker.running = true
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: []
// Handle discovered devices

View File

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

View File

@@ -10,7 +10,10 @@ Singleton {
// Process list properties
property var processes: []
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
property int totalMemoryKB: 0
@@ -109,28 +112,41 @@ Singleton {
}
}
// System and process monitoring timer
// System and process monitoring timer - now conditional
Timer {
id: processTimer
interval: root.processUpdateInterval
running: true
running: root.monitoringEnabled // Only run when monitoring is enabled
repeat: true
onTriggered: {
if (root.monitoringEnabled) {
updateSystemInfo()
updateProcessList()
}
}
}
// Public functions
function updateSystemInfo() {
if (!systemInfoProcess.running) {
if (!systemInfoProcess.running && root.monitoringEnabled) {
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() {
if (!root.isUpdating) {
if (!root.isUpdating && root.monitoringEnabled) {
root.isUpdating = true
// Update sort command based on current sort option

View File

@@ -28,10 +28,13 @@ Singleton {
// Temperature properties
property real cpuTemperature: 0.0
// Update intervals
property int cpuUpdateInterval: 1000
property int memoryUpdateInterval: 2000
property int temperatureUpdateInterval: 5000
property int cpuUpdateInterval: 3000
property int memoryUpdateInterval: 5000
property int temperatureUpdateInterval: 10000
// Performance control
property bool enabledForTopBar: true
property bool enabledForDetailedView: false
Component.onCompleted: {
console.log("SystemMonitorService: Starting initialization...")
@@ -176,38 +179,44 @@ Singleton {
Timer {
id: cpuTimer
interval: root.cpuUpdateInterval
running: true
running: root.enabledForTopBar || root.enabledForDetailedView
repeat: true
onTriggered: {
if (root.enabledForTopBar || root.enabledForDetailedView) {
cpuUsageProcess.running = true
cpuFrequencyProcess.running = true
}
}
}
// Memory monitoring timer
Timer {
id: memoryTimer
interval: root.memoryUpdateInterval
running: true
running: root.enabledForTopBar || root.enabledForDetailedView
repeat: true
onTriggered: {
if (root.enabledForTopBar || root.enabledForDetailedView) {
memoryUsageProcess.running = true
}
}
}
// Temperature monitoring timer
Timer {
id: temperatureTimer
interval: root.temperatureUpdateInterval
running: true
running: root.enabledForDetailedView
repeat: true
onTriggered: {
if (root.enabledForDetailedView) {
temperatureProcess.running = true
}
}
}
// Public functions
function getCpuInfo() {
@@ -215,11 +224,23 @@ Singleton {
}
function updateSystemStats() {
if (root.enabledForTopBar || root.enabledForDetailedView) {
cpuUsageProcess.running = true
memoryUsageProcess.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() {
if (cpuUsage > 80) return "#e74c3c" // Red

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -10,6 +10,9 @@ mkdir -p "$QS_DIR"
LINK="$QS_DIR/current_wallpaper"
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
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
# Notify running shell about wallpaper change (for dynamic theme updates)
NOTIFY_FILE="$QS_DIR/wallpaper_changed"
echo "$(date '+%s')" > "$NOTIFY_FILE"
echo "→ Shell notified: $NOTIFY_FILE"
# Notify running shell about wallpaper change via IPC
qs -c "DankMaterialShell" ipc call wallpaper refresh 2>/dev/null && echo "→ Shell notified via IPC" || echo "→ Shell not running or IPC failed"

View File

@@ -23,6 +23,11 @@ ShellRoot {
Component.onCompleted: {
// Make root accessible to Theme singleton for error handling
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
@@ -40,6 +45,17 @@ ShellRoot {
property MprisPlayer activePlayer: MprisController.activePlayer
property bool hasActiveMedia: activePlayer && (activePlayer.trackTitle || activePlayer.trackArtist)
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 powerMenuVisible: false
property bool powerConfirmVisible: false
@@ -165,16 +181,17 @@ ShellRoot {
// Weather configuration
// WiFi Auto-refresh Timer
Timer {
id: wifiAutoRefreshTimer
interval: 10000 // 10 seconds
interval: 20000
running: root.wifiAutoRefreshEnabled && root.controlCenterVisible
repeat: true
onTriggered: {
if (root.wifiAutoRefreshEnabled && root.controlCenterVisible) {
WifiService.scanWifi()
}
}
}
// WiFi Connection Status Timer
Timer {
@@ -375,4 +392,18 @@ ShellRoot {
ClipboardHistory {
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"
}
}
}