Merge branch 'main' into qt-scaling

This commit is contained in:
ItsLemmy
2025-10-12 18:27:56 -04:00
27 changed files with 600 additions and 241 deletions
+18
View File
@@ -324,6 +324,10 @@
"floating-distance": {
"label": "Dock-Schwebeabstand",
"description": "Schwebeabstand vom Bildschirmrand anpassen."
},
"colorize-icons": {
"label": "Symbole einfärben",
"description": "Theme-Farben auf Dock-App-Symbole anwenden (nur nicht fokussierte Apps)."
}
},
"monitors": {
@@ -935,6 +939,10 @@
"width": {
"description": "Steuert die horizontale Größe des Widgets.",
"label": "Widget-Breite"
},
"colorize-icons": {
"label": "Symbole einfärben",
"description": "Theme-Farben auf das aktive Fenster-Symbol anwenden."
}
},
"system-monitor": {
@@ -1128,6 +1136,16 @@
"only-same-output": {
"label": "Nur vom gleichen Bildschirm",
"description": "Zeige nur Apps vom dem Bildschirm an, wo sich die Taskbar befindet."
},
"colorize-icons": {
"label": "Symbole einfärben",
"description": "Theme-Farben auf Taskbar-Symbole anwenden."
}
},
"tray": {
"colorize-icons": {
"label": "Symbole einfärben",
"description": "Theme-Farben auf Tray-Symbole anwenden."
}
}
}
+18
View File
@@ -324,6 +324,10 @@
"floating-distance": {
"label": "Dock floating distance",
"description": "Adjust the floating distance from the screen edge."
},
"colorize-icons": {
"label": "Colorize Icons",
"description": "Apply theme colors to dock app icons (non-focused apps only)."
}
},
"monitors": {
@@ -918,6 +922,10 @@
"width": {
"label": "Widget Width",
"description": "Controls the horizontal size of the widget."
},
"colorize-icons": {
"label": "Colorize Icons",
"description": "Apply theme colors to active window icon."
}
},
"system-monitor": {
@@ -1111,6 +1119,16 @@
"only-same-output": {
"label": "Only from same output",
"description": "Show only apps from the output where the bar is located."
},
"colorize-icons": {
"label": "Colorize Icons",
"description": "Apply theme colors to taskbar icons."
}
},
"tray": {
"colorize-icons": {
"label": "Colorize Icons",
"description": "Apply theme colors to tray icons."
}
}
}
+18
View File
@@ -324,6 +324,10 @@
"floating-distance": {
"label": "Distancia de flotación del dock",
"description": "Ajusta la distancia de flotación desde el borde de la pantalla."
},
"colorize-icons": {
"label": "Colorear iconos",
"description": "Aplicar colores del tema a los iconos de aplicaciones del dock (solo aplicaciones no enfocadas)."
}
},
"monitors": {
@@ -918,6 +922,10 @@
"width": {
"description": "Controla el tamaño horizontal del widget.",
"label": "Ancho del widget"
},
"colorize-icons": {
"label": "Colorear iconos",
"description": "Aplicar colores del tema al icono de la ventana activa."
}
},
"system-monitor": {
@@ -1111,6 +1119,16 @@
"only-same-output": {
"description": "Muestra solo las aplicaciones del resultado donde se encuentra la barra.",
"label": "Solo de la misma salida"
},
"colorize-icons": {
"label": "Colorear iconos",
"description": "Aplicar colores del tema a los iconos de la barra de tareas."
}
},
"tray": {
"colorize-icons": {
"label": "Colorear iconos",
"description": "Aplicar colores del tema a los iconos de la bandeja del sistema."
}
}
}
+18
View File
@@ -324,6 +324,10 @@
"floating-distance": {
"label": "Distance de flottaison du dock",
"description": "Ajustez la distance de flottaison par rapport au bord de l'écran."
},
"colorize-icons": {
"label": "Coloriser les icônes",
"description": "Appliquer les couleurs du thème aux icônes d'applications du dock (applications non focalisées uniquement)."
}
},
"monitors": {
@@ -918,6 +922,10 @@
"width": {
"description": "Contrôle la taille horizontale du widget.",
"label": "Largeur du widget"
},
"colorize-icons": {
"label": "Coloriser les icônes",
"description": "Appliquer les couleurs du thème à l'icône de la fenêtre active."
}
},
"system-monitor": {
@@ -1111,6 +1119,16 @@
"only-same-output": {
"description": "Afficher uniquement les applications de la sortie où la barre est située.",
"label": "Seulement à partir de la même sortie"
},
"colorize-icons": {
"label": "Coloriser les icônes",
"description": "Appliquer les couleurs du thème aux icônes de la barre des tâches."
}
},
"tray": {
"colorize-icons": {
"label": "Coloriser les icônes",
"description": "Appliquer les couleurs du thème aux icônes de la barre système."
}
}
}
+18
View File
@@ -324,6 +324,10 @@
"floating-distance": {
"label": "Distância de flutuação da dock",
"description": "Ajuste a distância de flutuação da borda da tela."
},
"colorize-icons": {
"label": "Colorir ícones",
"description": "Aplicar cores do tema aos ícones de aplicativos da dock (apenas aplicativos não focados)."
}
},
"monitors": {
@@ -918,6 +922,10 @@
"width": {
"description": "Controla o tamanho horizontal do widget.",
"label": "Largura do Widget"
},
"colorize-icons": {
"label": "Colorir ícones",
"description": "Aplicar cores do tema ao ícone da janela ativa."
}
},
"system-monitor": {
@@ -1111,6 +1119,16 @@
"only-same-output": {
"description": "Mostrar apenas os aplicativos da saída onde a barra está localizada.",
"label": "Apenas da mesma saída"
},
"colorize-icons": {
"label": "Colorir ícones",
"description": "Aplicar cores do tema aos ícones da barra de tarefas."
}
},
"tray": {
"colorize-icons": {
"label": "Colorir ícones",
"description": "Aplicar cores do tema aos ícones da bandeja do sistema."
}
}
}
+18
View File
@@ -324,6 +324,10 @@
"floating-distance": {
"label": "Dock 浮动距离",
"description": "调整距离屏幕边缘的浮动距离。"
},
"colorize-icons": {
"label": "着色图标",
"description": "将主题颜色应用到 Dock 应用图标(仅限非聚焦应用)。"
}
},
"monitors": {
@@ -918,6 +922,10 @@
"width": {
"description": "控制小部件的水平尺寸。",
"label": "小部件宽度"
},
"colorize-icons": {
"label": "着色图标",
"description": "将主题颜色应用到活动窗口图标。"
}
},
"system-monitor": {
@@ -1111,6 +1119,16 @@
"only-same-output": {
"label": "仅显示同屏幕",
"description": "仅显示任务栏所在屏幕上的应用程序"
},
"colorize-icons": {
"label": "着色图标",
"description": "将主题颜色应用到任务栏图标。"
}
},
"tray": {
"colorize-icons": {
"label": "着色图标",
"description": "将主题颜色应用到系统托盘图标。"
}
}
}
+13 -4
View File
@@ -9,7 +9,6 @@
"floating": false,
"marginVertical": 0.25,
"marginHorizontal": 0.25,
"widgets": {
"left": [
{
@@ -37,6 +36,12 @@
{
"id": "NotificationHistory"
},
{
"id": "WiFi"
},
{
"id": "Bluetooth"
},
{
"id": "Battery"
},
@@ -63,7 +68,8 @@
"radiusRatio": 1,
"screenRadiusRatio": 1,
"animationSpeed": 1,
"animationDisabled": false
"animationDisabled": false,
"compactLockScreen": false
},
"location": {
"name": "Tokyo",
@@ -138,7 +144,8 @@
"floatingRatio": 1,
"onlySameOutput": true,
"monitors": [],
"pinnedApps": []
"pinnedApps": [],
"colorizeIcons": false
},
"network": {
"wifiEnabled": true
@@ -158,7 +165,8 @@
"enabled": true,
"location": "top_right",
"monitors": [],
"autoHideMs": 2000
"autoHideMs": 2000,
"alwaysOnTop": false
},
"audio": {
"volumeStep": 5,
@@ -189,6 +197,7 @@
"templates": {
"gtk": false,
"qt": false,
"kcolorscheme": false,
"kitty": false,
"ghostty": false,
"foot": false,
+18
View File
@@ -273,6 +273,7 @@ Singleton {
property list<string> monitors: []
// Desktop entry IDs pinned to the dock (e.g., "org.kde.konsole", "firefox.desktop")
property list<string> pinnedApps: []
property bool colorizeIcons: false
}
// network
@@ -374,6 +375,23 @@ Singleton {
}
}
// -----------------------------------------------------
// Function to preprocess paths by expanding "~" to user's home directory
function preprocessPath(path) {
if (typeof path !== "string" || path === "") {
return path
}
// Expand "~" to user's home directory
if (path.startsWith("~/")) {
return Quickshell.env("HOME") + path.substring(1)
} else if (path === "~") {
return Quickshell.env("HOME")
}
return path
}
// -----------------------------------------------------
// Public function to trigger immediate settings saving
function saveImmediate() {
+6 -4
View File
@@ -10,6 +10,8 @@ import qs.Widgets
NPanel {
id: root
readonly property var now: Time.date
preferredWidth: (Settings.data.location.showWeekNumberInCalendar ? 400 : 380) * Style.uiScaleRatio
preferredHeight: 520 * Style.uiScaleRatio
@@ -193,12 +195,12 @@ NPanel {
Canvas {
id: secondsProgress
anchors.fill: parent
property real progress: Time.date.getSeconds() / 60
property real progress: now.getSeconds() / 60
onProgressChanged: requestPaint()
Connections {
target: Time
function onDateChanged() {
const total = Time.date.getSeconds() * 1000 + Time.date.getMilliseconds()
const total = now.getSeconds() * 1000 + now.getMilliseconds()
secondsProgress.progress = total / 60000
}
}
@@ -233,7 +235,7 @@ NPanel {
NText {
text: {
var t = Settings.data.location.use12hourFormat ? Qt.locale().toString(Time.date, "hh AP") : Qt.locale().toString(Time.date, "HH")
var t = Settings.data.location.use12hourFormat ? Qt.locale().toString(now, "hh AP") : Qt.locale().toString(now, "HH")
return t.split(" ")[0]
}
@@ -245,7 +247,7 @@ NPanel {
}
NText {
text: Qt.formatTime(Time.date, "mm")
text: Qt.formatTime(now, "mm")
pointSize: Style.fontSizeXXS
font.weight: Style.fontWeightBold
color: Color.mOnPrimary
+18
View File
@@ -148,6 +148,15 @@ Item {
asynchronous: true
smooth: true
visible: source !== ""
// Apply dock shader to active window icon (always themed)
layer.enabled: widgetSettings.colorizeIcons !== false
layer.effect: ShaderEffect {
property color targetColor: Color.mOnSurface
property real colorizeMode: 0.0 // Dock mode (grayscale)
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
}
}
}
@@ -317,6 +326,15 @@ Item {
asynchronous: true
smooth: true
visible: source !== ""
// Apply dock shader to active window icon (always themed)
layer.enabled: widgetSettings.colorizeIcons !== false
layer.effect: ShaderEffect {
property color targetColor: Color.mOnSurface
property real colorizeMode: 0.0 // Dock mode (grayscale)
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
}
}
}
}
+9
View File
@@ -80,6 +80,15 @@ Rectangle {
asynchronous: true
opacity: modelData.isFocused ? Style.opacityFull : 0.6
// Apply dock shader to all taskbar icons
layer.enabled: widgetSettings.colorizeIcons !== false
layer.effect: ShaderEffect {
property color targetColor: Color.mOnSurface
property real colorizeMode: 0.0 // Dock mode (grayscale)
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
}
Rectangle {
anchors.bottomMargin: -2
anchors.bottom: parent.bottom
+8
View File
@@ -192,6 +192,14 @@ Rectangle {
}
opacity: status === Image.Ready ? 1 : 0
layer.enabled: widgetSettings.colorizeIcons !== false
layer.effect: ShaderEffect {
property color targetColor: Color.mOnSurface
property real colorizeMode: 1.0 // Tray mode (intensity-based)
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
+1 -1
View File
@@ -27,7 +27,7 @@ NBox {
NImageCircled {
width: Math.round(Style.baseWidgetSize * 1.25 * Style.uiScaleRatio)
height: width
imagePath: Settings.data.general.avatarImage
imagePath: Settings.preprocessPath(Settings.data.general.avatarImage)
fallbackIcon: "person"
borderColor: Color.mPrimary
borderWidth: Math.max(1, Style.borderM)
+1 -1
View File
@@ -32,7 +32,7 @@ NBox {
NImageCircled {
width: Style.baseWidgetSize * 1.25
height: width
imagePath: Settings.data.general.avatarImage
imagePath: Settings.preprocessPath(Settings.data.general.avatarImage)
fallbackIcon: "person"
borderColor: Color.mPrimary
borderWidth: Math.max(1, Style.borderM)
+9
View File
@@ -392,6 +392,15 @@ Variants {
scale: appButton.hovered ? 1.15 : 1.0
// Apply dock-specific colorization shader only to non-focused apps
layer.enabled: !appButton.isActive && Settings.data.dock.colorizeIcons
layer.effect: ShaderEffect {
property color targetColor: Color.mOnSurface
property real colorizeMode: 0.0 // Dock mode (grayscale)
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
}
Behavior on scale {
NumberAnimation {
duration: Style.animationNormal
+240 -139
View File
@@ -49,6 +49,8 @@ Loader {
locked: lockScreen.active
WlSessionLockSurface {
readonly property var now: Time.date
Item {
id: batteryIndicator
property var battery: UPower.displayDevice
@@ -101,8 +103,8 @@ Loader {
visible: Settings.data.general.showScreenCorners
property color cornerColor: Settings.data.general.forceBlackScreenCorners ? Qt.rgba(0, 0, 0, 1) : Qt.alpha(Color.mSurface, Settings.data.bar.backgroundOpacity)
property real cornerRadius: Style.screenRadius
property real cornerSize: Style.screenRadius
property real cornerRadius: Style.screenRadius
property real cornerSize: Style.screenRadius
// Top-left concave corner
Canvas {
@@ -246,12 +248,12 @@ Loader {
// Time, Date, and User Profile Container
Rectangle {
width: Math.max(500, contentRow.implicitWidth + 24)
height: 120
width: Math.max(500 , contentRow.implicitWidth + 32)
height: Math.max(120 , contentRow.implicitHeight + 32)
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 100
radius: Style.radiusL
anchors.topMargin: 100
radius: Style.radiusL
color: Color.mSurface
border.color: Qt.alpha(Color.mOutline, 0.2)
border.width: 1
@@ -259,13 +261,13 @@ Loader {
RowLayout {
id: contentRow
anchors.fill: parent
anchors.margins: 12
spacing: 8
anchors.margins: 16
spacing: 32
// Left side: Avatar
Rectangle {
Layout.preferredWidth: 70
Layout.preferredHeight: 70
Layout.preferredWidth: 70
Layout.preferredHeight: 70
Layout.alignment: Qt.AlignVCenter
radius: width * 0.5
color: Color.transparent
@@ -294,9 +296,9 @@ Loader {
NImageCircled {
anchors.centerIn: parent
width: 66
height: 66
imagePath: Settings.data.general.avatarImage
width: 66
height: 66
imagePath: Settings.preprocessPath(Settings.data.general.avatarImage)
fallbackIcon: "person"
SequentialAnimation on scale {
@@ -318,12 +320,12 @@ Loader {
// Center: User Info Column (left-aligned text)
ColumnLayout {
Layout.alignment: Qt.AlignVCenter
spacing: 2
spacing: 2
// Welcome back + Username on one line
NText {
text: I18n.tr("lock-screen.welcome-back") + " " + Quickshell.env("USER") + "!"
pointSize: Style.fontSizeXXXL
pointSize: Style.fontSizeXXL
font.weight: Font.Medium
color: Color.mOnSurface
horizontalAlignment: Text.AlignLeft
@@ -332,7 +334,7 @@ Loader {
// Date below
NText {
text: Qt.locale().toString(Time.date, "dddd, MMMM d")
pointSize: Style.fontSizeXXL
pointSize: Style.fontSizeXL
font.weight: Font.Medium
color: Color.mOnSurfaceVariant
horizontalAlignment: Text.AlignLeft
@@ -345,8 +347,8 @@ Loader {
}
Item {
Layout.preferredWidth: 70
Layout.preferredHeight: 70
Layout.preferredWidth: 70
Layout.preferredHeight: 70
Layout.alignment: Qt.AlignVCenter
// Seconds circular progress
@@ -369,21 +371,21 @@ Loader {
var ctx = getContext("2d")
var centerX = width / 2
var centerY = height / 2
var radius = Math.min(width, height) / 2 - 3
var radius = Math.min(width, height) / 2 - 3
ctx.reset()
// Background circle
ctx.beginPath()
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI)
ctx.lineWidth = 2.5
ctx.lineWidth = 2.5
ctx.strokeStyle = Qt.alpha(Color.mOnSurface, 0.15)
ctx.stroke()
// Progress arc
ctx.beginPath()
ctx.arc(centerX, centerY, radius, -Math.PI / 2, -Math.PI / 2 + progress * 2 * Math.PI)
ctx.lineWidth = 2.5
ctx.lineWidth = 2.5
ctx.strokeStyle = Color.mPrimary
ctx.lineCap = "round"
ctx.stroke()
@@ -400,7 +402,7 @@ Loader {
var t = Settings.data.location.use12hourFormat ? Qt.locale().toString(Time.date, "hh AP") : Qt.locale().toString(Time.date, "HH")
return t
}
pointSize: Style.fontSizeL
pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: Color.mOnSurface
horizontalAlignment: Text.AlignHCenter
@@ -409,7 +411,7 @@ Loader {
NText {
text: Qt.formatTime(Time.date, "mm")
pointSize: Style.fontSizeL
pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: Color.mOnSurfaceVariant
horizontalAlignment: Text.AlignHCenter
@@ -422,12 +424,12 @@ Loader {
// Error notification
Rectangle {
width: 450
height: 60
width: 450
height: 60
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 300
radius: 30
anchors.bottomMargin: 300
radius: 30
color: Color.mError
border.color: Color.mError
border.width: 1
@@ -436,18 +438,18 @@ Loader {
RowLayout {
anchors.centerIn: parent
spacing: 10
spacing: 10
NIcon {
icon: "alert-circle"
pointSize: Style.fontSizeL
pointSize: Style.fontSizeL
color: Color.mOnError
}
NText {
text: lockContext.errorMessage || "Authentication failed"
color: Color.mOnError
pointSize: Style.fontSizeL
pointSize: Style.fontSizeL
font.weight: Font.Medium
horizontalAlignment: Text.AlignHCenter
}
@@ -468,61 +470,62 @@ Loader {
var hasKeyboard = keyboardLayout.currentLayout !== "Unknown"
if (hasBattery && hasKeyboard) {
return 200
return 200
} else if (hasBattery || hasKeyboard) {
return 120
return 120
} else {
return 0
}
}
height: 40
height: 40
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 96 + (Settings.data.general.compactLockScreen ? 116 : 220)
topLeftRadius: Style.radiusL
topRightRadius: Style.radiusL
anchors.bottomMargin: 96 + (Settings.data.general.compactLockScreen ? 116 : 220 )
topLeftRadius: Style.radiusL
topRightRadius: Style.radiusL
color: Color.mSurface
visible: Settings.data.general.compactLockScreen && ((UPower.displayDevice && UPower.displayDevice.ready && UPower.displayDevice.isPresent) || keyboardLayout.currentLayout !== "Unknown")
RowLayout {
anchors.centerIn: parent
spacing: 16
spacing: 16
// Battery indicator
RowLayout {
spacing: 6
spacing: 6
visible: UPower.displayDevice && UPower.displayDevice.ready && UPower.displayDevice.isPresent
NIcon {
icon: BatteryService.getIcon(Math.round(UPower.displayDevice.percentage * 100), UPower.displayDevice.state === UPowerDeviceState.Charging, true)
pointSize: Style.fontSizeM
pointSize: Style.fontSizeM
color: UPower.displayDevice.state === UPowerDeviceState.Charging ? Color.mPrimary : Color.mOnSurfaceVariant
}
NText {
text: Math.round(UPower.displayDevice.percentage * 100) + "%"
color: Color.mOnSurfaceVariant
pointSize: Style.fontSizeM
pointSize: Style.fontSizeM
font.weight: Font.Medium
}
}
// Keyboard layout indicator
RowLayout {
spacing: 6
spacing: 6
visible: keyboardLayout.currentLayout !== "Unknown"
NIcon {
icon: "keyboard"
pointSize: Style.fontSizeM
pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
}
NText {
text: keyboardLayout.currentLayout
color: Color.mOnSurfaceVariant
pointSize: Style.fontSizeM
pointSize: Style.fontSizeM
font.weight: Font.Medium
elide: Text.ElideRight
}
}
}
@@ -530,38 +533,38 @@ Loader {
// Bottom container with weather, password input and controls
Rectangle {
width: 750
height: Settings.data.general.compactLockScreen ? 120 : 220
width: 750
height: Settings.data.general.compactLockScreen ? 120 : 220
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 100
radius: Style.radiusL
anchors.bottomMargin: 100
radius: Style.radiusL
color: Color.mSurface
ColumnLayout {
anchors.fill: parent
anchors.margins: 14
spacing: 14
anchors.margins: 14
spacing: 14
// Weather section
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: 65
spacing: 18
Layout.preferredHeight: 65
spacing: 18
visible: !Settings.data.general.compactLockScreen && LocationService.coordinatesReady && LocationService.data.weather !== null
// Media widget with visualizer
Rectangle {
Layout.preferredWidth: 220
Layout.preferredHeight: 50
radius: 25
Layout.preferredWidth: 220
Layout.preferredHeight: 50
radius: 25
color: Color.transparent
clip: true
visible: MediaService.currentPlayer && MediaService.canPlay
Loader {
anchors.fill: parent
anchors.margins: 4
anchors.margins: 4
active: Settings.data.audio.visualizerType === "linear"
z: 0
sourceComponent: LinearSpectrum {
@@ -574,7 +577,7 @@ Loader {
Loader {
anchors.fill: parent
anchors.margins: 4
anchors.margins: 4
active: Settings.data.audio.visualizerType === "mirrored"
z: 0
sourceComponent: MirroredSpectrum {
@@ -587,7 +590,7 @@ Loader {
Loader {
anchors.fill: parent
anchors.margins: 4
anchors.margins: 4
active: Settings.data.audio.visualizerType === "wave"
z: 0
sourceComponent: WaveSpectrum {
@@ -600,35 +603,35 @@ Loader {
RowLayout {
anchors.fill: parent
anchors.margins: 8
spacing: 8
anchors.margins: 8
spacing: 8
z: 1
Rectangle {
Layout.preferredWidth: 34
Layout.preferredHeight: 34
Layout.preferredWidth: 34
Layout.preferredHeight: 34
radius: width * 0.5
color: Color.transparent
clip: true
NImageCircled {
anchors.fill: parent
anchors.margins: 2
anchors.margins: 2
imagePath: MediaService.trackArtUrl
fallbackIcon: "disc"
fallbackIconSize: Style.fontSizeM
fallbackIconSize: Style.fontSizeM
borderColor: Color.mOutline
borderWidth: Math.max(1, Style.borderS)
borderWidth: Math.max(1, Style.borderS )
}
}
ColumnLayout {
Layout.fillWidth: true
spacing: 2
spacing: 2
NText {
text: MediaService.trackTitle || "No media"
pointSize: Style.fontSizeM
pointSize: Style.fontSizeM
font.weight: Style.fontWeightMedium
color: Color.mOnSurface
Layout.fillWidth: true
@@ -637,7 +640,7 @@ Loader {
NText {
text: MediaService.trackArtist || ""
pointSize: Style.fontSizeM
pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
Layout.fillWidth: true
elide: Text.ElideRight
@@ -649,46 +652,64 @@ Loader {
Rectangle {
Layout.preferredWidth: 1
Layout.fillHeight: true
Layout.rightMargin: 4
Layout.rightMargin: 4
color: Qt.alpha(Color.mOutline, 0.3)
visible: MediaService.currentPlayer && MediaService.canPlay
}
Item {
Layout.preferredWidth: Style.marginM
Layout.preferredWidth: Style.marginM
visible: !(MediaService.currentPlayer && MediaService.canPlay)
}
// Current weather
RowLayout {
Layout.preferredWidth: 180
spacing: 8
Layout.preferredWidth: 180
spacing: 8
NIcon {
Layout.alignment: Qt.AlignVCenter
icon: LocationService.weatherSymbolFromCode(LocationService.data.weather.current_weather.weathercode)
pointSize: Style.fontSizeXXXL
pointSize: Style.fontSizeXXXL
color: Color.mPrimary
}
ColumnLayout {
Layout.fillWidth: true
spacing: 2
spacing: 2
RowLayout {
Layout.fillWidth: true
spacing: 12
spacing: 12
NText {
text: Math.round(LocationService.data.weather.current_weather.temperature) + "°"
pointSize: Style.fontSizeXL
text: {
var temp = LocationService.data.weather.current_weather.temperature
var suffix = "C"
if (Settings.data.location.useFahrenheit) {
temp = LocationService.celsiusToFahrenheit(temp)
suffix = "F"
}
temp = Math.round(temp)
return temp + "°" + suffix
}
pointSize: Style.fontSizeXL
font.weight: Style.fontWeightBold
color: Color.mOnSurface
}
NText {
text: LocationService.data.weather.current_weather.windspeed + " km/h"
pointSize: Style.fontSizeM
text: {
var wind = LocationService.data.weather.current_weather.windspeed
var unit = "km/h"
if (Settings.data.location.useFahrenheit) {
wind = wind * 0.621371 // Convert km/h to mph
unit = "mph"
}
wind = Math.round(wind)
return wind + " " + unit
}
pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
font.weight: Font.Normal
}
@@ -696,17 +717,17 @@ Loader {
RowLayout {
Layout.fillWidth: true
spacing: 8
spacing: 8
NText {
text: Settings.data.location.name.split(",")[0]
pointSize: Style.fontSizeM
pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
}
NText {
text: (LocationService.data.weather.current && LocationService.data.weather.current.relativehumidity_2m) ? LocationService.data.weather.current.relativehumidity_2m + "% humidity" : ""
pointSize: Style.fontSizeM
pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
}
}
@@ -715,19 +736,19 @@ Loader {
// 3-day forecast
RowLayout {
Layout.preferredWidth: 260
Layout.rightMargin: 8
spacing: 4
Layout.preferredWidth: 260
Layout.rightMargin: 8
spacing: 4
Repeater {
model: 3
delegate: ColumnLayout {
Layout.fillWidth: true
spacing: 3
spacing: 3
NText {
text: Qt.locale().toString(new Date(LocationService.data.weather.daily.time[index].replace(/-/g, "/")), "ddd")
pointSize: Style.fontSizeM
text: Qt.locale().toString(now, "ddd")
pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
horizontalAlignment: Text.AlignHCenter
Layout.fillWidth: true
@@ -736,13 +757,23 @@ Loader {
NIcon {
Layout.alignment: Qt.AlignHCenter
icon: LocationService.weatherSymbolFromCode(LocationService.data.weather.daily.weathercode[index])
pointSize: Style.fontSizeXL
pointSize: Style.fontSizeXL
color: Color.mOnSurfaceVariant
}
NText {
text: Math.round(LocationService.data.weather.daily.temperature_2m_max[index]) + "°/" + Math.round(LocationService.data.weather.daily.temperature_2m_min[index]) + "°"
pointSize: Style.fontSizeM
text: {
var max = LocationService.data.weather.daily.temperature_2m_max[index]
var min = LocationService.data.weather.daily.temperature_2m_min[index]
if (Settings.data.location.useFahrenheit) {
max = LocationService.celsiusToFahrenheit(max)
min = LocationService.celsiusToFahrenheit(min)
}
max = Math.round(max)
min = Math.round(min)
return max + "°/" + min + "°"
}
pointSize: Style.fontSizeM
font.weight: Style.fontWeightMedium
color: Color.mOnSurfaceVariant
horizontalAlignment: Text.AlignHCenter
@@ -753,45 +784,49 @@ Loader {
}
// Battery and Keyboard Layout (full mode only)
RowLayout {
Layout.preferredWidth: 60
spacing: 4
ColumnLayout {
Layout.preferredWidth: 60
spacing: 8
// Battery
RowLayout {
spacing: 4
spacing: 4
visible: UPower.displayDevice && UPower.displayDevice.ready && UPower.displayDevice.isPresent
NIcon {
icon: BatteryService.getIcon(Math.round(UPower.displayDevice.percentage * 100), UPower.displayDevice.state === UPowerDeviceState.Charging, true)
pointSize: Style.fontSizeM
pointSize: Style.fontSizeM
color: UPower.displayDevice.state === UPowerDeviceState.Charging ? Color.mPrimary : Color.mOnSurfaceVariant
}
NText {
text: Math.round(UPower.displayDevice.percentage * 100) + "%"
color: Color.mOnSurfaceVariant
pointSize: Style.fontSizeM
pointSize: Style.fontSizeM
font.weight: Font.Medium
elide: Text.ElideRight
Layout.fillWidth: true
}
}
// Keyboard Layout
RowLayout {
spacing: 4
spacing: 4
visible: keyboardLayout.currentLayout !== "Unknown"
NIcon {
icon: "keyboard"
pointSize: Style.fontSizeM
pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
}
NText {
text: keyboardLayout.currentLayout
color: Color.mOnSurfaceVariant
pointSize: Style.fontSizeM
pointSize: Style.fontSizeM
font.weight: Font.Medium
elide: Text.ElideRight
Layout.fillWidth: true
}
}
}
@@ -803,26 +838,26 @@ Loader {
spacing: 0
Item {
Layout.preferredWidth: Style.marginM
Layout.preferredWidth: Style.marginM
}
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 48
radius: 24
Layout.preferredHeight: 48
radius: 24
color: Color.mSurface
border.color: passwordInput.activeFocus ? Color.mPrimary : Qt.alpha(Color.mOutline, 0.3)
border.width: passwordInput.activeFocus ? 2 : 1
Row {
anchors.left: parent.left
anchors.leftMargin: 18
anchors.leftMargin: 18
anchors.verticalCenter: parent.verticalCenter
spacing: 14
spacing: 14
NIcon {
icon: "lock"
pointSize: Style.fontSizeL
pointSize: Style.fontSizeL
color: passwordInput.activeFocus ? Color.mPrimary : Color.mOnSurfaceVariant
anchors.verticalCenter: parent.verticalCenter
}
@@ -834,7 +869,7 @@ Loader {
height: 0
visible: false
enabled: !lockContext.unlockInProgress
font.pointSize: Style.fontSizeM
font.pointSize: Style.fontSizeM
color: Color.mPrimary
echoMode: TextInput.Password
passwordCharacter: "•"
@@ -855,8 +890,8 @@ Loader {
spacing: 0
Rectangle {
width: 2
height: 20
width: 2
height: 20
color: Color.mPrimary
visible: passwordInput.activeFocus && passwordInput.text.length === 0
anchors.verticalCenter: parent.verticalCenter
@@ -876,7 +911,7 @@ Loader {
}
Row {
spacing: 6
spacing: 6
visible: passwordInput.text.length > 0
anchors.verticalCenter: parent.verticalCenter
@@ -885,7 +920,7 @@ Loader {
NIcon {
icon: "circle-filled"
pointSize: Style.fontSizeS
pointSize: Style.fontSizeS
color: Color.mPrimary
opacity: 1.0
}
@@ -893,8 +928,8 @@ Loader {
}
Rectangle {
width: 2
height: 20
width: 2
height: 20
color: Color.mPrimary
visible: passwordInput.activeFocus && passwordInput.text.length > 0
anchors.verticalCenter: parent.verticalCenter
@@ -917,10 +952,10 @@ Loader {
Rectangle {
anchors.right: parent.right
anchors.rightMargin: 8
anchors.rightMargin: 8
anchors.verticalCenter: parent.verticalCenter
width: 36
height: 36
width: 36
height: 36
radius: width * 0.5
color: submitButtonArea.containsMouse ? Color.mPrimary : Qt.alpha(Color.mPrimary, 0.8)
border.color: Color.mPrimary
@@ -930,7 +965,7 @@ Loader {
NIcon {
anchors.centerIn: parent
icon: "arrow-forward"
pointSize: Style.fontSizeM
pointSize: Style.fontSizeM
color: Color.mOnPrimary
}
@@ -951,40 +986,42 @@ Loader {
}
Item {
Layout.preferredWidth: Style.marginM
Layout.preferredWidth: Style.marginM
}
}
// System control buttons
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: 48
spacing: 10
Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 : 48
spacing: 10
Item {
Layout.preferredWidth: Style.marginM
Layout.preferredWidth: Style.marginM
}
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 48
radius: 24
Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 : 48
radius: Settings.data.general.compactLockScreen ? 18 : 24
color: logoutButtonArea.containsMouse ? Color.mTertiary : "transparent"
border.color: Color.mOutline
border.width: 1
RowLayout {
anchors.centerIn: parent
spacing: 6
spacing: 6
NIcon {
icon: "logout"
pointSize: Style.fontSizeL
pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeM : Style.fontSizeL
color: logoutButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
}
NText {
text: I18n.tr("session-menu.logout")
color: logoutButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
pointSize: Style.fontSizeM
pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeS : Style.fontSizeM
font.weight: Font.Medium
}
}
@@ -1002,28 +1039,85 @@ Loader {
easing.type: Easing.OutCubic
}
}
Behavior on border.color {
ColorAnimation {
duration: 200
easing.type: Easing.OutCubic
}
}
}
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 48
radius: 24
color: rebootButtonArea.containsMouse ? Color.mTertiary : "transparent"
Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 : 48
radius: Settings.data.general.compactLockScreen ? 18 : 24
color: suspendButtonArea.containsMouse ? Color.mTertiary : "transparent"
border.color: Color.mOutline
border.width: 1
RowLayout {
anchors.centerIn: parent
spacing: 6
spacing: 6
NIcon {
icon: "suspend"
pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeM : Style.fontSizeL
color: suspendButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
}
NText {
text: I18n.tr("session-menu.suspend")
color: suspendButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeS : Style.fontSizeM
font.weight: Font.Medium
}
}
MouseArea {
id: suspendButtonArea
anchors.fill: parent
hoverEnabled: true
onClicked: CompositorService.suspend()
}
Behavior on color {
ColorAnimation {
duration: 200
easing.type: Easing.OutCubic
}
}
Behavior on border.color {
ColorAnimation {
duration: 200
easing.type: Easing.OutCubic
}
}
}
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 : 48
radius: Settings.data.general.compactLockScreen ? 18 : 24
color: rebootButtonArea.containsMouse ? Color.mTertiary : "transparent"
border.color: Color.mOutline
border.width: 1
RowLayout {
anchors.centerIn: parent
spacing: 6
NIcon {
icon: "reboot"
pointSize: Style.fontSizeL
pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeM : Style.fontSizeL
color: rebootButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
}
NText {
text: I18n.tr("session-menu.reboot")
color: rebootButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
pointSize: Style.fontSizeM
pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeS : Style.fontSizeM
font.weight: Font.Medium
}
}
@@ -1041,30 +1135,37 @@ Loader {
easing.type: Easing.OutCubic
}
}
Behavior on border.color {
ColorAnimation {
duration: 200
easing.type: Easing.OutCubic
}
}
}
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 48
radius: 24
Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 : 48
radius: Settings.data.general.compactLockScreen ? 18 : 24
color: shutdownButtonArea.containsMouse ? Color.mError : "transparent"
border.color: shutdownButtonArea.containsMouse ? Color.mError : Color.transparent
border.color: shutdownButtonArea.containsMouse ? Color.mError : Color.mOutline
border.width: 1
RowLayout {
anchors.centerIn: parent
spacing: 6
spacing: 6
NIcon {
icon: "shutdown"
pointSize: Style.fontSizeL
pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeM : Style.fontSizeL
color: shutdownButtonArea.containsMouse ? Color.mOnError : Color.mOnSurfaceVariant
}
NText {
text: I18n.tr("session-menu.shutdown")
color: shutdownButtonArea.containsMouse ? Color.mOnError : Color.mOnSurfaceVariant
pointSize: Style.fontSizeM
pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeS : Style.fontSizeM
font.weight: Font.Medium
}
}
@@ -1092,7 +1193,7 @@ Loader {
}
Item {
Layout.preferredWidth: Style.marginM
Layout.preferredWidth: Style.marginM
}
}
}
@@ -1102,4 +1203,4 @@ Loader {
}
}
}
}
}
+75 -76
View File
@@ -129,17 +129,9 @@ Variants {
readonly property int hHeight: Math.round(64)
readonly property int vHeight: Math.round(320) // Vertical OSD height (matches horizontal width)
// Ensure an even width to keep the vertical bar perfectly centered
readonly property int barThickness: (function () {
readonly property int barThickness: {
const base = Math.max(8, Math.round(8))
return (base % 2 === 0) ? base : base + 1
})()
Component.onCompleted: {
}
Component.onDestruction: {
}
// Anchor selection based on location (window edges)
@@ -218,8 +210,10 @@ Variants {
opacity: 0
scale: 0.85
anchors.horizontalCenter: verticalMode ? undefined : parent.horizontalCenter
anchors.verticalCenter: verticalMode ? parent.verticalCenter : undefined
// Only horizontally center when the window itself is centered (top/bottom positions)
// For left/right vertical mode, fill the parent width
anchors.horizontalCenter: (!panel.verticalMode && panel.isCentered) ? parent.horizontalCenter : undefined
anchors.verticalCenter: panel.verticalMode ? parent.verticalCenter : undefined
Behavior on opacity {
NumberAnimation {
@@ -336,85 +330,90 @@ Variants {
Component {
id: verticalContent
ColumnLayout {
// Ensure inner padding respects the rounded corners; avoid clipping the icon/text
property int vMargin: (function () {
const styleMargin = Math.round(Style.marginL)
const cornerGuard = Math.round(osdItem.radius)
return Math.max(styleMargin, cornerGuard)
})()
property int vMarginTop: Math.max(Math.round(osdItem.radius), Math.round(Style.marginS))
property int balanceDelta: Math.round(Style.marginS)
Item {
anchors.fill: parent
anchors.topMargin: vMargin
anchors.leftMargin: vMargin
anchors.rightMargin: vMargin
anchors.bottomMargin: vMargin
spacing: Math.round(Style.marginS)
// Percentage text at top
Item {
Layout.fillWidth: true
Layout.preferredHeight: percentText.implicitHeight
NText {
id: percentText
text: root.getDisplayPercentage()
color: Color.mOnSurface
pointSize: Style.fontSizeS
family: Settings.data.ui.fontFixed
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
ColumnLayout {
// Ensure inner padding respects the rounded corners; avoid clipping the icon/text
property int vMargin: {
const styleMargin = Style.marginL
const cornerGuard = Math.round(osdItem.radius)
return Math.max(styleMargin, cornerGuard)
}
}
property int vMarginTop: Math.max(Math.round(osdItem.radius), Style.marginS)
property int balanceDelta: Style.marginS
anchors.fill: parent
anchors.topMargin: vMargin
anchors.leftMargin: vMargin
anchors.rightMargin: vMargin
anchors.bottomMargin: vMargin
spacing: Style.marginS
// Progress bar
Item {
Layout.fillWidth: true
Layout.fillHeight: true // Fill remaining space between text and icon
Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.bottom: parent.bottom
width: panel.barThickness
radius: Math.round(panel.barThickness / 2)
color: Color.mSurfaceVariant
// Percentage text at top
Item {
Layout.fillWidth: true
Layout.preferredHeight: 20
NText {
id: percentText
text: root.getDisplayPercentage()
color: Color.mOnSurface
pointSize: Style.fontSizeS
family: Settings.data.ui.fontFixed
width: 50
height: parent.height
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
// Progress bar
Item {
Layout.fillWidth: true
Layout.fillHeight: true // Fill remaining space between text and icon
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.bottom: parent.bottom
height: parent.height * Math.min(1.0, root.getCurrentValue())
radius: parent.radius
color: root.getProgressColor()
width: panel.barThickness
radius: Math.round(panel.barThickness / 2)
color: Color.mSurfaceVariant
Behavior on height {
NumberAnimation {
duration: Style.animationNormal
easing.type: Easing.InOutQuad
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: parent.height * Math.min(1.0, root.getCurrentValue())
radius: parent.radius
color: root.getProgressColor()
Behavior on height {
NumberAnimation {
duration: Style.animationNormal
easing.type: Easing.InOutQuad
}
}
}
Behavior on color {
ColorAnimation {
duration: Style.animationNormal
easing.type: Easing.InOutQuad
Behavior on color {
ColorAnimation {
duration: Style.animationNormal
easing.type: Easing.InOutQuad
}
}
}
}
}
}
// Icon at bottom
NIcon {
icon: root.getIcon()
color: root.getIconColor()
pointSize: Style.fontSizeXL
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Behavior on color {
ColorAnimation {
duration: Style.animationNormal
easing.type: Easing.InOutQuad
// Icon at bottom
NIcon {
icon: root.getIcon()
color: root.getIconColor()
pointSize: Style.fontSizeXL
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Behavior on color {
ColorAnimation {
duration: Style.animationNormal
easing.type: Easing.InOutQuad
}
}
}
}
@@ -18,6 +18,7 @@ ColumnLayout {
property bool valueAutoHide: widgetData.autoHide !== undefined ? widgetData.autoHide : widgetMetadata.autoHide
property string valueScrollingMode: widgetData.scrollingMode || widgetMetadata.scrollingMode
property int valueWidth: widgetData.width !== undefined ? widgetData.width : widgetMetadata.width
property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons
function saveSettings() {
var settings = Object.assign({}, widgetData || {})
@@ -25,6 +26,7 @@ ColumnLayout {
settings.showIcon = valueShowIcon
settings.scrollingMode = valueScrollingMode
settings.width = parseInt(widthInput.text) || widgetMetadata.width
settings.colorizeIcons = valueColorizeIcons
return settings
}
@@ -44,6 +46,14 @@ ColumnLayout {
onToggled: checked => root.valueShowIcon = checked
}
NToggle {
Layout.fillWidth: true
label: I18n.tr("bar.widget-settings.active-window.colorize-icons.label")
description: I18n.tr("bar.widget-settings.active-window.colorize-icons.description")
checked: root.valueColorizeIcons
onToggled: checked => root.valueColorizeIcons = checked
}
NTextInput {
id: widthInput
Layout.fillWidth: true
@@ -16,11 +16,13 @@ ColumnLayout {
// Local state
property bool valueOnlyActiveWorkspaces: widgetData.onlyActiveWorkspaces !== undefined ? widgetData.onlyActiveWorkspaces : widgetMetadata.onlyActiveWorkspaces
property bool valueOnlySameOutput: widgetData.onlySameOutput !== undefined ? widgetData.onlySameOutput : widgetMetadata.onlySameOutput
property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons
function saveSettings() {
var settings = Object.assign({}, widgetData || {})
settings.onlySameOutput = valueOnlySameOutput
settings.onlyActiveWorkspaces = valueOnlyActiveWorkspaces
settings.colorizeIcons = valueColorizeIcons
return settings
}
@@ -39,4 +41,12 @@ ColumnLayout {
checked: root.valueOnlyActiveWorkspaces
onToggled: checked => root.valueOnlyActiveWorkspaces = checked
}
NToggle {
Layout.fillWidth: true
label: I18n.tr("bar.widget-settings.taskbar.colorize-icons.label")
description: I18n.tr("bar.widget-settings.taskbar.colorize-icons.description")
checked: root.valueColorizeIcons
onToggled: checked => root.valueColorizeIcons = checked
}
}
@@ -5,12 +5,14 @@ import qs.Commons
import qs.Widgets
ColumnLayout {
id: root
// Properties to receive data from parent
property var widgetData: ({}) // Expected by BarWidgetSettingsDialog
property var widgetMetadata: ({}) // Expected by BarWidgetSettingsDialog
// Local state for the blacklist
// Local state
property var localBlacklist: widgetData.blacklist || []
property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons
ListModel {
id: blacklistModel
@@ -27,6 +29,14 @@ ColumnLayout {
spacing: Style.marginM
NToggle {
Layout.fillWidth: true
label: I18n.tr("bar.widget-settings.tray.colorize-icons.label")
description: I18n.tr("bar.widget-settings.tray.colorize-icons.description")
checked: root.valueColorizeIcons
onToggled: checked => root.valueColorizeIcons = checked
}
ColumnLayout {
Layout.fillWidth: true
spacing: Style.marginS
@@ -135,6 +145,7 @@ ColumnLayout {
// Return the updated settings for this widget instance
var settings = Object.assign({}, widgetData || {})
settings.blacklist = newBlacklist
settings.colorizeIcons = root.valueColorizeIcons
return settings
}
}
+14
View File
@@ -93,6 +93,20 @@ ColumnLayout {
Layout.bottomMargin: Style.marginXL
}
NToggle {
Layout.fillWidth: true
label: I18n.tr("settings.dock.appearance.colorize-icons.label")
description: I18n.tr("settings.dock.appearance.colorize-icons.description")
checked: Settings.data.dock.colorizeIcons
onToggled: checked => Settings.data.dock.colorizeIcons = checked
}
NDivider {
Layout.fillWidth: true
Layout.topMargin: Style.marginXL
Layout.bottomMargin: Style.marginXL
}
// Monitor Configuration
ColumnLayout {
spacing: Style.marginM
+4 -4
View File
@@ -21,9 +21,9 @@ ColumnLayout {
// Avatar preview
NImageCircled {
width: 108
height: 108
imagePath: Settings.data.general.avatarImage
width: 108 * Style.uiScaleRatio
height: 108 * Style.uiScaleRatio
imagePath: Settings.preprocessPath(Settings.data.general.avatarImage)
fallbackIcon: "person"
borderColor: Color.mPrimary
borderWidth: Math.max(1, Style.borderM)
@@ -50,7 +50,7 @@ ColumnLayout {
id: avatarPicker
title: I18n.tr("settings.general.profile.select-avatar")
selectionMode: "files"
initialPath: Settings.data.general.avatarImage.substr(0, Settings.data.general.avatarImage.lastIndexOf("/")) || Quickshell.env("HOME")
initialPath: Settings.preprocessPath(Settings.data.general.avatarImage).substr(0, Settings.preprocessPath(Settings.data.general.avatarImage).lastIndexOf("/")) || Quickshell.env("HOME")
nameFilters: ["*.jpg", "*.jpeg", "*.png", "*.gif", "*.pnm", "*.bmp"]
onAccepted: paths => {
if (paths.length > 0) {
+6 -3
View File
@@ -43,7 +43,8 @@ Singleton {
"showIcon": true,
"autoHide": false,
"scrollingMode": "hover",
"width": 145
"width": 145,
"colorizeIcons": false
},
"Battery": {
"allowUserSettings": true,
@@ -114,11 +115,13 @@ Singleton {
"Taskbar": {
"allowUserSettings": true,
"onlySameOutput": true,
"onlyActiveWorkspaces": true
"onlyActiveWorkspaces": true,
"colorizeIcons": false
},
"Tray": {
"allowUserSettings": true,
"blacklist": []
"blacklist": [],
"colorizeIcons": false
},
"Workspace": {
"allowUserSettings": true,
+1 -1
View File
@@ -49,7 +49,7 @@ Singleton {
function launchRecorder() {
var filename = Time.getFormattedTimestamp() + ".mp4"
var videoDir = settings.directory
var videoDir = Settings.preprocessPath(settings.directory)
if (videoDir && !videoDir.endsWith("/")) {
videoDir += "/"
}
+8 -7
View File
@@ -10,6 +10,7 @@ Singleton {
id: root
readonly property ListModel fillModeModel: ListModel {}
readonly property string defaultDirectory: Settings.preprocessPath(Settings.data.wallpaper.directory)
// All available wallpaper transitions
readonly property ListModel transitionsModel: ListModel {}
@@ -44,7 +45,7 @@ Singleton {
if (!Settings.data.wallpaper.enableMultiMonitorDirectories) {
// All monitors use the main directory
for (var i = 0; i < Quickshell.screens.length; i++) {
root.wallpaperDirectoryChanged(Quickshell.screens[i].name, Settings.data.wallpaper.directory)
root.wallpaperDirectoryChanged(Quickshell.screens[i].name, root.defaultDirectory)
}
} else {
// Only monitors without custom directories are affected
@@ -52,7 +53,7 @@ Singleton {
var screenName = Quickshell.screens[i].name
var monitor = root.getMonitorConfig(screenName)
if (!monitor || !monitor.directory) {
root.wallpaperDirectoryChanged(screenName, Settings.data.wallpaper.directory)
root.wallpaperDirectoryChanged(screenName, root.defaultDirectory)
}
}
}
@@ -177,16 +178,16 @@ Singleton {
// Get specific monitor directory
function getMonitorDirectory(screenName) {
if (!Settings.data.wallpaper.enableMultiMonitorDirectories) {
return Settings.data.wallpaper.directory
return root.defaultDirectory
}
var monitor = getMonitorConfig(screenName)
if (monitor !== undefined && monitor.directory !== undefined) {
return monitor.directory
return Settings.preprocessPath(monitor.directory)
}
// Fall back to the main/single directory
return Settings.data.wallpaper.directory
return root.defaultDirectory
}
// -------------------------------------------------------------------
@@ -218,7 +219,7 @@ Singleton {
// Update Settings with new array to ensure proper persistence
Settings.data.wallpaper.monitors = newMonitors.slice()
root.wallpaperDirectoryChanged(screenName, directory)
root.wallpaperDirectoryChanged(screenName, Settings.preprocessPath(directory))
}
// -------------------------------------------------------------------
@@ -274,7 +275,7 @@ Singleton {
found = true
return {
"name": screenName,
"directory": monitor.directory || getMonitorDirectory(screenName),
"directory": Settings.preprocessPath(monitor.directory) || getMonitorDirectory(screenName),
"wallpaper": path
}
}
+29
View File
@@ -0,0 +1,29 @@
#version 450
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
layout(binding = 1) uniform sampler2D source;
layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
vec4 targetColor;
float colorizeMode; // 0.0 = dock mode (grayscale), 1.0 = tray mode (intensity)
} ubuf;
void main() {
vec4 tex = texture(source, qt_TexCoord0);
float intensity;
if (ubuf.colorizeMode < 0.5) {
// Dock mode: Convert to grayscale using proper luminance weights
intensity = dot(tex.rgb, vec3(0.299, 0.587, 0.114));
} else {
// Tray mode: Use the maximum RGB channel value as intensity
intensity = max(max(tex.r, tex.g), tex.b);
// Normalize intensity to make all icons more uniform
intensity = smoothstep(0.1, 0.9, intensity);
}
fragColor = vec4(ubuf.targetColor.rgb * intensity, tex.a) * ubuf.qt_Opacity;
}
Binary file not shown.