mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 21:42:51 -05:00
Initial commit for nightMode automation
This commit is contained in:
@@ -18,6 +18,12 @@ Singleton {
|
||||
property bool doNotDisturb: false
|
||||
property bool nightModeEnabled: false
|
||||
property int nightModeTemperature: 4500
|
||||
property bool nightModeAutoEnabled: false
|
||||
property string nightModeAutoMode: "manual"
|
||||
property string nightModeStartTime: "20:00"
|
||||
property string nightModeEndTime: "06:00"
|
||||
property real latitude: 0.0
|
||||
property real longitude: 0.0
|
||||
property var pinnedApps: []
|
||||
property int selectedGpuIndex: 0
|
||||
property bool nvidiaGpuTempEnabled: false
|
||||
@@ -52,6 +58,16 @@ Singleton {
|
||||
!== undefined ? settings.nightModeEnabled : false
|
||||
nightModeTemperature = settings.nightModeTemperature
|
||||
!== undefined ? settings.nightModeTemperature : 4500
|
||||
nightModeAutoEnabled = settings.nightModeAutoEnabled
|
||||
!== undefined ? settings.nightModeAutoEnabled : false
|
||||
nightModeAutoMode = settings.nightModeAutoMode
|
||||
!== undefined ? settings.nightModeAutoMode : "manual"
|
||||
nightModeStartTime = settings.nightModeStartTime
|
||||
!== undefined ? settings.nightModeStartTime : "20:00"
|
||||
nightModeEndTime = settings.nightModeEndTime
|
||||
!== undefined ? settings.nightModeEndTime : "06:00"
|
||||
latitude = settings.latitude !== undefined ? settings.latitude : 0.0
|
||||
longitude = settings.longitude !== undefined ? settings.longitude : 0.0
|
||||
pinnedApps = settings.pinnedApps !== undefined ? settings.pinnedApps : []
|
||||
selectedGpuIndex = settings.selectedGpuIndex
|
||||
!== undefined ? settings.selectedGpuIndex : 0
|
||||
@@ -86,6 +102,12 @@ Singleton {
|
||||
"doNotDisturb": doNotDisturb,
|
||||
"nightModeEnabled": nightModeEnabled,
|
||||
"nightModeTemperature": nightModeTemperature,
|
||||
"nightModeAutoEnabled": nightModeAutoEnabled,
|
||||
"nightModeAutoMode": nightModeAutoMode,
|
||||
"nightModeStartTime": nightModeStartTime,
|
||||
"nightModeEndTime": nightModeEndTime,
|
||||
"latitude": latitude,
|
||||
"longitude": longitude,
|
||||
"pinnedApps": pinnedApps,
|
||||
"selectedGpuIndex": selectedGpuIndex,
|
||||
"nvidiaGpuTempEnabled": nvidiaGpuTempEnabled,
|
||||
@@ -119,6 +141,39 @@ Singleton {
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
function setNightModeAutoEnabled(enabled) {
|
||||
console.log("SessionData: Setting nightModeAutoEnabled to", enabled)
|
||||
nightModeAutoEnabled = enabled
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
function setNightModeAutoMode(mode) {
|
||||
nightModeAutoMode = mode
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
function setNightModeStartTime(time) {
|
||||
nightModeStartTime = time
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
function setNightModeEndTime(time) {
|
||||
nightModeEndTime = time
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
function setLatitude(lat) {
|
||||
console.log("SessionData: Setting latitude to", lat)
|
||||
latitude = lat
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
function setLongitude(lng) {
|
||||
console.log("SessionData: Setting longitude to", lng)
|
||||
longitude = lng
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
function setWallpaperPath(path) {
|
||||
wallpaperPath = path
|
||||
saveSettings()
|
||||
|
||||
@@ -762,9 +762,9 @@ DankPopout {
|
||||
implicitHeight: {
|
||||
let height = Theme.spacingL
|
||||
|
||||
if (BrightnessService.brightnessAvailable) {
|
||||
if (DisplayService.brightnessAvailable) {
|
||||
height += 80
|
||||
if (BrightnessService.devices.length > 1) {
|
||||
if (DisplayService.devices.length > 1) {
|
||||
height += 40
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,9 @@ Item {
|
||||
width: parent.width
|
||||
sourceComponent: settingsComponent
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Component {
|
||||
@@ -43,7 +45,7 @@ Item {
|
||||
Column {
|
||||
width: parent.width
|
||||
spacing: Theme.spacingS
|
||||
visible: BrightnessService.brightnessAvailable
|
||||
visible: DisplayService.brightnessAvailable
|
||||
|
||||
StyledText {
|
||||
text: "Brightness"
|
||||
@@ -54,102 +56,105 @@ Item {
|
||||
|
||||
DankDropdown {
|
||||
id: deviceDropdown
|
||||
|
||||
width: parent.width
|
||||
height: 40
|
||||
visible: BrightnessService.devices.length > 1
|
||||
visible: DisplayService.devices.length > 1
|
||||
text: "Device"
|
||||
description: {
|
||||
const deviceInfo = BrightnessService.getCurrentDeviceInfo()
|
||||
if (deviceInfo && deviceInfo.class === "ddc") {
|
||||
return "DDC changes can be slow and unreliable"
|
||||
}
|
||||
return ""
|
||||
const deviceInfo = DisplayService.getCurrentDeviceInfo();
|
||||
if (deviceInfo && deviceInfo.class === "ddc")
|
||||
return "DDC changes can be slow and unreliable";
|
||||
|
||||
return "";
|
||||
}
|
||||
currentValue: BrightnessService.currentDevice
|
||||
options: BrightnessService.devices.map(function (d) {
|
||||
return d.name
|
||||
currentValue: DisplayService.currentDevice
|
||||
options: DisplayService.devices.map(function(d) {
|
||||
return d.name;
|
||||
})
|
||||
optionIcons: BrightnessService.devices.map(function (d) {
|
||||
optionIcons: DisplayService.devices.map(function(d) {
|
||||
if (d.class === "backlight")
|
||||
return "desktop_windows"
|
||||
return "desktop_windows";
|
||||
|
||||
if (d.class === "ddc")
|
||||
return "tv"
|
||||
return "tv";
|
||||
|
||||
if (d.name.includes("kbd"))
|
||||
return "keyboard"
|
||||
return "keyboard";
|
||||
|
||||
return "lightbulb"
|
||||
return "lightbulb";
|
||||
})
|
||||
onValueChanged: function (value) {
|
||||
BrightnessService.setCurrentDevice(value, true)
|
||||
onValueChanged: function(value) {
|
||||
DisplayService.setCurrentDevice(value, true);
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: BrightnessService
|
||||
function onDevicesChanged() {
|
||||
if (BrightnessService.currentDevice) {
|
||||
deviceDropdown.currentValue = BrightnessService.currentDevice
|
||||
}
|
||||
if (DisplayService.currentDevice)
|
||||
deviceDropdown.currentValue = DisplayService.currentDevice;
|
||||
|
||||
// Check if saved device is now available
|
||||
const lastDevice = SessionData.lastBrightnessDevice
|
||||
|| ""
|
||||
const lastDevice = SessionData.lastBrightnessDevice || "";
|
||||
if (lastDevice) {
|
||||
const deviceExists = BrightnessService.devices.some(
|
||||
d => d.name === lastDevice)
|
||||
if (deviceExists
|
||||
&& (!BrightnessService.currentDevice
|
||||
|| BrightnessService.currentDevice !== lastDevice)) {
|
||||
BrightnessService.setCurrentDevice(lastDevice,
|
||||
false)
|
||||
}
|
||||
const deviceExists = DisplayService.devices.some((d) => {
|
||||
return d.name === lastDevice;
|
||||
});
|
||||
if (deviceExists && (!DisplayService.currentDevice || DisplayService.currentDevice !== lastDevice))
|
||||
DisplayService.setCurrentDevice(lastDevice, false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function onDeviceSwitched() {
|
||||
// Force update the description when device switches
|
||||
deviceDropdown.description = Qt.binding(function () {
|
||||
const deviceInfo = BrightnessService.getCurrentDeviceInfo()
|
||||
if (deviceInfo && deviceInfo.class === "ddc") {
|
||||
return "DDC changes can be slow and unreliable"
|
||||
}
|
||||
return ""
|
||||
})
|
||||
deviceDropdown.description = Qt.binding(function() {
|
||||
const deviceInfo = DisplayService.getCurrentDeviceInfo();
|
||||
if (deviceInfo && deviceInfo.class === "ddc")
|
||||
return "DDC changes can be slow and unreliable";
|
||||
|
||||
return "";
|
||||
});
|
||||
}
|
||||
|
||||
target: DisplayService
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DankSlider {
|
||||
id: brightnessSlider
|
||||
|
||||
width: parent.width
|
||||
value: BrightnessService.brightnessLevel
|
||||
value: DisplayService.brightnessLevel
|
||||
leftIcon: "brightness_low"
|
||||
rightIcon: "brightness_high"
|
||||
enabled: BrightnessService.brightnessAvailable
|
||||
&& BrightnessService.isCurrentDeviceReady()
|
||||
opacity: BrightnessService.isCurrentDeviceReady() ? 1.0 : 0.5
|
||||
onSliderValueChanged: function (newValue) {
|
||||
brightnessDebounceTimer.pendingValue = newValue
|
||||
brightnessDebounceTimer.restart()
|
||||
enabled: DisplayService.brightnessAvailable && DisplayService.isCurrentDeviceReady()
|
||||
opacity: DisplayService.isCurrentDeviceReady() ? 1 : 0.5
|
||||
onSliderValueChanged: function(newValue) {
|
||||
brightnessDebounceTimer.pendingValue = newValue;
|
||||
brightnessDebounceTimer.restart();
|
||||
}
|
||||
onSliderDragFinished: function (finalValue) {
|
||||
brightnessDebounceTimer.stop()
|
||||
BrightnessService.setBrightnessInternal(
|
||||
finalValue, BrightnessService.currentDevice)
|
||||
onSliderDragFinished: function(finalValue) {
|
||||
brightnessDebounceTimer.stop();
|
||||
DisplayService.setBrightnessInternal(finalValue, DisplayService.currentDevice);
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: BrightnessService
|
||||
function onBrightnessChanged() {
|
||||
brightnessSlider.value = BrightnessService.brightnessLevel
|
||||
brightnessSlider.value = DisplayService.brightnessLevel;
|
||||
}
|
||||
|
||||
function onDeviceSwitched() {
|
||||
brightnessSlider.value = BrightnessService.brightnessLevel
|
||||
brightnessSlider.value = DisplayService.brightnessLevel;
|
||||
}
|
||||
|
||||
target: DisplayService
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Component {
|
||||
@@ -174,32 +179,40 @@ Item {
|
||||
width: (parent.width - Theme.spacingM) / 2
|
||||
height: 80
|
||||
radius: Theme.cornerRadius
|
||||
color: BrightnessService.nightModeActive ? Qt.rgba(
|
||||
Theme.primary.r,
|
||||
Theme.primary.g,
|
||||
Theme.primary.b,
|
||||
0.12) : (nightModeToggle.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08))
|
||||
border.color: BrightnessService.nightModeActive ? Theme.primary : "transparent"
|
||||
border.width: BrightnessService.nightModeActive ? 1 : 0
|
||||
color: DisplayService.nightModeActive ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : (nightModeToggle.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08))
|
||||
border.color: DisplayService.nightModeActive ? Theme.primary : "transparent"
|
||||
border.width: DisplayService.nightModeActive ? 1 : 0
|
||||
opacity: SessionData.nightModeAutoEnabled ? 0.6 : 1
|
||||
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
spacing: Theme.spacingS
|
||||
|
||||
DankIcon {
|
||||
name: BrightnessService.nightModeActive ? "nightlight" : "dark_mode"
|
||||
name: DisplayService.nightModeActive ? "nightlight" : "dark_mode"
|
||||
size: Theme.iconSizeLarge
|
||||
color: BrightnessService.nightModeActive ? Theme.primary : Theme.surfaceText
|
||||
color: DisplayService.nightModeActive ? Theme.primary : Theme.surfaceText
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: "Night Mode"
|
||||
text: SessionData.nightModeAutoEnabled ? "Night Mode (Auto)" : "Night Mode"
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: BrightnessService.nightModeActive ? Theme.primary : Theme.surfaceText
|
||||
color: DisplayService.nightModeActive ? Theme.primary : Theme.surfaceText
|
||||
font.weight: Font.Medium
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DankIcon {
|
||||
name: "schedule"
|
||||
size: 16
|
||||
color: Theme.primary
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.margins: Theme.spacingS
|
||||
visible: SessionData.nightModeAutoEnabled
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
@@ -209,20 +222,17 @@ Item {
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
BrightnessService.toggleNightMode()
|
||||
DisplayService.toggleNightMode();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: (parent.width - Theme.spacingM) / 2
|
||||
height: 80
|
||||
radius: Theme.cornerRadius
|
||||
color: SessionData.isLightMode ? Qt.rgba(
|
||||
Theme.primary.r,
|
||||
Theme.primary.g,
|
||||
Theme.primary.b,
|
||||
0.12) : (lightModeToggle.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08))
|
||||
color: SessionData.isLightMode ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : (lightModeToggle.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08))
|
||||
border.color: SessionData.isLightMode ? Theme.primary : "transparent"
|
||||
border.width: SessionData.isLightMode ? 1 : 0
|
||||
|
||||
@@ -244,6 +254,7 @@ Item {
|
||||
font.weight: Font.Medium
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
@@ -253,7 +264,7 @@ Item {
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
Theme.toggleLightMode()
|
||||
Theme.toggleLightMode();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,10 +273,15 @@ Item {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Theme.standardEasing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
brightnessDebounceTimer: Timer {
|
||||
@@ -273,13 +289,13 @@ Item {
|
||||
|
||||
interval: {
|
||||
// Use longer interval for DDC devices since ddcutil is slow
|
||||
const deviceInfo = BrightnessService.getCurrentDeviceInfo()
|
||||
return (deviceInfo && deviceInfo.class === "ddc") ? 100 : 50
|
||||
const deviceInfo = DisplayService.getCurrentDeviceInfo();
|
||||
return (deviceInfo && deviceInfo.class === "ddc") ? 100 : 50;
|
||||
}
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
BrightnessService.setBrightnessInternal(
|
||||
pendingValue, BrightnessService.currentDevice)
|
||||
DisplayService.setBrightnessInternal(pendingValue, DisplayService.currentDevice);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,18 +15,18 @@ DankOSD {
|
||||
property int pendingValue: 0
|
||||
|
||||
interval: {
|
||||
const deviceInfo = BrightnessService.getCurrentDeviceInfo()
|
||||
const deviceInfo = DisplayService.getCurrentDeviceInfo()
|
||||
return (deviceInfo && deviceInfo.class === "ddc") ? 200 : 50
|
||||
}
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
BrightnessService.setBrightnessInternal(pendingValue, BrightnessService.lastIpcDevice)
|
||||
DisplayService.setBrightnessInternal(pendingValue, DisplayService.lastIpcDevice)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Connections {
|
||||
target: BrightnessService
|
||||
target: DisplayService
|
||||
function onBrightnessChanged() {
|
||||
root.show()
|
||||
}
|
||||
@@ -53,7 +53,7 @@ DankOSD {
|
||||
DankIcon {
|
||||
anchors.centerIn: parent
|
||||
name: {
|
||||
const deviceInfo = BrightnessService.getCurrentDeviceInfo()
|
||||
const deviceInfo = DisplayService.getCurrentDeviceInfo()
|
||||
if (!deviceInfo || deviceInfo.class === "backlight" || deviceInfo.class === "ddc")
|
||||
return "brightness_medium"
|
||||
else if (deviceInfo.name.includes("kbd"))
|
||||
@@ -75,17 +75,17 @@ DankOSD {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
minimum: 1
|
||||
maximum: 100
|
||||
enabled: BrightnessService.brightnessAvailable
|
||||
enabled: DisplayService.brightnessAvailable
|
||||
showValue: true
|
||||
unit: "%"
|
||||
|
||||
Component.onCompleted: {
|
||||
if (BrightnessService.brightnessAvailable)
|
||||
value = BrightnessService.brightnessLevel
|
||||
if (DisplayService.brightnessAvailable)
|
||||
value = DisplayService.brightnessLevel
|
||||
}
|
||||
|
||||
onSliderValueChanged: function(newValue) {
|
||||
if (BrightnessService.brightnessAvailable) {
|
||||
if (DisplayService.brightnessAvailable) {
|
||||
root.brightnessDebounceTimer.pendingValue = newValue
|
||||
root.brightnessDebounceTimer.restart()
|
||||
resetHideTimer()
|
||||
@@ -97,23 +97,23 @@ DankOSD {
|
||||
}
|
||||
|
||||
onSliderDragFinished: function(finalValue) {
|
||||
if (BrightnessService.brightnessAvailable) {
|
||||
if (DisplayService.brightnessAvailable) {
|
||||
root.brightnessDebounceTimer.stop()
|
||||
BrightnessService.setBrightnessInternal(finalValue, BrightnessService.lastIpcDevice)
|
||||
DisplayService.setBrightnessInternal(finalValue, DisplayService.lastIpcDevice)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: BrightnessService
|
||||
target: DisplayService
|
||||
|
||||
function onBrightnessChanged() {
|
||||
if (!brightnessSlider.pressed)
|
||||
brightnessSlider.value = BrightnessService.brightnessLevel
|
||||
brightnessSlider.value = DisplayService.brightnessLevel
|
||||
}
|
||||
|
||||
function onDeviceSwitched() {
|
||||
if (!brightnessSlider.pressed)
|
||||
brightnessSlider.value = BrightnessService.brightnessLevel
|
||||
brightnessSlider.value = DisplayService.brightnessLevel
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,10 +121,10 @@ DankOSD {
|
||||
}
|
||||
|
||||
onOsdShown: {
|
||||
if (BrightnessService.brightnessAvailable && contentLoader.item) {
|
||||
if (DisplayService.brightnessAvailable && contentLoader.item) {
|
||||
let slider = contentLoader.item.children[0].children[1]
|
||||
if (slider)
|
||||
slider.value = BrightnessService.brightnessLevel
|
||||
slider.value = DisplayService.brightnessLevel
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,7 @@ import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.Common
|
||||
import qs.Services
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
@@ -245,6 +246,12 @@ Singleton {
|
||||
}
|
||||
|
||||
function toggleNightMode() {
|
||||
// Check if automation is active - show warning if trying to manually toggle
|
||||
if (SessionData.nightModeAutoEnabled) {
|
||||
ToastService.showWarning("Night mode is in automatic mode. Disable automation in settings to control manually.")
|
||||
return
|
||||
}
|
||||
|
||||
if (nightModeActive) {
|
||||
disableNightMode()
|
||||
} else {
|
||||
@@ -271,10 +278,10 @@ Singleton {
|
||||
onExited: function (exitCode) {
|
||||
ddcAvailable = (exitCode === 0)
|
||||
if (ddcAvailable) {
|
||||
console.log("BrightnessService: ddcutil detected")
|
||||
console.log("DisplayService: ddcutil detected")
|
||||
ddcDisplayDetectionProcess.running = true
|
||||
} else {
|
||||
console.log("BrightnessService: ddcutil not available")
|
||||
console.log("DisplayService: ddcutil not available")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -288,7 +295,7 @@ Singleton {
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
if (!text.trim()) {
|
||||
console.log("BrightnessService: No DDC displays found")
|
||||
console.log("DisplayService: No DDC displays found")
|
||||
ddcDevices = []
|
||||
return
|
||||
}
|
||||
@@ -311,7 +318,7 @@ Singleton {
|
||||
}
|
||||
|
||||
ddcDevices = newDdcDevices
|
||||
console.log("BrightnessService: Found", ddcDevices.length,
|
||||
console.log("DisplayService: Found", ddcDevices.length,
|
||||
"DDC displays")
|
||||
|
||||
// Queue initial brightness readings for DDC devices
|
||||
@@ -339,7 +346,7 @@ Singleton {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("BrightnessService: Failed to parse DDC devices:",
|
||||
console.warn("DisplayService: Failed to parse DDC devices:",
|
||||
error)
|
||||
ddcDevices = []
|
||||
}
|
||||
@@ -348,7 +355,7 @@ Singleton {
|
||||
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode !== 0) {
|
||||
console.warn("BrightnessService: Failed to detect DDC displays:",
|
||||
console.warn("DisplayService: Failed to detect DDC displays:",
|
||||
exitCode)
|
||||
ddcDevices = []
|
||||
}
|
||||
@@ -361,7 +368,7 @@ Singleton {
|
||||
command: ["brightnessctl", "-m", "-l"]
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode !== 0) {
|
||||
console.warn("BrightnessService: Failed to list devices:",
|
||||
console.warn("DisplayService: Failed to list devices:",
|
||||
exitCode)
|
||||
brightnessAvailable = false
|
||||
}
|
||||
@@ -370,7 +377,7 @@ Singleton {
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
if (!text.trim()) {
|
||||
console.warn("BrightnessService: No devices found")
|
||||
console.warn("DisplayService: No devices found")
|
||||
return
|
||||
}
|
||||
const lines = text.trim().split("\n")
|
||||
@@ -417,7 +424,7 @@ Singleton {
|
||||
running: false
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode !== 0)
|
||||
console.warn("BrightnessService: Failed to set brightness:",
|
||||
console.warn("DisplayService: Failed to set brightness:",
|
||||
exitCode)
|
||||
}
|
||||
}
|
||||
@@ -429,7 +436,7 @@ Singleton {
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode !== 0)
|
||||
console.warn(
|
||||
"BrightnessService: Failed to set DDC brightness:",
|
||||
"DisplayService: Failed to set DDC brightness:",
|
||||
exitCode)
|
||||
}
|
||||
}
|
||||
@@ -440,7 +447,7 @@ Singleton {
|
||||
running: false
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode !== 0)
|
||||
console.warn("BrightnessService: Failed to get initial DDC brightness:",
|
||||
console.warn("DisplayService: Failed to get initial DDC brightness:",
|
||||
exitCode)
|
||||
|
||||
processNextDdcInit()
|
||||
@@ -470,7 +477,7 @@ Singleton {
|
||||
delete newPending[deviceName]
|
||||
ddcPendingInit = newPending
|
||||
|
||||
console.log("BrightnessService: Initial DDC Device",
|
||||
console.log("DisplayService: Initial DDC Device",
|
||||
deviceName, "brightness:", brightness + "%")
|
||||
}
|
||||
}
|
||||
@@ -484,7 +491,7 @@ Singleton {
|
||||
running: false
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode !== 0)
|
||||
console.warn("BrightnessService: Failed to get brightness:",
|
||||
console.warn("DisplayService: Failed to get brightness:",
|
||||
exitCode)
|
||||
}
|
||||
|
||||
@@ -508,7 +515,7 @@ Singleton {
|
||||
}
|
||||
|
||||
brightnessInitialized = true
|
||||
console.log("BrightnessService: Device", currentDevice,
|
||||
console.log("DisplayService: Device", currentDevice,
|
||||
"brightness:", brightness + "%")
|
||||
brightnessChanged()
|
||||
}
|
||||
@@ -523,7 +530,7 @@ Singleton {
|
||||
onExited: function (exitCode) {
|
||||
if (exitCode !== 0)
|
||||
console.warn(
|
||||
"BrightnessService: Failed to get DDC brightness:",
|
||||
"DisplayService: Failed to get DDC brightness:",
|
||||
exitCode)
|
||||
}
|
||||
|
||||
@@ -548,7 +555,7 @@ Singleton {
|
||||
}
|
||||
|
||||
brightnessInitialized = true
|
||||
console.log("BrightnessService: DDC Device", currentDevice,
|
||||
console.log("DisplayService: DDC Device", currentDevice,
|
||||
"brightness:", brightness + "%")
|
||||
brightnessChanged()
|
||||
}
|
||||
@@ -569,7 +576,7 @@ Singleton {
|
||||
SessionData.setNightModeEnabled(true)
|
||||
} else {
|
||||
// gammastep not found
|
||||
console.warn("BrightnessService: gammastep not found")
|
||||
console.warn("DisplayService: gammastep not found")
|
||||
ToastService.showWarning(
|
||||
"Night mode failed: gammastep not found")
|
||||
}
|
||||
@@ -588,7 +595,7 @@ Singleton {
|
||||
onExited: function (exitCode) {
|
||||
// If process exits with non-zero code while we think it should be running
|
||||
if (nightModeActive && exitCode !== 0) {
|
||||
console.warn("BrightnessService: Night mode process crashed with exit code:",
|
||||
console.warn("DisplayService: Night mode process crashed with exit code:",
|
||||
exitCode)
|
||||
nightModeActive = false
|
||||
SessionData.setNightModeEnabled(false)
|
||||
363
Services/NightModeAutomationService.qml
Normal file
363
Services/NightModeAutomationService.qml
Normal file
@@ -0,0 +1,363 @@
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.Common
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property bool automationAvailable: false
|
||||
property bool locationProviderAvailable: false
|
||||
property var availableProviders: []
|
||||
property string currentProvider: ""
|
||||
property bool isAutomaticNightTime: false
|
||||
property string currentLocation: ""
|
||||
property real latitude: 0.0
|
||||
property real longitude: 0.0
|
||||
|
||||
Component.onCompleted: {
|
||||
console.log("NightModeAutomationService: Component completed")
|
||||
checkAvailability()
|
||||
updateFromSessionData()
|
||||
if (SessionData.nightModeAutoEnabled) {
|
||||
console.log("NightModeAutomationService: Auto-starting automation on init")
|
||||
startAutomation()
|
||||
}
|
||||
}
|
||||
|
||||
function checkAvailability() {
|
||||
gammaStepTestProcess.running = true
|
||||
}
|
||||
|
||||
function startAutomation() {
|
||||
if (!automationAvailable) {
|
||||
console.warn("NightModeAutomationService: Gammastep not available")
|
||||
return
|
||||
}
|
||||
|
||||
const mode = SessionData.nightModeAutoMode || "manual"
|
||||
|
||||
switch (mode) {
|
||||
case "time":
|
||||
startTimeBasedMode()
|
||||
break
|
||||
case "location":
|
||||
startLocationBasedMode()
|
||||
break
|
||||
case "manual":
|
||||
default:
|
||||
stopAutomation()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function stopAutomation() {
|
||||
automationTimer.stop()
|
||||
locationTimer.stop()
|
||||
if (gammaStepAutomationProcess.running) {
|
||||
gammaStepAutomationProcess.kill()
|
||||
}
|
||||
isAutomaticNightTime = false
|
||||
}
|
||||
|
||||
function startTimeBasedMode() {
|
||||
console.log("NightModeAutomationService: Starting time-based automation")
|
||||
automationTimer.start()
|
||||
checkTimeBasedMode()
|
||||
}
|
||||
|
||||
function startLocationBasedMode() {
|
||||
if (!locationProviderAvailable) {
|
||||
console.warn("NightModeAutomationService: No location provider available, falling back to time-based mode")
|
||||
startTimeBasedMode()
|
||||
return
|
||||
}
|
||||
|
||||
console.log("NightModeAutomationService: Starting location-based automation")
|
||||
|
||||
const temperature = SessionData.nightModeTemperature || 4500
|
||||
const dayTemp = 6500
|
||||
|
||||
if (latitude !== 0.0 && longitude !== 0.0) {
|
||||
gammaStepAutomationProcess.command = [
|
||||
"gammastep",
|
||||
"-m", "wayland",
|
||||
"-l", `${latitude.toFixed(6)}:${longitude.toFixed(6)}`,
|
||||
"-t", `${dayTemp}:${temperature}`,
|
||||
"-v"
|
||||
]
|
||||
} else {
|
||||
gammaStepAutomationProcess.command = [
|
||||
"gammastep",
|
||||
"-m", "wayland",
|
||||
"-l", currentProvider || "manual",
|
||||
"-t", `${dayTemp}:${temperature}`,
|
||||
"-v"
|
||||
]
|
||||
}
|
||||
|
||||
gammaStepAutomationProcess.running = true
|
||||
locationTimer.start()
|
||||
}
|
||||
|
||||
function checkTimeBasedMode() {
|
||||
if (!SessionData.nightModeAutoEnabled || SessionData.nightModeAutoMode !== "time") {
|
||||
console.log("NightModeAutomationService: checkTimeBasedMode - not enabled or wrong mode")
|
||||
return
|
||||
}
|
||||
|
||||
const now = new Date()
|
||||
const currentHour = now.getHours()
|
||||
const currentMinute = now.getMinutes()
|
||||
const currentTime = currentHour * 60 + currentMinute
|
||||
|
||||
const startTime = SessionData.nightModeStartTime || "20:00"
|
||||
const endTime = SessionData.nightModeEndTime || "06:00"
|
||||
|
||||
const startParts = startTime.split(":")
|
||||
const endParts = endTime.split(":")
|
||||
|
||||
const startMinutes = parseInt(startParts[0]) * 60 + parseInt(startParts[1])
|
||||
const endMinutes = parseInt(endParts[0]) * 60 + parseInt(endParts[1])
|
||||
|
||||
let shouldBeNight = false
|
||||
|
||||
if (startMinutes > endMinutes) {
|
||||
shouldBeNight = (currentTime >= startMinutes) || (currentTime < endMinutes)
|
||||
} else {
|
||||
shouldBeNight = (currentTime >= startMinutes) && (currentTime < endMinutes)
|
||||
}
|
||||
|
||||
console.log(`NightModeAutomationService: Time check - Current: ${currentHour}:${currentMinute.toString().padStart(2, '0')} (${currentTime}), Range: ${startTime}-${endTime} (${startMinutes}-${endMinutes}), Should be night: ${shouldBeNight}`)
|
||||
|
||||
if (shouldBeNight !== isAutomaticNightTime) {
|
||||
isAutomaticNightTime = shouldBeNight
|
||||
console.log("NightModeAutomationService: Automatic night time status changed to:", shouldBeNight)
|
||||
|
||||
if (shouldBeNight) {
|
||||
requestNightModeActivation()
|
||||
} else {
|
||||
requestNightModeDeactivation()
|
||||
}
|
||||
} else {
|
||||
console.log("NightModeAutomationService: No change needed, isAutomaticNightTime already:", isAutomaticNightTime)
|
||||
}
|
||||
}
|
||||
|
||||
function requestNightModeActivation() {
|
||||
console.log("NightModeAutomationService: Requesting night mode activation")
|
||||
const temperature = SessionData.nightModeTemperature || 4500
|
||||
console.log("NightModeAutomationService: Using temperature:", temperature + "K")
|
||||
|
||||
gammaStepOneTimeProcess.command = [
|
||||
"gammastep",
|
||||
"-m", "wayland",
|
||||
"-O", String(temperature),
|
||||
"-P"
|
||||
]
|
||||
console.log("NightModeAutomationService: Running gamma command:", gammaStepOneTimeProcess.command.join(" "))
|
||||
gammaStepOneTimeProcess.running = true
|
||||
|
||||
SessionData.setNightModeEnabled(true)
|
||||
}
|
||||
|
||||
function requestNightModeDeactivation() {
|
||||
console.log("NightModeAutomationService: Requesting night mode deactivation")
|
||||
|
||||
gammaStepResetProcess.command = [
|
||||
"gammastep",
|
||||
"-m", "wayland",
|
||||
"-O", "6500",
|
||||
"-P"
|
||||
]
|
||||
gammaStepResetProcess.running = true
|
||||
|
||||
SessionData.setNightModeEnabled(false)
|
||||
}
|
||||
|
||||
function setLocation(lat, lon) {
|
||||
latitude = lat
|
||||
longitude = lon
|
||||
currentLocation = `${lat.toFixed(6)},${lon.toFixed(6)}`
|
||||
|
||||
if (SessionData.nightModeAutoEnabled && SessionData.nightModeAutoMode === "location") {
|
||||
startLocationBasedMode()
|
||||
}
|
||||
}
|
||||
|
||||
function updateFromSessionData() {
|
||||
console.log("NightModeAutomationService: Updating from SessionData - lat:", SessionData.latitude, "lng:", SessionData.longitude)
|
||||
if (SessionData.latitude !== 0.0 && SessionData.longitude !== 0.0) {
|
||||
setLocation(SessionData.latitude, SessionData.longitude)
|
||||
}
|
||||
}
|
||||
|
||||
function detectLocationProviders() {
|
||||
locationProviderDetectionProcess.running = true
|
||||
}
|
||||
|
||||
function testAutomationNow() {
|
||||
console.log("NightModeAutomationService: Manual test triggered")
|
||||
console.log("NightModeAutomationService: Current settings - autoEnabled:", SessionData.nightModeAutoEnabled, "mode:", SessionData.nightModeAutoMode)
|
||||
if (SessionData.nightModeAutoMode === "time") {
|
||||
checkTimeBasedMode()
|
||||
} else if (SessionData.nightModeAutoMode === "location") {
|
||||
console.log("NightModeAutomationService: Location mode - coordinates:", latitude, longitude)
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: automationTimer
|
||||
interval: 60000
|
||||
running: false
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
checkTimeBasedMode()
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: locationTimer
|
||||
interval: 300000
|
||||
running: false
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
if (SessionData.nightModeAutoEnabled && SessionData.nightModeAutoMode === "location") {
|
||||
detectLocationProviders()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: gammaStepTestProcess
|
||||
command: ["which", "gammastep"]
|
||||
running: false
|
||||
|
||||
onExited: function(exitCode) {
|
||||
automationAvailable = (exitCode === 0)
|
||||
if (automationAvailable) {
|
||||
console.log("NightModeAutomationService: Gammastep available")
|
||||
detectLocationProviders()
|
||||
} else {
|
||||
console.warn("NightModeAutomationService: Gammastep not available")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: locationProviderDetectionProcess
|
||||
command: ["gammastep", "-l", "list"]
|
||||
running: false
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
if (text.trim()) {
|
||||
availableProviders = text.trim().split('\n').filter(line => line.trim().length > 0)
|
||||
locationProviderAvailable = availableProviders.length > 0
|
||||
|
||||
if (locationProviderAvailable && !currentProvider) {
|
||||
currentProvider = availableProviders[0]
|
||||
}
|
||||
|
||||
console.log("NightModeAutomationService: Available providers:", availableProviders)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onExited: function(exitCode) {
|
||||
if (exitCode !== 0) {
|
||||
console.warn("NightModeAutomationService: Failed to detect location providers")
|
||||
locationProviderAvailable = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: gammaStepAutomationProcess
|
||||
running: false
|
||||
|
||||
onExited: function(exitCode) {
|
||||
if (SessionData.nightModeAutoEnabled && SessionData.nightModeAutoMode === "location" && exitCode !== 0) {
|
||||
console.warn("NightModeAutomationService: Location-based automation failed, exit code:", exitCode)
|
||||
restartTimer.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: gammaStepOneTimeProcess
|
||||
running: false
|
||||
|
||||
onExited: function(exitCode) {
|
||||
if (exitCode !== 0) {
|
||||
console.warn("NightModeAutomationService: Failed to enable night mode, exit code:", exitCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Process {
|
||||
id: gammaStepResetProcess
|
||||
running: false
|
||||
|
||||
onExited: function(exitCode) {
|
||||
if (exitCode !== 0) {
|
||||
console.warn("NightModeAutomationService: Failed to reset gamma, exit code:", exitCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: restartTimer
|
||||
interval: 10000
|
||||
running: false
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
if (SessionData.nightModeAutoEnabled && SessionData.nightModeAutoMode === "location") {
|
||||
startLocationBasedMode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: SessionData
|
||||
function onNightModeAutoEnabledChanged() {
|
||||
console.log("NightModeAutomationService: Auto enabled changed to", SessionData.nightModeAutoEnabled)
|
||||
if (SessionData.nightModeAutoEnabled) {
|
||||
startAutomation()
|
||||
} else {
|
||||
stopAutomation()
|
||||
}
|
||||
}
|
||||
function onNightModeAutoModeChanged() {
|
||||
if (SessionData.nightModeAutoEnabled) {
|
||||
startAutomation()
|
||||
}
|
||||
}
|
||||
function onNightModeStartTimeChanged() {
|
||||
console.log("NightModeAutomationService: Start time changed to", SessionData.nightModeStartTime)
|
||||
if (SessionData.nightModeAutoEnabled && SessionData.nightModeAutoMode === "time") {
|
||||
checkTimeBasedMode()
|
||||
}
|
||||
}
|
||||
function onNightModeEndTimeChanged() {
|
||||
console.log("NightModeAutomationService: End time changed to", SessionData.nightModeEndTime)
|
||||
if (SessionData.nightModeAutoEnabled && SessionData.nightModeAutoMode === "time") {
|
||||
checkTimeBasedMode()
|
||||
}
|
||||
}
|
||||
function onNightModeTemperatureChanged() {
|
||||
if (SessionData.nightModeAutoEnabled) {
|
||||
startAutomation()
|
||||
}
|
||||
}
|
||||
function onLatitudeChanged() {
|
||||
updateFromSessionData()
|
||||
}
|
||||
function onLongitudeChanged() {
|
||||
updateFromSessionData()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user