Add Noctalia shell with Quickshell overview

- Add `noctalia` input to flake and lock it in `flake.lock`.
- Include `noctalia` and `quickshell` modules in `flake.nix`.
- Extend core packages to accept `inputs` and `system`; add
  `quickshell.nix`
  with required Qt6 packages and environment variables.
- Enable `upower` service for battery handling.
- Add home modules `noctalia.nix` and `overview.nix` (QML UI, README,
  assets, widgets, services) to provide a workspace overview.
- Comment out unused rofi and web‑search binds; update `exec‑once` to
  start
  the overview daemon and `noctalia-shell`.
- Provide `restart.noctalia` script and its Nix wrapper.
- Enable `noctalia-shell` in `stylix` configuration.
This commit is contained in:
2026-02-02 01:57:56 +01:00
parent 51ad90dc9c
commit 8ccb9205bf
35 changed files with 1524 additions and 10 deletions

View File

@@ -0,0 +1,148 @@
pragma Singleton
pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import "functions"
Singleton {
id: root
property QtObject m3colors
property QtObject animation
property QtObject animationCurves
property QtObject colors
property QtObject rounding
property QtObject font
property QtObject sizes
m3colors: QtObject {
property bool darkmode: true
property color m3primary: "#E5B6F2"
property color m3onPrimary: "#452152"
property color m3primaryContainer: "#5D386A"
property color m3onPrimaryContainer: "#F9D8FF"
property color m3secondary: "#D5C0D7"
property color m3onSecondary: "#392C3D"
property color m3secondaryContainer: "#534457"
property color m3onSecondaryContainer: "#F2DCF3"
property color m3background: "#161217"
property color m3onBackground: "#EAE0E7"
property color m3surface: "#161217"
property color m3surfaceContainerLow: "#1F1A1F"
property color m3surfaceContainer: "#231E23"
property color m3surfaceContainerHigh: "#2D282E"
property color m3surfaceContainerHighest: "#383339"
property color m3onSurface: "#EAE0E7"
property color m3surfaceVariant: "#4C444D"
property color m3onSurfaceVariant: "#CFC3CD"
property color m3inverseSurface: "#EAE0E7"
property color m3inverseOnSurface: "#342F34"
property color m3outline: "#988E97"
property color m3outlineVariant: "#4C444D"
property color m3shadow: "#000000"
}
colors: QtObject {
property color colSubtext: m3colors.m3outline
property color colLayer0: m3colors.m3background
property color colOnLayer0: m3colors.m3onBackground
property color colLayer0Border: ColorUtils.mix(root.m3colors.m3outlineVariant, colLayer0, 0.4)
property color colLayer1: m3colors.m3surfaceContainerLow
property color colOnLayer1: m3colors.m3onSurfaceVariant
property color colOnLayer1Inactive: ColorUtils.mix(colOnLayer1, colLayer1, 0.45)
property color colLayer1Hover: ColorUtils.mix(colLayer1, colOnLayer1, 0.92)
property color colLayer1Active: ColorUtils.mix(colLayer1, colOnLayer1, 0.85)
property color colLayer2: m3colors.m3surfaceContainer
property color colOnLayer2: m3colors.m3onSurface
property color colLayer2Hover: ColorUtils.mix(colLayer2, colOnLayer2, 0.90)
property color colLayer2Active: ColorUtils.mix(colLayer2, colOnLayer2, 0.80)
property color colPrimary: m3colors.m3primary
property color colOnPrimary: m3colors.m3onPrimary
property color colSecondary: m3colors.m3secondary
property color colSecondaryContainer: m3colors.m3secondaryContainer
property color colOnSecondaryContainer: m3colors.m3onSecondaryContainer
property color colTooltip: m3colors.m3inverseSurface
property color colOnTooltip: m3colors.m3inverseOnSurface
property color colShadow: ColorUtils.transparentize(m3colors.m3shadow, 0.7)
property color colOutline: m3colors.m3outline
}
rounding: QtObject {
property int unsharpen: 2
property int verysmall: 8
property int small: 12
property int normal: 17
property int large: 23
property int full: 9999
property int screenRounding: large
property int windowRounding: 18
}
font: QtObject {
property QtObject family: QtObject {
property string main: "sans-serif"
property string title: "sans-serif"
property string expressive: "sans-serif"
}
property QtObject pixelSize: QtObject {
property int smaller: 12
property int small: 15
property int normal: 16
property int larger: 19
property int huge: 22
}
}
animationCurves: QtObject {
readonly property list<real> expressiveDefaultSpatial: [0.38, 1.21, 0.22, 1.00, 1, 1]
readonly property list<real> expressiveEffects: [0.34, 0.80, 0.34, 1.00, 1, 1]
readonly property list<real> emphasizedDecel: [0.05, 0.7, 0.1, 1, 1, 1]
readonly property real expressiveDefaultSpatialDuration: 500
readonly property real expressiveEffectsDuration: 200
}
animation: QtObject {
property QtObject elementMove: QtObject {
property int duration: animationCurves.expressiveDefaultSpatialDuration
property int type: Easing.BezierSpline
property list<real> bezierCurve: animationCurves.expressiveDefaultSpatial
property Component numberAnimation: Component {
NumberAnimation {
duration: root.animation.elementMove.duration
easing.type: root.animation.elementMove.type
easing.bezierCurve: root.animation.elementMove.bezierCurve
}
}
}
property QtObject elementMoveEnter: QtObject {
property int duration: 400
property int type: Easing.BezierSpline
property list<real> bezierCurve: animationCurves.emphasizedDecel
property Component numberAnimation: Component {
NumberAnimation {
duration: root.animation.elementMoveEnter.duration
easing.type: root.animation.elementMoveEnter.type
easing.bezierCurve: root.animation.elementMoveEnter.bezierCurve
}
}
}
property QtObject elementMoveFast: QtObject {
property int duration: animationCurves.expressiveEffectsDuration
property int type: Easing.BezierSpline
property list<real> bezierCurve: animationCurves.expressiveEffects
property Component numberAnimation: Component {
NumberAnimation {
duration: root.animation.elementMoveFast.duration
easing.type: root.animation.elementMoveFast.type
easing.bezierCurve: root.animation.elementMoveFast.bezierCurve
}
}
}
}
sizes: QtObject {
property real elevationMargin: 10
}
}

