switch to tinty for theming

This commit is contained in:
lucy 2026-03-19 11:32:23 +01:00
parent aceea87c0a
commit c1cd3da38c
18 changed files with 301 additions and 207 deletions

View File

@ -1,107 +1,26 @@
pragma Singleton
import QtQuick
import Quickshell
Singleton {
readonly property color background: "#111318"
readonly property color error: "#ffb4ab"
readonly property color error_container: "#93000a"
readonly property color inverse_on_surface: "#2e3036"
readonly property color inverse_primary: "#425e91"
readonly property color inverse_surface: "#e2e2e9"
readonly property color on_background: "#e2e2e9"
readonly property color on_error: "#690005"
readonly property color on_error_container: "#ffdad6"
readonly property color on_primary: "#0c305f"
readonly property color on_primary_container: "#d7e2ff"
readonly property color on_primary_fixed: "#001b3f"
readonly property color on_primary_fixed_variant: "#284677"
readonly property color on_secondary: "#283041"
readonly property color on_secondary_container: "#dae2f9"
readonly property color on_secondary_fixed: "#131c2b"
readonly property color on_secondary_fixed_variant: "#3e4759"
readonly property color on_surface: "#e2e2e9"
readonly property color on_surface_variant: "#c4c6d0"
readonly property color on_tertiary: "#3f2844"
readonly property color on_tertiary_container: "#fad8fd"
readonly property color on_tertiary_fixed: "#29132e"
readonly property color on_tertiary_fixed_variant: "#573e5c"
readonly property color outline: "#8e9099"
readonly property color outline_variant: "#44474e"
readonly property color primary: "#abc7ff"
readonly property color primary_container: "#284677"
readonly property color primary_fixed: "#d7e2ff"
readonly property color primary_fixed_dim: "#abc7ff"
readonly property color scrim: "#000000"
readonly property color secondary: "#bec6dc"
readonly property color secondary_container: "#3e4759"
readonly property color secondary_fixed: "#dae2f9"
readonly property color secondary_fixed_dim: "#bec6dc"
readonly property color shadow: "#000000"
readonly property color source_color: "#01224c"
readonly property color surface: "#111318"
readonly property color surface_bright: "#37393e"
readonly property color surface_container: "#1e2025"
readonly property color surface_container_high: "#282a2f"
readonly property color surface_container_highest: "#33353a"
readonly property color surface_container_low: "#1a1c20"
readonly property color surface_container_lowest: "#0c0e13"
readonly property color surface_dim: "#111318"
readonly property color surface_tint: "#abc7ff"
readonly property color surface_variant: "#44474e"
readonly property color tertiary: "#ddbce0"
readonly property color tertiary_container: "#573e5c"
readonly property color tertiary_fixed: "#fad8fd"
readonly property color tertiary_fixed_dim: "#ddbce0"
QtObject {
// --- The Backgrounds (Darkest to Lightest) ---
readonly property string base00: "#1e1e2e" // Default Background
readonly property string base01: "#181825" // Lighter Background (Status bars, panels)
readonly property string base02: "#313244" // Selection Background
readonly property string base03: "#45475a" // Comments, Invisibles, line highlighting
// --- The Foregrounds (Darkest to Lightest) ---
readonly property string base04: "#585b70" // Dark Foreground (Used for status bars)
readonly property string base05: "#cdd6f4" // Default Foreground, Caret
readonly property string base06: "#f5e0dc" // Light Foreground (Rarely used)
readonly property string base07: "#b4befe" // Lightest Foreground
// --- The Accent Colors ---
readonly property string base08: "#f38ba8" // Red (Variables, errors)
readonly property string base09: "#fab387" // Orange (Integers, booleans, constants)
readonly property string base0A: "#f9e2af" // Yellow (Classes, search text bg, warnings)
readonly property string base0B: "#a6e3a1" // Green (Strings, success states)
readonly property string base0C: "#94e2d5" // Cyan (Support, regex, escape chars)
readonly property string base0D: "#89b4fa" // Blue (Functions, methods, headings)
readonly property string base0E: "#cba6f7" // Purple/Mauve (Keywords, storage, selectors)
readonly property string base0F: "#f2cdcd" // Brown/Flamingo (Deprecated, embedded tags)
}

View File

@ -1,5 +1,7 @@
pragma ComponentBehavior: Bound
import Quickshell
import QtQuick
import Quickshell.Widgets
import QtQuick.Layouts
import qs.settings
import qs
@ -10,24 +12,24 @@ Variants {
id: root
required property ShellScreen modelData
aboveWindows: true
margins {
top: Settings.config.floating ? Settings.config.margins : 0
left: Settings.config.floating ? Settings.config.margins : 0
right: Settings.config.floating ? Settings.config.margins : 0
}
screen: modelData
anchors {
top: true
left: true
right: true
}
margins {
top: Settings.config.floating ? Settings.config.margins : 0
left: Settings.config.floating ? Settings.config.margins : 0
right: Settings.config.floating ? Settings.config.margins : 0
}
implicitHeight: Settings.config.barHeight
color: "transparent"
Rectangle {
anchors.fill: parent
id: bar
radius: Settings.config.floating ? Settings.config.rounding * 2 : 0
anchors.fill: parent
color: Colors.surface
color: Colors.base00
RowLayout {
id: left
anchors.leftMargin: Settings.config.floating ? 3 : 10
@ -52,7 +54,7 @@ Variants {
anchors {
right: parent.right
verticalCenter: parent.verticalCenter
rightMargin: Settings.config.floating ? 3 : 10
rightMargin: Settings.config.floating ? 6 : 10
}
Clock {}
StatusIcons {}

View File

@ -1,12 +1,23 @@
import Quickshell
import QtQuick
import Qt5Compat.GraphicalEffects
import qs.settings
import qs
import qs.widgets
Rectangle {
layer {
enabled: true
effect: DropShadow {
color: Colors.base01
radius: 4
verticalOffset: 2
horizontalOffset: 2
samples: 18
}
}
id: root
color: Colors.surface_container_low
color: Colors.base02
implicitWidth: clockText.implicitWidth + 14
implicitHeight: Settings.config.barHeight / 1.5
radius: Settings.config.rounding

View File

@ -1,14 +1,25 @@
import Quickshell
import Quickshell.Services.Mpris
import QtQuick
import Qt5Compat.GraphicalEffects
import QtQuick.Layouts
import qs
import qs.settings
import qs.widgets
Rectangle {
layer {
enabled: true
effect: DropShadow {
color: Colors.base01
radius: 4
verticalOffset: 2
horizontalOffset: 2
samples: 18
}
}
id: root
color: Colors.surface_container_low
color: Colors.base02
implicitWidth: songLayout.implicitWidth + 14
implicitHeight: Settings.config.barHeight / 1.5
radius: Settings.config.rounding

80
modules/Bar/NiriWs.qml Normal file
View File

@ -0,0 +1,80 @@
pragma ComponentBehavior: Bound
import Quickshell
import Niri
import QtQuick
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
import qs
import qs.settings
import qs.widgets
Rectangle {
id: wsWrap
Niri {
id: niri
Component.onCompleted: connect()
onConnected: console.log("Connected to niri")
onErrorOccurred: function (error) {
console.error("Error:", error);
}
}
required property ShellScreen barScreen
color: "transparent"
radius: Settings.config.rounding
implicitWidth: wsLayout.implicitWidth + 6
implicitHeight: wsLayout.implicitHeight + 6
RowLayout {
id: wsLayout
spacing: 6
anchors.centerIn: parent
Repeater {
id: wsRep
model: niri.workspaces
delegate: Rectangle {
id: wsRect
layer {
enabled: true
effect: DropShadow {
color: Colors.base01
radius: 8
verticalOffset: 1
horizontalOffset: 1
samples: 18
}
}
implicitWidth: modelData.isFocused ? Settings.config.barHeight * 1.5 : Settings.config.barHeight / 2 + 10
implicitHeight: Settings.config.barHeight / 1.5
visible: modelData.id < 0 ? false : modelData.output == wsWrap.barScreen.name
required property var modelData
color: modelData.isFocused ? Colors.base0D : Colors.base02
radius: Settings.config.rounding
CText {
id: wsText
anchors.centerIn: parent
text: wsRect.modelData.index
color: parent.modelData.isFocused ? Colors.base01 : Colors.base07
opacity: parent.modelData.isFocused ? 1 : 0.5
}
Behavior on implicitWidth {
NumberAnimation {
easing {
type: Easing.OutBack
overshoot: 2
}
duration: 400
}
}
MouseArea {
id: mouseHandler
acceptedButtons: Qt.LeftButton
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
niri.focusWorkspace(wsRect.modelData.index);
}
}
}
}
}
}

View File

@ -1,14 +1,25 @@
import Quickshell.Services.UPower
import Quickshell.Services.Pipewire
import QtQuick
import Qt5Compat.GraphicalEffects
import QtQuick.Layouts
import qs
import qs.settings
import qs.widgets
Rectangle {
layer {
enabled: true
effect: DropShadow {
color: Colors.base01
radius: 4
verticalOffset: 2
horizontalOffset: 2
samples: 18
}
}
id: root
color: Colors.surface_container_low
color: Colors.base02
implicitWidth: iconLayout.implicitWidth + 14
implicitHeight: Settings.config.barHeight / 1.5
radius: Settings.config.rounding
@ -47,6 +58,8 @@ Rectangle {
}
if (percentage >= 0.84) {
return "\uf24f";
} else {
return "";
}
}
function getVolumeIcon() {
@ -61,23 +74,28 @@ Rectangle {
}
if (audioPercentage >= 0.66) {
return "\ue050";
} else {
return "";
}
}
RowLayout {
id: iconLayout
anchors.centerIn: parent
spacing: 5
CIcon {
id: batteryIcon
text: root.getBatteryIcon()
Layout.leftMargin: 2
text: root.getBatteryIcon()
}
CIcon {
id: volIcon
text: root.getVolumeIcon()
text: root.getVolumeIcon()
}
}
property var audioSink: Pipewire.defaultAudioSink
PwObjectTracker {
id: audioTracker
objects: Pipewire.ready ? Pipewire.defaultAudioSink : []
}
}

View File

@ -1,4 +1,5 @@
import Quickshell
import Qt5Compat.GraphicalEffects
import Quickshell.Wayland
import QtQuick
import QtQuick.Layouts
@ -8,17 +9,27 @@ import qs.settings
Rectangle {
id: root
layer {
enabled: true
effect: DropShadow {
color: Colors.base01
radius: 4
verticalOffset: 2
horizontalOffset: 2
samples: 18
}
}
property var activeWindow: ToplevelManager.activeToplevel
property bool active: activeWindow ? activeWindow.activated ? true : false : false
radius: Settings.config.rounding
color: active ? Colors.surface_container_low : "transparent"
color: active ? Colors.base02 : "transparent"
implicitHeight: Settings.config.barHeight / 1.5
implicitWidth: titleText.width + 14
RowLayout {
anchors.centerIn: parent
anchors.centerIn: parent
CText {
id: titleText
Layout.maximumWidth: 300
Layout.maximumWidth: 300
text: root.activeWindow ? root.activeWindow.activated ? root.activeWindow.title : "" : ""
elide: Text.ElideRight // Allows wrapping
}

View File

@ -1,19 +1,30 @@
import Quickshell.Services.SystemTray
import QtQuick
import Qt5Compat.GraphicalEffects
import qs
import qs.settings
import QtQuick.Layouts
Rectangle {
id: root
layer {
enabled: true
effect: DropShadow {
color: Colors.base01
radius: 4
verticalOffset: 2
horizontalOffset: 2
samples: 18
}
}
implicitWidth: trayRow.implicitWidth + 14
implicitHeight: Settings.config.barHeight / 1.5
visible: trayRep.count > 0
color: Colors.surface_container_low
visible: trayRep.count > 0
color: Colors.base02
radius: Settings.config.rounding
RowLayout {
id: trayRow
anchors.centerIn: parent
anchors.centerIn: parent
Repeater {
id: trayRep
model: SystemTray.items

View File

@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
import Quickshell
import Quickshell.Hyprland
import QtQuick
import Qt5Compat.GraphicalEffects
import QtQuick.Layouts
import qs
import qs.settings
@ -22,18 +23,29 @@ Rectangle {
id: wsRep
model: Hyprland.workspaces
delegate: Rectangle {
layer {
enabled: true
effect: DropShadow {
color: Colors.base01
radius: 8
verticalOffset: 1
horizontalOffset: 1
samples: 18
}
}
id: wsRect
implicitWidth: modelData.focused ? Settings.config.barHeight * 1.5 : Settings.config.barHeight / 2 + 10
implicitHeight: Settings.config.barHeight / 1.5
visible: modelData.id < 0 ? false : modelData.monitor?.name == wsWrap.barScreen.name
required property var modelData
color: modelData.focused ? Colors.primary_container : Colors.surface_container_low
color: modelData.focused ? Colors.base0D : Colors.base02
radius: Settings.config.rounding
CText {
id: wsText
anchors.centerIn: parent
text: wsRect.modelData.id
opacity: parent.modelData.focused ? 1 : 0.5
color: parent.modelData.focused ? Colors.base00 : Colors.base07
}
Behavior on implicitWidth {
NumberAnimation {

View File

@ -1,10 +1,20 @@
import Quickshell
import QtQuick
import Quickshell.Io
import qs
import qs.settings
IpcHandler {
target: "colors"
function reload() {
ThemeLoader.reload()
}
Item {
IpcHandler {
target: "colors"
function reload() {
ThemeLoader.reload();
}
}
IpcHandler {
target: "settings"
function toggleWall() {
Settings.config.wallswitchershown = !Settings.config.wallswitchershown;
}
}
}

View File

@ -2,6 +2,7 @@ import QtQuick
import qs.settings
import QtQuick.Layouts
import qs
import Quickshell
import qs.modules.Bar
import qs.widgets
import Quickshell.Widgets
@ -10,11 +11,11 @@ Rectangle {
id: notifyItem
required property var modelData
implicitWidth: ListView.view ? ListView.view.width : 300
implicitHeight: fullLayout.implicitHeight + 20
color: dismissArea.containsMouse ? Colors.surface : Colors.surface_container
implicitHeight: fullLayout.implicitHeight + 40
color: dismissArea.containsMouse ? Colors.base02 : Colors.base00
radius: Settings.config.rounding
border.width: 2
border.color: Colors.primary
border.width: 0
border.color: Colors.base0D
Timer {
id: dismissTimer
interval: 5000
@ -36,9 +37,9 @@ Rectangle {
implicitWidth: 64
color: "transparent"
implicitHeight: 64
visible: notifyItem.modelData.image !== ""
visible: notifyItem.modelData.appIcon !== ""
IconImage {
source: notifyItem.modelData.image
source: Quickshell.iconPath(notifyItem.modelData.appIcon)
visible: notifyItem.modelData.image !== ""
implicitSize: 64
asynchronous: true

View File

@ -1,34 +1,48 @@
import Quickshell
import Quickshell.Widgets
import QtQuick
import Qt5Compat.GraphicalEffects
import qs
import qs.settings
import qs.widgets
Rectangle {
Item {
id: root
implicitWidth: dataLayout.implicitWidth + 10
implicitHeight: dataLayout.implicitHeight + 10
color: Colors.surface
radius: Settings.config.rounding
SystemClock {
id: clock
precision: SystemClock.Minutes
}
Column {
id: dataLayout
anchors.fill: parent
anchors.centerIn: parent
spacing: 0
anchors.leftMargin: 5
CText {
text: Qt.formatDateTime(clock.date, "hh:mm")
font.pixelSize: 48
implicitWidth: wrapper.width
implicitHeight: wrapper.height
ClippingWrapperRectangle {
layer {
enabled: true
effect: DropShadow {
color: Colors.base00
horizontalOffset: 2
verticalOffset: 2
radius: 8
samples: 16
}
}
id: wrapper
SystemClock {
id: clock
precision: SystemClock.Minutes
}
CText {
text: Qt.formatDateTime(clock.date, "dd.MM.yy")
opacity: 0.6
font.pixelSize: 24
color: Colors.base01
radius: Settings.config.rounding
anchors.centerIn: parent
margin: 10
child: Column {
id: dataLayout
spacing: 0
anchors.margins: 0
CText {
text: Qt.formatDateTime(clock.date, "hh:mm")
font.pixelSize: 48
}
CText {
text: Qt.formatDateTime(clock.date, "dd.MM.yy")
opacity: 0.6
font.pixelSize: 24
}
}
}
}

View File

@ -2,6 +2,7 @@ pragma ComponentBehavior: Bound
import Quickshell.Services.Mpris
import Quickshell.Widgets
import QtQuick
import Qt5Compat.GraphicalEffects
import QtQuick.Layouts
import QtQuick.Controls
import qs
@ -10,16 +11,26 @@ import qs.widgets
Rectangle {
id: root
color: Colors.surface
radius: Settings.config.rounding * 2
color: Colors.base01
radius: Settings.config.rounding
implicitWidth: 600
implicitHeight: 200
visible: getSpotify() != null
layer {
enabled: true
effect: DropShadow {
color: Colors.base00
horizontalOffset: 2
verticalOffset: 2
radius: 8
samples: 16
}
}
MouseArea {
id: hoverDetect
hoverEnabled: true
anchors.fill: parent
onExited: title.x = 0
id: hoverDetect
hoverEnabled: true
anchors.fill: parent
onExited: title.x = 0
}
function getSpotify() {
for (var i = 0; i < Mpris.players.values.length; i++) {
@ -40,7 +51,7 @@ Rectangle {
id: songWrapper
radius: Settings.config.rounding
anchors.margins: 10
margin: 10
margin: 0
anchors.fill: parent
color: "transparent"
@ -49,7 +60,8 @@ Rectangle {
spacing: 0
ClippingWrapperRectangle {
id: coverRounder
radius: 8
Layout.leftMargin: 10
radius: 16
Image {
id: songCover
source: root.art
@ -63,7 +75,9 @@ Rectangle {
id: songInfo
Layout.alignment: Qt.AlignVCenter
Layout.fillWidth: true
Layout.fillHeight: true
Layout.leftMargin: 20
Layout.topMargin: 2
Item {
id: titleContainer
Layout.fillWidth: true
@ -81,11 +95,6 @@ Rectangle {
running: hoverDetect.containsMouse && title.width > titleContainer.width
loops: Animation.Infinite
// Pause at the start
PauseAnimation {
duration: 2000
}
// Scroll to the end
NumberAnimation {
to: titleContainer.width - title.width
@ -93,11 +102,6 @@ Rectangle {
easing.type: Easing.InOutQuad
}
// Pause at the end
PauseAnimation {
duration: 2000
}
// Scroll back to the start
NumberAnimation {
to: 0
@ -118,7 +122,7 @@ Rectangle {
id: songProgress
FrameAnimation {
// only emit the signal when the position is actually changing.
running: root.spotify.playbackState == MprisPlaybackState.Playing || root.visible
running: root.spotify ? root.spotify.playbackState == MprisPlaybackState.Playing || root.visible : false
// emit the positionChanged signal every frame.
onTriggered: root.spotify.positionChanged()
}
@ -130,7 +134,7 @@ Rectangle {
background: Rectangle {
implicitWidth: 200
implicitHeight: 6
color: Colors.surface_container_highest
color: Colors.base02
radius: 32
}
contentItem: Item {
@ -142,14 +146,14 @@ Rectangle {
width: songProgress.visualPosition * parent.width
height: parent.height
radius: 32
color: Colors.primary
color: Colors.base07
visible: !songProgress.indeterminate
}
}
}
RowLayout {
id: playerControls
spacing: 15
Layout.maximumWidth: 200
CIcon {
id: previous
text: "\ue045"
@ -167,7 +171,8 @@ Rectangle {
}
CIcon {
id: pause
text: root.spotify.isPlaying ? "\ue034" : "\ue037"
text: root.spotify ? root.spotify.isPlaying ? "\ue034" : "\ue037" : ""
Layout.alignment: Qt.AlignHCenter
MouseArea {
id: pauseHandler
anchors.fill: parent

View File

@ -27,7 +27,7 @@ Variants {
anchors {
bottom: parent.bottom
right: parent.right
margins: Settings.config.margins + 20
margins: Settings.config.margins + 5
}
}
PlayerWidget {

View File

@ -9,23 +9,10 @@ import qs.settings
FloatingWindow {
id: root
GlobalShortcut {
id: wallswitcherToggle
name: "showWallSwitcher"
onPressed: {
Settings.config.wallswitchershown = true;
}
}
Process {
id: matugenRunner
property string matugen: "matugen image " + Settings.config.currentWall + " --source-color-index=0"
running: false
command: [ "sh", "-c", matugen ]
}
implicitWidth: 700
title: "qs-wallpicker"
implicitHeight: 600
color: Colors.surface
color: Colors.base00
visible: Settings.config.wallswitchershown
onClosed: Settings.config.wallswitchershown = false
@ -36,7 +23,7 @@ FloatingWindow {
fill: parent
margins: 8
}
color: Colors.surface_container
color: Colors.base02
FolderListModel {
id: wpModel
folder: "file:///home/lucy/.walls/"
@ -62,7 +49,6 @@ FloatingWindow {
anchors.fill: parent
onClicked: {
Settings.config.currentWall = wpPreview.filePath;
matugenRunner.running = true
}
}
}

View File

@ -1,10 +1,10 @@
{
"barHeight": 34,
"barHeight": 38,
"currentWall": "/home/lucy/.walls/mooon.png",
"floating": true,
"font": "Lora",
"fontSize": 14,
"font": "Maple Mono",
"fontSize": 12,
"margins": 10,
"rounding": 12,
"rounding": 26,
"wallswitchershown": false
}

View File

@ -4,15 +4,17 @@ import qs.settings
Text {
id: root
color: Colors.on_surface
property real iconSize: 13
property real fill: 1
color: Colors.base05
property real iconSize: 18
property var fill: true
renderType: Text.NativeRendering
font {
family: "Material Symbols Sharp"
pointSize: iconSize
hintingPreference: Font.PreferNoHinting
family: "Material Symbols Rounded"
pixelSize: iconSize
weight: Font.Normal + (Font.DemiBold - Font.Normal) * fill
variableAxes: {
"FILL": 1,
"FILL": fill,
"opsz": iconSize
}
}

View File

@ -5,5 +5,6 @@ import qs.settings
Text {
font.family: Settings.config.font
font.pixelSize: Settings.config.fontSize
color: Colors.on_surface
color: Colors.base05
font.weight: 700
}