mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-05 21:15:38 -05:00
gamma/nightmode: use dms V6 implementation - Scraps gammastep depednency
This commit is contained in:
1
.github/workflows/copr-release.yml
vendored
1
.github/workflows/copr-release.yml
vendored
@@ -106,7 +106,6 @@ jobs:
|
|||||||
Recommends: hyprpicker
|
Recommends: hyprpicker
|
||||||
Recommends: matugen
|
Recommends: matugen
|
||||||
Recommends: wl-clipboard
|
Recommends: wl-clipboard
|
||||||
Recommends: gammastep
|
|
||||||
Recommends: NetworkManager
|
Recommends: NetworkManager
|
||||||
Recommends: qt6-qtmultimedia
|
Recommends: qt6-qtmultimedia
|
||||||
Suggests: qt6ct
|
Suggests: qt6ct
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ Singleton {
|
|||||||
property int nightModeEndMinute: 0
|
property int nightModeEndMinute: 0
|
||||||
property real latitude: 0.0
|
property real latitude: 0.0
|
||||||
property real longitude: 0.0
|
property real longitude: 0.0
|
||||||
|
property bool nightModeUseIPLocation: false
|
||||||
property string nightModeLocationProvider: ""
|
property string nightModeLocationProvider: ""
|
||||||
|
|
||||||
property var pinnedApps: []
|
property var pinnedApps: []
|
||||||
@@ -112,6 +113,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
latitude = settings.latitude !== undefined ? settings.latitude : 0.0
|
latitude = settings.latitude !== undefined ? settings.latitude : 0.0
|
||||||
longitude = settings.longitude !== undefined ? settings.longitude : 0.0
|
longitude = settings.longitude !== undefined ? settings.longitude : 0.0
|
||||||
|
nightModeUseIPLocation = settings.nightModeUseIPLocation !== undefined ? settings.nightModeUseIPLocation : false
|
||||||
nightModeLocationProvider = settings.nightModeLocationProvider !== undefined ? settings.nightModeLocationProvider : ""
|
nightModeLocationProvider = settings.nightModeLocationProvider !== undefined ? settings.nightModeLocationProvider : ""
|
||||||
pinnedApps = settings.pinnedApps !== undefined ? settings.pinnedApps : []
|
pinnedApps = settings.pinnedApps !== undefined ? settings.pinnedApps : []
|
||||||
selectedGpuIndex = settings.selectedGpuIndex !== undefined ? settings.selectedGpuIndex : 0
|
selectedGpuIndex = settings.selectedGpuIndex !== undefined ? settings.selectedGpuIndex : 0
|
||||||
@@ -171,6 +173,7 @@ Singleton {
|
|||||||
"nightModeEndMinute": nightModeEndMinute,
|
"nightModeEndMinute": nightModeEndMinute,
|
||||||
"latitude": latitude,
|
"latitude": latitude,
|
||||||
"longitude": longitude,
|
"longitude": longitude,
|
||||||
|
"nightModeUseIPLocation": nightModeUseIPLocation,
|
||||||
"nightModeLocationProvider": nightModeLocationProvider,
|
"nightModeLocationProvider": nightModeLocationProvider,
|
||||||
"pinnedApps": pinnedApps,
|
"pinnedApps": pinnedApps,
|
||||||
"selectedGpuIndex": selectedGpuIndex,
|
"selectedGpuIndex": selectedGpuIndex,
|
||||||
@@ -536,6 +539,11 @@ Singleton {
|
|||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setNightModeUseIPLocation(use) {
|
||||||
|
nightModeUseIPLocation = use
|
||||||
|
saveSettings()
|
||||||
|
}
|
||||||
|
|
||||||
function setLatitude(lat) {
|
function setLatitude(lat) {
|
||||||
console.log("SessionData: Setting latitude to", lat)
|
console.log("SessionData: Setting latitude to", lat)
|
||||||
latitude = lat
|
latitude = lat
|
||||||
|
|||||||
@@ -116,8 +116,9 @@ Item {
|
|||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: I18n.tr("Night Mode")
|
text: I18n.tr("Night Mode")
|
||||||
description: I18n.tr("Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.")
|
description: DisplayService.gammaControlAvailable ? I18n.tr("Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.") : I18n.tr("Gamma control not available. Requires DMS API v6+.")
|
||||||
checked: DisplayService.nightModeEnabled
|
checked: DisplayService.nightModeEnabled
|
||||||
|
enabled: DisplayService.gammaControlAvailable
|
||||||
onToggled: checked => {
|
onToggled: checked => {
|
||||||
DisplayService.toggleNightMode()
|
DisplayService.toggleNightMode()
|
||||||
}
|
}
|
||||||
@@ -136,6 +137,7 @@ Item {
|
|||||||
spacing: 0
|
spacing: 0
|
||||||
leftPadding: Theme.spacingM
|
leftPadding: Theme.spacingM
|
||||||
rightPadding: Theme.spacingM
|
rightPadding: Theme.spacingM
|
||||||
|
visible: DisplayService.gammaControlAvailable
|
||||||
|
|
||||||
DankDropdown {
|
DankDropdown {
|
||||||
width: parent.width - parent.leftPadding - parent.rightPadding
|
width: parent.width - parent.leftPadding - parent.rightPadding
|
||||||
@@ -162,6 +164,7 @@ Item {
|
|||||||
text: I18n.tr("Automatic Control")
|
text: I18n.tr("Automatic Control")
|
||||||
description: I18n.tr("Only adjust gamma based on time or location rules.")
|
description: I18n.tr("Only adjust gamma based on time or location rules.")
|
||||||
checked: SessionData.nightModeAutoEnabled
|
checked: SessionData.nightModeAutoEnabled
|
||||||
|
visible: DisplayService.gammaControlAvailable
|
||||||
onToggled: checked => {
|
onToggled: checked => {
|
||||||
if (checked && !DisplayService.nightModeEnabled) {
|
if (checked && !DisplayService.nightModeEnabled) {
|
||||||
DisplayService.toggleNightMode()
|
DisplayService.toggleNightMode()
|
||||||
@@ -183,7 +186,7 @@ Item {
|
|||||||
id: automaticSettings
|
id: automaticSettings
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
visible: SessionData.nightModeAutoEnabled
|
visible: SessionData.nightModeAutoEnabled && DisplayService.gammaControlAvailable
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: SessionData
|
target: SessionData
|
||||||
@@ -360,27 +363,28 @@ Item {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
DankToggle {
|
DankToggle {
|
||||||
|
id: ipLocationToggle
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: I18n.tr("Auto-location")
|
text: I18n.tr("Use IP Location")
|
||||||
description: DisplayService.geoclueAvailable ? I18n.tr("Use automatic location detection (geoclue2)") : I18n.tr("Geoclue service not running - cannot auto-detect location")
|
description: I18n.tr("Automatically detect location based on IP address")
|
||||||
checked: SessionData.nightModeLocationProvider === "geoclue2"
|
checked: SessionData.nightModeUseIPLocation || false
|
||||||
enabled: DisplayService.geoclueAvailable
|
|
||||||
onToggled: checked => {
|
onToggled: checked => {
|
||||||
if (checked && DisplayService.geoclueAvailable) {
|
SessionData.setNightModeUseIPLocation(checked)
|
||||||
SessionData.setNightModeLocationProvider("geoclue2")
|
}
|
||||||
SessionData.setLatitude(0.0)
|
|
||||||
SessionData.setLongitude(0.0)
|
Connections {
|
||||||
} else {
|
target: SessionData
|
||||||
SessionData.setNightModeLocationProvider("")
|
function onNightModeUseIPLocationChanged() {
|
||||||
}
|
ipLocationToggle.checked = SessionData.nightModeUseIPLocation
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
visible: SessionData.nightModeLocationProvider !== "geoclue2"
|
|
||||||
leftPadding: Theme.spacingM
|
leftPadding: Theme.spacingM
|
||||||
|
visible: !SessionData.nightModeUseIPLocation
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: I18n.tr("Manual Coordinates")
|
text: I18n.tr("Manual Coordinates")
|
||||||
|
|||||||
@@ -333,7 +333,6 @@ sudo sh -c "curl -L https://github.com/AvengeMedia/dgop/releases/latest/download
|
|||||||
- `wl-clipboard`: Required for copying various elements to clipboard.
|
- `wl-clipboard`: Required for copying various elements to clipboard.
|
||||||
- `cava`: Audio visualizer
|
- `cava`: Audio visualizer
|
||||||
- `cliphist`: Clipboard history
|
- `cliphist`: Clipboard history
|
||||||
- `gammastep`: Night mode support
|
|
||||||
- `qt6-multimedia`: System sound support
|
- `qt6-multimedia`: System sound support
|
||||||
|
|
||||||
## Compositor Configuration
|
## Compositor Configuration
|
||||||
|
|||||||
@@ -38,13 +38,8 @@ Singleton {
|
|||||||
|
|
||||||
property bool nightModeEnabled: false
|
property bool nightModeEnabled: false
|
||||||
property bool automationAvailable: false
|
property bool automationAvailable: false
|
||||||
property bool geoclueAvailable: false
|
property bool gammaControlAvailable: false
|
||||||
property bool isAutomaticNightTime: false
|
readonly property int dayTemp: 6500
|
||||||
|
|
||||||
function buildGammastepCommand(gammastepArgs) {
|
|
||||||
const commandStr = "pkill gammastep; " + ["gammastep"].concat(gammastepArgs).join(" ")
|
|
||||||
return ["sh", "-c", commandStr]
|
|
||||||
}
|
|
||||||
|
|
||||||
function setBrightnessInternal(percentage, device) {
|
function setBrightnessInternal(percentage, device) {
|
||||||
const clampedValue = Math.max(1, Math.min(100, percentage))
|
const clampedValue = Math.max(1, Math.min(100, percentage))
|
||||||
@@ -216,34 +211,49 @@ Singleton {
|
|||||||
|
|
||||||
// Night Mode Functions - Simplified
|
// Night Mode Functions - Simplified
|
||||||
function enableNightMode() {
|
function enableNightMode() {
|
||||||
if (!automationAvailable) {
|
if (!gammaControlAvailable) {
|
||||||
gammaStepTestProcess.running = true
|
ToastService.showWarning("Night mode failed: DMS gamma control not available")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
nightModeEnabled = true
|
nightModeEnabled = true
|
||||||
SessionData.setNightModeEnabled(true)
|
SessionData.setNightModeEnabled(true)
|
||||||
|
|
||||||
// Apply immediately or start automation
|
DMSService.sendRequest("wayland.gamma.setEnabled", {
|
||||||
if (SessionData.nightModeAutoEnabled) {
|
"enabled": true
|
||||||
startAutomation()
|
}, response => {
|
||||||
} else {
|
if (response.error) {
|
||||||
applyNightModeDirectly()
|
console.error("DisplayService: Failed to enable gamma control:", response.error)
|
||||||
}
|
ToastService.showError("Failed to enable night mode: " + response.error)
|
||||||
|
nightModeEnabled = false
|
||||||
|
SessionData.setNightModeEnabled(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SessionData.nightModeAutoEnabled) {
|
||||||
|
startAutomation()
|
||||||
|
} else {
|
||||||
|
applyNightModeDirectly()
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function disableNightMode() {
|
function disableNightMode() {
|
||||||
nightModeEnabled = false
|
nightModeEnabled = false
|
||||||
SessionData.setNightModeEnabled(false)
|
SessionData.setNightModeEnabled(false)
|
||||||
stopAutomation()
|
|
||||||
// Nuclear approach - kill ALL gammastep processes multiple times
|
if (!gammaControlAvailable) {
|
||||||
Quickshell.execDetached(["pkill", "-f", "gammastep"])
|
return
|
||||||
Quickshell.execDetached(["pkill", "-9", "gammastep"])
|
}
|
||||||
Quickshell.execDetached(["killall", "gammastep"])
|
|
||||||
// Also stop all related processes
|
DMSService.sendRequest("wayland.gamma.setEnabled", {
|
||||||
gammaStepProcess.running = false
|
"enabled": false
|
||||||
automationProcess.running = false
|
}, response => {
|
||||||
gammaStepTestProcess.running = false
|
if (response.error) {
|
||||||
|
console.error("DisplayService: Failed to disable gamma control:", response.error)
|
||||||
|
ToastService.showError("Failed to disable night mode: " + response.error)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleNightMode() {
|
function toggleNightMode() {
|
||||||
@@ -255,14 +265,35 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function applyNightModeDirectly() {
|
function applyNightModeDirectly() {
|
||||||
const temperature = SessionData.nightModeTemperature || 4500
|
const temperature = SessionData.nightModeTemperature || 4000
|
||||||
gammaStepProcess.command = buildGammastepCommand(["-m", "wayland", "-O", String(temperature)])
|
|
||||||
gammaStepProcess.running = true
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetToNormalMode() {
|
DMSService.sendRequest("wayland.gamma.setManualTimes", {
|
||||||
// Just kill gammastep to return to normal display temperature
|
"sunrise": null,
|
||||||
Quickshell.execDetached(["pkill", "gammastep"])
|
"sunset": null
|
||||||
|
}, response => {
|
||||||
|
if (response.error) {
|
||||||
|
console.error("DisplayService: Failed to clear manual times:", response.error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
DMSService.sendRequest("wayland.gamma.setUseIPLocation", {
|
||||||
|
"use": false
|
||||||
|
}, response => {
|
||||||
|
if (response.error) {
|
||||||
|
console.error("DisplayService: Failed to disable IP location:", response.error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
DMSService.sendRequest("wayland.gamma.setTemperature", {
|
||||||
|
"temp": temperature
|
||||||
|
}, response => {
|
||||||
|
if (response.error) {
|
||||||
|
console.error("DisplayService: Failed to set temperature:", response.error)
|
||||||
|
ToastService.showError("Failed to set night mode temperature: " + response.error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function startAutomation() {
|
function startAutomation() {
|
||||||
@@ -282,70 +313,103 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopAutomation() {
|
|
||||||
automationProcess.running = false
|
|
||||||
gammaStepProcess.running = false
|
|
||||||
isAutomaticNightTime = false
|
|
||||||
// Nuclear approach - kill ALL gammastep processes multiple times
|
|
||||||
Quickshell.execDetached(["pkill", "-f", "gammastep"])
|
|
||||||
Quickshell.execDetached(["pkill", "-9", "gammastep"])
|
|
||||||
Quickshell.execDetached(["killall", "gammastep"])
|
|
||||||
}
|
|
||||||
|
|
||||||
function startTimeBasedMode() {
|
function startTimeBasedMode() {
|
||||||
checkTimeBasedMode()
|
const temperature = SessionData.nightModeTemperature || 4000
|
||||||
|
const sunriseHour = SessionData.nightModeEndHour
|
||||||
|
const sunriseMinute = SessionData.nightModeEndMinute
|
||||||
|
const sunsetHour = SessionData.nightModeStartHour
|
||||||
|
const sunsetMinute = SessionData.nightModeStartMinute
|
||||||
|
|
||||||
|
const sunrise = `${String(sunriseHour).padStart(2, '0')}:${String(sunriseMinute).padStart(2, '0')}`
|
||||||
|
const sunset = `${String(sunsetHour).padStart(2, '0')}:${String(sunsetMinute).padStart(2, '0')}`
|
||||||
|
|
||||||
|
DMSService.sendRequest("wayland.gamma.setUseIPLocation", {
|
||||||
|
"use": false
|
||||||
|
}, response => {
|
||||||
|
if (response.error) {
|
||||||
|
console.error("DisplayService: Failed to disable IP location:", response.error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
DMSService.sendRequest("wayland.gamma.setTemperature", {
|
||||||
|
"low": temperature,
|
||||||
|
"high": dayTemp
|
||||||
|
}, response => {
|
||||||
|
if (response.error) {
|
||||||
|
console.error("DisplayService: Failed to set temperature:", response.error)
|
||||||
|
ToastService.showError("Failed to set night mode temperature: " + response.error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
DMSService.sendRequest("wayland.gamma.setManualTimes", {
|
||||||
|
"sunrise": sunrise,
|
||||||
|
"sunset": sunset
|
||||||
|
}, response => {
|
||||||
|
if (response.error) {
|
||||||
|
console.error("DisplayService: Failed to set manual times:", response.error)
|
||||||
|
ToastService.showError("Failed to set night mode schedule: " + response.error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function startLocationBasedMode() {
|
function startLocationBasedMode() {
|
||||||
const temperature = SessionData.nightModeTemperature || 4500
|
const temperature = SessionData.nightModeTemperature || 4000
|
||||||
const dayTemp = 6500
|
const dayTemp = 6500
|
||||||
|
|
||||||
if (SessionData.latitude !== 0.0 && SessionData.longitude !== 0.0) {
|
DMSService.sendRequest("wayland.gamma.setManualTimes", {
|
||||||
automationProcess.command = buildGammastepCommand(["-m", "wayland", "-l", `${SessionData.latitude.toFixed(6)}:${SessionData.longitude.toFixed(6)}`, "-t", `${dayTemp}:${temperature}`, "-v"])
|
"sunrise": null,
|
||||||
automationProcess.running = true
|
"sunset": null
|
||||||
return
|
}, response => {
|
||||||
}
|
if (response.error) {
|
||||||
|
console.error("DisplayService: Failed to clear manual times:", response.error)
|
||||||
if (SessionData.nightModeLocationProvider === "geoclue2") {
|
return
|
||||||
automationProcess.command = buildGammastepCommand(["-m", "wayland", "-l", "geoclue2", "-t", `${dayTemp}:${temperature}`, "-v"])
|
|
||||||
automationProcess.running = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
console.warn("DisplayService: Location mode selected but no coordinates or geoclue provider set")
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkTimeBasedMode() {
|
|
||||||
if (!nightModeEnabled || !SessionData.nightModeAutoEnabled || SessionData.nightModeAutoMode !== "time") {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentTime = systemClock.hours * 60 + systemClock.minutes
|
|
||||||
|
|
||||||
const startMinutes = SessionData.nightModeStartHour * 60 + SessionData.nightModeStartMinute
|
|
||||||
const endMinutes = SessionData.nightModeEndHour * 60 + SessionData.nightModeEndMinute
|
|
||||||
|
|
||||||
let shouldBeNight = false
|
|
||||||
|
|
||||||
if (startMinutes > endMinutes) {
|
|
||||||
shouldBeNight = (currentTime >= startMinutes) || (currentTime < endMinutes)
|
|
||||||
} else {
|
|
||||||
shouldBeNight = (currentTime >= startMinutes) && (currentTime < endMinutes)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldBeNight !== isAutomaticNightTime) {
|
|
||||||
isAutomaticNightTime = shouldBeNight
|
|
||||||
|
|
||||||
if (shouldBeNight) {
|
|
||||||
applyNightModeDirectly()
|
|
||||||
} else {
|
|
||||||
resetToNormalMode()
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function detectLocationProviders() {
|
DMSService.sendRequest("wayland.gamma.setTemperature", {
|
||||||
geoclueDetectionProcess.running = true
|
"low": temperature,
|
||||||
|
"high": dayTemp
|
||||||
|
}, response => {
|
||||||
|
if (response.error) {
|
||||||
|
console.error("DisplayService: Failed to set temperature:", response.error)
|
||||||
|
ToastService.showError("Failed to set night mode temperature: " + response.error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SessionData.nightModeUseIPLocation) {
|
||||||
|
DMSService.sendRequest("wayland.gamma.setUseIPLocation", {
|
||||||
|
"use": true
|
||||||
|
}, response => {
|
||||||
|
if (response.error) {
|
||||||
|
console.error("DisplayService: Failed to enable IP location:", response.error)
|
||||||
|
ToastService.showError("Failed to enable IP location: " + response.error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (SessionData.latitude !== 0.0 && SessionData.longitude !== 0.0) {
|
||||||
|
DMSService.sendRequest("wayland.gamma.setUseIPLocation", {
|
||||||
|
"use": false
|
||||||
|
}, response => {
|
||||||
|
if (response.error) {
|
||||||
|
console.error("DisplayService: Failed to disable IP location:", response.error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
DMSService.sendRequest("wayland.gamma.setLocation", {
|
||||||
|
"latitude": SessionData.latitude,
|
||||||
|
"longitude": SessionData.longitude
|
||||||
|
}, response => {
|
||||||
|
if (response.error) {
|
||||||
|
console.error("DisplayService: Failed to set location:", response.error)
|
||||||
|
ToastService.showError("Failed to set night mode location: " + response.error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.warn("DisplayService: Location mode selected but no coordinates set and IP location disabled")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function setNightModeAutomationMode(mode) {
|
function setNightModeAutomationMode(mode) {
|
||||||
@@ -353,9 +417,6 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function evaluateNightMode() {
|
function evaluateNightMode() {
|
||||||
// Always stop all processes first to clean slate
|
|
||||||
stopAutomation()
|
|
||||||
|
|
||||||
if (!nightModeEnabled) {
|
if (!nightModeEnabled) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -369,8 +430,50 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkNightModeAvailability() {
|
function checkGammaControlAvailability() {
|
||||||
gammastepAvailabilityProcess.running = true
|
if (!DMSService.isConnected) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DMSService.apiVersion < 6) {
|
||||||
|
gammaControlAvailable = false
|
||||||
|
automationAvailable = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DMSService.capabilities.includes("gamma")) {
|
||||||
|
gammaControlAvailable = false
|
||||||
|
automationAvailable = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
DMSService.sendRequest("wayland.gamma.getState", null, response => {
|
||||||
|
if (response.error) {
|
||||||
|
gammaControlAvailable = false
|
||||||
|
automationAvailable = false
|
||||||
|
console.error("DisplayService: Gamma control not available:", response.error)
|
||||||
|
} else {
|
||||||
|
gammaControlAvailable = true
|
||||||
|
automationAvailable = true
|
||||||
|
|
||||||
|
if (nightModeEnabled) {
|
||||||
|
DMSService.sendRequest("wayland.gamma.setEnabled", {
|
||||||
|
"enabled": true
|
||||||
|
}, enableResponse => {
|
||||||
|
if (enableResponse.error) {
|
||||||
|
console.error("DisplayService: Failed to enable gamma control on startup:", enableResponse.error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SessionData.nightModeAutoEnabled) {
|
||||||
|
startAutomation()
|
||||||
|
} else {
|
||||||
|
applyNightModeDirectly()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
@@ -392,27 +495,9 @@ Singleton {
|
|||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
ddcDetectionProcess.running = true
|
ddcDetectionProcess.running = true
|
||||||
refreshDevices()
|
refreshDevices()
|
||||||
checkNightModeAvailability()
|
|
||||||
|
|
||||||
// Initialize night mode state from session
|
|
||||||
nightModeEnabled = SessionData.nightModeEnabled
|
nightModeEnabled = SessionData.nightModeEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onDestruction: {
|
|
||||||
gammaStepProcess.running = false
|
|
||||||
automationProcess.running = false
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemClock {
|
|
||||||
id: systemClock
|
|
||||||
precision: SystemClock.Minutes
|
|
||||||
onDateChanged: {
|
|
||||||
if (nightModeEnabled && SessionData.nightModeAutoEnabled && SessionData.nightModeAutoMode === "time") {
|
|
||||||
checkTimeBasedMode()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: ddcDetectionProcess
|
id: ddcDetectionProcess
|
||||||
|
|
||||||
@@ -679,83 +764,20 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Connections {
|
||||||
id: gammastepAvailabilityProcess
|
target: DMSService
|
||||||
command: ["which", "gammastep"]
|
|
||||||
running: false
|
|
||||||
|
|
||||||
onExited: function (exitCode) {
|
function onConnectionStateChanged() {
|
||||||
automationAvailable = (exitCode === 0)
|
if (DMSService.isConnected) {
|
||||||
if (automationAvailable) {
|
checkGammaControlAvailability()
|
||||||
detectLocationProviders()
|
|
||||||
|
|
||||||
// If night mode should be enabled on startup
|
|
||||||
if (nightModeEnabled && SessionData.nightModeAutoEnabled) {
|
|
||||||
startAutomation()
|
|
||||||
} else if (nightModeEnabled) {
|
|
||||||
applyNightModeDirectly()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
console.log("DisplayService: gammastep not available")
|
gammaControlAvailable = false
|
||||||
|
automationAvailable = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
function onCapabilitiesReceived() {
|
||||||
id: geoclueDetectionProcess
|
checkGammaControlAvailability()
|
||||||
command: ["sh", "-c", "busctl --system list | grep -qF org.freedesktop.GeoClue2"]
|
|
||||||
running: false
|
|
||||||
|
|
||||||
onExited: function (exitCode) {
|
|
||||||
geoclueAvailable = (exitCode === 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
|
||||||
id: gammaStepTestProcess
|
|
||||||
command: ["which", "gammastep"]
|
|
||||||
running: false
|
|
||||||
|
|
||||||
onExited: function (exitCode) {
|
|
||||||
if (exitCode === 0) {
|
|
||||||
automationAvailable = true
|
|
||||||
nightModeEnabled = true
|
|
||||||
SessionData.setNightModeEnabled(true)
|
|
||||||
|
|
||||||
if (SessionData.nightModeAutoEnabled) {
|
|
||||||
startAutomation()
|
|
||||||
} else {
|
|
||||||
applyNightModeDirectly()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.warn("DisplayService: gammastep not found")
|
|
||||||
ToastService.showWarning("Night mode failed: gammastep not found")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
|
||||||
id: gammaStepProcess
|
|
||||||
running: false
|
|
||||||
|
|
||||||
onExited: function (exitCode) {
|
|
||||||
if (nightModeEnabled && exitCode !== 0 && exitCode !== 15) {
|
|
||||||
console.warn("DisplayService: Night mode process failed:", exitCode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
|
||||||
id: automationProcess
|
|
||||||
running: false
|
|
||||||
property string processType: "automation"
|
|
||||||
|
|
||||||
onExited: function (exitCode) {
|
|
||||||
if (nightModeEnabled && SessionData.nightModeAutoEnabled && exitCode !== 0 && exitCode !== 15) {
|
|
||||||
console.warn("DisplayService: Night mode automation failed:", exitCode)
|
|
||||||
// Location mode failed
|
|
||||||
console.warn("DisplayService: Location-based night mode failed")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -795,7 +817,7 @@ Singleton {
|
|||||||
function onLongitudeChanged() {
|
function onLongitudeChanged() {
|
||||||
evaluateNightMode()
|
evaluateNightMode()
|
||||||
}
|
}
|
||||||
function onNightModeLocationProviderChanged() {
|
function onNightModeUseIPLocationChanged() {
|
||||||
evaluateNightMode()
|
evaluateNightMode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1
dms.spec
1
dms.spec
@@ -43,7 +43,6 @@ Recommends: quickshell-git
|
|||||||
Recommends: wl-clipboard
|
Recommends: wl-clipboard
|
||||||
|
|
||||||
# Recommended system packages
|
# Recommended system packages
|
||||||
Recommends: gammastep
|
|
||||||
Recommends: NetworkManager
|
Recommends: NetworkManager
|
||||||
Recommends: qt6-qtmultimedia
|
Recommends: qt6-qtmultimedia
|
||||||
Suggests: qt6ct
|
Suggests: qt6ct
|
||||||
|
|||||||
@@ -151,7 +151,6 @@ in {
|
|||||||
++ lib.optionals cfg.enableClipboard [pkgs.cliphist pkgs.wl-clipboard]
|
++ lib.optionals cfg.enableClipboard [pkgs.cliphist pkgs.wl-clipboard]
|
||||||
++ lib.optionals cfg.enableVPN [pkgs.glib pkgs.networkmanager]
|
++ lib.optionals cfg.enableVPN [pkgs.glib pkgs.networkmanager]
|
||||||
++ lib.optional cfg.enableBrightnessControl pkgs.brightnessctl
|
++ lib.optional cfg.enableBrightnessControl pkgs.brightnessctl
|
||||||
++ lib.optional cfg.enableNightMode pkgs.gammastep
|
|
||||||
++ lib.optional cfg.enableDynamicTheming pkgs.matugen
|
++ lib.optional cfg.enableDynamicTheming pkgs.matugen
|
||||||
++ lib.optional cfg.enableAudioWavelength pkgs.cava
|
++ lib.optional cfg.enableAudioWavelength pkgs.cava
|
||||||
++ lib.optional cfg.enableCalendarEvents pkgs.khal
|
++ lib.optional cfg.enableCalendarEvents pkgs.khal
|
||||||
|
|||||||
@@ -386,7 +386,7 @@
|
|||||||
{
|
{
|
||||||
"term": "Back",
|
"term": "Back",
|
||||||
"context": "Back",
|
"context": "Back",
|
||||||
"reference": "Modules/DankBar/Widgets/SystemTrayBar.qml:454",
|
"reference": "Modules/DankBar/Widgets/SystemTrayBar.qml:467",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -860,7 +860,7 @@
|
|||||||
{
|
{
|
||||||
"term": "DEMO MODE - Click anywhere to exit",
|
"term": "DEMO MODE - Click anywhere to exit",
|
||||||
"context": "DEMO MODE - Click anywhere to exit",
|
"context": "DEMO MODE - Click anywhere to exit",
|
||||||
"reference": "Modules/Lock/LockScreenContent.qml:634",
|
"reference": "Modules/Lock/LockScreenContent.qml:628",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1187,6 +1187,18 @@
|
|||||||
"reference": "Modals/FileBrowser/FileInfo.qml:200",
|
"reference": "Modals/FileBrowser/FileInfo.qml:200",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Failed to set profile image",
|
||||||
|
"context": "Failed to set profile image",
|
||||||
|
"reference": "Services/PortalService.qml:150",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"term": "Failed to set profile image: ",
|
||||||
|
"context": "Failed to set profile image: ",
|
||||||
|
"reference": "Services/PortalService.qml:159",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Feels Like",
|
"term": "Feels Like",
|
||||||
"context": "Feels Like",
|
"context": "Feels Like",
|
||||||
@@ -2141,6 +2153,12 @@
|
|||||||
"reference": "Modules/Settings/DankBarTab.qml:88",
|
"reference": "Modules/Settings/DankBarTab.qml:88",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Permission denied to set profile image.",
|
||||||
|
"context": "Permission denied to set profile image.",
|
||||||
|
"reference": "Services/PortalService.qml:155",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Personalization",
|
"term": "Personalization",
|
||||||
"context": "Personalization",
|
"context": "Personalization",
|
||||||
@@ -2297,6 +2315,18 @@
|
|||||||
"reference": "Modules/ProcessList/ProcessListView.qml:41",
|
"reference": "Modules/ProcessList/ProcessListView.qml:41",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Profile Image Error",
|
||||||
|
"context": "Profile Image Error",
|
||||||
|
"reference": "Services/PortalService.qml:162",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"term": "Profile image is too large. Please use a smaller image.",
|
||||||
|
"context": "Profile image is too large. Please use a smaller image.",
|
||||||
|
"reference": "Services/PortalService.qml:153",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "QML, JavaScript, Go",
|
"term": "QML, JavaScript, Go",
|
||||||
"context": "QML, JavaScript, Go",
|
"context": "QML, JavaScript, Go",
|
||||||
@@ -2549,6 +2579,12 @@
|
|||||||
"reference": "Modules/Settings/PersonalizationTab.qml:930",
|
"reference": "Modules/Settings/PersonalizationTab.qml:930",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Selected image file not found.",
|
||||||
|
"context": "Selected image file not found.",
|
||||||
|
"reference": "Services/PortalService.qml:157",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Separator",
|
"term": "Separator",
|
||||||
"context": "Separator",
|
"context": "Separator",
|
||||||
|
|||||||
@@ -1385,6 +1385,20 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Failed to set profile image",
|
||||||
|
"translation": "",
|
||||||
|
"context": "",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"term": "Failed to set profile image: ",
|
||||||
|
"translation": "",
|
||||||
|
"context": "",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Feels Like",
|
"term": "Feels Like",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -2498,6 +2512,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Permission denied to set profile image.",
|
||||||
|
"translation": "",
|
||||||
|
"context": "",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Personalization",
|
"term": "Personalization",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -2680,6 +2701,20 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Profile Image Error",
|
||||||
|
"translation": "",
|
||||||
|
"context": "",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"term": "Profile image is too large. Please use a smaller image.",
|
||||||
|
"translation": "",
|
||||||
|
"context": "",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "QML, JavaScript, Go",
|
"term": "QML, JavaScript, Go",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
@@ -2974,6 +3009,13 @@
|
|||||||
"reference": "",
|
"reference": "",
|
||||||
"comment": ""
|
"comment": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"term": "Selected image file not found.",
|
||||||
|
"translation": "",
|
||||||
|
"context": "",
|
||||||
|
"reference": "",
|
||||||
|
"comment": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"term": "Separator",
|
"term": "Separator",
|
||||||
"translation": "",
|
"translation": "",
|
||||||
|
|||||||
Reference in New Issue
Block a user