View File

@@ -0,0 +1,22 @@
pragma Singleton
pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
Singleton {
id: root
property QtObject options: QtObject {
property QtObject overview: QtObject {
property int rows: 2
property int columns: 5
property real scale: 0.16
property bool enable: true
}
property QtObject hacks: QtObject {
property int arbitraryRaceConditionDelay: 150
}
}
}

View File

@@ -0,0 +1,68 @@
pragma Singleton
import Quickshell
Singleton {
id: root
function colorWithHueOf(color1, color2) {
var c1 = Qt.color(color1);
var c2 = Qt.color(color2);
var hue = c2.hsvHue;
var sat = c1.hsvSaturation;
var val = c1.hsvValue;
var alpha = c1.a;
return Qt.hsva(hue, sat, val, alpha);
}
function colorWithSaturationOf(color1, color2) {
var c1 = Qt.color(color1);
var c2 = Qt.color(color2);
var hue = c1.hsvHue;
var sat = c2.hsvSaturation;
var val = c1.hsvValue;
var alpha = c1.a;
return Qt.hsva(hue, sat, val, alpha);
}
function colorWithLightness(color, lightness) {
var c = Qt.color(color);
return Qt.hsla(c.hslHue, c.hslSaturation, lightness, c.a);
}
function colorWithLightnessOf(color1, color2) {
var c2 = Qt.color(color2);
return colorWithLightness(color1, c2.hslLightness);
}
function adaptToAccent(color1, color2) {
var c1 = Qt.color(color1);
var c2 = Qt.color(color2);
var hue = c2.hslHue;
var sat = c2.hslSaturation;
var light = c1.hslLightness;
var alpha = c1.a;
return Qt.hsla(hue, sat, light, alpha);
}
function mix(color1, color2, percentage = 0.5) {
var c1 = Qt.color(color1);
var c2 = Qt.color(color2);
return Qt.rgba(
percentage * c1.r + (1 - percentage) * c2.r,
percentage * c1.g + (1 - percentage) * c2.g,
percentage * c1.b + (1 - percentage) * c2.b,
percentage * c1.a + (1 - percentage) * c2.a
);
}
function transparentize(color, percentage = 1) {
var c = Qt.color(color);
return Qt.rgba(c.r, c.g, c.b, c.a * (1 - percentage));
}
function applyAlpha(color, alpha) {
var c = Qt.color(color);
var a = Math.max(0, Math.min(1, alpha));
return Qt.rgba(c.r, c.g, c.b, a);
}
}

