Create separate matugen toggles, add MatugenService
Matugen: add Matugen.qml as central place for templates, add MatugenService to take care of .toml generation Notification: possible fix for "children of null"
This commit is contained in:
parent
85b92d9c6f
commit
f510c1922d
10 changed files with 610 additions and 501 deletions
52
Assets/Matugen/Matugen.qml
Normal file
52
Assets/Matugen/Matugen.qml
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
|
||||
// Central place to define which templates we generate and where they write.
|
||||
// Users can extend it by dropping additional templates into:
|
||||
// - Assets/Matugen/templates/
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
// Build the base TOML using current settings
|
||||
function buildConfigToml() {
|
||||
var lines = []
|
||||
lines.push("[config]")
|
||||
|
||||
// Always include noctalia colors output for the shell
|
||||
lines.push("[templates.noctalia]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/noctalia.json"')
|
||||
lines.push('output_path = "' + Settings.configDir + 'colors.json"')
|
||||
|
||||
if (Settings.data.matugen.gtk4) {
|
||||
lines.push("\n[templates.gtk4]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/gtk4.css"')
|
||||
lines.push('output_path = "~/.config/gtk-4.0/gtk.css"')
|
||||
}
|
||||
if (Settings.data.matugen.gtk3) {
|
||||
lines.push("\n[templates.gtk3]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/gtk3.css"')
|
||||
lines.push('output_path = "~/.config/gtk-3.0/gtk.css"')
|
||||
}
|
||||
if (Settings.data.matugen.qt6) {
|
||||
lines.push("\n[templates.qt6]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/qtct.conf"')
|
||||
lines.push('output_path = "~/.config/qt6ct/colors/noctalia.conf"')
|
||||
}
|
||||
if (Settings.data.matugen.qt5) {
|
||||
lines.push("\n[templates.qt5]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/qtct.conf"')
|
||||
lines.push('output_path = "~/.config/qt5ct/colors/noctalia.conf"')
|
||||
}
|
||||
if (Settings.data.matugen.kitty) {
|
||||
lines.push("\n[templates.kitty]")
|
||||
lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/kitty.conf"')
|
||||
lines.push('output_path = "~/.config/kitty/themes/noctalia.conf"')
|
||||
lines.push("post_hook = 'kitty +kitten themes --reload-in=all noctalia'")
|
||||
}
|
||||
|
||||
return lines.join("\n") + "\n"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
# Base: only write Noctalia colors.json for the shell
|
||||
[config]
|
||||
|
||||
[templates.noctalia]
|
||||
input_path = "templates/noctalia.json"
|
||||
output_path = "~/.config/noctalia/colors.json"
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
# This file configures how matugen generates colors from wallpapers for Noctalia
|
||||
[config]
|
||||
|
||||
|
||||
[templates.noctalia]
|
||||
input_path = "templates/noctalia.json"
|
||||
output_path = "~/.config/noctalia/colors.json"
|
||||
|
||||
# GTK 4 (libadwaita) variables override
|
||||
[templates.gtk4]
|
||||
input_path = "templates/gtk4.css"
|
||||
output_path = "~/.config/gtk-4.0/gtk.css"
|
||||
|
||||
# GTK 3 named-colors fallback for legacy apps
|
||||
[templates.gtk3]
|
||||
input_path = "templates/gtk3.css"
|
||||
output_path = "~/.config/gtk-3.0/gtk.css"
|
||||
|
||||
# Qt6ct color scheme (can also be used by qt5ct in many distros)
|
||||
[templates.qt6]
|
||||
input_path = "templates/qtct.conf"
|
||||
output_path = "~/.config/qt6ct/colors/noctalia.conf"
|
||||
|
||||
[templates.qt5]
|
||||
input_path = "templates/qtct.conf"
|
||||
output_path = "~/.config/qt5ct/colors/noctalia.conf"
|
||||
|
||||
[templates.kitty]
|
||||
input_path = "templates/kitty.conf"
|
||||
output_path = "~/.config/kitty/themes/noctalia.conf"
|
||||
post_hook = 'kitty +kitten themes --reload-in=all noctalia'
|
||||
|
|
@ -256,8 +256,16 @@ Singleton {
|
|||
property bool useWallpaperColors: false
|
||||
property string predefinedScheme: ""
|
||||
property bool darkMode: true
|
||||
// External app theming (GTK & Qt)
|
||||
property bool themeApps: false
|
||||
}
|
||||
|
||||
// matugen templates toggles
|
||||
property JsonObject matugen: JsonObject {
|
||||
// Per-template flags to control dynamic config generation
|
||||
property bool gtk4: false
|
||||
property bool gtk3: false
|
||||
property bool qt6: false
|
||||
property bool qt5: false
|
||||
property bool kitty: false
|
||||
}
|
||||
|
||||
// night light
|
||||
|
|
|
|||
|
|
@ -25,8 +25,10 @@ Variants {
|
|||
property var removingNotifications: ({})
|
||||
|
||||
// If no notification display activated in settings, then show them all
|
||||
active: Settings.isLoaded && modelData && (NotificationService.notificationModel.count > 0) ? (Settings.data.notifications.monitors.includes(modelData.name)
|
||||
|| (Settings.data.notifications.monitors.length === 0)) : false
|
||||
active: Settings.isLoaded && modelData
|
||||
&& (NotificationService.notificationModel.count > 0) ? (Settings.data.notifications.monitors.includes(
|
||||
modelData.name)
|
||||
|| (Settings.data.notifications.monitors.length === 0)) : false
|
||||
|
||||
visible: (NotificationService.notificationModel.count > 0)
|
||||
|
||||
|
|
@ -51,7 +53,7 @@ Variants {
|
|||
NotificationService.animateAndRemove.connect(function (notification, index) {
|
||||
// Prefer lookup by identity to avoid index mismatches
|
||||
var delegate = null
|
||||
if (notificationStack.children && notificationStack.children.length > 0) {
|
||||
if (notificationStack && notificationStack.children && notificationStack.children.length > 0) {
|
||||
for (var i = 0; i < notificationStack.children.length; i++) {
|
||||
var child = notificationStack.children[i]
|
||||
if (child && child.model && child.model.rawNotification === notification) {
|
||||
|
|
@ -62,7 +64,7 @@ Variants {
|
|||
}
|
||||
|
||||
// Fallback to index if identity lookup failed
|
||||
if (!delegate && notificationStack.children && notificationStack.children[index]) {
|
||||
if (!delegate && notificationStack && notificationStack.children && notificationStack.children[index]) {
|
||||
delegate = notificationStack.children[index]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import qs.Services
|
|||
import qs.Widgets
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
id: root
|
||||
|
||||
property string latestVersion: GitHubService.latestVersion
|
||||
property string currentVersion: "Unknown" // Fallback version
|
||||
|
|
@ -37,199 +37,196 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Noctalia Shell"
|
||||
font.pointSize: Style.fontSizeXXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
columns: 2
|
||||
rowSpacing: Style.marginXS * scaling
|
||||
columnSpacing: Style.marginS * scaling
|
||||
|
||||
NText {
|
||||
text: "Latest Version:"
|
||||
color: Color.mOnSurface
|
||||
Layout.alignment: Qt.AlignRight
|
||||
}
|
||||
|
||||
NText {
|
||||
text: root.latestVersion
|
||||
color: Color.mOnSurface
|
||||
font.weight: Style.fontWeightBold
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Installed Version:"
|
||||
color: Color.mOnSurface
|
||||
Layout.alignment: Qt.AlignRight
|
||||
}
|
||||
|
||||
NText {
|
||||
text: root.currentVersion
|
||||
color: Color.mOnSurface
|
||||
font.weight: Style.fontWeightBold
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.topMargin: Style.marginS * scaling
|
||||
Layout.preferredWidth: updateText.implicitWidth + 46 * scaling
|
||||
Layout.preferredHeight: Style.barHeight * scaling
|
||||
radius: Style.radiusL * scaling
|
||||
color: updateArea.containsMouse ? Color.mPrimary : Color.transparent
|
||||
border.color: Color.mPrimary
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
visible: {
|
||||
if (root.currentVersion === "Unknown" || root.latestVersion === "Unknown")
|
||||
return false
|
||||
|
||||
const latest = root.latestVersion.replace("v", "").split(".")
|
||||
const current = root.currentVersion.replace("v", "").split(".")
|
||||
for (var i = 0; i < Math.max(latest.length, current.length); i++) {
|
||||
const l = parseInt(latest[i] || "0")
|
||||
const c = parseInt(current[i] || "0")
|
||||
if (l > c)
|
||||
return true
|
||||
|
||||
if (l < c)
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: Style.marginS * scaling
|
||||
|
||||
NIcon {
|
||||
text: "system_update"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
color: updateArea.containsMouse ? Color.mSurface : Color.mPrimary
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Noctalia Shell"
|
||||
font.pointSize: Style.fontSizeXXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
id: updateText
|
||||
text: "Download latest release"
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
color: updateArea.containsMouse ? Color.mSurface : Color.mPrimary
|
||||
}
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
columns: 2
|
||||
rowSpacing: Style.marginXS * scaling
|
||||
columnSpacing: Style.marginS * scaling
|
||||
MouseArea {
|
||||
id: updateArea
|
||||
|
||||
NText {
|
||||
text: "Latest Version:"
|
||||
color: Color.mOnSurface
|
||||
Layout.alignment: Qt.AlignRight
|
||||
}
|
||||
|
||||
NText {
|
||||
text: root.latestVersion
|
||||
color: Color.mOnSurface
|
||||
font.weight: Style.fontWeightBold
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Installed Version:"
|
||||
color: Color.mOnSurface
|
||||
Layout.alignment: Qt.AlignRight
|
||||
}
|
||||
|
||||
NText {
|
||||
text: root.currentVersion
|
||||
color: Color.mOnSurface
|
||||
font.weight: Style.fontWeightBold
|
||||
}
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
Quickshell.execDetached(["xdg-open", "https://github.com/Ly-sec/Noctalia/releases/latest"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.topMargin: Style.marginS * scaling
|
||||
Layout.preferredWidth: updateText.implicitWidth + 46 * scaling
|
||||
Layout.preferredHeight: Style.barHeight * scaling
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginxL * scaling
|
||||
}
|
||||
|
||||
NText {
|
||||
text: `Shout-out to our ${root.contributors.length} awesome contributors!`
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.topMargin: Style.marginL * 2
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.preferredWidth: 200 * Style.marginXS * scaling
|
||||
Layout.fillHeight: true
|
||||
Layout.topMargin: Style.marginL * scaling
|
||||
clip: true
|
||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
||||
|
||||
GridView {
|
||||
id: contributorsGrid
|
||||
|
||||
anchors.fill: parent
|
||||
width: 200 * 4 * scaling
|
||||
height: Math.ceil(root.contributors.length / 4) * 100
|
||||
cellWidth: Style.baseWidgetSize * 6.25 * scaling
|
||||
cellHeight: Style.baseWidgetSize * 3.125 * scaling
|
||||
model: root.contributors
|
||||
|
||||
delegate: Rectangle {
|
||||
width: contributorsGrid.cellWidth - Style.marginL * scaling
|
||||
height: contributorsGrid.cellHeight - Style.marginXS * scaling
|
||||
radius: Style.radiusL * scaling
|
||||
color: updateArea.containsMouse ? Color.mPrimary : Color.transparent
|
||||
border.color: Color.mPrimary
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
visible: {
|
||||
if (root.currentVersion === "Unknown" || root.latestVersion === "Unknown")
|
||||
return false
|
||||
|
||||
const latest = root.latestVersion.replace("v", "").split(".")
|
||||
const current = root.currentVersion.replace("v", "").split(".")
|
||||
for (var i = 0; i < Math.max(latest.length, current.length); i++) {
|
||||
const l = parseInt(latest[i] || "0")
|
||||
const c = parseInt(current[i] || "0")
|
||||
if (l > c)
|
||||
return true
|
||||
|
||||
if (l < c)
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
color: contributorArea.containsMouse ? Color.mSecondary : Color.transparent
|
||||
|
||||
RowLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: Style.marginS * scaling
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginS * scaling
|
||||
spacing: Style.marginM * scaling
|
||||
|
||||
NIcon {
|
||||
text: "system_update"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
color: updateArea.containsMouse ? Color.mSurface : Color.mPrimary
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.preferredWidth: Style.baseWidgetSize * 2 * scaling
|
||||
Layout.preferredHeight: Style.baseWidgetSize * 2 * scaling
|
||||
|
||||
NImageCircled {
|
||||
imagePath: modelData.avatar_url || ""
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginXS * scaling
|
||||
fallbackIcon: "person"
|
||||
borderColor: Color.mPrimary
|
||||
borderWidth: Math.max(1, Style.borderM * scaling)
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
id: updateText
|
||||
text: "Download latest release"
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
color: updateArea.containsMouse ? Color.mSurface : Color.mPrimary
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXS * scaling
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
|
||||
NText {
|
||||
text: modelData.login || "Unknown"
|
||||
font.weight: Style.fontWeightBold
|
||||
color: contributorArea.containsMouse ? Color.mSurface : Color.mOnSurface
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
NText {
|
||||
text: (modelData.contributions || 0) + " " + ((modelData.contributions || 0) === 1 ? "commit" : "commits")
|
||||
font.pointSize: Style.fontSizeXS * scaling
|
||||
color: contributorArea.containsMouse ? Color.mSurface : Color.mOnSurface
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: updateArea
|
||||
id: contributorArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
Quickshell.execDetached(["xdg-open", "https://github.com/Ly-sec/Noctalia/releases/latest"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginxL * scaling
|
||||
}
|
||||
|
||||
NText {
|
||||
text: `Shout-out to our ${root.contributors.length} awesome contributors!`
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.topMargin: Style.marginL * 2
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.preferredWidth: 200 * Style.marginXS * scaling
|
||||
Layout.fillHeight: true
|
||||
Layout.topMargin: Style.marginL * scaling
|
||||
clip: true
|
||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
||||
|
||||
GridView {
|
||||
id: contributorsGrid
|
||||
|
||||
anchors.fill: parent
|
||||
width: 200 * 4 * scaling
|
||||
height: Math.ceil(root.contributors.length / 4) * 100
|
||||
cellWidth: Style.baseWidgetSize * 6.25 * scaling
|
||||
cellHeight: Style.baseWidgetSize * 3.125 * scaling
|
||||
model: root.contributors
|
||||
|
||||
delegate: Rectangle {
|
||||
width: contributorsGrid.cellWidth - Style.marginL * scaling
|
||||
height: contributorsGrid.cellHeight - Style.marginXS * scaling
|
||||
radius: Style.radiusL * scaling
|
||||
color: contributorArea.containsMouse ? Color.mSecondary : Color.transparent
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginS * scaling
|
||||
spacing: Style.marginM * scaling
|
||||
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.preferredWidth: Style.baseWidgetSize * 2 * scaling
|
||||
Layout.preferredHeight: Style.baseWidgetSize * 2 * scaling
|
||||
|
||||
NImageCircled {
|
||||
imagePath: modelData.avatar_url || ""
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginXS * scaling
|
||||
fallbackIcon: "person"
|
||||
borderColor: Color.mPrimary
|
||||
borderWidth: Math.max(1, Style.borderM * scaling)
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXS * scaling
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
|
||||
NText {
|
||||
text: modelData.login || "Unknown"
|
||||
font.weight: Style.fontWeightBold
|
||||
color: contributorArea.containsMouse ? Color.mSurface : Color.mOnSurface
|
||||
elide: Text.ElideRight
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
NText {
|
||||
text: (modelData.contributions || 0) + " " + ((modelData.contributions
|
||||
|| 0) === 1 ? "commit" : "commits")
|
||||
font.pointSize: Style.fontSizeXS * scaling
|
||||
color: contributorArea.containsMouse ? Color.mSurface : Color.mOnSurface
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: contributorArea
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (modelData.html_url)
|
||||
Quickshell.execDetached(["xdg-open", modelData.html_url])
|
||||
}
|
||||
}
|
||||
if (modelData.html_url)
|
||||
Quickshell.execDetached(["xdg-open", modelData.html_url])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,7 +104,6 @@ ColumnLayout {
|
|||
}
|
||||
|
||||
ColumnLayout {
|
||||
width: scrollView.availableWidth
|
||||
spacing: 0
|
||||
|
||||
Item {
|
||||
|
|
@ -125,7 +124,7 @@ ColumnLayout {
|
|||
onToggled: checked => {
|
||||
Settings.data.colorSchemes.darkMode = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors) {
|
||||
ColorSchemeService.changedWallpaper()
|
||||
MatugenService.generateFromWallpaper()
|
||||
} else if (Settings.data.colorSchemes.predefinedScheme) {
|
||||
// Re-apply current scheme to pick the right variant
|
||||
ColorSchemeService.applyScheme(Settings.data.colorSchemes.predefinedScheme)
|
||||
|
|
@ -137,19 +136,6 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
// App theming
|
||||
NToggle {
|
||||
label: "Theme external apps (GTK, Qt & kitty)"
|
||||
description: "Writes GTK (gtk.css), Qt5/6 (noctalia.conf) and Kitty (noctalia.conf) themes based on your colors."
|
||||
checked: Settings.data.colorSchemes.themeApps
|
||||
onToggled: checked => {
|
||||
Settings.data.colorSchemes.themeApps = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors) {
|
||||
ColorSchemeService.changedWallpaper()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use Matugen
|
||||
NToggle {
|
||||
label: "Enable Matugen"
|
||||
|
|
@ -348,5 +334,84 @@ ColumnLayout {
|
|||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
visible: Settings.data.colorSchemes.useWallpaperColors
|
||||
}
|
||||
|
||||
// Matugen template toggles (moved from MatugenTab)
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
visible: Settings.data.colorSchemes.useWallpaperColors
|
||||
|
||||
NText {
|
||||
text: "Matugen Templates"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mSecondary
|
||||
Layout.bottomMargin: Style.marginS * scaling
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Choose which external components should be themed by Matugen."
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.fillWidth: true
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: "GTK 4 (libadwaita)"
|
||||
description: "Write ~/.config/gtk-4.0/gtk.css"
|
||||
checked: Settings.data.matugen.gtk4
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.gtk4 = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: "GTK 3"
|
||||
description: "Write ~/.config/gtk-3.0/gtk.css"
|
||||
checked: Settings.data.matugen.gtk3
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.gtk3 = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: "Qt6ct"
|
||||
description: "Write ~/.config/qt6ct/colors/noctalia.conf"
|
||||
checked: Settings.data.matugen.qt6
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.qt6 = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: "Qt5ct"
|
||||
description: "Write ~/.config/qt5ct/colors/noctalia.conf"
|
||||
checked: Settings.data.matugen.qt5
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.qt5 = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: "Kitty"
|
||||
description: "Write ~/.config/kitty/themes/noctalia.conf and reload"
|
||||
checked: Settings.data.matugen.kitty
|
||||
onToggled: checked => {
|
||||
Settings.data.matugen.kitty = checked
|
||||
if (Settings.data.colorSchemes.useWallpaperColors)
|
||||
MatugenService.generateFromWallpaper()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,168 +43,166 @@ ColumnLayout {
|
|||
})
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Monitor-specific configuration"
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Monitor-specific configuration"
|
||||
font.pointSize: Style.fontSizeL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
}
|
||||
NText {
|
||||
text: "Bars and notifications appear on all displays by default. Choose specific displays below to limit where they're shown."
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: parent.width - (Style.marginL * 2 * scaling)
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Bars and notifications appear on all displays by default. Choose specific displays below to limit where they're shown."
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: parent.width - (Style.marginL * 2 * scaling)
|
||||
}
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.topMargin: Style.marginL * scaling
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.topMargin: Style.marginL * scaling
|
||||
Repeater {
|
||||
model: Quickshell.screens || []
|
||||
delegate: Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 550 * scaling
|
||||
radius: Style.radiusM * scaling
|
||||
color: Color.mSurface
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
implicitHeight: contentCol.implicitHeight + Style.marginXL * 2 * scaling
|
||||
|
||||
Repeater {
|
||||
model: Quickshell.screens || []
|
||||
delegate: Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 550 * scaling
|
||||
radius: Style.radiusM * scaling
|
||||
color: Color.mSurface
|
||||
border.color: Color.mOutline
|
||||
border.width: Math.max(1, Style.borderS * scaling)
|
||||
implicitHeight: contentCol.implicitHeight + Style.marginXL * 2 * scaling
|
||||
ColumnLayout {
|
||||
id: contentCol
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginL * scaling
|
||||
spacing: Style.marginXXS * scaling
|
||||
|
||||
NText {
|
||||
text: (modelData.name || "Unknown")
|
||||
font.pointSize: Style.fontSizeXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mSecondary
|
||||
}
|
||||
|
||||
NText {
|
||||
text: `Resolution: ${modelData.width}x${modelData.height} - Position: (${modelData.x}, ${modelData.y})`
|
||||
font.pointSize: Style.fontSizeXS * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: contentCol
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginL * scaling
|
||||
spacing: Style.marginXXS * scaling
|
||||
spacing: Style.marginL * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NText {
|
||||
text: (modelData.name || "Unknown")
|
||||
font.pointSize: Style.fontSizeXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mSecondary
|
||||
NToggle {
|
||||
Layout.fillWidth: true
|
||||
label: "Bar"
|
||||
description: "Enable the bar on this monitor."
|
||||
checked: (Settings.data.bar.monitors || []).indexOf(modelData.name) !== -1
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
Settings.data.bar.monitors = addMonitor(Settings.data.bar.monitors, modelData.name)
|
||||
} else {
|
||||
Settings.data.bar.monitors = removeMonitor(Settings.data.bar.monitors, modelData.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
text: `Resolution: ${modelData.width}x${modelData.height} - Position: (${modelData.x}, ${modelData.y})`
|
||||
font.pointSize: Style.fontSizeXS * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
NToggle {
|
||||
Layout.fillWidth: true
|
||||
label: "Notifications"
|
||||
description: "Enable notifications on this monitor."
|
||||
checked: (Settings.data.notifications.monitors || []).indexOf(modelData.name) !== -1
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
Settings.data.notifications.monitors = addMonitor(Settings.data.notifications.monitors,
|
||||
modelData.name)
|
||||
} else {
|
||||
Settings.data.notifications.monitors = removeMonitor(Settings.data.notifications.monitors,
|
||||
modelData.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
Layout.fillWidth: true
|
||||
label: "Dock"
|
||||
description: "Enable the dock on this monitor."
|
||||
checked: (Settings.data.dock.monitors || []).indexOf(modelData.name) !== -1
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
Settings.data.dock.monitors = addMonitor(Settings.data.dock.monitors, modelData.name)
|
||||
} else {
|
||||
Settings.data.dock.monitors = removeMonitor(Settings.data.dock.monitors, modelData.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginL * scaling
|
||||
spacing: Style.marginS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NToggle {
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
label: "Bar"
|
||||
description: "Enable the bar on this monitor."
|
||||
checked: (Settings.data.bar.monitors || []).indexOf(modelData.name) !== -1
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
Settings.data.bar.monitors = addMonitor(Settings.data.bar.monitors, modelData.name)
|
||||
} else {
|
||||
Settings.data.bar.monitors = removeMonitor(Settings.data.bar.monitors, modelData.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
spacing: Style.marginL * scaling
|
||||
|
||||
NToggle {
|
||||
Layout.fillWidth: true
|
||||
label: "Notifications"
|
||||
description: "Enable notifications on this monitor."
|
||||
checked: (Settings.data.notifications.monitors || []).indexOf(modelData.name) !== -1
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
Settings.data.notifications.monitors = addMonitor(Settings.data.notifications.monitors,
|
||||
modelData.name)
|
||||
} else {
|
||||
Settings.data.notifications.monitors = removeMonitor(
|
||||
Settings.data.notifications.monitors, modelData.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
Layout.fillWidth: true
|
||||
label: "Dock"
|
||||
description: "Enable the dock on this monitor."
|
||||
checked: (Settings.data.dock.monitors || []).indexOf(modelData.name) !== -1
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
Settings.data.dock.monitors = addMonitor(Settings.data.dock.monitors, modelData.name)
|
||||
} else {
|
||||
Settings.data.dock.monitors = removeMonitor(Settings.data.dock.monitors, modelData.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
RowLayout {
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXXS * scaling
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginL * scaling
|
||||
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXXS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NText {
|
||||
text: "Scale"
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
}
|
||||
NText {
|
||||
text: "Scale the user interface on this monitor."
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
text: `${Math.round(ScalingService.scaleByName(modelData.name) * 100)}%`
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.minimumWidth: 50 * scaling
|
||||
horizontalAlignment: Text.AlignRight
|
||||
text: "Scale"
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mOnSurface
|
||||
}
|
||||
NText {
|
||||
text: "Scale the user interface on this monitor."
|
||||
font.pointSize: Style.fontSizeS * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
Layout.fillWidth: true
|
||||
NText {
|
||||
text: `${Math.round(ScalingService.scaleByName(modelData.name) * 100)}%`
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.minimumWidth: 50 * scaling
|
||||
horizontalAlignment: Text.AlignRight
|
||||
}
|
||||
}
|
||||
|
||||
NSlider {
|
||||
id: scaleSlider
|
||||
from: 0.7
|
||||
to: 1.8
|
||||
stepSize: 0.01
|
||||
value: ScalingService.scaleByName(modelData.name)
|
||||
onPressedChanged: {
|
||||
var data = Settings.data.monitorsScaling || {}
|
||||
data[modelData.name] = value
|
||||
Settings.data.monitorsScaling = data
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 150 * scaling
|
||||
RowLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
Layout.fillWidth: true
|
||||
|
||||
NSlider {
|
||||
id: scaleSlider
|
||||
from: 0.7
|
||||
to: 1.8
|
||||
stepSize: 0.01
|
||||
value: ScalingService.scaleByName(modelData.name)
|
||||
onPressedChanged: {
|
||||
var data = Settings.data.monitorsScaling || {}
|
||||
data[modelData.name] = value
|
||||
Settings.data.monitorsScaling = data
|
||||
}
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 150 * scaling
|
||||
}
|
||||
|
||||
NIconButton {
|
||||
icon: "refresh"
|
||||
tooltipText: "Reset Scaling"
|
||||
onClicked: {
|
||||
var data = Settings.data.monitorsScaling || {}
|
||||
data[modelData.name] = 1.0
|
||||
Settings.data.monitorsScaling = data
|
||||
}
|
||||
NIconButton {
|
||||
icon: "refresh"
|
||||
tooltipText: "Reset Scaling"
|
||||
onClicked: {
|
||||
var data = Settings.data.monitorsScaling || {}
|
||||
data[modelData.name] = 1.0
|
||||
Settings.data.monitorsScaling = data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -212,121 +210,121 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
}
|
||||
|
||||
// Night Light Section
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXS * scaling
|
||||
NText {
|
||||
text: "Night Light"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mSecondary
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Reduce blue light emission to help you sleep better and reduce eye strain."
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginXL * scaling
|
||||
Layout.bottomMargin: Style.marginXL * scaling
|
||||
Layout.preferredWidth: parent.width - (Style.marginL * 2 * scaling)
|
||||
}
|
||||
}
|
||||
|
||||
// Night Light Section
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXS * scaling
|
||||
NText {
|
||||
text: "Night Light"
|
||||
font.pointSize: Style.fontSizeXXL * scaling
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mSecondary
|
||||
}
|
||||
NToggle {
|
||||
label: "Enable Night Light"
|
||||
description: "Apply a warm color filter to reduce blue light emission."
|
||||
checked: Settings.data.nightLight.enabled
|
||||
onToggled: checked => Settings.data.nightLight.enabled = checked
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Reduce blue light emission to help you sleep better and reduce eye strain."
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
wrapMode: Text.WordWrap
|
||||
NToggle {
|
||||
label: "Auto Schedule"
|
||||
description: "Automatically enable night light based on time schedule."
|
||||
checked: Settings.data.nightLight.autoSchedule
|
||||
onToggled: checked => Settings.data.nightLight.autoSchedule = checked
|
||||
}
|
||||
|
||||
// Intensity settings
|
||||
ColumnLayout {
|
||||
NLabel {
|
||||
label: "Intensity"
|
||||
description: "Higher values create warmer light."
|
||||
}
|
||||
RowLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
|
||||
NSlider {
|
||||
from: 0
|
||||
to: 1
|
||||
stepSize: 0.01
|
||||
value: Settings.data.nightLight.intensity
|
||||
onMoved: Settings.data.nightLight.intensity = value
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: parent.width - (Style.marginL * 2 * scaling)
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: "Enable Night Light"
|
||||
description: "Apply a warm color filter to reduce blue light emission."
|
||||
checked: Settings.data.nightLight.enabled
|
||||
onToggled: checked => Settings.data.nightLight.enabled = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: "Auto Schedule"
|
||||
description: "Automatically enable night light based on time schedule."
|
||||
checked: Settings.data.nightLight.autoSchedule
|
||||
onToggled: checked => Settings.data.nightLight.autoSchedule = checked
|
||||
}
|
||||
|
||||
// Intensity settings
|
||||
ColumnLayout {
|
||||
NLabel {
|
||||
label: "Intensity"
|
||||
description: "Higher values create warmer light."
|
||||
}
|
||||
RowLayout {
|
||||
spacing: Style.marginS * scaling
|
||||
|
||||
NSlider {
|
||||
from: 0
|
||||
to: 1
|
||||
stepSize: 0.01
|
||||
value: Settings.data.nightLight.intensity
|
||||
onMoved: Settings.data.nightLight.intensity = value
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumWidth: 150 * scaling
|
||||
}
|
||||
|
||||
NText {
|
||||
text: `${Math.round(Settings.data.nightLight.intensity * 100)}%`
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.minimumWidth: 60 * scaling
|
||||
horizontalAlignment: Text.AlignRight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Schedule settings
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXS * scaling
|
||||
|
||||
NLabel {
|
||||
label: "Schedule"
|
||||
description: "Set a start and end time for automatic schedule."
|
||||
Layout.minimumWidth: 150 * scaling
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: false
|
||||
spacing: Style.marginM * scaling
|
||||
|
||||
NText {
|
||||
text: "Start Time"
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
|
||||
NComboBox {
|
||||
model: timeOptions
|
||||
currentKey: Settings.data.nightLight.startTime
|
||||
placeholder: "Select start time"
|
||||
onSelected: key => Settings.data.nightLight.startTime = key
|
||||
preferredWidth: 120 * scaling
|
||||
}
|
||||
|
||||
Item {// add a little more spacing
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Stop Time"
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
NComboBox {
|
||||
model: timeOptions
|
||||
currentKey: Settings.data.nightLight.stopTime
|
||||
placeholder: "Select stop time"
|
||||
onSelected: key => Settings.data.nightLight.stopTime = key
|
||||
preferredWidth: 120 * scaling
|
||||
}
|
||||
NText {
|
||||
text: `${Math.round(Settings.data.nightLight.intensity * 100)}%`
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.minimumWidth: 60 * scaling
|
||||
horizontalAlignment: Text.AlignRight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Schedule settings
|
||||
ColumnLayout {
|
||||
spacing: Style.marginXS * scaling
|
||||
|
||||
NLabel {
|
||||
label: "Schedule"
|
||||
description: "Set a start and end time for automatic schedule."
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: false
|
||||
spacing: Style.marginM * scaling
|
||||
|
||||
NText {
|
||||
text: "Start Time"
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
|
||||
NComboBox {
|
||||
model: timeOptions
|
||||
currentKey: Settings.data.nightLight.startTime
|
||||
placeholder: "Select start time"
|
||||
onSelected: key => Settings.data.nightLight.startTime = key
|
||||
preferredWidth: 120 * scaling
|
||||
}
|
||||
|
||||
Item {// add a little more spacing
|
||||
}
|
||||
|
||||
NText {
|
||||
text: "Stop Time"
|
||||
font.pointSize: Style.fontSizeM * scaling
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
NComboBox {
|
||||
model: timeOptions
|
||||
currentKey: Settings.data.nightLight.stopTime
|
||||
placeholder: "Select stop time"
|
||||
onSelected: key => Settings.data.nightLight.stopTime = key
|
||||
preferredWidth: 120 * scaling
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import Qt.labs.folderlistmodel
|
|||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.Commons
|
||||
import qs.Services
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
|
@ -37,7 +38,7 @@ Singleton {
|
|||
function changedWallpaper() {
|
||||
if (Settings.data.colorSchemes.useWallpaperColors) {
|
||||
Logger.log("ColorScheme", "Starting color generation from wallpaper")
|
||||
generateColorsProcess.running = true
|
||||
MatugenService.generateFromWallpaper()
|
||||
// Invalidate potential predefined scheme
|
||||
Settings.data.colorSchemes.predefinedScheme = ""
|
||||
}
|
||||
|
|
@ -137,35 +138,5 @@ Singleton {
|
|||
colorsWriter.writeAdapter()
|
||||
}
|
||||
|
||||
Process {
|
||||
id: generateColorsProcess
|
||||
command: {
|
||||
// Choose config based on external theming toggles
|
||||
var cfg = Quickshell.shellDir + "/Assets/Matugen/matugen.toml"
|
||||
if (!Settings.data.colorSchemes.themeApps) {
|
||||
cfg = Quickshell.shellDir + "/Assets/Matugen/matugen.base.toml"
|
||||
}
|
||||
var cmd = ["matugen", "image", WallpaperService.currentWallpaper, "--config", cfg]
|
||||
if (!Settings.data.colorSchemes.darkMode) {
|
||||
cmd.push("--mode", "light")
|
||||
} else {
|
||||
cmd.push("--mode", "dark")
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
workingDirectory: Quickshell.shellDir
|
||||
running: false
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
Logger.log("ColorScheme", "Completed colors generation")
|
||||
}
|
||||
}
|
||||
stderr: StdioCollector {
|
||||
onStreamFinished: {
|
||||
if (this.text !== "") {
|
||||
Logger.error(this.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Matugen generation moved to MatugenService
|
||||
}
|
||||
|
|
|
|||
53
Services/MatugenService.qml
Normal file
53
Services/MatugenService.qml
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.Commons
|
||||
import qs.Assets.Matugen
|
||||
import qs.Services
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property string dynamicConfigPath: Settings.cacheDir + "matugen.dynamic.toml"
|
||||
|
||||
// Build TOML content based on settings
|
||||
function buildConfigToml() {
|
||||
return Matugen.buildConfigToml()
|
||||
}
|
||||
|
||||
// Generate colors using current wallpaper and settings
|
||||
function generateFromWallpaper() {
|
||||
// Ensure cache dir exists
|
||||
Quickshell.execDetached(["mkdir", "-p", Settings.cacheDir])
|
||||
|
||||
var content = buildConfigToml()
|
||||
var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light"
|
||||
var wp = WallpaperService.currentWallpaper.replace(/'/g, "'\\''")
|
||||
var pathEsc = dynamicConfigPath.replace(/'/g, "'\\''")
|
||||
var extraRepo = (Quickshell.shellDir + "/Assets/Matugen/extra").replace(/'/g, "'\\''")
|
||||
var extraUser = (Settings.configDir + "matugen.d").replace(/'/g, "'\\''")
|
||||
var script = "cat > '" + pathEsc + "' << 'EOF'\n" + content + "EOF\n" + "for d in '" + extraRepo + "' '" + extraUser
|
||||
+ "'; do\n" + " if [ -d \"$d\" ]; then\n"
|
||||
+ " for f in \"$d\"/*.toml; do\n" + " [ -f \"$f\" ] && { echo; echo \"# extra: $f\"; cat \"$f\"; } >> '"
|
||||
+ pathEsc + "'\n" + " done\n" + " fi\n" + "done\n" + "matugen image '" + wp + "' --config '" + pathEsc + "' --mode " + mode
|
||||
generateProcess.command = ["bash", "-lc", script]
|
||||
generateProcess.running = true
|
||||
}
|
||||
|
||||
Process {
|
||||
id: generateProcess
|
||||
workingDirectory: Quickshell.shellDir
|
||||
running: false
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: Logger.log("Matugen", "Completed colors generation")
|
||||
}
|
||||
stderr: StdioCollector {
|
||||
onStreamFinished: if (this.text !== "")
|
||||
Logger.error(this.text)
|
||||
}
|
||||
}
|
||||
|
||||
// No separate writer; the write happens inline via bash heredoc
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue