add noctalia and fuzzel

This commit is contained in:
2026-05-23 21:20:58 +02:00
parent 364801f1a3
commit 9a3eceb3ab
599 changed files with 204318 additions and 0 deletions
@@ -0,0 +1,65 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.Commons
import qs.Services.UI
import qs.Widgets
ColumnLayout {
id: root
spacing: Style.marginL
Layout.fillWidth: true
enabled: Settings.data.wallpaper.enabled
NToggle {
label: I18n.tr("panels.wallpaper.automation-scheduled-change-label")
description: I18n.tr("panels.wallpaper.automation-scheduled-change-description")
checked: Settings.data.wallpaper.automationEnabled
onToggled: checked => Settings.data.wallpaper.automationEnabled = checked
}
ColumnLayout {
enabled: Settings.data.wallpaper.automationEnabled
spacing: Style.marginL
Layout.fillWidth: true
NComboBox {
label: I18n.tr("panels.wallpaper.automation-change-mode-label")
description: I18n.tr("panels.wallpaper.automation-change-mode-description")
Layout.fillWidth: true
model: [
{
"key": "random",
"name": I18n.tr("common.random")
},
{
"key": "alphabetical",
"name": I18n.tr("panels.wallpaper.automation-change-mode-alphabetical")
}
]
currentKey: Settings.data.wallpaper.wallpaperChangeMode || "random"
onSelected: key => Settings.data.wallpaper.wallpaperChangeMode = key
defaultValue: Settings.getDefaultValue("wallpaper.wallpaperChangeMode")
}
NSpinBox {
label: I18n.tr("panels.wallpaper.automation-interval-label")
description: I18n.tr("panels.wallpaper.automation-interval-description")
Layout.fillWidth: true
from: 1
to: 1440
stepSize: 1
suffix: "m"
value: Math.round(Settings.data.wallpaper.randomIntervalSec / 60)
defaultValue: Settings.getDefaultValue("wallpaper.randomIntervalSec") !== undefined ? Math.round(Settings.getDefaultValue("wallpaper.randomIntervalSec") / 60) : undefined
onValueChanged: {
let newSec = value * 60;
if (newSec !== Settings.data.wallpaper.randomIntervalSec) {
Settings.data.wallpaper.randomIntervalSec = newSec;
WallpaperService.restartRandomWallpaperTimer();
}
}
}
}
}
@@ -0,0 +1,261 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import qs.Commons
import qs.Services.Compositor
import qs.Services.UI
import qs.Widgets
ColumnLayout {
id: root
spacing: Style.marginL
Layout.fillWidth: true
property var screen
signal openMainFolderPicker
signal openMonitorFolderPicker(string monitorName)
NToggle {
label: I18n.tr("panels.wallpaper.settings-enable-management-label")
description: I18n.tr("panels.wallpaper.settings-enable-management-description")
checked: Settings.data.wallpaper.enabled
onToggled: checked => Settings.data.wallpaper.enabled = checked
defaultValue: Settings.getDefaultValue("wallpaper.enabled")
}
ColumnLayout {
enabled: Settings.data.wallpaper.enabled
spacing: Style.marginL
Layout.fillWidth: true
RowLayout {
NLabel {
label: I18n.tr("tooltips.wallpaper-selector")
description: I18n.tr("panels.wallpaper.settings-selector-description")
Layout.alignment: Qt.AlignTop
}
NIconButton {
icon: "wallpaper-selector"
tooltipText: I18n.tr("tooltips.wallpaper-selector")
onClicked: PanelService.getPanel("wallpaperPanel", root.screen)?.toggle()
}
}
NComboBox {
label: I18n.tr("common.position")
description: I18n.tr("panels.wallpaper.settings-selector-position-description")
Layout.fillWidth: true
model: [
{
"key": "follow_bar",
"name": I18n.tr("positions.follow-bar")
},
{
"key": "center",
"name": I18n.tr("positions.center")
},
{
"key": "top_center",
"name": I18n.tr("positions.top-center")
},
{
"key": "top_left",
"name": I18n.tr("positions.top-left")
},
{
"key": "top_right",
"name": I18n.tr("positions.top-right")
},
{
"key": "bottom_left",
"name": I18n.tr("positions.bottom-left")
},
{
"key": "bottom_right",
"name": I18n.tr("positions.bottom-right")
},
{
"key": "bottom_center",
"name": I18n.tr("positions.bottom-center")
}
]
currentKey: Settings.data.wallpaper.panelPosition
onSelected: key => Settings.data.wallpaper.panelPosition = key
defaultValue: Settings.getDefaultValue("wallpaper.panelPosition")
}
NComboBox {
label: I18n.tr("panels.wallpaper.settings-view-mode-label")
description: I18n.tr("panels.wallpaper.settings-view-mode-description")
Layout.fillWidth: true
model: [
{
"key": "single",
"name": I18n.tr("panels.wallpaper.view-mode-single")
},
{
"key": "recursive",
"name": I18n.tr("panels.wallpaper.view-mode-recursive")
},
{
"key": "browse",
"name": I18n.tr("panels.wallpaper.view-mode-browse")
}
]
currentKey: Settings.data.wallpaper.viewMode
onSelected: key => Settings.data.wallpaper.viewMode = key
defaultValue: Settings.getDefaultValue("wallpaper.viewMode")
}
NTextInputButton {
id: wallpaperPathInput
label: I18n.tr("panels.wallpaper.settings-folder-label")
description: I18n.tr("panels.wallpaper.settings-folder-description")
text: Settings.data.wallpaper.directory
buttonIcon: "folder-open"
buttonTooltip: I18n.tr("panels.wallpaper.settings-folder-label")
Layout.fillWidth: true
onInputTextChanged: text => Settings.data.wallpaper.directory = text
onButtonClicked: root.openMainFolderPicker()
}
NToggle {
label: I18n.tr("panels.wallpaper.settings-monitor-specific-label")
description: I18n.tr("panels.wallpaper.settings-monitor-specific-description")
checked: Settings.data.wallpaper.enableMultiMonitorDirectories
onToggled: checked => Settings.data.wallpaper.enableMultiMonitorDirectories = checked
defaultValue: Settings.getDefaultValue("wallpaper.enableMultiMonitorDirectories")
}
NBox {
visible: Settings.data.wallpaper.enableMultiMonitorDirectories
Layout.fillWidth: true
radius: Style.radiusM
color: Color.mSurface
border.color: Color.mOutline
border.width: Style.borderS
implicitHeight: contentCol.implicitHeight + Style.margin2L
clip: true
ColumnLayout {
id: contentCol
anchors.fill: parent
anchors.margins: Style.marginL
spacing: Style.marginM
Repeater {
model: Quickshell.screens || []
delegate: ColumnLayout {
Layout.fillWidth: true
spacing: Style.marginS
NText {
text: (modelData.name || "Unknown")
color: Color.mPrimary
font.weight: Style.fontWeightBold
pointSize: Style.fontSizeM
}
NTextInputButton {
id: monitorDirInput
text: WallpaperService.getMonitorDirectory(modelData.name)
buttonIcon: "folder-open"
buttonTooltip: I18n.tr("panels.wallpaper.settings-monitor-specific-tooltip")
Layout.fillWidth: true
onInputEditingFinished: WallpaperService.setMonitorDirectory(modelData.name, monitorDirInput.text)
onButtonClicked: root.openMonitorFolderPicker(modelData.name)
}
}
}
}
}
}
NDivider {
Layout.fillWidth: true
}
NToggle {
label: I18n.tr("panels.wallpaper.settings-use-original-images-label")
description: I18n.tr("panels.wallpaper.settings-use-original-images-description")
checked: Settings.data.wallpaper.useOriginalImages
enabled: Settings.data.wallpaper.enabled
onToggled: checked => Settings.data.wallpaper.useOriginalImages = checked
defaultValue: Settings.getDefaultValue("wallpaper.useOriginalImages")
}
RowLayout {
spacing: Style.marginM
Layout.fillWidth: true
enabled: Settings.data.wallpaper.enabled
NLabel {
label: I18n.tr("panels.wallpaper.settings-clear-cache-label")
description: I18n.tr("panels.wallpaper.settings-clear-cache-description")
Layout.fillWidth: true
}
NButton {
icon: "trash"
text: I18n.tr("panels.wallpaper.settings-clear-cache-button")
outlined: true
onClicked: {
ImageCacheService.clearLarge();
ToastService.showNotice(I18n.tr("panels.wallpaper.settings-clear-cache-toast"));
}
}
}
NDivider {
Layout.fillWidth: true
visible: CompositorService.isNiri
}
ColumnLayout {
visible: CompositorService.isNiri
enabled: Settings.data.wallpaper.enabled
spacing: Style.marginL
Layout.fillWidth: true
NToggle {
label: I18n.tr("panels.wallpaper.settings-enable-overview-label")
description: I18n.tr("panels.wallpaper.settings-enable-overview-description")
checked: Settings.data.wallpaper.enabled && Settings.data.wallpaper.overviewEnabled
onToggled: checked => Settings.data.wallpaper.overviewEnabled = checked
defaultValue: Settings.getDefaultValue("wallpaper.overviewEnabled")
}
NValueSlider {
Layout.fillWidth: true
visible: Settings.data.wallpaper.overviewEnabled
label: I18n.tr("panels.wallpaper.settings-overview-blur-strength-label")
description: I18n.tr("panels.wallpaper.settings-overview-blur-strength-description")
from: 0.0
to: 1.0
stepSize: 0.01
showReset: true
value: Settings.data.wallpaper.overviewBlur
onMoved: value => Settings.data.wallpaper.overviewBlur = value
text: ((Settings.data.wallpaper.overviewBlur) * 100).toFixed(0) + "%"
defaultValue: Settings.getDefaultValue("wallpaper.overviewBlur")
}
NValueSlider {
Layout.fillWidth: true
visible: Settings.data.wallpaper.overviewEnabled
label: I18n.tr("panels.wallpaper.settings-overview-tint-label")
description: I18n.tr("panels.wallpaper.settings-overview-tint-description")
from: 0.0
to: 1.0
stepSize: 0.01
showReset: true
value: Settings.data.wallpaper.overviewTint
onMoved: value => Settings.data.wallpaper.overviewTint = value
text: ((Settings.data.wallpaper.overviewTint) * 100).toFixed(0) + "%"
defaultValue: Settings.getDefaultValue("wallpaper.overviewTint")
}
}
}
@@ -0,0 +1,114 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.Commons
import qs.Services.UI
import qs.Widgets
ColumnLayout {
id: root
spacing: Style.marginL
Layout.fillWidth: true
enabled: Settings.data.wallpaper.enabled
property var screen
NComboBox {
label: I18n.tr("panels.wallpaper.look-feel-fill-mode-label")
description: I18n.tr("panels.wallpaper.look-feel-fill-mode-description")
model: WallpaperService.fillModeModel
currentKey: Settings.data.wallpaper.fillMode
onSelected: key => Settings.data.wallpaper.fillMode = key
defaultValue: Settings.getDefaultValue("wallpaper.fillMode")
}
RowLayout {
NLabel {
label: I18n.tr("bar.audio-visualizer.color-name-label")
description: I18n.tr("panels.wallpaper.look-feel-fill-color-description")
Layout.alignment: Qt.AlignTop
}
NColorPicker {
screen: root.screen
selectedColor: Settings.data.wallpaper.fillColor
onColorSelected: color => Settings.data.wallpaper.fillColor = color
}
}
NDivider {
Layout.fillWidth: true
}
ColumnLayout {
spacing: Style.marginS
Layout.fillWidth: true
NLabel {
label: I18n.tr("panels.wallpaper.look-feel-transition-type-label")
description: I18n.tr("panels.wallpaper.look-feel-transition-type-description")
}
Repeater {
model: WallpaperService.allTransitions
NCheckbox {
required property string modelData
label: {
var key = "wallpaper.transitions." + modelData;
return I18n.tr(key);
}
labelSize: Style.fontSizeM
checked: Settings.data.wallpaper.transitionType.includes(modelData)
onToggled: checked => {
var arr = Array.from(Settings.data.wallpaper.transitionType);
if (checked) {
if (!arr.includes(modelData))
arr.push(modelData);
} else {
arr = arr.filter(k => k !== modelData);
}
Settings.data.wallpaper.transitionType = arr;
}
}
}
}
NDivider {
Layout.fillWidth: true
}
NToggle {
label: I18n.tr("panels.wallpaper.look-feel-skip-startup-transition-label")
description: I18n.tr("panels.wallpaper.look-feel-skip-startup-transition-description")
checked: Settings.data.wallpaper.skipStartupTransition
onToggled: Settings.data.wallpaper.skipStartupTransition = checked
}
NValueSlider {
Layout.fillWidth: true
label: I18n.tr("panels.wallpaper.look-feel-transition-duration-label")
description: I18n.tr("panels.wallpaper.look-feel-transition-duration-description")
from: 500
to: 10000
stepSize: 100
showReset: true
value: Settings.data.wallpaper.transitionDuration
onMoved: value => Settings.data.wallpaper.transitionDuration = value
text: (Settings.data.wallpaper.transitionDuration / 1000).toFixed(1) + "s"
defaultValue: Settings.getDefaultValue("wallpaper.transitionDuration")
}
NValueSlider {
Layout.fillWidth: true
label: I18n.tr("panels.wallpaper.look-feel-edge-smoothness-label")
description: I18n.tr("panels.wallpaper.look-feel-edge-smoothness-description")
from: 0.0
to: 1.0
showReset: true
value: Settings.data.wallpaper.transitionEdgeSmoothness
onMoved: value => Settings.data.wallpaper.transitionEdgeSmoothness = value
text: Math.round(Settings.data.wallpaper.transitionEdgeSmoothness * 100) + "%"
defaultValue: Settings.getDefaultValue("wallpaper.transitionEdgeSmoothness")
}
}
@@ -0,0 +1,93 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import qs.Commons
import qs.Services.UI
import qs.Widgets
ColumnLayout {
id: root
spacing: 0
property var screen
function openMainFolderPicker() {
mainFolderPicker.open();
}
function openMonitorFolderPicker(monitorName) {
specificFolderMonitorName = monitorName;
monitorFolderPicker.open();
}
property string specificFolderMonitorName: ""
NTabBar {
id: subTabBar
Layout.fillWidth: true
Layout.bottomMargin: Style.marginM
distributeEvenly: true
currentIndex: tabView.currentIndex
NTabButton {
text: I18n.tr("common.general")
tabIndex: 0
checked: subTabBar.currentIndex === 0
}
NTabButton {
text: I18n.tr("common.look")
tabIndex: 1
checked: subTabBar.currentIndex === 1
}
NTabButton {
text: I18n.tr("common.automation")
tabIndex: 2
checked: subTabBar.currentIndex === 2
}
}
Item {
Layout.fillWidth: true
Layout.preferredHeight: Style.marginL
}
NTabView {
id: tabView
currentIndex: subTabBar.currentIndex
GeneralSubTab {
screen: root.screen
onOpenMainFolderPicker: root.openMainFolderPicker()
onOpenMonitorFolderPicker: monitorName => root.openMonitorFolderPicker(monitorName)
}
LookAndFeelSubTab {
screen: root.screen
}
AutomationSubTab {}
}
NFilePicker {
id: mainFolderPicker
selectionMode: "folders"
title: I18n.tr("setup.wallpaper.dir-select-title")
initialPath: Settings.data.wallpaper.directory || Quickshell.env("HOME") + "/Pictures"
onAccepted: paths => {
if (paths.length > 0) {
Settings.data.wallpaper.directory = paths[0];
}
}
}
NFilePicker {
id: monitorFolderPicker
selectionMode: "folders"
title: I18n.tr("panels.wallpaper.settings-select-monitor-folder")
initialPath: WallpaperService.getMonitorDirectory(specificFolderMonitorName) || Quickshell.env("HOME") + "/Pictures"
onAccepted: paths => {
if (paths.length > 0) {
WallpaperService.setMonitorDirectory(specificFolderMonitorName, paths[0]);
}
}
}
}