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:
@@ -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() {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
audioSinkLister.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
|
||||
audioSourceLister.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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
updateSystemInfo()
|
||||
updateProcessList()
|
||||
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
|
||||
|
||||
@@ -28,11 +28,14 @@ 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...")
|
||||
getCpuInfo()
|
||||
@@ -176,12 +179,14 @@ Singleton {
|
||||
Timer {
|
||||
id: cpuTimer
|
||||
interval: root.cpuUpdateInterval
|
||||
running: true
|
||||
running: root.enabledForTopBar || root.enabledForDetailedView
|
||||
repeat: true
|
||||
|
||||
onTriggered: {
|
||||
cpuUsageProcess.running = true
|
||||
cpuFrequencyProcess.running = true
|
||||
if (root.enabledForTopBar || root.enabledForDetailedView) {
|
||||
cpuUsageProcess.running = true
|
||||
cpuFrequencyProcess.running = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,11 +194,13 @@ Singleton {
|
||||
Timer {
|
||||
id: memoryTimer
|
||||
interval: root.memoryUpdateInterval
|
||||
running: true
|
||||
running: root.enabledForTopBar || root.enabledForDetailedView
|
||||
repeat: true
|
||||
|
||||
onTriggered: {
|
||||
memoryUsageProcess.running = true
|
||||
if (root.enabledForTopBar || root.enabledForDetailedView) {
|
||||
memoryUsageProcess.running = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,11 +208,13 @@ Singleton {
|
||||
Timer {
|
||||
id: temperatureTimer
|
||||
interval: root.temperatureUpdateInterval
|
||||
running: true
|
||||
running: root.enabledForDetailedView
|
||||
repeat: true
|
||||
|
||||
onTriggered: {
|
||||
temperatureProcess.running = true
|
||||
if (root.enabledForDetailedView) {
|
||||
temperatureProcess.running = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,10 +224,22 @@ Singleton {
|
||||
}
|
||||
|
||||
function updateSystemStats() {
|
||||
cpuUsageProcess.running = true
|
||||
memoryUsageProcess.running = true
|
||||
cpuFrequencyProcess.running = true
|
||||
temperatureProcess.running = true
|
||||
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() {
|
||||
@@ -245,4 +266,4 @@ Singleton {
|
||||
if (cpuTemperature > 65) return "#f39c12" // Orange
|
||||
return "#27ae60" // Green
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ PanelWindow {
|
||||
radius: parent.radius
|
||||
|
||||
SequentialAnimation on opacity {
|
||||
running: true
|
||||
running: root.calendarVisible
|
||||
loops: Animation.Infinite
|
||||
NumberAnimation {
|
||||
to: 0.08
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -121,7 +121,7 @@ PanelWindow {
|
||||
radius: parent.radius
|
||||
|
||||
SequentialAnimation on opacity {
|
||||
running: true
|
||||
running: false
|
||||
loops: Animation.Infinite
|
||||
NumberAnimation {
|
||||
to: 0.08
|
||||
|
||||
@@ -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"
|
||||
37
shell.qml
37
shell.qml
@@ -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,14 +181,15 @@ ShellRoot {
|
||||
// Weather configuration
|
||||
|
||||
|
||||
// WiFi Auto-refresh Timer
|
||||
Timer {
|
||||
id: wifiAutoRefreshTimer
|
||||
interval: 10000 // 10 seconds
|
||||
interval: 20000
|
||||
running: root.wifiAutoRefreshEnabled && root.controlCenterVisible
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
WifiService.scanWifi()
|
||||
if (root.wifiAutoRefreshEnabled && root.controlCenterVisible) {
|
||||
WifiService.scanWifi()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user