Merge branch 'main' into feat/llm-chat-tab
C++ / fmt (pull_request) Failing after 3s
C++ / build (pull_request) Failing after 9s
C++ / clang-tidy (pull_request) Failing after 9s
JS/TS / fmt (pull_request) Successful in 9s
JS/TS / lint (pull_request) Successful in 10s
Python / static (pull_request) Successful in 28s
Rust / build (pull_request) Successful in 49s
Python / verify (pull_request) Successful in 1m40s
Rust / fmt (pull_request) Successful in 27s
Rust / clippy (pull_request) Successful in 46s

This commit is contained in:
2026-09-30 17:59:14 +02:00
298 changed files with 18329 additions and 6057 deletions
+2 -2
View File
@@ -56,14 +56,14 @@ PageBase {
CustomText {
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Tokens.spacing.small
font.pointSize: Tokens.font.size.large
font: Tokens.font.headline.large
text: "ZShell"
}
CustomText {
Layout.alignment: Qt.AlignHCenter
color: Colors.palette.m3onSurfaceVariant
font.pointSize: Tokens.font.size.normal
font: Tokens.font.body.medium
text: ZUtils.version ? `v${ZUtils.version}` : "…"
}
}
+5 -5
View File
@@ -56,7 +56,7 @@ PageBase {
IconImage {
asynchronous: true
implicitSize: Math.round(Tokens.font.size.large * 1.8)
implicitSize: Math.round(Tokens.font.icon.large * 1.8)
source: Quickshell.iconPath(appItem.modelData.icon, "image-missing")
}
@@ -67,7 +67,7 @@ PageBase {
CustomText {
Layout.fillWidth: true
elide: Text.ElideRight
font.pointSize: Tokens.font.size.small
font: Tokens.font.body.small
text: appItem.modelData.name
}
@@ -75,7 +75,7 @@ PageBase {
Layout.fillWidth: true
color: Colors.palette.m3outline
elide: Text.ElideRight
font.pointSize: Tokens.font.size.small
font: Tokens.font.label.small
text: (appItem.modelData.comment || appItem.modelData.genericName) ?? ""
visible: text
}
@@ -84,14 +84,14 @@ PageBase {
MaterialIcon {
color: Colors.palette.m3primary
fill: 1
font.pointSize: Tokens.font.size.small
fontStyle: Tokens.font.icon.small
text: "favorite"
visible: Strings.testRegexList(Config.launcher.favoriteApps, appItem.modelData.id)
}
MaterialIcon {
color: Colors.palette.m3onSurfaceVariant
font.pointSize: Tokens.font.size.normal
fontStyle: Tokens.font.icon.medium
text: "chevron_right"
}
}
+4 -5
View File
@@ -47,7 +47,7 @@ PageBase {
IconImage {
asynchronous: true
implicitSize: Math.round(Tokens.font.size.large * 3)
implicitSize: Math.round(Tokens.font.icon.large.pointSize * 3)
source: Quickshell.iconPath(root.app?.icon, "image-missing")
}
@@ -57,7 +57,7 @@ PageBase {
CustomText {
Layout.fillWidth: true
font.pointSize: Tokens.font.size.normal
font: Tokens.font.body.medium
text: root.app?.name ?? ""
wrapMode: Text.WordWrap
}
@@ -65,7 +65,7 @@ PageBase {
CustomText {
Layout.fillWidth: true
color: Colors.palette.m3outline
font.pointSize: Tokens.font.size.small
font: Tokens.font.body.small
text: (root.app?.comment || root.app?.genericName) ?? ""
visible: text
wrapMode: Text.WordWrap
@@ -152,7 +152,7 @@ PageBase {
id: label
Layout.alignment: Qt.AlignTop
font.pointSize: Tokens.font.size.small
font: Tokens.font.label.small
}
Item {
@@ -165,7 +165,6 @@ PageBase {
Layout.fillWidth: true
Layout.maximumWidth: implicitWidth + 1 // Whyyyyyyyyy
color: Colors.palette.m3onSurfaceVariant
font.pointSize: Tokens.font.size.small
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
}
}
+5 -5
View File
@@ -76,7 +76,7 @@ PageBase {
icon: "apps"
last: true
settingAnchor: "apps-all-apps"
status: qsTr("Browse installed apps, set favorites and hidden")
subtext: qsTr("Browse installed apps, set favorites and hidden")
text: qsTr("All apps")
onClicked: root.sState.openSubPage(1)
@@ -143,7 +143,7 @@ PageBase {
IconImage {
asynchronous: true
implicitSize: Math.round(Tokens.font.size.large * 1.8)
implicitSize: Math.round(Tokens.font.icon.large.pointSize * 1.8)
source: Quickshell.iconPath(appItem.modelData.icon, "image-missing")
}
@@ -154,7 +154,7 @@ PageBase {
CustomText {
Layout.fillWidth: true
elide: Text.ElideRight
font.pointSize: Tokens.font.size.small
font: Tokens.font.body.small
text: appItem.modelData.name
}
@@ -162,7 +162,7 @@ PageBase {
Layout.fillWidth: true
color: Colors.palette.m3outline
elide: Text.ElideRight
font.pointSize: Tokens.font.size.small
font: Tokens.font.body.small
text: (appItem.modelData.comment || appItem.modelData.genericName) ?? ""
visible: text
}
@@ -171,7 +171,7 @@ PageBase {
MaterialIcon {
color: Colors.palette.m3primary
fill: 1
font.pointSize: Tokens.font.size.small
fontStyle: Tokens.font.icon.small
text: "favorite"
visible: Strings.testRegexList(Config.launcher.favoriteApps, appItem.modelData.id)
}
@@ -28,7 +28,6 @@ PageBase {
Layout.fillWidth: true
Layout.leftMargin: Tokens.padding.extraSmall
color: Colors.palette.m3outline
font.pointSize: Tokens.font.size.small
text: qsTr("Adjust the volume of individual apps currently playing audio.")
wrapMode: Text.WordWrap
}
+4 -4
View File
@@ -103,7 +103,7 @@ PageBase {
spacing: Tokens.spacing.small
MaterialIcon {
font.pointSize: Tokens.font.size.normal
fontStyle: Tokens.font.icon.medium
text: "tune"
}
@@ -114,7 +114,7 @@ PageBase {
CustomText {
Layout.fillWidth: true
elide: Text.ElideRight
font.pointSize: Tokens.font.size.small
font: Tokens.font.body.small
text: qsTr("App volumes")
}
@@ -123,14 +123,14 @@ PageBase {
animate: true
color: Colors.palette.m3outline
elide: Text.ElideRight
font.pointSize: Tokens.font.size.small
font: Tokens.font.body.small
text: Audio.streams.length === 0 ? qsTr("No apps playing audio") : Audio.streams.length === 1 ? qsTr("1 app playing audio") : qsTr("%1 apps playing audio").arg(Audio.streams.length)
}
}
MaterialIcon {
color: Colors.palette.m3onSurfaceVariant
font.pointSize: Tokens.font.size.normal
fontStyle: Tokens.font.icon.medium
text: "chevron_right"
}
}
@@ -57,6 +57,7 @@ PageBase {
icon: "add"
last: true
label: qsTr("Add entry")
last: true
model: {
const present = new Set(Config.bar.tray.statusIcons.values.map(item => item.id));
return Object.keys(root.builtinIcons).filter(id => !present.has(id)).map(id => ({
@@ -65,6 +66,7 @@ PageBase {
}));
}
rootParent: root.flickable
settingAnchor: "panels-bar-status-icons-add-item"
onAccepted: {
if (!selectedItem)
+3 -3
View File
@@ -91,7 +91,7 @@ PageBase {
first: true
icon: "widgets"
settingAnchor: "bar-tray"
status: qsTr("System tray icons")
subtext: qsTr("System tray icons")
text: qsTr("Tray")
onClicked: root.sState.openSubPage(6)
@@ -100,7 +100,7 @@ PageBase {
NavRow {
icon: "signal_cellular_alt"
settingAnchor: "bar-statusicons"
status: qsTr("Visible indicators")
subtext: qsTr("Visible indicators")
text: qsTr("Status icons")
onClicked: root.sState.openSubPage(7)
@@ -110,7 +110,7 @@ PageBase {
icon: "schedule"
last: true
settingAnchor: "bar-clock"
status: qsTr("Date, icon, background")
subtext: qsTr("Date, icon, background")
text: qsTr("Clock")
onClicked: root.sState.openSubPage(8)
@@ -33,5 +33,73 @@ PageBase {
onToggled: Config.dashboard.enabled = checked
}
// Tabs
SectionHeader {
text: qsTr("Tabs")
}
ToggleRow {
first: true
checked: Config.dashboard.showDashboard
settingAnchor: "dashboard-show-dashboard"
text: qsTr("Dashboard")
onToggled: Config.dashboard.showDashboard = checked
}
ToggleRow {
checked: Config.dashboard.showWeather
settingAnchor: "dashboard-show-weather"
text: qsTr("Weather")
onToggled: Config.dashboard.showWeather = checked
}
ToggleRow {
checked: Config.dashboard.showMedia
settingAnchor: "dashboard-show-media"
text: qsTr("Media")
onToggled: Config.dashboard.showMedia = checked
}
ToggleRow {
checked: Config.dashboard.showProcesses
settingAnchor: "dashboard-show-processes"
text: qsTr("Processes")
last: true
onToggled: Config.dashboard.showProcesses = checked
}
// Behavior
SectionHeader {
text: qsTr("Behavior")
}
ToggleRow {
checked: Config.dashboard.showOnHover
first: true
settingAnchor: "dashboard-showonhover"
text: qsTr("Show on hover")
subtext: qsTr("Dashboard %1 be shown when hovering the middle-top part of the shell").arg(checked ? "will" : "will not")
onToggled: Config.dashboard.showOnHover = checked
}
SpinRow {
from: 30
settingAnchor: "dashboard-drag-threshold"
stepSize: 20
enabled: !Config.dashboard.showOnHover
subtext: qsTr("How far you need to drag before the panel opens")
text: qsTr("Drag threshold")
to: 100
value: Config.dashboard.dragThreshold
last: true
onMoved: v => Config.dashboard.dragThreshold = v
}
}
}
@@ -88,6 +88,10 @@ PageBase {
enabled: Object.keys(model).length > 0
header: qsTr("Add new entry")
icon: "add"
onOpenChanged: {
root.sState.dimmed = open;
}
settingAnchor: "panels-sidebar-quick-toggles-add-item"
label: qsTr("Add entry")
last: true
model: {
+5 -5
View File
@@ -17,7 +17,7 @@ PageBase {
first: true
icon: "dock_to_bottom"
settingAnchor: "panels-bar"
status: !Config.bar.autoHide ? qsTr("Always visible") : qsTr("Reveal on hover")
subtext: !Config.bar.autoHide ? qsTr("Always visible") : qsTr("Reveal on hover")
text: qsTr("Bar")
onClicked: root.sState.openSubPage(1)
@@ -26,7 +26,7 @@ PageBase {
NavRow {
icon: "dashboard"
settingAnchor: "panels-dashboard"
status: Config.dashboard.enabled ? qsTr("Enabled") : qsTr("Disabled")
subtext: Config.dashboard.enabled ? qsTr("Enabled") : qsTr("Disabled")
text: qsTr("Dashboard")
onClicked: root.sState.openSubPage(2)
@@ -35,7 +35,7 @@ PageBase {
NavRow {
icon: "insert_chart"
settingAnchor: "panels-resources"
status: Config.dashboard.performance.enabled ? qsTr("Enabled") : qsTr("Disabled")
subtext: Config.dashboard.performance.enabled ? qsTr("Enabled") : qsTr("Disabled")
text: qsTr("Resources")
onClicked: root.sState.openSubPage(3)
@@ -44,7 +44,7 @@ PageBase {
NavRow {
icon: "apps"
settingAnchor: "panels-launcher"
status: Config.launcher.enabled ? qsTr("Enabled") : qsTr("Disabled")
subtext: Config.launcher.enabled ? qsTr("Enabled") : qsTr("Disabled")
text: qsTr("Launcher")
onClicked: root.sState.openSubPage(4)
@@ -54,7 +54,7 @@ PageBase {
icon: "dock_to_right"
last: true
settingAnchor: "panels-sidebar"
status: Config.sidebar.enabled ? qsTr("Enabled") : qsTr("Disabled")
subtext: Config.sidebar.enabled ? qsTr("Enabled") : qsTr("Disabled")
text: qsTr("Sidebar")
onClicked: root.sState.openSubPage(5)
+3 -3
View File
@@ -72,7 +72,7 @@ PageBase {
icon: "notifications"
last: true
settingAnchor: "services-notifications"
status: qsTr("Notifications, toasts, timeouts")
subtext: qsTr("Notifications, toasts, timeouts")
text: qsTr("Notifications")
onClicked: root.sState.openSubPage(1)
@@ -202,12 +202,12 @@ PageBase {
}
ToggleRow {
checked: Config.general.color.smart
checked: Config.colors.smart
settingAnchor: "services-smart-color-scheme"
subtext: qsTr("Derive theme mode from the wallpaper")
text: qsTr("Smart color scheme")
onToggled: Config.general.color.smart = checked
onToggled: Config.colors.smart = checked
}
SelectRow {
@@ -0,0 +1,327 @@
pragma ComponentBehavior: Bound
import Quickshell
import Quickshell.Io
import QtQuick
import QtQuick.Layouts
import ZShell.Config
import qs.Paths
import qs.Services
import qs.Modules.Settings.Common
PageBase {
id: root
readonly property list<string> fonts: Qt.fontFamilies()
readonly property var schemes: [
{
id: "onedark",
label: qsTr("One Dark")
},
{
id: "nord",
label: qsTr("Nord")
},
{
id: "dracula",
label: qsTr("Dracula")
},
{
id: "darkgreen",
label: qsTr("Darkgreen")
},
{
id: "solarized",
label: qsTr("Solarized")
},
{
id: "rosepine",
label: qsTr("Rosepine")
},
{
id: "gruvbox",
label: qsTr("Gruvbox")
},
{
id: "catppuccin",
label: qsTr("Catppuccin")
},
{
id: "tokyonight",
label: qsTr("Tokyo Night")
},
{
id: "shadotheme",
label: qsTr("Shadotheme")
}
]
isSubPage: true
title: qsTr("Colors & font")
ColumnLayout {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
spacing: Tokens.spacing.extraSmall / 2
width: root.cappedWidth
SectionHeader {
first: true
text: qsTr("Colors")
}
ToggleRow {
text: qsTr("Dynamic colors")
first: true
subtext: qsTr("Automatic color scheme based on wallpaper is %1").arg(Config.colors.schemeGen ? "enabled" : "disabled")
checked: Config.colors.schemeGen
settingAnchor: "colors-fonts-dynamic-colors"
onToggled: {
Config.colors.schemeGen = checked;
if (checked)
Colors.setMode(Config.colors.mode);
}
}
DialogSelectButton {
settingAnchor: "colors-fonts-preset-scheme"
model: root.schemes
acceptLabel: qsTr("Confirm")
enabled: !Config.colors.schemeGen
header: qsTr("Select scheme")
rowButton.activeItem: root.schemes.find(s => {
var regex = new RegExp(Config.colors.presets.name, "i");
return regex.test(s.id);
}).label ?? ""
label: qsTr("Preset scheme")
subtext: qsTr("Select preset color scheme")
rootParent: root.flickable
FileView {
id: view
path: `${Paths.state}/presets.json`
watchChanges: true
onFileChanged: reload()
JsonAdapter {
id: adapter
property var presets
}
}
initialSelect: Config.colors.presets.name.toLowerCase()
onAccepted: {
if (!selectedItem)
return;
const s = selectedItem.toLowerCase();
let v = "";
let a = "";
const existingVariant = Config.colors.presets.variant;
const existingAccent = Config.colors.presets.accent;
const variantKeys = Object.keys(adapter.presets[s].variants);
if (existingVariant !== "" && variantKeys.some(v => v === existingVariant))
v = existingVariant;
if (v !== "" && existingAccent !== "" && adapter.presets[s].variants[v]?.accents.some(a => a === existingAccent))
a = existingAccent;
if (a !== "")
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`, "-a", `${a}`]);
else if (v !== "")
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`]);
else
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${variantKeys[0]}`]);
}
}
DialogSelectButton {
settingAnchor: "colors-fonts-preset-variant"
// qmlformat off
model: {
const v = adapter.presets[Config.colors.presets.name].variants;
const map = Object.keys(v).map(v => ({
id: v,
label: qsTr("%1%2")
.arg(v.charAt(0).toUpperCase())
.arg(v.slice(1).toLowerCase())
}));
return map;
}
// qmlformat on
acceptLabel: qsTr("Confirm")
enabled: !Config.colors.schemeGen && model.length > 1
header: qsTr("Select variant")
rowButton.activeItem: {
const v = Config.colors.presets.variant ?? "";
if (v === "")
return "";
return qsTr("%1%2").arg(v.charAt(0).toUpperCase()).arg(v.slice(1).toLowerCase());
}
label: qsTr("Variant")
subtext: qsTr("Select preset variant")
rootParent: root.flickable
initialSelect: Config.colors.presets.variant
onAccepted: {
if (!selectedItem)
return;
const v = selectedItem.toLowerCase();
const s = Config.colors.presets.name;
const existingAccent = Config.colors.presets.accent;
let a = "";
if (existingAccent !== "" && adapter.presets[s].variants[v]?.accents.some(a => a === existingAccent))
a = existingAccent;
if (a !== "")
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`, "-a", `${a}`]);
else
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`]);
}
}
DialogSelectButton {
settingAnchor: "colors-fonts-preset-accent"
// qmlformat off
model: {
const a = adapter.presets[Config.colors.presets.name].variants[Config.colors.presets.variant]?.accents ?? [];
if (a.length === 0)
return a;
const map = a.map(a => ({
id: a,
label: qsTr("%1%2")
.arg(a.charAt(0).toUpperCase())
.arg(a.slice(1).toLowerCase())
}));
return map;
}
// qmlformat on
acceptLabel: qsTr("Confirm")
enabled: !Config.colors.schemeGen && model.length > 1
header: qsTr("Select accent")
rowButton.activeItem: {
const a = Config.colors.presets.accent ?? "";
if (a === "")
return "";
return qsTr("%1%2").arg(a.charAt(0).toUpperCase()).arg(a.slice(1).toLowerCase());
}
label: qsTr("Accent")
last: true
subtext: qsTr("Select preset accent")
rootParent: root.flickable
initialSelect: Config.colors.presets.accent
onAccepted: {
if (!selectedItem)
return;
const a = selectedItem.toLowerCase();
const v = Config.colors.presets.variant;
const s = Config.colors.presets.name;
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`, "-a", `${a}`]);
}
}
SectionHeader {
text: qsTr("Fonts")
}
SearchPopup {
id: selectSansFont
settingAnchor: "colors-fonts-sans-font"
model: root.fonts
acceptLabel: qsTr("Confirm")
enabled: Object.keys(model).length > 0
separateContent: false
header: qsTr("Select font")
first: true
rowButton.activeItem: root.fonts.find(s => {
var regex = new RegExp(Config.appearance.font.family.sans, "i");
return regex.test(s);
}) ?? ""
label: qsTr("Sans font")
subtext: qsTr("Select desired sans font")
rootParent: root.flickable
initialSelect: Config.appearance.font.family.sans
onAccepted: {
if (!selectedItem)
return;
Config.appearance.font.family.sans = selectedItem;
}
}
SearchPopup {
id: selectMonoFont
acceptLabel: qsTr("Confirm")
enabled: Object.keys(model).length > 0
settingAnchor: "colors-fonts-mono-font"
separateContent: false
header: qsTr("Select font")
rowButton.activeItem: root.fonts.find(s => {
var regex = new RegExp(Config.appearance.font.family.mono, "i");
return regex.test(s);
}) ?? ""
label: qsTr("Mono font")
subtext: qsTr("Select desired mono font")
model: root.fonts
rootParent: root.flickable
initialSelect: Config.appearance.font.family.mono
onAccepted: {
if (!selectedItem)
return;
Config.appearance.font.family.mono = selectedItem;
}
}
SearchPopup {
id: selectClockFont
acceptLabel: qsTr("Confirm")
enabled: Object.keys(model).length > 0
separateContent: false
settingAnchor: "colors-fonts-clock-font"
header: qsTr("Select font")
last: true
rowButton.activeItem: root.fonts.find(s => {
var regex = new RegExp(Config.appearance.font.family.clock, "i");
return regex.test(s);
}) ?? ""
label: qsTr("Clock font")
subtext: qsTr("Select desired clock font")
model: root.fonts
rootParent: root.flickable
initialSelect: Config.appearance.font.family.clock
onAccepted: {
if (!selectedItem)
return;
Config.appearance.font.family.clock = selectedItem;
}
}
}
}
@@ -25,7 +25,7 @@ PageBase {
CustomText {
Layout.topMargin: Tokens.spacing.largeIncreased
font.pointSize: Tokens.font.size.large
font: Tokens.font.title.small
text: qsTr("Wallpapers")
}
+107 -59
View File
@@ -33,18 +33,35 @@ PageBase {
}
}
IconTextButton {
ButtonRow {
Layout.alignment: Qt.AlignHCenter
enabled: Config.background.enabled
horizontalPadding: Tokens.padding.extraLarge
icon: "wallpaper"
isRound: true
shapeMorph: true
text: qsTr("Wallpapers")
type: IconTextButton.Tonal
verticalPadding: Tokens.padding.small
spacing: Tokens.spacing.small
onClicked: root.sState.openSubPage(1) // Wallpaper page
IconTextButton {
enabled: Config.background.enabled
horizontalPadding: Tokens.padding.extraLarge
icon: "wallpaper"
isRound: true
shapeMorph: true
text: qsTr("Wallpapers")
type: IconTextButton.Tonal
verticalPadding: Tokens.padding.small
onClicked: root.sState.openSubPage(1) // Wallpaper page
}
IconTextButton {
enabled: Config.background.enabled
horizontalPadding: Tokens.padding.extraLarge
icon: "palette"
isRound: true
shapeMorph: true
text: qsTr("Colors & font")
type: IconTextButton.Tonal
verticalPadding: Tokens.padding.small
onClicked: root.sState.openSubPage(2) // Colors & font page
}
}
ToggleRow {
@@ -76,85 +93,116 @@ PageBase {
onToggled: Colors.setMode(checked ? "dark" : "light")
}
OverlayRow {
id: darkMode
TimeDialogSelect {
readonly property string endTime: {
var d = new Date(0, 0, 0, 0, 0, 0, 0);
d.setMinutes(Config.general.color.scheduleDarkEnd);
d.setMinutes(Config.colors.scheduleDarkEnd);
return Qt.formatTime(d, "hh:mm AP");
}
readonly property string startTime: {
var d = new Date(0, 0, 0, 0, 0, 0, 0);
d.setMinutes(Config.general.color.scheduleDarkStart);
d.setMinutes(Config.colors.scheduleDarkStart);
return Qt.formatTime(d, "hh:mm AP");
}
checked: Config.general.color.scheduleDark
rowButton.checked: Config.colors.scheduleDark
rowButton.onToggled: Config.colors.scheduleDark = rowButton.checked
start: Config.colors.scheduleDarkStart
end: Config.colors.scheduleDarkEnd
first: true
last: true
settingAnchor: "style-schedule-dark-mode"
acceptLabel: qsTr("Apply")
rootParent: root.flickable
header: qsTr("Select time")
subtext: qsTr("Dark mode will turn on at %1, and turn off at %2.").arg(startTime).arg(endTime)
text: qsTr("Schedule dark mode")
label: qsTr("Schedule dark mode")
popup: Component {
TimeInput {
object: Config.general.color
settings: ["scheduleDark", "scheduleDarkStart", "scheduleDarkEnd"]
onApplySettings: (start, end) => {
Config.general.color.scheduleDarkStart = start;
Config.general.color.scheduleDarkEnd = end;
ModeScheduler.checkStartup();
PopupManager.requestClose();
}
onClose: PopupManager.requestClose()
}
onOpenChanged: {
root.sState.dimmed = open;
}
onClicked: value => {
Config.general.color.scheduleDark = value;
onAccepted: {
Config.colors.scheduleDarkStart = startCurrent;
Config.colors.scheduleDarkEnd = endCurrent;
ModeScheduler.checkStartup();
}
}
OverlayRow {
id: hyprsunset
TimeDialogSelect {
readonly property string endTime: {
var d = new Date(0, 0, 0, 0, 0, 0, 0);
d.setMinutes(Config.general.color.scheduleHyprsunsetEnd);
d.setMinutes(Config.display.nightlight.scheduleEnd);
return Qt.formatTime(d, "hh:mm AP");
}
readonly property string startTime: {
var d = new Date(0, 0, 0, 0, 0, 0, 0);
d.setMinutes(Config.general.color.scheduleHyprsunsetStart);
d.setMinutes(Config.display.nightlight.scheduleStart);
return Qt.formatTime(d, "hh:mm AP");
}
rowButton.checked: Config.display.nightlight.schedule
rowButton.onToggled: Config.display.nightlight.schedule = rowButton.checked
start: Config.display.nightlight.scheduleStart
end: Config.display.nightlight.scheduleEnd
first: true
settingAnchor: "style-schedule-nightlight"
acceptLabel: qsTr("Apply")
rootParent: root.flickable
header: qsTr("Select time")
subtext: qsTr("Nightlight will turn on at %1, and turn off at %2.").arg(startTime).arg(endTime)
label: qsTr("Schedule nightlight")
onOpenChanged: {
root.sState.dimmed = open;
}
onAccepted: {
Config.display.nightlight.scheduleStart = startCurrent;
Config.display.nightlight.scheduleEnd = endCurrent;
Nightlight.checkStartup();
}
}
ToggleRow {
Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing
checked: Config.general.color.scheduleHyprsunset
checked: Config.display.nightlight.useNative
settingAnchor: "display-nightlight-useNative"
text: qsTr("Use native")
subtext: qsTr("Use native shader nightlight for more features")
onToggled: Config.display.nightlight.useNative = checked
}
SpinRow {
Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing
from: 2000
settingAnchor: "display-nightlight-temp"
stepSize: 100
subtext: qsTr("How warm/orange the screen will be. Lower is warmer (Kelvin)")
text: qsTr("Temperature")
to: 6500
value: Config.display.nightlight.temp
onMoved: v => Config.display.nightlight.temp = v
}
SpinRow {
Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing
from: 0
settingAnchor: "display-nightlight-fade-duration"
enabled: Config.display.nightlight.useNative
last: true
settingAnchor: "style-schedule-hyprsunset"
subtext: qsTr("Hyprsunset will turn on at %1, and turn off at %2.").arg(startTime).arg(endTime)
text: qsTr("Schedule hyprsunset")
stepSize: 1
subtext: qsTr("How long it takes for the gradual nightlight to finish (s)")
text: qsTr("Fade duration")
to: 60 * 5
value: Config.display.nightlight.fadeDuration / 1000
popup: Component {
TimeInput {
object: Config.general.color
settings: ["scheduleHyprsunset", "scheduleHyprsunsetStart", "scheduleHyprsunsetEnd"]
onApplySettings: (start, end) => {
Config.general.color.scheduleHyprsunsetStart = start;
Config.general.color.scheduleHyprsunsetEnd = end;
Hyprsunset.checkStartup();
PopupManager.requestClose();
}
onClose: PopupManager.requestClose()
}
}
onClicked: value => {
Config.general.color.scheduleHyprsunset = value;
}
onMoved: v => Config.display.nightlight.fadeDuration = v * 1000
}
}
}