1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-30 00:12:50 -05:00

gamma: display automation state in UI

This commit is contained in:
bbedward
2025-12-09 11:26:28 -05:00
parent da4561cb35
commit f88f1ea951
7 changed files with 279 additions and 68 deletions

View File

@@ -255,7 +255,6 @@ Singleton {
property int batterySuspendBehavior: SettingsData.SuspendBehavior.Suspend property int batterySuspendBehavior: SettingsData.SuspendBehavior.Suspend
property string batteryProfileName: "" property string batteryProfileName: ""
property bool lockBeforeSuspend: false property bool lockBeforeSuspend: false
property bool preventIdleForMedia: false
property bool loginctlLockIntegration: true property bool loginctlLockIntegration: true
property bool fadeToLockEnabled: false property bool fadeToLockEnabled: false
property int fadeToLockGracePeriod: 5 property int fadeToLockGracePeriod: 5

View File

@@ -154,7 +154,6 @@ var SPEC = {
batterySuspendBehavior: { def: 0 }, batterySuspendBehavior: { def: 0 },
batteryProfileName: { def: "" }, batteryProfileName: { def: "" },
lockBeforeSuspend: { def: false }, lockBeforeSuspend: { def: false },
preventIdleForMedia: { def: false },
loginctlLockIntegration: { def: true }, loginctlLockIntegration: { def: true },
fadeToLockEnabled: { def: false }, fadeToLockEnabled: { def: false },
fadeToLockGracePeriod: { def: 5 }, fadeToLockGracePeriod: { def: 5 },

View File

@@ -8,6 +8,19 @@ import qs.Widgets
Item { Item {
id: displaysTab id: displaysTab
function formatGammaTime(isoString) {
if (!isoString)
return "";
try {
const date = new Date(isoString);
if (isNaN(date.getTime()))
return "";
return date.toLocaleTimeString(Qt.locale(), "HH:mm");
} catch (e) {
return "";
}
}
function getBarComponentsFromSettings() { function getBarComponentsFromSettings() {
const bars = SettingsData.barConfigs || []; const bars = SettingsData.barConfigs || [];
return bars.map(bar => ({ return bars.map(bar => ({
@@ -530,6 +543,233 @@ Item {
} }
} }
} }
Rectangle {
width: parent.width
height: 1
color: Theme.outline
opacity: 0.2
visible: gammaStatusSection.visible
}
Column {
id: gammaStatusSection
width: parent.width
spacing: Theme.spacingM
visible: DisplayService.nightModeEnabled && DisplayService.gammaCurrentTemp > 0
Row {
width: parent.width
spacing: Theme.spacingS
DankIcon {
name: DisplayService.gammaIsDay ? "light_mode" : "dark_mode"
size: Theme.iconSizeSmall
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("Current Status")
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
Row {
width: parent.width
spacing: Theme.spacingM
Rectangle {
width: (parent.width - Theme.spacingM) / 2
height: tempColumn.implicitHeight + Theme.spacingM * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
Column {
id: tempColumn
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
name: "device_thermostat"
size: Theme.iconSize
color: Theme.primary
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: DisplayService.gammaCurrentTemp + "K"
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: I18n.tr("Current Temp")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
Rectangle {
width: (parent.width - Theme.spacingM) / 2
height: periodColumn.implicitHeight + Theme.spacingM * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
Column {
id: periodColumn
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
name: DisplayService.gammaIsDay ? "wb_sunny" : "nightlight"
size: Theme.iconSize
color: DisplayService.gammaIsDay ? "#FFA726" : "#7E57C2"
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: DisplayService.gammaIsDay ? I18n.tr("Daytime") : I18n.tr("Night")
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: I18n.tr("Current Period")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
}
Row {
width: parent.width
spacing: Theme.spacingM
visible: SessionData.nightModeAutoMode === "location" && (DisplayService.gammaSunriseTime || DisplayService.gammaSunsetTime)
Rectangle {
width: (parent.width - Theme.spacingM) / 2
height: sunriseColumn.implicitHeight + Theme.spacingM * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
visible: DisplayService.gammaSunriseTime
Column {
id: sunriseColumn
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
name: "wb_twilight"
size: Theme.iconSize
color: "#FF7043"
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: displaysTab.formatGammaTime(DisplayService.gammaSunriseTime)
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: I18n.tr("Sunrise")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
Rectangle {
width: (parent.width - Theme.spacingM) / 2
height: sunsetColumn.implicitHeight + Theme.spacingM * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
visible: DisplayService.gammaSunsetTime
Column {
id: sunsetColumn
anchors.centerIn: parent
spacing: Theme.spacingXS
DankIcon {
name: "wb_twilight"
size: Theme.iconSize
color: "#5C6BC0"
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: displaysTab.formatGammaTime(DisplayService.gammaSunsetTime)
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium
color: Theme.surfaceText
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: I18n.tr("Sunset")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
}
Rectangle {
width: parent.width
height: nextChangeRow.implicitHeight + Theme.spacingM * 2
radius: Theme.cornerRadius
color: Theme.surfaceContainerHigh
visible: DisplayService.gammaNextTransition
Row {
id: nextChangeRow
anchors.centerIn: parent
spacing: Theme.spacingM
DankIcon {
name: "schedule"
size: Theme.iconSize
color: Theme.primary
anchors.verticalCenter: parent.verticalCenter
}
Column {
spacing: 2
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: I18n.tr("Next Transition")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
StyledText {
text: displaysTab.formatGammaTime(DisplayService.gammaNextTransition)
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
}
}
}
}
}
} }
} }
} }

View File

@@ -61,14 +61,6 @@ Item {
} }
} }
SettingsToggleRow {
text: I18n.tr("Prevent idle for media")
description: I18n.tr("Inhibit idle timeout when audio or video is playing")
checked: SettingsData.preventIdleForMedia
visible: IdleService.idleMonitorAvailable
onToggled: checked => SettingsData.set("preventIdleForMedia", checked)
}
SettingsToggleRow { SettingsToggleRow {
text: I18n.tr("Fade to lock screen") text: I18n.tr("Fade to lock screen")
description: I18n.tr("Gradually fade the screen before locking with a configurable grace period") description: I18n.tr("Gradually fade the screen before locking with a configurable grace period")
@@ -76,6 +68,14 @@ Item {
onToggled: checked => SettingsData.set("fadeToLockEnabled", checked) onToggled: checked => SettingsData.set("fadeToLockEnabled", checked)
} }
SettingsToggleRow {
text: I18n.tr("Lock before suspend")
description: I18n.tr("Automatically lock the screen when the system prepares to suspend")
checked: SettingsData.lockBeforeSuspend
visible: SessionService.loginctlAvailable && SettingsData.loginctlLockIntegration
onToggled: checked => SettingsData.set("lockBeforeSuspend", checked)
}
SettingsDropdownRow { SettingsDropdownRow {
id: fadeGracePeriodDropdown id: fadeGracePeriodDropdown
property var periodOptions: ["1 second", "2 seconds", "3 seconds", "4 seconds", "5 seconds", "10 seconds", "15 seconds", "20 seconds", "30 seconds"] property var periodOptions: ["1 second", "2 seconds", "3 seconds", "4 seconds", "5 seconds", "10 seconds", "15 seconds", "20 seconds", "30 seconds"]
@@ -114,14 +114,14 @@ Item {
function onCurrentIndexChanged() { function onCurrentIndexChanged() {
const currentProfile = powerCategory.currentIndex === 0 ? SettingsData.acProfileName : SettingsData.batteryProfileName; const currentProfile = powerCategory.currentIndex === 0 ? SettingsData.acProfileName : SettingsData.batteryProfileName;
const index = powerProfileDropdown.profileValues.indexOf(currentProfile); const index = powerProfileDropdown.profileValues.indexOf(currentProfile);
powerProfileDropdown.currentValue = powerProfileDropdown.profileOptions[index] powerProfileDropdown.currentValue = powerProfileDropdown.profileOptions[index];
} }
} }
Component.onCompleted: { Component.onCompleted: {
const currentProfile = powerCategory.currentIndex === 0 ? SettingsData.acProfileName : SettingsData.batteryProfileName; const currentProfile = powerCategory.currentIndex === 0 ? SettingsData.acProfileName : SettingsData.batteryProfileName;
const index = profileValues.indexOf(currentProfile); const index = profileValues.indexOf(currentProfile);
currentValue = profileOptions[index] currentValue = profileOptions[index];
} }
onValueChanged: value => { onValueChanged: value => {

View File

@@ -49,6 +49,7 @@ Singleton {
signal extWorkspaceStateUpdate(var data) signal extWorkspaceStateUpdate(var data)
signal wlrOutputStateUpdate(var data) signal wlrOutputStateUpdate(var data)
signal evdevStateUpdate(var data) signal evdevStateUpdate(var data)
signal gammaStateUpdate(var data)
signal openUrlRequested(string url) signal openUrlRequested(string url)
signal appPickerRequested(var data) signal appPickerRequested(var data)
@@ -267,9 +268,9 @@ Singleton {
function removeSubscription(service) { function removeSubscription(service) {
if (activeSubscriptions.includes("all")) { if (activeSubscriptions.includes("all")) {
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "dwl", "brightness", "extworkspace", "browser"] const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "dwl", "brightness", "extworkspace", "browser"];
const filtered = allServices.filter(s => s !== service) const filtered = allServices.filter(s => s !== service);
subscribe(filtered) subscribe(filtered);
} else { } else {
const filtered = activeSubscriptions.filter(s => s !== service); const filtered = activeSubscriptions.filter(s => s !== service);
if (filtered.length === 0) { if (filtered.length === 0) {
@@ -289,9 +290,9 @@ Singleton {
excludeServices = [excludeServices]; excludeServices = [excludeServices];
} }
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "cups", "dwl", "brightness", "extworkspace", "browser"] const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "cups", "dwl", "brightness", "extworkspace", "browser"];
const filtered = allServices.filter(s => !excludeServices.includes(s)) const filtered = allServices.filter(s => !excludeServices.includes(s));
subscribe(filtered) subscribe(filtered);
} }
function handleSubscriptionEvent(response) { function handleSubscriptionEvent(response) {
@@ -355,16 +356,18 @@ Singleton {
if (data.capsLock !== undefined) { if (data.capsLock !== undefined) {
capsLockState = data.capsLock; capsLockState = data.capsLock;
} }
evdevStateUpdate(data) evdevStateUpdate(data);
} else if (service === "gamma") {
gammaStateUpdate(data);
} else if (service === "browser.open_requested") { } else if (service === "browser.open_requested") {
if (data.target) { if (data.target) {
if (data.requestType === "url" || !data.requestType) { if (data.requestType === "url" || !data.requestType) {
openUrlRequested(data.target) openUrlRequested(data.target);
} else { } else {
appPickerRequested(data) appPickerRequested(data);
} }
} else if (data.url) { } else if (data.url) {
openUrlRequested(data.url) openUrlRequested(data.url);
} }
} }
} }

View File

@@ -41,6 +41,18 @@ Singleton {
property bool automationAvailable: false property bool automationAvailable: false
property bool gammaControlAvailable: false property bool gammaControlAvailable: false
property var gammaState: ({})
property int gammaCurrentTemp: gammaState?.currentTemp ?? 0
property string gammaNextTransition: gammaState?.nextTransition ?? ""
property string gammaSunriseTime: gammaState?.sunriseTime ?? ""
property string gammaSunsetTime: gammaState?.sunsetTime ?? ""
property string gammaDawnTime: gammaState?.dawnTime ?? ""
property string gammaNightTime: gammaState?.nightTime ?? ""
property bool gammaIsDay: gammaState?.isDay ?? true
property real gammaSunPosition: gammaState?.sunPosition ?? 0
property int gammaLowTemp: gammaState?.config?.LowTemp ?? 0
property int gammaHighTemp: gammaState?.config?.HighTemp ?? 0
function markDeviceUserControlled(deviceId) { function markDeviceUserControlled(deviceId) {
const newControlled = Object.assign({}, userControlledDevices); const newControlled = Object.assign({}, userControlledDevices);
newControlled[deviceId] = Date.now(); newControlled[deviceId] = Date.now();
@@ -809,6 +821,10 @@ Singleton {
osdSuppressTimer.restart(); osdSuppressTimer.restart();
} }
} }
function onGammaStateUpdate(data) {
root.gammaState = data;
}
} }
// Session Data Connections // Session Data Connections

View File

@@ -58,43 +58,12 @@ Singleton {
property var monitorOffMonitor: null property var monitorOffMonitor: null
property var lockMonitor: null property var lockMonitor: null
property var suspendMonitor: null property var suspendMonitor: null
property var mediaInhibitor: null
property var lockComponent: null property var lockComponent: null
function wake() { function wake() {
requestMonitorOn(); requestMonitorOn();
} }
function createMediaInhibitor() {
if (!idleInhibitorAvailable) {
return;
}
if (mediaInhibitor) {
mediaInhibitor.destroy();
mediaInhibitor = null;
}
const inhibitorString = `
import QtQuick
import Quickshell.Wayland
IdleInhibitor {
active: false
}
`;
mediaInhibitor = Qt.createQmlObject(inhibitorString, root, "IdleService.MediaInhibitor");
mediaInhibitor.active = Qt.binding(() => root.mediaPlaying);
}
function destroyMediaInhibitor() {
if (mediaInhibitor) {
mediaInhibitor.destroy();
mediaInhibitor = null;
}
}
function createIdleMonitors() { function createIdleMonitors() {
if (!idleMonitorAvailable) { if (!idleMonitorAvailable) {
console.info("IdleService: IdleMonitor not available, skipping creation"); console.info("IdleService: IdleMonitor not available, skipping creation");
@@ -152,10 +121,6 @@ Singleton {
root.requestSuspend(); root.requestSuspend();
} }
}); });
if (SettingsData.preventIdleForMedia) {
createMediaInhibitor();
}
} catch (e) { } catch (e) {
console.warn("IdleService: Error creating IdleMonitors:", e); console.warn("IdleService: Error creating IdleMonitors:", e);
} }
@@ -176,17 +141,6 @@ Singleton {
} }
} }
Connections {
target: SettingsData
function onPreventIdleForMediaChanged() {
if (SettingsData.preventIdleForMedia) {
createMediaInhibitor();
} else {
destroyMediaInhibitor();
}
}
}
Component.onCompleted: { Component.onCompleted: {
if (!idleMonitorAvailable) { if (!idleMonitorAvailable) {
console.warn("IdleService: IdleMonitor not available - power management disabled. This requires a newer version of Quickshell."); console.warn("IdleService: IdleMonitor not available - power management disabled. This requires a newer version of Quickshell.");