hyprsunset schedule and toggle
This commit is contained in:
@@ -40,6 +40,10 @@ JsonObject {
|
|||||||
id: "spacer",
|
id: "spacer",
|
||||||
enabled: true
|
enabled: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "hyprsunset",
|
||||||
|
enabled: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "tray",
|
id: "tray",
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@@ -177,6 +177,10 @@ Singleton {
|
|||||||
mode: general.color.mode,
|
mode: general.color.mode,
|
||||||
smart: general.color.smart,
|
smart: general.color.smart,
|
||||||
scheduleDark: general.color.scheduleDark,
|
scheduleDark: general.color.scheduleDark,
|
||||||
|
scheduleHyprsunset: general.color.scheduleHyprsunset,
|
||||||
|
scheduleHyprsunsetStart: general.color.scheduleHyprsunsetStart,
|
||||||
|
hyprsunsetTemp: general.color.hyprsunsetTemp,
|
||||||
|
scheduleHyprsunsetEnd: general.color.scheduleHyprsunsetEnd,
|
||||||
schemeGeneration: general.color.schemeGeneration,
|
schemeGeneration: general.color.schemeGeneration,
|
||||||
scheduleDarkStart: general.color.scheduleDarkStart,
|
scheduleDarkStart: general.color.scheduleDarkStart,
|
||||||
scheduleDarkEnd: general.color.scheduleDarkEnd,
|
scheduleDarkEnd: general.color.scheduleDarkEnd,
|
||||||
@@ -374,6 +378,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
onLoaded: {
|
onLoaded: {
|
||||||
ModeScheduler.checkStartup();
|
ModeScheduler.checkStartup();
|
||||||
|
Hyprsunset.checkStartup();
|
||||||
try {
|
try {
|
||||||
JSON.parse(text());
|
JSON.parse(text());
|
||||||
const elapsed = timer.elapsedMs();
|
const elapsed = timer.elapsedMs();
|
||||||
|
|||||||
@@ -19,11 +19,15 @@ JsonObject {
|
|||||||
property list<string> terminal: ["kitty"]
|
property list<string> terminal: ["kitty"]
|
||||||
}
|
}
|
||||||
component Color: JsonObject {
|
component Color: JsonObject {
|
||||||
|
property int hyprsunsetTemp: 5000
|
||||||
property string mode: "dark"
|
property string mode: "dark"
|
||||||
property bool neovimColors: false
|
property bool neovimColors: false
|
||||||
property bool scheduleDark: false
|
property bool scheduleDark: false
|
||||||
property int scheduleDarkEnd: 0
|
property int scheduleDarkEnd: 0
|
||||||
property int scheduleDarkStart: 0
|
property int scheduleDarkStart: 0
|
||||||
|
property bool scheduleHyprsunset: false
|
||||||
|
property int scheduleHyprsunsetEnd: 0
|
||||||
|
property int scheduleHyprsunsetStart: 0
|
||||||
property bool schemeGeneration: true
|
property bool schemeGeneration: true
|
||||||
property bool smart: false
|
property bool smart: false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import Quickshell
|
||||||
|
import QtQuick
|
||||||
|
import qs.Config
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool enabled
|
||||||
|
readonly property int end: Config.general.color.scheduleHyprsunsetEnd
|
||||||
|
property bool manualToggle: false
|
||||||
|
readonly property int start: Config.general.color.scheduleHyprsunsetStart
|
||||||
|
readonly property int temp: Config.general.color.hyprsunsetTemp
|
||||||
|
|
||||||
|
function checkStartup(): void {
|
||||||
|
if (!Config.general.color.scheduleHyprsunset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var now = new Date();
|
||||||
|
if (now.getHours() >= root.start || now.getHours() < root.end) {
|
||||||
|
root.startNightLight(root.temp);
|
||||||
|
} else {
|
||||||
|
root.stopNightLight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function startNightLight(temp: int): void {
|
||||||
|
Quickshell.execDetached(["hyprctl", "hyprsunset", "temperature", `${temp}`]);
|
||||||
|
root.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopNightLight(): void {
|
||||||
|
Quickshell.execDetached(["hyprctl", "hyprsunset", "identity"]);
|
||||||
|
root.enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleNightLight(): void {
|
||||||
|
if (enabled)
|
||||||
|
stopNightLight();
|
||||||
|
else
|
||||||
|
startNightLight(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
onManualToggleChanged: {
|
||||||
|
if (root.manualToggle)
|
||||||
|
manualTimer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: manualTimer
|
||||||
|
|
||||||
|
interval: 60000 * 60
|
||||||
|
repeat: false
|
||||||
|
running: false
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
root.manualToggle = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
interval: 5000
|
||||||
|
repeat: true
|
||||||
|
running: true
|
||||||
|
triggeredOnStart: true
|
||||||
|
|
||||||
|
onTriggered: {
|
||||||
|
console.log("start");
|
||||||
|
if (!Config.general.color.scheduleHyprsunset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (root.manualToggle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var now = new Date();
|
||||||
|
if (now.getHours() >= root.start || now.getHours() < root.end) {
|
||||||
|
root.startNightLight(root.temp);
|
||||||
|
} else {
|
||||||
|
root.stopNightLight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -66,6 +66,15 @@ RowLayout {
|
|||||||
DelegateChooser {
|
DelegateChooser {
|
||||||
role: "id"
|
role: "id"
|
||||||
|
|
||||||
|
DelegateChoice {
|
||||||
|
roleValue: "hyprsunset"
|
||||||
|
|
||||||
|
delegate: WrappedLoader {
|
||||||
|
sourceComponent: HyprsunsetWidget {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DelegateChoice {
|
DelegateChoice {
|
||||||
roleValue: "spacer"
|
roleValue: "spacer"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import QtQuick
|
||||||
|
import qs.Components
|
||||||
|
import qs.Helpers
|
||||||
|
import qs.Config
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool tempEnabled: Hyprsunset.enabled
|
||||||
|
|
||||||
|
color: root.tempEnabled ? DynamicColors.palette.m3primary : DynamicColors.tPalette.m3surfaceContainer
|
||||||
|
implicitHeight: Config.barConfig.height + Appearance.padding.smallest * 2
|
||||||
|
implicitWidth: implicitHeight
|
||||||
|
radius: Appearance.rounding.full
|
||||||
|
|
||||||
|
StateLayer {
|
||||||
|
onClicked: {
|
||||||
|
Hyprsunset.toggleNightLight();
|
||||||
|
Hyprsunset.manualToggle = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
animate: true
|
||||||
|
color: root.tempEnabled ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSurface
|
||||||
|
text: root.tempEnabled ? "lightbulb" : "light_off"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -163,6 +163,15 @@ SettingsPage {
|
|||||||
object: Config.general.color
|
object: Config.general.color
|
||||||
settings: ["scheduleDarkStart", "scheduleDarkEnd", "scheduleDark"]
|
settings: ["scheduleDarkStart", "scheduleDarkEnd", "scheduleDark"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Separator {
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingHyprSpinner {
|
||||||
|
name: "Schedule Hyprsunset"
|
||||||
|
object: Config.general.color
|
||||||
|
settings: ["scheduleHyprsunsetStart", "scheduleHyprsunsetEnd", "scheduleHyprsunset", "hyprsunsetTemp"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsSection {
|
SettingsSection {
|
||||||
|
|||||||
@@ -0,0 +1,180 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import qs.Components
|
||||||
|
import qs.Config
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property string name
|
||||||
|
required property var object
|
||||||
|
required property list<string> settings
|
||||||
|
|
||||||
|
function commitChoice(choice: int, setting: string): void {
|
||||||
|
root.object[setting] = choice;
|
||||||
|
Config.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
function formattedValue(setting: string): string {
|
||||||
|
const value = root.object[setting];
|
||||||
|
|
||||||
|
if (value === null || value === undefined)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
return String(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function hourToAmPm(hour) {
|
||||||
|
var h = Number(hour) % 24;
|
||||||
|
var d = new Date(2000, 0, 1, h, 0, 0);
|
||||||
|
return Qt.formatTime(d, "h AP");
|
||||||
|
}
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: row.implicitHeight + Appearance.padding.smaller * 2
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: row
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.margins: Appearance.padding.small
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
id: text
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
|
Layout.fillWidth: true
|
||||||
|
font.pointSize: Appearance.font.size.larger
|
||||||
|
text: root.name
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
Layout.alignment: Qt.AlignLeft
|
||||||
|
color: DynamicColors.palette.m3onSurfaceVariant
|
||||||
|
font.pointSize: Appearance.font.size.normal
|
||||||
|
text: qsTr("Hyprsunset will turn on at %1, and turn off at %2.").arg(root.hourToAmPm(root.object[root.settings[0]])).arg(root.hourToAmPm(root.object[root.settings[1]]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: optionLayout
|
||||||
|
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.preferredWidth: 100
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.preferredWidth: optionLayout.width
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
Layout.alignment: Qt.AlignLeft | Qt.AlignHCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Enabled: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomSwitch {
|
||||||
|
id: enabledSwitch
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignHCenter
|
||||||
|
checked: root.object[root.settings[2]]
|
||||||
|
|
||||||
|
onToggled: {
|
||||||
|
root.object[root.settings[2]] = checked;
|
||||||
|
Config.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.preferredWidth: optionLayout.width
|
||||||
|
z: setting2.expanded ? -1 : 1
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
Layout.alignment: Qt.AlignLeft | Qt.AlignHCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Start: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
SpinnerButton {
|
||||||
|
id: setting1
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignHCenter
|
||||||
|
Layout.preferredHeight: Appearance.font.size.large + Appearance.padding.smaller * 2
|
||||||
|
Layout.preferredWidth: height * 2
|
||||||
|
currentIndex: root.object[root.settings[0]]
|
||||||
|
enabled: enabledSwitch.checked
|
||||||
|
text: root.formattedValue(root.settings[0])
|
||||||
|
|
||||||
|
menu.onItemSelected: item => {
|
||||||
|
root.commitChoice(item, root.settings[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.preferredWidth: optionLayout.width
|
||||||
|
z: setting1.expanded ? -1 : 1
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
Layout.alignment: Qt.AlignLeft | Qt.AlignHCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("End: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
SpinnerButton {
|
||||||
|
id: setting2
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignRight | Qt.AlignHCenter
|
||||||
|
Layout.preferredHeight: Appearance.font.size.large + Appearance.padding.smaller * 2
|
||||||
|
Layout.preferredWidth: height * 2
|
||||||
|
currentIndex: root.object[root.settings[1]]
|
||||||
|
enabled: enabledSwitch.checked
|
||||||
|
text: root.formattedValue(root.settings[1])
|
||||||
|
|
||||||
|
menu.onItemSelected: item => {
|
||||||
|
root.commitChoice(item, root.settings[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Layout.preferredWidth: optionLayout.width
|
||||||
|
z: -2
|
||||||
|
|
||||||
|
CustomText {
|
||||||
|
Layout.alignment: Qt.AlignLeft | Qt.AlignHCenter
|
||||||
|
Layout.fillWidth: true
|
||||||
|
text: qsTr("Temp: ")
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomRect {
|
||||||
|
id: rect
|
||||||
|
|
||||||
|
Layout.preferredHeight: 33
|
||||||
|
Layout.preferredWidth: Math.max(Math.min(textField.contentWidth + Appearance.padding.normal * 2, 200), 50)
|
||||||
|
color: DynamicColors.tPalette.m3surfaceContainerHigh
|
||||||
|
radius: Appearance.rounding.full
|
||||||
|
|
||||||
|
CustomTextField {
|
||||||
|
id: textField
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
implicitWidth: Math.min(contentWidth + Appearance.padding.normal * 2, 200)
|
||||||
|
text: root.formattedValue(root.settings[3])
|
||||||
|
|
||||||
|
onEditingFinished: {
|
||||||
|
root.object[root.settings[3]] = textField.text;
|
||||||
|
Config.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user