View File

@@ -0,0 +1 @@
singleton ColorUtils 1.0 ColorUtils.qml

View File

@@ -0,0 +1,7 @@
singleton Appearance 1.0 Appearance.qml
singleton Config 1.0 Config.qml
singleton ColorUtils 1.0 functions/ColorUtils.qml
StyledText 1.0 widgets/StyledText.qml
StyledRectangularShadow 1.0 widgets/StyledRectangularShadow.qml
StyledToolTip 1.0 widgets/StyledToolTip.qml
StyledToolTipContent 1.0 widgets/StyledToolTipContent.qml

View File

@@ -0,0 +1,14 @@
import QtQuick
import QtQuick.Effects
import ".."
RectangularShadow {
required property var target
anchors.fill: target
radius: 20
blur: 0.9 * Appearance.sizes.elevationMargin
offset: Qt.vector2d(0.0, 1.0)
spread: 1
color: Appearance.colors.colShadow
cached: true
}

View File

@@ -0,0 +1,16 @@
import QtQuick
import ".."
Text {
id: root
property bool animateChange: false
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
font {
hintingPreference: Font.PreferFullHinting
family: Appearance?.font.family.main ?? "sans-serif"
pixelSize: Appearance?.font.pixelSize.small ?? 15
}
color: Appearance?.m3colors.m3onBackground ?? "white"
}

View File

@@ -0,0 +1,23 @@
import QtQuick
import QtQuick.Controls
import "."
ToolTip {
id: root
property bool extraVisibleCondition: true
property bool alternativeVisibleCondition: false
readonly property bool internalVisibleCondition: (extraVisibleCondition && (parent.hovered === undefined || parent?.hovered)) || alternativeVisibleCondition
verticalPadding: 5
horizontalPadding: 10
background: null
visible: internalVisibleCondition
contentItem: StyledToolTipContent {
id: contentItem
text: root.text
shown: root.internalVisibleCondition
horizontalPadding: root.horizontalPadding
verticalPadding: root.verticalPadding
}
}

View File

@@ -0,0 +1,49 @@
import QtQuick
import "."
import "../"
Item {
id: root
required property string text
property bool shown: false
property real horizontalPadding: 10
property real verticalPadding: 5
implicitWidth: tooltipTextObject.implicitWidth + 2 * root.horizontalPadding
implicitHeight: tooltipTextObject.implicitHeight + 2 * root.verticalPadding
property bool isVisible: backgroundRectangle.implicitHeight > 0
Rectangle {
id: backgroundRectangle
anchors {
bottom: root.bottom
horizontalCenter: root.horizontalCenter
}
color: Appearance?.colors.colTooltip ?? "#3C4043"
radius: Appearance?.rounding.verysmall ?? 7
opacity: shown ? 1 : 0
implicitWidth: shown ? (tooltipTextObject.implicitWidth + 2 * root.horizontalPadding) : 0
implicitHeight: shown ? (tooltipTextObject.implicitHeight + 2 * root.verticalPadding) : 0
clip: true
Behavior on implicitWidth {
animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this)
}
Behavior on implicitHeight {
animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this)
}
Behavior on opacity {
animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this)
}
StyledText {
id: tooltipTextObject
anchors.centerIn: parent
text: root.text
font.pixelSize: Appearance?.font.pixelSize.smaller ?? 14
font.hintingPreference: Font.PreferNoHinting
color: Appearance?.colors.colOnTooltip ?? "#FFFFFF"
wrapMode: Text.Wrap
}
}
}

View File

@@ -0,0 +1,4 @@
StyledText 1.0 StyledText.qml
StyledRectangularShadow 1.0 StyledRectangularShadow.qml
StyledToolTip 1.0 StyledToolTip.qml
StyledToolTipContent 1.0 StyledToolTipContent.qml