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,34 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.Commons
import qs.Widgets
ColumnLayout {
id: root
spacing: Style.marginL
width: parent.width
// Enable/Disable Toggle
NToggle {
label: I18n.tr("panels.hooks.system-hooks-enable-label")
description: I18n.tr("panels.hooks.system-hooks-enable-description")
checked: Settings.data.hooks.enabled
onToggled: checked => Settings.data.hooks.enabled = checked
}
NDivider {
Layout.fillWidth: true
}
// Info section
ColumnLayout {
spacing: Style.marginM
Layout.fillWidth: true
NLabel {
label: I18n.tr("panels.hooks.info-parameters-label")
description: I18n.tr("panels.hooks.info-parameters-description")
}
}
}
@@ -0,0 +1,118 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.Commons
import qs.Widgets
Popup {
id: root
modal: true
closePolicy: Popup.NoAutoClose
dim: true
anchors.centerIn: parent
// Use a reasonable width/height relative to parent or fixed
width: Math.min(600 * Style.uiScaleRatio, parent.width * 0.9)
height: Math.min(contentLayout.implicitHeight + padding * 2, parent.height * 0.9)
padding: Style.marginL
property string hookLabel: ""
property string hookDescription: ""
property string hookPlaceholder: ""
property string initialValue: ""
signal saved(string newValue)
signal test(string value)
property var _savedSlot: null
property var _testSlot: null
background: Rectangle {
color: Color.mSurface
radius: Style.radiusL
border.color: Color.mOutline
border.width: Style.borderS
}
onOpened: {
commandInput.text = initialValue;
commandInput.forceActiveFocus();
}
contentItem: ColumnLayout {
id: contentLayout
spacing: Style.marginL
// Header
RowLayout {
Layout.fillWidth: true
NText {
text: root.hookLabel
font.weight: Style.fontWeightBold
pointSize: Style.fontSizeL
Layout.fillWidth: true
}
NIconButton {
icon: "close"
onClicked: root.close()
}
}
// Description/Help
NText {
text: root.hookDescription
color: Color.mOnSurfaceVariant
wrapMode: Text.WordWrap
Layout.fillWidth: true
}
// Input Area
ColumnLayout {
Layout.fillWidth: true
spacing: Style.marginS
NTextInput {
id: commandInput
Layout.fillWidth: true
placeholderText: root.hookPlaceholder
// Allow multiline? Hooks are usually oneline commands but can be scripts.
// NTextInput is likely single line. Let's assume single line for now as per previous implementation.
}
}
// Action Buttons
RowLayout {
Layout.fillWidth: true
spacing: Style.marginM
NButton {
text: I18n.tr("common.test")
icon: "caret-right"
onClicked: root.test(commandInput.text)
// Disable test if empty? Or maybe allow testing defined script.
enabled: commandInput.text !== ""
}
Item {
Layout.fillWidth: true
} // Spacer
NButton {
text: I18n.tr("common.cancel")
outlined: true
onClicked: root.close()
}
NButton {
text: I18n.tr("common.save")
icon: "check"
backgroundColor: Color.mPrimary
textColor: Color.mOnPrimary
onClicked: {
root.saved(commandInput.text);
root.close();
}
}
}
}
}
@@ -0,0 +1,28 @@
import QtQuick
import QtQuick.Layouts
import qs.Commons
import qs.Widgets
RowLayout {
id: root
property string label: ""
property string description: ""
property string value: ""
signal editClicked
spacing: Style.marginM
NLabel {
label: root.label
description: root.description
labelColor: root.value ? Color.mPrimary : Color.mOnSurface
}
NIconButton {
icon: "settings"
onClicked: root.editClicked()
tooltipText: I18n.tr("common.edit")
}
}
@@ -0,0 +1,172 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import qs.Commons
import qs.Services.Control
import qs.Services.UI
import qs.Widgets
ColumnLayout {
id: root
enabled: Settings.data.hooks.enabled
spacing: Style.marginL
width: parent.width
// Shared Edit Popup
HookEditPopup {
id: editPopup
parent: Overlay.overlay
}
// Helper to open popup
function openEdit(label, description, placeholder, value, onSave, onTest) {
editPopup.hookLabel = label;
editPopup.hookDescription = description;
editPopup.hookPlaceholder = placeholder;
editPopup.initialValue = value;
// Disconnect previous signals
try {
editPopup.saved.disconnect(editPopup._savedSlot);
} catch (e) {}
try {
editPopup.test.disconnect(editPopup._testSlot);
} catch (e) {}
// Define slots
editPopup._savedSlot = onSave;
editPopup._testSlot = onTest;
// Connect new signals
editPopup.saved.connect(editPopup._savedSlot);
editPopup.test.connect(editPopup._testSlot);
editPopup.open();
}
// Startup Hook
HookRow {
label: I18n.tr("panels.hooks.noctalia-started-label")
description: I18n.tr("panels.hooks.noctalia-started-description")
value: Settings.data.hooks.startup
onEditClicked: openEdit(label, description, I18n.tr("panels.hooks.noctalia-started-placeholder"), value, newValue => {
Settings.data.hooks.startup = newValue;
Settings.saveImmediate();
}, val => {
HooksService.executeStartupHook();
})
}
// Wallpaper Hook
HookRow {
label: I18n.tr("panels.hooks.wallpaper-changed-label")
description: I18n.tr("panels.hooks.wallpaper-changed-description")
value: Settings.data.hooks.wallpaperChange
onEditClicked: openEdit(label, description, I18n.tr("panels.hooks.wallpaper-changed-placeholder"), value, newValue => {
Settings.data.hooks.wallpaperChange = newValue;
Settings.saveImmediate();
}, val => {
if (val)
Quickshell.execDetached(["sh", "-lc", val.replace("$1", "test_wallpaper_path").replace("$2", "test_screen").replace("$3", "dark")]);
})
}
// Color Generation Hook
HookRow {
label: I18n.tr("panels.hooks.color-generation-label")
description: I18n.tr("panels.hooks.color-generation-description")
value: Settings.data.hooks.colorGeneration
onEditClicked: openEdit(label, description, I18n.tr("panels.hooks.color-generation-placeholder"), value, newValue => {
Settings.data.hooks.colorGeneration = newValue;
Settings.saveImmediate();
}, val => {
if (val)
Quickshell.execDetached(["sh", "-lc", val.replace("$1", "dark")]);
})
}
// Theme Hook
HookRow {
label: I18n.tr("panels.hooks.theme-changed-label")
description: I18n.tr("panels.hooks.theme-changed-description")
value: Settings.data.hooks.darkModeChange
onEditClicked: openEdit(label, description, I18n.tr("panels.hooks.theme-changed-placeholder"), value, newValue => {
Settings.data.hooks.darkModeChange = newValue;
Settings.saveImmediate();
}, val => {
if (val)
Quickshell.execDetached(["sh", "-lc", val.replace("$1", "true")]);
})
}
// Screen Lock Hook
HookRow {
label: I18n.tr("panels.hooks.screen-lock-label")
description: I18n.tr("panels.hooks.screen-lock-description")
value: Settings.data.hooks.screenLock
onEditClicked: openEdit(label, description, I18n.tr("panels.hooks.screen-lock-placeholder"), value, newValue => {
Settings.data.hooks.screenLock = newValue;
Settings.saveImmediate();
}, val => {
if (val)
Quickshell.execDetached(["sh", "-lc", val]);
})
}
// Screen Unlock Hook
HookRow {
label: I18n.tr("panels.hooks.screen-unlock-label")
description: I18n.tr("panels.hooks.screen-unlock-description")
value: Settings.data.hooks.screenUnlock
onEditClicked: openEdit(label, description, I18n.tr("panels.hooks.screen-unlock-placeholder"), value, newValue => {
Settings.data.hooks.screenUnlock = newValue;
Settings.saveImmediate();
}, val => {
if (val)
Quickshell.execDetached(["sh", "-lc", val]);
})
}
// Performance Mode Enabled Hook
HookRow {
label: I18n.tr("panels.hooks.performance-mode-enabled-label")
description: I18n.tr("panels.hooks.performance-mode-enabled-description")
value: Settings.data.hooks.performanceModeEnabled
onEditClicked: openEdit(label, description, I18n.tr("panels.hooks.performance-mode-enabled-placeholder"), value, newValue => {
Settings.data.hooks.performanceModeEnabled = newValue;
Settings.saveImmediate();
}, val => {
if (val)
Quickshell.execDetached(["sh", "-lc", val]);
})
}
// Performance Mode Disabled Hook
HookRow {
label: I18n.tr("panels.hooks.performance-mode-disabled-label")
description: I18n.tr("panels.hooks.performance-mode-disabled-description")
value: Settings.data.hooks.performanceModeDisabled
onEditClicked: openEdit(label, description, I18n.tr("panels.hooks.performance-mode-disabled-placeholder"), value, newValue => {
Settings.data.hooks.performanceModeDisabled = newValue;
Settings.saveImmediate();
}, val => {
if (val)
Quickshell.execDetached(["sh", "-lc", val]);
})
}
// Session Hook
HookRow {
label: I18n.tr("panels.hooks.session-label")
description: I18n.tr("panels.hooks.session-description")
value: Settings.data.hooks.session
onEditClicked: openEdit(label, description, I18n.tr("panels.hooks.session-placeholder"), value, newValue => {
Settings.data.hooks.session = newValue;
Settings.saveImmediate();
}, val => {
if (val)
Quickshell.execDetached(["sh", "-lc", val + " test"]);
})
}
}
@@ -0,0 +1,43 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import qs.Commons
import qs.Services.UI
import qs.Widgets
ColumnLayout {
id: root
spacing: 0
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("panels.hooks.title")
tabIndex: 1
checked: subTabBar.currentIndex === 1
}
}
Item {
Layout.fillWidth: true
Layout.preferredHeight: Style.marginS
}
NTabView {
id: tabView
currentIndex: subTabBar.currentIndex
GeneralSubTab {}
HooksListSubTab {}
}
}