From a2443c6f89ea283807b1d93c909c3d26671ae8aa Mon Sep 17 00:00:00 2001 From: Thibault Martin Date: Fri, 27 Feb 2026 15:44:32 +0100 Subject: [PATCH 01/20] Show workspace applications on hover --- Assets/Translations/en.json | 2 + Assets/settings-widgets-default.json | 1 + Modules/Bar/Widgets/Workspace.qml | 57 +++++++++++++++---- .../Bar/WidgetSettings/WorkspaceSettings.qml | 13 +++++ Services/UI/BarWidgetRegistry.qml | 1 + 5 files changed, 63 insertions(+), 11 deletions(-) diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index 7f0d77071..887682ed3 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -310,6 +310,8 @@ "reverse-scrolling-label": "Reverse scrolling", "show-applications-description": "Display application icons inside each workspace.", "show-applications-label": "Show applications", + "show-applications-hover-description": "Display application icons inside each workspace when the workspace is hovered.", + "show-applications-hover-label": "Show applications when hovered", "show-badge-description": "Show the workspace number badge in grouped mode.", "show-badge-label": "Show workspace badge", "show-labels-only-when-occupied-description": "Only show workspace labels when they contain windows.", diff --git a/Assets/settings-widgets-default.json b/Assets/settings-widgets-default.json index 61a7239e6..d810117ff 100644 --- a/Assets/settings-widgets-default.json +++ b/Assets/settings-widgets-default.json @@ -215,6 +215,7 @@ "hideUnoccupied": false, "characterCount": 2, "showApplications": false, + "showApplicationsHover": false, "showLabelsOnlyWhenOccupied": true, "colorizeIcons": false, "unfocusedIconsOpacity": 1, diff --git a/Modules/Bar/Widgets/Workspace.qml b/Modules/Bar/Widgets/Workspace.qml index 68d27434a..0d1375087 100644 --- a/Modules/Bar/Widgets/Workspace.qml +++ b/Modules/Bar/Widgets/Workspace.qml @@ -69,6 +69,7 @@ Item { // Grouped mode (show applications) settings readonly property bool showApplications: (widgetSettings.showApplications !== undefined) ? widgetSettings.showApplications : widgetMetadata.showApplications + readonly property bool showApplicationsHover: (widgetSettings.showApplicationsHover !== undefined) ? widgetSettings.showApplicationsHover : widgetMetadata.showApplicationsHover readonly property bool showLabelsOnlyWhenOccupied: (widgetSettings.showLabelsOnlyWhenOccupied !== undefined) ? widgetSettings.showLabelsOnlyWhenOccupied : widgetMetadata.showLabelsOnlyWhenOccupied readonly property bool colorizeIcons: (widgetSettings.colorizeIcons !== undefined) ? widgetSettings.colorizeIcons : widgetMetadata.colorizeIcons readonly property real unfocusedIconsOpacity: (widgetSettings.unfocusedIconsOpacity !== undefined) ? widgetSettings.unfocusedIconsOpacity : widgetMetadata.unfocusedIconsOpacity @@ -128,8 +129,33 @@ Item { signal workspaceChanged(int workspaceId, color accentColor) - implicitWidth: showApplications ? (isVertical ? groupedGrid.implicitWidth : Math.round(groupedGrid.implicitWidth + horizontalPadding * hasLabel)) : (isVertical ? barHeight : computeWidth()) - implicitHeight: showApplications ? (isVertical ? Math.round(groupedGrid.implicitHeight + horizontalPadding * 0.6 * hasLabel) : barHeight) : (isVertical ? computeHeight() : barHeight) + property bool isHovered: false + + HoverHandler { + id: hoverHandler + onHoveredChanged: { + if(hovered) { + hoverEval.stop(); + isHovered = true; + } else { + hoverEval.restart(); + } + } + } + + Timer { + id: hoverEval + interval: 50 + repeat: false + onTriggered: { + isHovered = hoverHandler.hovered || contextMenu.visible; + } + } + + readonly property bool appVisible: showApplications && (!showApplicationsHover || root.isHovered) + + implicitWidth: appVisible ? (isVertical ? groupedGrid.implicitWidth : Math.round(groupedGrid.implicitWidth + horizontalPadding * hasLabel)) : (isVertical ? barHeight : computeWidth()) + implicitHeight: appVisible ? (isVertical ? Math.round(groupedGrid.implicitHeight + horizontalPadding * 0.6 * hasLabel) : barHeight) : (isVertical ? computeHeight() : barHeight) function getWorkspaceWidth(ws, activeOverride) { const d = Math.round(capsuleHeight * root.baseDimensionRatio); @@ -258,7 +284,7 @@ Item { onScreenChanged: Qt.callLater(refreshWorkspaces) onScreenNameChanged: Qt.callLater(refreshWorkspaces) onHideUnoccupiedChanged: Qt.callLater(refreshWorkspaces) - onShowApplicationsChanged: Qt.callLater(refreshWorkspaces) + onAppVisibleChanged: Qt.callLater(refreshWorkspaces) Connections { target: CompositorService @@ -266,13 +292,13 @@ Item { refreshWorkspaces(); } function onWindowListChanged() { - if (showApplications || showLabelsOnlyWhenOccupied) { + if (appVisible || showLabelsOnlyWhenOccupied) { root.windowRevision++; refreshWorkspaces(); } } function onActiveWindowChanged() { - if (showApplications) { + if (appVisible) { root.windowRevision++; refreshWorkspaces(); } @@ -410,6 +436,15 @@ Item { NPopupContextMenu { id: contextMenu + onVisibleChanged: { + if (visible) { + hoverEval.stop(); + root.isHovered = true; + } else { + hoverEval.restart(); + } + } + model: { var items = []; if (root.selectedWindowId) { @@ -486,7 +521,7 @@ Item { Rectangle { id: workspaceBackground - visible: !showApplications + visible: !appVisible width: isVertical ? capsuleHeight : parent.width height: isVertical ? parent.height : capsuleHeight radius: Style.radiusM @@ -557,7 +592,7 @@ Item { spacing: spacingBetweenPills x: horizontalPadding y: 0 - visible: !isVertical && !showApplications + visible: !isVertical && !appVisible Repeater { id: workspaceRepeaterHorizontal @@ -592,7 +627,7 @@ Item { spacing: spacingBetweenPills x: 0 y: horizontalPadding - visible: isVertical && !showApplications + visible: isVertical && !appVisible Repeater { id: workspaceRepeaterVertical @@ -622,7 +657,7 @@ Item { } // ======================================== - // Grouped mode (showApplications = true) + // Grouped mode (appVisible = true) // ======================================== Component { id: groupedWorkspaceDelegate @@ -906,7 +941,7 @@ Item { Flow { id: groupedGrid - visible: showApplications + visible: appVisible x: root.isVertical ? Style.pixelAlignCenter(parent.width, width) : Math.round(horizontalPadding * root.hasLabel) y: root.isVertical ? Math.round(horizontalPadding * 0.4 * root.hasLabel) : Style.pixelAlignCenter(parent.height, height) @@ -915,7 +950,7 @@ Item { flow: root.isVertical ? Flow.TopToBottom : Flow.LeftToRight Repeater { - model: showApplications ? localWorkspaces : null + model: appVisible ? localWorkspaces : null delegate: groupedWorkspaceDelegate } } diff --git a/Modules/Panels/Settings/Bar/WidgetSettings/WorkspaceSettings.qml b/Modules/Panels/Settings/Bar/WidgetSettings/WorkspaceSettings.qml index 5a3ac254e..5606df081 100644 --- a/Modules/Panels/Settings/Bar/WidgetSettings/WorkspaceSettings.qml +++ b/Modules/Panels/Settings/Bar/WidgetSettings/WorkspaceSettings.qml @@ -22,6 +22,7 @@ ColumnLayout { // Grouped mode settings property bool valueShowApplications: widgetData.showApplications !== undefined ? widgetData.showApplications : widgetMetadata.showApplications + property bool valueShowApplicationsHover: widgetData.showApplicationsHover !== undefined ? widgetData.showApplicationsHover : widgetMetadata.showApplicationsHover property bool valueShowLabelsOnlyWhenOccupied: widgetData.showLabelsOnlyWhenOccupied !== undefined ? widgetData.showLabelsOnlyWhenOccupied : widgetMetadata.showLabelsOnlyWhenOccupied property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons property real valueUnfocusedIconsOpacity: widgetData.unfocusedIconsOpacity !== undefined ? widgetData.unfocusedIconsOpacity : widgetMetadata.unfocusedIconsOpacity @@ -42,6 +43,7 @@ ColumnLayout { settings.characterCount = valueCharacterCount; settings.followFocusedScreen = valueFollowFocusedScreen; settings.showApplications = valueShowApplications; + settings.showApplicationsHover = valueShowApplicationsHover; settings.showLabelsOnlyWhenOccupied = valueShowLabelsOnlyWhenOccupied; settings.colorizeIcons = valueColorizeIcons; settings.unfocusedIconsOpacity = valueUnfocusedIconsOpacity; @@ -201,6 +203,17 @@ ColumnLayout { } } + NToggle { + label: I18n.tr("bar.workspace.show-applications-hover-label") + description: I18n.tr("bar.workspace.show-applications-hover-description") + checked: valueShowApplicationsHover + onToggled: checked => { + valueShowApplicationsHover = checked; + saveSettings(); + } + visible: valueShowApplications + } + NToggle { label: I18n.tr("bar.workspace.show-badge-label") description: I18n.tr("bar.workspace.show-badge-description") diff --git a/Services/UI/BarWidgetRegistry.qml b/Services/UI/BarWidgetRegistry.qml index 238d5f281..2c0461da0 100644 --- a/Services/UI/BarWidgetRegistry.qml +++ b/Services/UI/BarWidgetRegistry.qml @@ -293,6 +293,7 @@ Singleton { "hideUnoccupied": false, "characterCount": 2, "showApplications": false, + "showApplicationsHover": false, "showLabelsOnlyWhenOccupied": true, "colorizeIcons": false, "unfocusedIconsOpacity": 1.0, From c161f04966e6c336e2d998ae8b09e39d6e29bccb Mon Sep 17 00:00:00 2001 From: Thibault Martin Date: Fri, 27 Feb 2026 16:05:58 +0100 Subject: [PATCH 02/20] Remove unused hovered properties --- Modules/Bar/Widgets/Workspace.qml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Modules/Bar/Widgets/Workspace.qml b/Modules/Bar/Widgets/Workspace.qml index 0d1375087..f267fbfd5 100644 --- a/Modules/Bar/Widgets/Workspace.qml +++ b/Modules/Bar/Widgets/Workspace.qml @@ -107,7 +107,6 @@ Item { } property bool isDestroying: false - property bool hovered: false // Revision counter to force icon re-evaluation property int iconRevision: 0 @@ -133,6 +132,7 @@ Item { HoverHandler { id: hoverHandler + enabled: showApplications && showApplicationsHover onHoveredChanged: { if(hovered) { hoverEval.stop(); @@ -747,8 +747,6 @@ Item { delegate: Item { id: groupedTaskbarItem - property bool itemHovered: false - width: root.iconSize height: root.iconSize @@ -808,11 +806,9 @@ Item { } } onEntered: { - groupedTaskbarItem.itemHovered = true; TooltipService.show(groupedTaskbarItem, modelData.title || modelData.appId || "Unknown app.", BarService.getTooltipDirection(root.screenName)); } onExited: { - groupedTaskbarItem.itemHovered = false; TooltipService.hide(); } } From a9526c3ab0c5cf648d2b4181bb8a5ceff56b0268 Mon Sep 17 00:00:00 2001 From: Thibault Martin Date: Sun, 1 Mar 2026 11:17:39 +0100 Subject: [PATCH 03/20] Add animation between workspace displays --- Modules/Bar/Widgets/Workspace.qml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Modules/Bar/Widgets/Workspace.qml b/Modules/Bar/Widgets/Workspace.qml index f267fbfd5..fae15aa7b 100644 --- a/Modules/Bar/Widgets/Workspace.qml +++ b/Modules/Bar/Widgets/Workspace.qml @@ -593,6 +593,14 @@ Item { x: horizontalPadding y: 0 visible: !isVertical && !appVisible + scale: visible ? 1.0 : 0.8 + Behavior on scale { + NumberAnimation { + duration: Style.animationFast + easing.type: Easing.OutBack + easing.overshoot: 1.2 + } + } Repeater { id: workspaceRepeaterHorizontal @@ -628,6 +636,14 @@ Item { x: 0 y: horizontalPadding visible: isVertical && !appVisible + scale : visible ? 1.0 : 0.8 + Behavior on scale { + NumberAnimation { + duration: Style.animationFast + easing.type: Easing.OutBack + easing.overshoot: 1.2 + } + } Repeater { id: workspaceRepeaterVertical @@ -938,6 +954,14 @@ Item { Flow { id: groupedGrid visible: appVisible + scale: visible ? 1.0 : 0.8 + Behavior on scale { + NumberAnimation { + duration: Style.animationFast + easing.type: Easing.OutBack + easing.overshoot: 1.2 + } + } x: root.isVertical ? Style.pixelAlignCenter(parent.width, width) : Math.round(horizontalPadding * root.hasLabel) y: root.isVertical ? Math.round(horizontalPadding * 0.4 * root.hasLabel) : Style.pixelAlignCenter(parent.height, height) From fd15bcf2dbbf7221db35f7c1e8a1a0d7905cc5b5 Mon Sep 17 00:00:00 2001 From: Thibault Martin Date: Sun, 1 Mar 2026 11:18:03 +0100 Subject: [PATCH 04/20] Add hover feedback on border color --- Modules/Bar/Widgets/Workspace.qml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Modules/Bar/Widgets/Workspace.qml b/Modules/Bar/Widgets/Workspace.qml index fae15aa7b..1903ec4ea 100644 --- a/Modules/Bar/Widgets/Workspace.qml +++ b/Modules/Bar/Widgets/Workspace.qml @@ -706,11 +706,15 @@ Item { } } + HoverHandler { + id: hoverHandler + } + width: Style.toOdd((hasWindows ? groupedIconsFlow.implicitWidth : root.iconSize) + (root.isVertical ? (root.baseItemSize - root.iconSize + Style.marginXS) : Style.marginXL)) height: Style.toOdd((hasWindows ? groupedIconsFlow.implicitHeight : root.iconSize) + (root.isVertical ? Style.marginL : (root.baseItemSize - root.iconSize + Style.marginXS))) color: Style.capsuleColor radius: Style.radiusS - border.color: Settings.data.bar.showOutline ? Style.capsuleBorderColor : Qt.alpha((workspaceModel.isFocused ? Color.mPrimary : Color.mOutline), root.groupedBorderOpacity) + border.color: Settings.data.bar.showOutline ? Style.capsuleBorderColor : Qt.alpha((workspaceModel.isFocused ? Color.mPrimary : (hoverHandler.hovered ? Color.mHover : Color.mOutline)), root.groupedBorderOpacity) border.width: Style.borderS Behavior on width { From f3699e786d112eaffa3aaa8f05d82cbbec0c76c2 Mon Sep 17 00:00:00 2001 From: Thibault Martin Date: Sun, 1 Mar 2026 11:24:17 +0100 Subject: [PATCH 05/20] Add hover feedback on window icons --- Modules/Bar/Widgets/Workspace.qml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Modules/Bar/Widgets/Workspace.qml b/Modules/Bar/Widgets/Workspace.qml index 1903ec4ea..f8f549d55 100644 --- a/Modules/Bar/Widgets/Workspace.qml +++ b/Modules/Bar/Widgets/Workspace.qml @@ -770,11 +770,23 @@ Item { width: root.iconSize height: root.iconSize + HoverHandler { + id: hoverHandler + } + IconImage { id: groupedAppIcon width: parent.width height: parent.height + scale: hoverHandler.hovered ? (root.isVertical ? 1.1 : 1.2) : (root.isVertical ? 0.9 : 1.0) + Behavior on scale { + NumberAnimation { + duration: Style.animationNormal + easing.type: Easing.OutBack + } + } + source: { root.iconRevision; // Force re-evaluation when revision changes return ThemeIcons.iconForAppId(modelData.appId?.toLowerCase()); From 0c503ccea3113de41a7289d8ae663b7dceea8c87 Mon Sep 17 00:00:00 2001 From: Thibault Martin Date: Wed, 11 Mar 2026 09:24:59 +0100 Subject: [PATCH 06/20] Applies Lemmy's review - Renamed handlers - longer timer delay - copy taskbar hover clue - Only refresh when visible --- Modules/Bar/Widgets/Workspace.qml | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/Modules/Bar/Widgets/Workspace.qml b/Modules/Bar/Widgets/Workspace.qml index f8f549d55..69facca93 100644 --- a/Modules/Bar/Widgets/Workspace.qml +++ b/Modules/Bar/Widgets/Workspace.qml @@ -131,7 +131,7 @@ Item { property bool isHovered: false HoverHandler { - id: hoverHandler + id: workspaceHoverHandler enabled: showApplications && showApplicationsHover onHoveredChanged: { if(hovered) { @@ -145,10 +145,10 @@ Item { Timer { id: hoverEval - interval: 50 + interval: 150 repeat: false onTriggered: { - isHovered = hoverHandler.hovered || contextMenu.visible; + isHovered = workspaceHoverHandler.hovered || contextMenu.visible; } } @@ -284,7 +284,11 @@ Item { onScreenChanged: Qt.callLater(refreshWorkspaces) onScreenNameChanged: Qt.callLater(refreshWorkspaces) onHideUnoccupiedChanged: Qt.callLater(refreshWorkspaces) - onAppVisibleChanged: Qt.callLater(refreshWorkspaces) + onAppVisibleChanged: { + if (appVisible) { + Qt.callLater(refreshWorkspaces) + } + } Connections { target: CompositorService @@ -707,14 +711,14 @@ Item { } HoverHandler { - id: hoverHandler + id: groupHoverHandler } width: Style.toOdd((hasWindows ? groupedIconsFlow.implicitWidth : root.iconSize) + (root.isVertical ? (root.baseItemSize - root.iconSize + Style.marginXS) : Style.marginXL)) height: Style.toOdd((hasWindows ? groupedIconsFlow.implicitHeight : root.iconSize) + (root.isVertical ? Style.marginL : (root.baseItemSize - root.iconSize + Style.marginXS))) color: Style.capsuleColor radius: Style.radiusS - border.color: Settings.data.bar.showOutline ? Style.capsuleBorderColor : Qt.alpha((workspaceModel.isFocused ? Color.mPrimary : (hoverHandler.hovered ? Color.mHover : Color.mOutline)), root.groupedBorderOpacity) + border.color: Settings.data.bar.showOutline ? Style.capsuleBorderColor : Qt.alpha((workspaceModel.isFocused ? Color.mPrimary : (groupHoverHandler.hovered ? Color.mHover : Color.mOutline)), root.groupedBorderOpacity) border.width: Style.borderS Behavior on width { @@ -771,7 +775,7 @@ Item { height: root.iconSize HoverHandler { - id: hoverHandler + id: windowHoverHandler } IconImage { @@ -779,13 +783,6 @@ Item { width: parent.width height: parent.height - scale: hoverHandler.hovered ? (root.isVertical ? 1.1 : 1.2) : (root.isVertical ? 0.9 : 1.0) - Behavior on scale { - NumberAnimation { - duration: Style.animationNormal - easing.type: Easing.OutBack - } - } source: { root.iconRevision; // Force re-evaluation when revision changes @@ -798,13 +795,13 @@ Item { Rectangle { id: groupedFocusIndicator - visible: modelData.isFocused + visible: modelData.isFocused || windowHoverHandler.hovered anchors.bottomMargin: -2 anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter width: Style.toOdd(root.iconSize * 0.25) height: 4 - color: Color.mPrimary + color: modelData.isFocused ? Color.mPrimary : Color.mHover radius: Math.min(Style.radiusXXS, width / 2) } From cf4f6b70a5c8e97631865968eb04119f8f8948fd Mon Sep 17 00:00:00 2001 From: pa1va Date: Wed, 11 Mar 2026 12:09:05 -0300 Subject: [PATCH 07/20] fix: prevent TypeError when Bluetooth device name or icon are not strings --- Helpers/BluetoothUtils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Helpers/BluetoothUtils.js b/Helpers/BluetoothUtils.js index e158bfbd5..879b275c7 100644 --- a/Helpers/BluetoothUtils.js +++ b/Helpers/BluetoothUtils.js @@ -85,8 +85,8 @@ var signalIcon = (p) => { // Icon mapping var deviceIcon = (name, icon) => { - var s1 = (name || "").toLowerCase(); - var s2 = (icon || "").toLowerCase(); + var s1 = String(name || "").toLowerCase(); + var s2 = String(icon || "").toLowerCase(); // Prefer icon-based hints for display devices first to avoid "audio" catching TVs var displayHints = ["display", "tv", "monitor", "projector", "screen", "chromecast", "cast"]; From 09dab00f2740196e6b84df903051b63d642854fb Mon Sep 17 00:00:00 2001 From: Lemmy Date: Wed, 11 Mar 2026 20:04:16 -0400 Subject: [PATCH 08/20] chore(i18n): update + autofmt --- Assets/Translations/de.json | 2 ++ Assets/Translations/en.json | 2 +- Assets/Translations/es.json | 2 ++ Assets/Translations/fr.json | 2 ++ Assets/Translations/hu.json | 2 ++ Assets/Translations/it.json | 2 ++ Assets/Translations/ja.json | 2 ++ Assets/Translations/ko-KR.json | 2 ++ Assets/Translations/nl.json | 2 ++ Assets/Translations/nn-NO.json | 37 +++++++++++++++++++++++++++++++ Assets/Translations/pl.json | 2 ++ Assets/Translations/pt.json | 2 ++ Assets/Translations/ru.json | 2 ++ Assets/Translations/sv.json | 2 ++ Assets/Translations/tr.json | 2 ++ Assets/Translations/uk-UA.json | 2 ++ Assets/Translations/zh-CN.json | 2 ++ Assets/Translations/zh-TW.json | 2 ++ Modules/Bar/Widgets/Workspace.qml | 8 +++---- 19 files changed, 74 insertions(+), 5 deletions(-) diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index 71475b772..306cc0de9 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "Die Richtung des Arbeitsflächenwechsels beim Scrollen umkehren.", "reverse-scrolling-label": "Scrollen umkehren", "show-applications-description": "Anwendungssymbole in jeder Arbeitsfläche anzeigen.", + "show-applications-hover-description": "Anwendungssymbole in jedem Arbeitsbereich anzeigen, wenn der Arbeitsbereich überfahren wird.", + "show-applications-hover-label": "Anwendungen beim Hovern anzeigen", "show-applications-label": "Anwendungen anzeigen", "show-badge-description": "Zeige die Arbeitsflächennummer als Abzeichen im gruppierten Modus an.", "show-badge-label": "Arbeitsflächen-Abzeichen anzeigen", diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index 887682ed3..5c83e6d29 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -309,9 +309,9 @@ "reverse-scrolling-description": "Reverse the direction of workspace switching when scrolling.", "reverse-scrolling-label": "Reverse scrolling", "show-applications-description": "Display application icons inside each workspace.", - "show-applications-label": "Show applications", "show-applications-hover-description": "Display application icons inside each workspace when the workspace is hovered.", "show-applications-hover-label": "Show applications when hovered", + "show-applications-label": "Show applications", "show-badge-description": "Show the workspace number badge in grouped mode.", "show-badge-label": "Show workspace badge", "show-labels-only-when-occupied-description": "Only show workspace labels when they contain windows.", diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index ae374c781..770ac5472 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "Invertir la dirección del cambio de espacios de trabajo al desplazarse.", "reverse-scrolling-label": "Desplazamiento inverso", "show-applications-description": "Mostrar los iconos de las aplicaciones dentro de cada espacio de trabajo.", + "show-applications-hover-description": "Mostrar iconos de aplicación dentro de cada espacio de trabajo cuando se pasa el ratón por encima.", + "show-applications-hover-label": "Mostrar aplicaciones al pasar el ratón", "show-applications-label": "Mostrar aplicaciones", "show-badge-description": "Mostrar la insignia del número de espacio de trabajo en modo agrupado.", "show-badge-label": "Mostrar insignia del espacio de trabajo", diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json index cc15f4f27..e9f21c3be 100644 --- a/Assets/Translations/fr.json +++ b/Assets/Translations/fr.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "Inverser la direction du changement d'espace de travail lors du défilement.", "reverse-scrolling-label": "Défilement inversé", "show-applications-description": "Afficher les icônes des applications dans chaque espace de travail.", + "show-applications-hover-description": "Afficher les icônes d'application dans chaque espace de travail lorsque celui-ci est survolé.", + "show-applications-hover-label": "Afficher les applications au survol", "show-applications-label": "Afficher les applications", "show-badge-description": "Afficher le badge du numéro d'espace de travail en mode groupé.", "show-badge-label": "Afficher le badge de l'espace de travail", diff --git a/Assets/Translations/hu.json b/Assets/Translations/hu.json index 8136d287b..d8a363e79 100644 --- a/Assets/Translations/hu.json +++ b/Assets/Translations/hu.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "Görgetéskor fordított irányba váltson a munkaterületek között.", "reverse-scrolling-label": "Görgetés megfordítása", "show-applications-description": "Alkalmazásikonok megjelenítése minden munkaterületen belül.", + "show-applications-hover-description": "Alkalmazásikonok megjelenítése minden munkaterületen belül, amikor a munkaterület fölé viszi az egeret.", + "show-applications-hover-label": "Alkalmazások megjelenítése rámutatáskor", "show-applications-label": "Alkalmazások megjelenítése", "show-badge-description": "Munkaterület számának jelzése csoportosított módban.", "show-badge-label": "Munkafelület jelvény megjelenítése", diff --git a/Assets/Translations/it.json b/Assets/Translations/it.json index fc99560c3..3c06fc326 100644 --- a/Assets/Translations/it.json +++ b/Assets/Translations/it.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "Inverti direzione del cambio workspace quando scorri.", "reverse-scrolling-label": "Inverti scorrimento", "show-applications-description": "Mostra icone applicazioni dentro ogni workspace.", + "show-applications-hover-description": "Mostra le icone delle applicazioni all'interno di ogni spazio di lavoro quando lo spazio di lavoro viene sorvolato.", + "show-applications-hover-label": "Mostra applicazioni al passaggio del mouse", "show-applications-label": "Mostra applicazioni", "show-badge-description": "Mostra badge numero workspace in modalità raggruppata.", "show-badge-label": "Mostra badge workspace", diff --git a/Assets/Translations/ja.json b/Assets/Translations/ja.json index 63bf6758d..ada5e4440 100644 --- a/Assets/Translations/ja.json +++ b/Assets/Translations/ja.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "スクロール時のワークスペース切り替え方向を反転する。", "reverse-scrolling-label": "スクロール方向を反転", "show-applications-description": "各ワークスペース内にアプリアイコンを表示します。", + "show-applications-hover-description": "ワークスペースにカーソルを合わせたときに、各ワークスペース内にアプリケーションアイコンを表示します。", + "show-applications-hover-label": "ホバー時にアプリケーションを表示", "show-applications-label": "アプリアイコンを表示", "show-badge-description": "グループ化モードでワークスペース番号バッジを表示します。", "show-badge-label": "ワークスペースバッジを表示", diff --git a/Assets/Translations/ko-KR.json b/Assets/Translations/ko-KR.json index 7c57dbd75..4db96102b 100644 --- a/Assets/Translations/ko-KR.json +++ b/Assets/Translations/ko-KR.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "스크롤할 때 작업 공간 전환 방향을 반대로 합니다.", "reverse-scrolling-label": "스크롤 반전", "show-applications-description": "각 작업 공간 내부에 애플리케이션 아이콘을 표시합니다.", + "show-applications-hover-description": "작업 공간에 마우스를 올렸을 때 각 작업 공간 내에 애플리케이션 아이콘을 표시합니다.", + "show-applications-hover-label": "마우스 오버 시 애플리케이션 표시", "show-applications-label": "애플리케이션 표시", "show-badge-description": "그룹화 모드에서 작업 공간 번호 배지를 표시합니다.", "show-badge-label": "작업 공간 배지 표시", diff --git a/Assets/Translations/nl.json b/Assets/Translations/nl.json index a4d41d6cf..6e18d183d 100644 --- a/Assets/Translations/nl.json +++ b/Assets/Translations/nl.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "Keer de richting van het wisselen van werkruimtes om bij het scrollen.", "reverse-scrolling-label": "Omgekeerd scrollen", "show-applications-description": "Toon applicatiepictogrammen in elke werkruimte.", + "show-applications-hover-description": "Toon applicatiepictogrammen in elke werkruimte wanneer de werkruimte wordt aangewezen.", + "show-applications-hover-label": "Toon applicaties bij hoveren", "show-applications-label": "Toon applicaties", "show-badge-description": "Toon de werkomgevingnummerbadge in gegroepeerde modus.", "show-badge-label": "Werkruimtebadge weergeven", diff --git a/Assets/Translations/nn-NO.json b/Assets/Translations/nn-NO.json index 84f9fe1e9..f5fb1a46f 100644 --- a/Assets/Translations/nn-NO.json +++ b/Assets/Translations/nn-NO.json @@ -8,6 +8,7 @@ "disable-dnd": "Slå av Ikkje forstyrr", "disable-wifi": "Slå av Wi-Fi", "disconnect-vpn": "Kopla frå {name}", + "dock-settings": "Festepunktinstillingar", "enable-bluetooth": "Slå på Bluetooth", "enable-dnd": "Slå på Ikkje forstyrr", "enable-wifi": "Slå på Wi-Fi", @@ -40,6 +41,7 @@ "audio-visualizer": { "color-name-description": "Vel farge for visualiseraren.", "color-name-label": "Fyll farge", + "height-description": "Eigendefinert komponentbreidd", "hide-when-idle-description": "Når dette er på, gøymer visualiseraren seg med mindre noko aktivt spelar.", "hide-when-idle-label": "Gøym når ingenting spelar av", "width-description": "Eigendefinert komponentbreidd." @@ -144,11 +146,13 @@ "text-stream-description": "Strøymde linjer frå kommandoen viser seg som tekst på knappen.", "text-stream-label": "Strøym", "wheel-description": "Kommando som køyrer når ein brukar rullehjulet.
Bruk $delta for rullehjulsdeltaen i kommandoen.", + "wheel-down": "Rull nedetter", "wheel-down-description": "Kommando som køyrer når ein rullar ned på rullehjulet.", "wheel-down-label": "Hjul ned-kommando", "wheel-label": "Rullehjul", "wheel-mode-separate-description": "Slår på åtskilde kommandoar for når ein rullar opp eller ned.", "wheel-mode-separate-label": "Skilde hjulekommandoar", + "wheel-up": "Rull oppetter", "wheel-up-description": "Kommando som køyrer når ein rullar opp på rullehjulet.", "wheel-up-label": "Hjul opp-kommando", "wheel-update-text": "Oppdater vist tekst på rulling" @@ -209,6 +213,8 @@ "system-monitor": { "compact-mode-description": "Viser statistikk som småe stolpediagram heller enn tekst. Stoggar oppsettet frå å skifta.", "compact-mode-label": "Tettmodus", + "cpu-cores-description": "Syn prosessorkjernebruk åtskilde.", + "cpu-cores-label": "Prosessorkjerner", "cpu-frequency-description": "Vis prosessorklokkefrekvens no i GHz", "cpu-frequency-label": "Vis prosessorfrekvens", "cpu-temperature-description": "Viser temperaturmålingar frå prosessoren om mogeleg.", @@ -288,6 +294,8 @@ "focused-color-label": "Fokusert arbeidsområde-farge", "follow-focused-screen-description": "Viser arbeidsrom frå den aktive skjermen, heller enn skjermen der panelet finn seg.", "follow-focused-screen-label": "Fylg aktiv skjerm", + "font-weight-description": "Fastset synleg tyngd for tekst innan arbeidsrom.", + "font-weight-label": "Skrifttyngd", "grouped-border-opacity-description": "Fastset kor ugjennomsynlege grensene på arbeidsromrammene er.", "grouped-border-opacity-label": "Ugjennomsynlege grenser", "hide-unoccupied-description": "Viser ikkje arbeidsrom utan vindaugo.", @@ -311,6 +319,7 @@ } }, "battery": { + "all-batteries": "Alle batteria (i sum)", "battery-health": "Batterihelse", "battery-level": "Batterinivå", "capacity-level": "Kapasitet: {level}", @@ -367,13 +376,16 @@ }, "common": { "actions": "Handlingar", + "active": "Aktiv", "add": "Legg til", "appearance": "Utsjånad", "apply": "Bruk", + "auto-connect": "Kopla til automatisk", "automation": "Automatisering", "available": "Tilgjengelege", "back": "Attende", "battery": "Batteri", + "behavior": "Åtferd", "bluetooth": "Bluetooth", "brightness": "Ljosstyrke", "browse": "Blad", @@ -396,6 +408,7 @@ "contributors": "Medverkarar", "copied-to-clipboard": "Kopiert til utklippstavla", "countdown": "Nedteljing", + "customize": "Måta til", "date": "Dato", "default": "Standard", "delete": "Slett", @@ -406,6 +419,7 @@ "disconnected": "Kopla frå", "disconnecting": "Koplar frå...", "display-mode": "Visingsmodus", + "documentation": "Dokumentasjon", "download": "Last ned", "duration": "Varing", "dysfunctional": "I uorden", @@ -417,6 +431,11 @@ "execute": "Utfør", "faithful": "Tru", "focus": "Fokus", + "font-weight-bold": "Feit", + "font-weight-light": "Tynn", + "font-weight-medium": "Mellomstor", + "font-weight-regular": "Vanleg", + "font-weight-semibold": "Halvfeit", "frequency": "Frekvens", "gateway": "Port", "general": "Generell", @@ -462,6 +481,7 @@ "panels": "Panel", "password": "Passord", "pause": "Pause", + "performance": "Yting", "pin": "Fest", "play": "Spel", "polling": "Spørjing", @@ -483,6 +503,8 @@ "scanning": "Leitar...", "screen-corners": "Skjermhyrne", "search": "Søk", + "second": "{count} sekund", + "second-plural": "{count} sekund", "secondary": "Sekundær", "security": "Trygging", "select": "Vel", @@ -512,6 +534,7 @@ "unpin": "Fest av", "update": "Oppdater", "upload": "Lasta opp", + "userspace-reboot": "Start brukarromet å nyo", "version": "Versjon", "vibrant": "Livleg", "visualizer": "Visualiserar", @@ -692,16 +715,20 @@ "about": { "become-supporter": "Vert med og støtt", "changelog": "Sjå endringar", + "changelog-on-startup": "Syn endringshistorikk etter oppdatering", + "changelog-on-startup-desc": "Syn endringshistorikken automatisk når Noctalia er oppdatert", "contributors-description": "Takk og ære til den {count} framifrå medverkaren vår!", "contributors-description-plural": "Takk og ære til alle dei {count} framifrå medverkarane våre!", "copy-info": "Kopier info", "debug-disabled": "Feilsøking av", "debug-enabled": "Feilsøking på", "info-copied": "Info kopiert til utklippstavla", + "noctalia-available": "Tilgjengeleg:", "noctalia-desc": "Eit lettfram og minimalistisk skrivebordsskal skapa med omhug for Wayland, bygt med Quickshell.", "noctalia-git-commit": "Git commit:", "noctalia-installed-version": "Installert versjon:", "noctalia-latest-version": "Nyaste versjon:", + "noctalia-qs-version": "Noctalia QS versjon:", "noctalia-title": "Noctaliaskal", "privacy-policy": "Personvernfråsegn", "support": "Støtt oss", @@ -709,6 +736,7 @@ "supporters-desc": "Ein stor takk til alle framifrå støttarar!", "supporters-desc-plural": "Ein stor takk til alle {count} framifrå støttarar!", "supporters-loading": "Lastar inn støttarar...", + "system-board": "Brett:", "system-cpu": "Prosessor:", "system-disk": "Disk:", "system-gpu": "Skjermkort:", @@ -765,6 +793,9 @@ "visualizer-type-description": "Vel visualiseringstypen når ein spelar av media.", "visualizer-type-label": "Visualiseringstype", "volumes-desc": "Endrar kontrollane for ljodstyrke og ljodnivå", + "volumes-feedback-sound-file-description": "Bane til ljoden som spelar av når du endrar ljodstyrke.", + "volumes-feedback-sound-file-label": "Ljodstyrkeendring ljodfil", + "volumes-feedback-sound-file-select-title": "Vel ljodfila som spelar av med ljodstyrkeendring", "volumes-input-volume-description": "Mikrofon inn-nivå", "volumes-mute-input-description": "Demp standard ljodinneining (mikrofon).", "volumes-mute-input-label": "Demp ljodinndata", @@ -790,12 +821,18 @@ "appearance-capsule-color-label": "Ilåtsfarge", "appearance-capsule-opacity-description": "Set kor ugjennomsynlege bakgrunnen er for miniprogram når ilåtet er på skjermen.", "appearance-capsule-opacity-label": "Ugjennomsynleg ilåt", + "appearance-content-padding-description": "Måta til utfyllinga mellom panelrender og miniprogram.", + "appearance-content-padding-label": "Innhaldsutfylling", "appearance-density-description": "Fastset utfylling på lina for å gjera henne tett eller romsleg.", "appearance-density-label": "Tettleik på oppgåvelina", "appearance-desc": "Måtar til kor oppgåvelina ser ut og kvar ho er.", "appearance-display-mode-description": "Vel når baren er synleg.", + "appearance-enable-exclusion-zone-inset-description": "Minska ekskluderingsona med 1 fysisk piksel slik at vindaugo som er kant-i-kant bløder saman.", + "appearance-enable-exclusion-zone-inset-label": "Innrykt ekskluderingssone", "appearance-floating-description": "Viser oppgåvelina som flytande 'pille'.", "appearance-floating-label": "Flytande oppgåvelina", + "appearance-font-scale-description": "Måta til skala for skriftstorleik for skrift på panelen.", + "appearance-font-scale-label": "Skriftskala", "appearance-frame-radius": "Innradius", "appearance-frame-settings-description": "Endrar rammetjukn og innradius på hyrnet", "appearance-frame-settings-label": "Innstillingar for ramma", diff --git a/Assets/Translations/pl.json b/Assets/Translations/pl.json index 3f10b9cc7..eb667ed46 100644 --- a/Assets/Translations/pl.json +++ b/Assets/Translations/pl.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "Odwróć kierunek przełączania obszarów roboczych podczas przewijania.", "reverse-scrolling-label": "Odwróć przewijanie", "show-applications-description": "Wyświetl ikony aplikacji wewnątrz każdego obszaru roboczego.", + "show-applications-hover-description": "Wyświetl ikony aplikacji w każdym obszarze roboczym po najechaniu na obszar roboczy.", + "show-applications-hover-label": "Pokaż aplikacje po najechaniu kursorem", "show-applications-label": "Pokaż aplikacje", "show-badge-description": "Pokaż plakietkę z numerem obszaru roboczego w trybie grupowym.", "show-badge-label": "Pokaż odznakę obszaru roboczego", diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index 56b97347a..8fcbcf0ea 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "Inverter a direção da troca de áreas de trabalho ao rolar.", "reverse-scrolling-label": "Rolagem invertida", "show-applications-description": "Exibir ícones de aplicativos dentro de cada espaço de trabalho.", + "show-applications-hover-description": "Exibir ícones de aplicativos dentro de cada área de trabalho quando a área de trabalho é sobreposta.", + "show-applications-hover-label": "Mostrar aplicativos ao passar o mouse", "show-applications-label": "Mostrar aplicativos", "show-badge-description": "Mostrar o selo do número da área de trabalho no modo agrupado.", "show-badge-label": "Mostrar selo da área de trabalho", diff --git a/Assets/Translations/ru.json b/Assets/Translations/ru.json index 96b9dcdf8..b35e6665b 100644 --- a/Assets/Translations/ru.json +++ b/Assets/Translations/ru.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "Изменить направление переключения рабочих пространств при прокрутке.", "reverse-scrolling-label": "Обратная прокрутка", "show-applications-description": "Отображать значки приложений внутри каждого рабочего пространства.", + "show-applications-hover-description": "Отображать значки приложений внутри каждого рабочего пространства при наведении на него.", + "show-applications-hover-label": "Показывать приложения при наведении", "show-applications-label": "Показать приложения", "show-badge-description": "Показывать значок номера рабочего пространства в сгруппированном режиме.", "show-badge-label": "Показывать значок рабочего стола", diff --git a/Assets/Translations/sv.json b/Assets/Translations/sv.json index 15481362b..8a0c38696 100644 --- a/Assets/Translations/sv.json +++ b/Assets/Translations/sv.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "Vänd riktningen för arbetsyteväxling vid rullning.", "reverse-scrolling-label": "Omvänd rullning", "show-applications-description": "Visa applikationsikoner i varje arbetsyta.", + "show-applications-hover-description": "Visa programikoner i varje arbetsyta när arbetsytan hovras över.", + "show-applications-hover-label": "Visa applikationer vid hovring", "show-applications-label": "Visa applikationer", "show-badge-description": "Visa arbetsytans nummerskylt i grupperat läge.", "show-badge-label": "Visa arbetsytans skylt", diff --git a/Assets/Translations/tr.json b/Assets/Translations/tr.json index 9f15abad2..a98414138 100644 --- a/Assets/Translations/tr.json +++ b/Assets/Translations/tr.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "Kaydırırken çalışma alanı geçiş yönünü tersine çevir.", "reverse-scrolling-label": "Ters kaydırma", "show-applications-description": "Her çalışma alanının içinde uygulama simgelerini görüntüle.", + "show-applications-hover-description": "Çalışma alanının üzerine gelindiğinde, her çalışma alanının içinde uygulama simgelerini görüntüle.", + "show-applications-hover-label": "Üzerine gelindiğinde uygulamaları göster", "show-applications-label": "Uygulamaları göster", "show-badge-description": "Gruplandırılmış modda çalışma alanı numarası işaretini göster.", "show-badge-label": "Çalışma alanı rozetini göster", diff --git a/Assets/Translations/uk-UA.json b/Assets/Translations/uk-UA.json index 1adb21bb7..a63d1c8e6 100644 --- a/Assets/Translations/uk-UA.json +++ b/Assets/Translations/uk-UA.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "Змінити напрямок перемикання робочих просторів під час прокручування.", "reverse-scrolling-label": "Зворотне прокручування", "show-applications-description": "Відображати значки програм у кожному робочому просторі.", + "show-applications-hover-description": "Відображати піктограми програм всередині кожного робочого простору при наведенні на нього.", + "show-applications-hover-label": "Показувати програми при наведенні", "show-applications-label": "Показати застосунки", "show-badge-description": "Показувати значок номера робочого столу в згрупованому режимі.", "show-badge-label": "Показати значок робочого столу", diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json index 9e181b10c..a401eccc9 100644 --- a/Assets/Translations/zh-CN.json +++ b/Assets/Translations/zh-CN.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "滚动时反转工作区切换方向。", "reverse-scrolling-label": "反转滚动", "show-applications-description": "在每个工作区内显示应用程序图标。", + "show-applications-hover-description": "当鼠标悬停在工作区上时,在每个工作区内显示应用程序图标。", + "show-applications-hover-label": "鼠标悬停时显示应用程序", "show-applications-label": "显示应用程序", "show-badge-description": "在分组模式下显示工作区编号徽章。", "show-badge-label": "显示工作区徽章", diff --git a/Assets/Translations/zh-TW.json b/Assets/Translations/zh-TW.json index f948273a5..23fe5d4b2 100644 --- a/Assets/Translations/zh-TW.json +++ b/Assets/Translations/zh-TW.json @@ -309,6 +309,8 @@ "reverse-scrolling-description": "捲動時反轉工作區切換方向。", "reverse-scrolling-label": "反轉捲動", "show-applications-description": "顯示各個工作區的程式圖示", + "show-applications-hover-description": "當滑鼠懸停在工作區上時,在每個工作區內顯示應用程式圖示。", + "show-applications-hover-label": "滑鼠懸停時顯示應用程式", "show-applications-label": "顯示應用程式", "show-badge-description": "在群組模式下顯示工作區編號徽章。", "show-badge-label": "顯示工作區標記", diff --git a/Modules/Bar/Widgets/Workspace.qml b/Modules/Bar/Widgets/Workspace.qml index 69facca93..2afb1ddb9 100644 --- a/Modules/Bar/Widgets/Workspace.qml +++ b/Modules/Bar/Widgets/Workspace.qml @@ -134,7 +134,7 @@ Item { id: workspaceHoverHandler enabled: showApplications && showApplicationsHover onHoveredChanged: { - if(hovered) { + if (hovered) { hoverEval.stop(); isHovered = true; } else { @@ -154,7 +154,7 @@ Item { readonly property bool appVisible: showApplications && (!showApplicationsHover || root.isHovered) - implicitWidth: appVisible ? (isVertical ? groupedGrid.implicitWidth : Math.round(groupedGrid.implicitWidth + horizontalPadding * hasLabel)) : (isVertical ? barHeight : computeWidth()) + implicitWidth: appVisible ? (isVertical ? groupedGrid.implicitWidth : Math.round(groupedGrid.implicitWidth + horizontalPadding * hasLabel)) : (isVertical ? barHeight : computeWidth()) implicitHeight: appVisible ? (isVertical ? Math.round(groupedGrid.implicitHeight + horizontalPadding * 0.6 * hasLabel) : barHeight) : (isVertical ? computeHeight() : barHeight) function getWorkspaceWidth(ws, activeOverride) { @@ -286,7 +286,7 @@ Item { onHideUnoccupiedChanged: Qt.callLater(refreshWorkspaces) onAppVisibleChanged: { if (appVisible) { - Qt.callLater(refreshWorkspaces) + Qt.callLater(refreshWorkspaces); } } @@ -640,7 +640,7 @@ Item { x: 0 y: horizontalPadding visible: isVertical && !appVisible - scale : visible ? 1.0 : 0.8 + scale: visible ? 1.0 : 0.8 Behavior on scale { NumberAnimation { duration: Style.animationFast From 84229bc7445a2a353023c678b4168ea3fe3a0b71 Mon Sep 17 00:00:00 2001 From: Lemmy Date: Wed, 11 Mar 2026 20:14:47 -0400 Subject: [PATCH 09/20] chore(i18n/lockscreen): relocate the language to dateformat map for easier maintenance --- Commons/I18n.qml | 27 +++++++++++++++++++++++++ Modules/LockScreen/LockScreenHeader.qml | 19 +---------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/Commons/I18n.qml b/Commons/I18n.qml index 7cd839350..5cb9335f8 100644 --- a/Commons/I18n.qml +++ b/Commons/I18n.qml @@ -187,6 +187,33 @@ Singleton { }; } + // Default date format per language (used by lock screen, etc.) + readonly property var dateFormats: ({ + "de": "dddd, d. MMMM", + "en": "dddd, MMMM d", + "es": "dddd, d 'de' MMMM", + "fr": "dddd d MMMM", + "hu": "dddd, MMMM d.", + "it": "dddd d MMMM", + "ja": "yyyy年M月d日 dddd", + "ko": "yyyy년 M월 d일 dddd", + "ku": "dddd, dê MMMM", + "nl": "dddd d MMMM", + "nn": "dddd d. MMMM", + "pl": "dddd, d MMMM", + "pt": "dddd, d 'de' MMMM", + "ru": "dddd, d MMMM", + "sv": "dddd d MMMM", + "tr": "dddd, d MMMM", + "uk": "dddd, d MMMM", + "zh": "yyyy年M月d日 dddd" + }) + + function dateFormat() { + var lang = langCode.split("-")[0]; + return dateFormats[lang] || "dddd, d MMMM"; + } + // ------------------------------------------- function setLanguage(newLangCode, fullLocale) { if (typeof fullLocale === "undefined") { diff --git a/Modules/LockScreen/LockScreenHeader.qml b/Modules/LockScreen/LockScreenHeader.qml index d75b37c6c..cc2e71a45 100644 --- a/Modules/LockScreen/LockScreenHeader.qml +++ b/Modules/LockScreen/LockScreenHeader.qml @@ -118,24 +118,7 @@ Rectangle { // Date below NText { text: { - var lang = I18n.locale.name.split("_")[0]; - var formats = { - "de": "dddd, d. MMMM", - "en": "dddd, MMMM d", - "es": "dddd, d 'de' MMMM", - "fr": "dddd d MMMM", - "hu": "dddd, MMMM d.", - "it": "dddd d MMMM", - "ja": "yyyy年M月d日 dddd", - "ko": "yyyy년 M월 d일 dddd", - "ku": "dddd, dê MMMM", - "nl": "dddd d MMMM", - "nn": "dddd d. MMMM", - "pt": "dddd, d 'de' MMMM", - "sv": "dddd d MMMM", - "zh": "yyyy年M月d日 dddd" - }; - var dateString = I18n.locale.toString(root.currentDate, formats[lang] || "dddd, d MMMM"); + var dateString = I18n.locale.toString(root.currentDate, I18n.dateFormat()); return dateString.charAt(0).toUpperCase() + dateString.slice(1); } pointSize: Style.fontSizeXL From 039be7d851baff99fbeb5d1512e5bc3133ebda81 Mon Sep 17 00:00:00 2001 From: Lemmy Date: Wed, 11 Mar 2026 20:25:17 -0400 Subject: [PATCH 10/20] fix(workspace): more defer Workspace compositor signal handlers with Qt.callLater to avoid SIGSEGV --- Modules/Bar/Widgets/Workspace.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/Bar/Widgets/Workspace.qml b/Modules/Bar/Widgets/Workspace.qml index 2afb1ddb9..7a5c3ef74 100644 --- a/Modules/Bar/Widgets/Workspace.qml +++ b/Modules/Bar/Widgets/Workspace.qml @@ -293,18 +293,18 @@ Item { Connections { target: CompositorService function onWorkspacesChanged() { - refreshWorkspaces(); + Qt.callLater(refreshWorkspaces); } function onWindowListChanged() { if (appVisible || showLabelsOnlyWhenOccupied) { root.windowRevision++; - refreshWorkspaces(); + Qt.callLater(refreshWorkspaces); } } function onActiveWindowChanged() { if (appVisible) { root.windowRevision++; - refreshWorkspaces(); + Qt.callLater(refreshWorkspaces); } } } From 49db78a22bcefd117c0278dd7736418e59f28430 Mon Sep 17 00:00:00 2001 From: Lemmy Date: Wed, 11 Mar 2026 21:31:43 -0400 Subject: [PATCH 11/20] feat(settings): unified the settings search in a new singleton --- .../Launcher/Providers/SettingsProvider.qml | 35 ++-- Modules/Panels/Settings/SettingsContent.qml | 163 +----------------- Services/UI/SettingsSearchService.qml | 158 +++++++++++++++++ 3 files changed, 172 insertions(+), 184 deletions(-) create mode 100644 Services/UI/SettingsSearchService.qml diff --git a/Modules/Panels/Launcher/Providers/SettingsProvider.qml b/Modules/Panels/Launcher/Providers/SettingsProvider.qml index 6ebea61b8..8993d2a30 100644 --- a/Modules/Panels/Launcher/Providers/SettingsProvider.qml +++ b/Modules/Panels/Launcher/Providers/SettingsProvider.qml @@ -1,6 +1,4 @@ import QtQuick -import Quickshell -import Quickshell.Io import qs.Commons import qs.Services.UI @@ -14,23 +12,6 @@ Item { property string supportedLayouts: "list" property string iconMode: Settings.data.appLauncher.iconMode - property var searchIndex: [] - - FileView { - id: searchIndexFile - path: Quickshell.shellDir + "/Assets/settings-search-index.json" - watchChanges: false - printErrors: false - - onLoaded: { - try { - root.searchIndex = JSON.parse(text()); - } catch (e) { - root.searchIndex = []; - } - } - } - function init() { Logger.d("SettingsProvider", "Initialized"); } @@ -57,7 +38,7 @@ Item { } function getResults(query) { - if (!query || searchIndex.length === 0) + if (!query || SettingsSearchService.searchIndex.length === 0) return []; var trimmed = query.trim(); @@ -78,10 +59,12 @@ Item { return []; } - // Build searchable items with resolved translations + // Build searchable items with resolved translations, filtering out invisible entries let items = []; - for (let j = 0; j < searchIndex.length; j++) { - const entry = searchIndex[j]; + for (let j = 0; j < SettingsSearchService.searchIndex.length; j++) { + const entry = SettingsSearchService.searchIndex[j]; + if (!SettingsSearchService.isEntryVisible(entry)) + continue; items.push({ "labelKey": entry.labelKey, "descriptionKey": entry.descriptionKey, @@ -133,8 +116,10 @@ Item { function getAllSettings() { var launcherItems = []; - for (var j = 0; j < searchIndex.length; j++) { - var entry = searchIndex[j]; + for (var j = 0; j < SettingsSearchService.searchIndex.length; j++) { + var entry = SettingsSearchService.searchIndex[j]; + if (!SettingsSearchService.isEntryVisible(entry)) + continue; var label = I18n.tr(entry.labelKey); var tabName = I18n.tr(entry.tabLabel); var subTabName = entry.subTabLabel ? I18n.tr(entry.subTabLabel) : ""; diff --git a/Modules/Panels/Settings/SettingsContent.qml b/Modules/Panels/Settings/SettingsContent.qml index d4c6cf1cd..6b4087bab 100644 --- a/Modules/Panels/Settings/SettingsContent.qml +++ b/Modules/Panels/Settings/SettingsContent.qml @@ -2,7 +2,6 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import Quickshell -import Quickshell.Io import qs.Commons import qs.Modules.Panels.Settings.Tabs import qs.Modules.Panels.Settings.Tabs.About @@ -53,7 +52,6 @@ Item { // Search state property string searchText: "" - property var searchIndex: [] property var searchResults: [] property int searchSelectedIndex: 0 property string highlightLabelKey: "" @@ -76,159 +74,6 @@ Item { // Signal when close button is clicked signal closeRequested - // Load search index - FileView { - id: searchIndexFile - path: Quickshell.shellDir + "/Assets/settings-search-index.json" - watchChanges: false - printErrors: false - - onLoaded: { - try { - root.searchIndex = JSON.parse(text()); - } catch (e) { - root.searchIndex = []; - } - } - } - - // Visibility condition evaluation for search filtering. - // Resolves a dotted property path on a known root object. - function _resolveValue(path) { - const roots = { - "CompositorService": CompositorService, - "Settings": Settings, - "Quickshell": Quickshell, - "IdleService": IdleService, - "SystemStatService": SystemStatService, - "SoundService": SoundService - }; - - const parts = path.split("."); - const rootObj = roots[parts[0]]; - if (rootObj === undefined) - return undefined; - - let obj = rootObj; - for (let i = 1; i < parts.length; i++) { - if (obj === undefined || obj === null) - return undefined; - // Strip optional chaining marker (e.g. "sounds?" -> "sounds") - let key = parts[i]; - if (key.endsWith("?")) - key = key.slice(0, -1); - obj = obj[key]; - } - return obj; - } - - // Split an expression on top-level && (respecting parentheses). - function _splitAnd(expr) { - const parts = []; - let depth = 0; - let current = ""; - for (let i = 0; i < expr.length; i++) { - const ch = expr[i]; - if (ch === "(") - depth++; - else if (ch === ")") - depth--; - else if (depth === 0 && ch === "&" && i + 1 < expr.length && expr[i + 1] === "&") { - parts.push(current); - current = ""; - i++; // skip second & - continue; - } - current += ch; - } - parts.push(current); - return parts; - } - - // Evaluate a single visibility condition expression. - // Returns true if the condition is met (item should be visible). - // Falls back to true for unrecognized expressions. - function _evalCondition(expr) { - expr = expr.trim(); - - // Strip outer parentheses - if (expr.startsWith("(") && expr.endsWith(")")) { - let depth = 0; - let allWrapped = true; - for (let i = 0; i < expr.length - 1; i++) { - if (expr[i] === "(") - depth++; - else if (expr[i] === ")") - depth--; - if (depth === 0) { - allWrapped = false; - break; - } - } - if (allWrapped) - return _evalCondition(expr.slice(1, -1)); - } - - // AND: all parts must be true - if (expr.includes("&&")) { - const parts = _splitAnd(expr); - if (parts.length > 1) { - for (let i = 0; i < parts.length; i++) { - if (!_evalCondition(parts[i])) - return false; - } - return true; - } - } - - // Negation - if (expr.startsWith("!")) - return !_evalCondition(expr.slice(1).trim()); - - // Literal false - if (expr === "false") - return false; - - // Strip nullish coalescing fallback (e.g. "expr ?? false") - const nullishMatch = expr.match(/^(.+?)\s*\?\?\s*(?:false|true)\s*$/); - if (nullishMatch) - return _evalCondition(nullishMatch[1]); - - // === comparison - let m = expr.match(/^(.+?)\s*===\s*"([^"]*)"\s*$/); - if (m) - return _resolveValue(m[1].trim()) === m[2]; - - // !== comparison - m = expr.match(/^(.+?)\s*!==\s*"([^"]*)"\s*$/); - if (m) - return _resolveValue(m[1].trim()) !== m[2]; - - // > comparison - m = expr.match(/^(.+?)\s*>\s*(\d+)\s*$/); - if (m) - return _resolveValue(m[1].trim()) > parseInt(m[2]); - - // Simple property path — resolve and return truthiness - const val = _resolveValue(expr); - if (val !== undefined) - return !!val; - - // Unrecognized expression — assume visible - return true; - } - - // Check if a search index entry is currently visible. - function _isEntryVisible(entry) { - if (!entry.visibleWhen || entry.visibleWhen.length === 0) - return true; - for (let i = 0; i < entry.visibleWhen.length; i++) { - if (!_evalCondition(entry.visibleWhen[i])) - return false; - } - return true; - } - // Search function onSearchTextChanged: { if (searchText.trim() === "") { @@ -249,14 +94,14 @@ Item { root.sidebarExpanded = true; } - if (searchIndex.length === 0) + if (SettingsSearchService.searchIndex.length === 0) return; // Build searchable items with resolved translations, filtering out invisible entries let items = []; - for (let j = 0; j < searchIndex.length; j++) { - const entry = searchIndex[j]; - if (!_isEntryVisible(entry)) + for (let j = 0; j < SettingsSearchService.searchIndex.length; j++) { + const entry = SettingsSearchService.searchIndex[j]; + if (!SettingsSearchService.isEntryVisible(entry)) continue; items.push({ "labelKey": entry.labelKey, diff --git a/Services/UI/SettingsSearchService.qml b/Services/UI/SettingsSearchService.qml new file mode 100644 index 000000000..50dc7ac56 --- /dev/null +++ b/Services/UI/SettingsSearchService.qml @@ -0,0 +1,158 @@ +pragma Singleton + +import QtQuick +import Quickshell +import Quickshell.Io +import qs.Commons +import qs.Services.Compositor +import qs.Services.Power +import qs.Services.System + +Singleton { + id: root + + property var searchIndex: [] + + FileView { + path: Quickshell.shellDir + "/Assets/settings-search-index.json" + watchChanges: false + printErrors: false + + onLoaded: { + try { + root.searchIndex = JSON.parse(text()); + } catch (e) { + root.searchIndex = []; + } + } + } + + readonly property var _roots: ({ + "CompositorService": CompositorService, + "Settings": Settings, + "Quickshell": Quickshell, + "IdleService": IdleService, + "SystemStatService": SystemStatService, + "SoundService": SoundService + }) + + function isEntryVisible(entry) { + if (!entry.visibleWhen || entry.visibleWhen.length === 0) + return true; + for (let i = 0; i < entry.visibleWhen.length; i++) { + if (!_evalCondition(entry.visibleWhen[i])) + return false; + } + return true; + } + + function _resolveValue(path) { + const parts = path.split("."); + const rootObj = _roots[parts[0]]; + if (rootObj === undefined) + return undefined; + + let obj = rootObj; + for (let i = 1; i < parts.length; i++) { + if (obj === undefined || obj === null) + return undefined; + let key = parts[i]; + if (key.endsWith("?")) + key = key.slice(0, -1); + obj = obj[key]; + } + return obj; + } + + function _splitAnd(expr) { + const parts = []; + let depth = 0; + let current = ""; + for (let i = 0; i < expr.length; i++) { + const ch = expr[i]; + if (ch === "(") + depth++; + else if (ch === ")") + depth--; + else if (depth === 0 && ch === "&" && i + 1 < expr.length && expr[i + 1] === "&") { + parts.push(current); + current = ""; + i++; + continue; + } + current += ch; + } + parts.push(current); + return parts; + } + + function _evalCondition(expr) { + expr = expr.trim(); + + // Strip outer parentheses + if (expr.startsWith("(") && expr.endsWith(")")) { + let depth = 0; + let allWrapped = true; + for (let i = 0; i < expr.length - 1; i++) { + if (expr[i] === "(") + depth++; + else if (expr[i] === ")") + depth--; + if (depth === 0) { + allWrapped = false; + break; + } + } + if (allWrapped) + return _evalCondition(expr.slice(1, -1)); + } + + // AND: all parts must be true + if (expr.includes("&&")) { + const parts = _splitAnd(expr); + if (parts.length > 1) { + for (let i = 0; i < parts.length; i++) { + if (!_evalCondition(parts[i])) + return false; + } + return true; + } + } + + // Negation + if (expr.startsWith("!")) + return !_evalCondition(expr.slice(1).trim()); + + // Literal false + if (expr === "false") + return false; + + // Strip nullish coalescing fallback + const nullishMatch = expr.match(/^(.+?)\s*\?\?\s*(?:false|true)\s*$/); + if (nullishMatch) + return _evalCondition(nullishMatch[1]); + + // === comparison + let m = expr.match(/^(.+?)\s*===\s*"([^"]*)"\s*$/); + if (m) + return _resolveValue(m[1].trim()) === m[2]; + + // !== comparison + m = expr.match(/^(.+?)\s*!==\s*"([^"]*)"\s*$/); + if (m) + return _resolveValue(m[1].trim()) !== m[2]; + + // > comparison + m = expr.match(/^(.+?)\s*>\s*(\d+)\s*$/); + if (m) + return _resolveValue(m[1].trim()) > parseInt(m[2]); + + // Simple property path — resolve and return truthiness + const val = _resolveValue(expr); + if (val !== undefined) + return !!val; + + // Unrecognized expression — assume visible + return true; + } +} From 74b2bce935b688d6df66c7b1a99fdc47127c39ab Mon Sep 17 00:00:00 2001 From: Lemmy Date: Wed, 11 Mar 2026 21:36:30 -0400 Subject: [PATCH 12/20] feat(settings): allow up/down navigation in search results when settings are windowed --- .../Panels/Settings/SettingsPanelWindow.qml | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/Modules/Panels/Settings/SettingsPanelWindow.qml b/Modules/Panels/Settings/SettingsPanelWindow.qml index 3b7e8aed6..279f6a517 100644 --- a/Modules/Panels/Settings/SettingsPanelWindow.qml +++ b/Modules/Panels/Settings/SettingsPanelWindow.qml @@ -83,16 +83,32 @@ FloatingWindow { onActivated: settingsContent.selectPreviousTab() } - Shortcut { - sequence: "Up" - enabled: !PanelService.isKeybindRecording - onActivated: settingsContent.scrollUp() + Instantiator { + model: Settings.data.general.keybinds.keyUp || [] + Shortcut { + sequence: modelData + enabled: !PanelService.isKeybindRecording + onActivated: { + if (settingsContent.searchText.trim() !== "") + settingsContent.searchSelectPrevious(); + else + settingsContent.scrollUp(); + } + } } - Shortcut { - sequence: "Down" - enabled: !PanelService.isKeybindRecording - onActivated: settingsContent.scrollDown() + Instantiator { + model: Settings.data.general.keybinds.keyDown || [] + Shortcut { + sequence: modelData + enabled: !PanelService.isKeybindRecording + onActivated: { + if (settingsContent.searchText.trim() !== "") + settingsContent.searchSelectNext(); + else + settingsContent.scrollDown(); + } + } } // Main content From 96930af7591b721210f7550a4995c2824d68eb0b Mon Sep 17 00:00:00 2001 From: Lemmy Date: Wed, 11 Mar 2026 22:41:25 -0400 Subject: [PATCH 13/20] feat(launcher): trying a less boxy look --- Modules/Panels/Launcher/LauncherGridDelegate.qml | 2 +- Modules/Panels/Launcher/LauncherListDelegate.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Panels/Launcher/LauncherGridDelegate.qml b/Modules/Panels/Launcher/LauncherGridDelegate.qml index e6bc3f84c..0bcc57217 100644 --- a/Modules/Panels/Launcher/LauncherGridDelegate.qml +++ b/Modules/Panels/Launcher/LauncherGridDelegate.qml @@ -30,7 +30,7 @@ Item { id: gridEntry anchors.fill: parent anchors.margins: Style.marginXXS - color: gridEntryContainer.isSelected ? Color.mHover : Color.mSurfaceVariant + color: gridEntryContainer.isSelected ? Color.mHover : "transparent" forceOpaque: gridEntryContainer.isSelected Behavior on color { diff --git a/Modules/Panels/Launcher/LauncherListDelegate.qml b/Modules/Panels/Launcher/LauncherListDelegate.qml index 63f1d767f..631fe7aec 100644 --- a/Modules/Panels/Launcher/LauncherListDelegate.qml +++ b/Modules/Panels/Launcher/LauncherListDelegate.qml @@ -18,7 +18,7 @@ NBox { width: ListView.view.width implicitHeight: launcher.entryHeight clip: true - color: entry.isSelected ? Color.mHover : Color.mSurfaceVariant + color: entry.isSelected ? Color.mHover : "transparent" forceOpaque: entry.isSelected // Prepare item when it becomes visible (e.g., decode images) From 71ca1b3f603c3a7ea224f442a2946c0ee39ff0b1 Mon Sep 17 00:00:00 2001 From: Lemmy Date: Wed, 11 Mar 2026 22:49:41 -0400 Subject: [PATCH 14/20] Revert "feat(launcher): trying a less boxy look" This reverts commit 96930af7591b721210f7550a4995c2824d68eb0b. --- Modules/Panels/Launcher/LauncherGridDelegate.qml | 2 +- Modules/Panels/Launcher/LauncherListDelegate.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Panels/Launcher/LauncherGridDelegate.qml b/Modules/Panels/Launcher/LauncherGridDelegate.qml index 0bcc57217..e6bc3f84c 100644 --- a/Modules/Panels/Launcher/LauncherGridDelegate.qml +++ b/Modules/Panels/Launcher/LauncherGridDelegate.qml @@ -30,7 +30,7 @@ Item { id: gridEntry anchors.fill: parent anchors.margins: Style.marginXXS - color: gridEntryContainer.isSelected ? Color.mHover : "transparent" + color: gridEntryContainer.isSelected ? Color.mHover : Color.mSurfaceVariant forceOpaque: gridEntryContainer.isSelected Behavior on color { diff --git a/Modules/Panels/Launcher/LauncherListDelegate.qml b/Modules/Panels/Launcher/LauncherListDelegate.qml index 631fe7aec..63f1d767f 100644 --- a/Modules/Panels/Launcher/LauncherListDelegate.qml +++ b/Modules/Panels/Launcher/LauncherListDelegate.qml @@ -18,7 +18,7 @@ NBox { width: ListView.view.width implicitHeight: launcher.entryHeight clip: true - color: entry.isSelected ? Color.mHover : "transparent" + color: entry.isSelected ? Color.mHover : Color.mSurfaceVariant forceOpaque: entry.isSelected // Prepare item when it becomes visible (e.g., decode images) From 175e85302db8d989977ceab0083155cc7eb4c87b Mon Sep 17 00:00:00 2001 From: Lemmy Date: Wed, 11 Mar 2026 22:51:50 -0400 Subject: [PATCH 15/20] fix(launcher): restore background behind icons --- Modules/Panels/Launcher/LauncherGridDelegate.qml | 2 +- Modules/Panels/Launcher/LauncherListDelegate.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/Panels/Launcher/LauncherGridDelegate.qml b/Modules/Panels/Launcher/LauncherGridDelegate.qml index e6bc3f84c..67317c95e 100644 --- a/Modules/Panels/Launcher/LauncherGridDelegate.qml +++ b/Modules/Panels/Launcher/LauncherGridDelegate.qml @@ -57,7 +57,7 @@ Item { Rectangle { anchors.fill: parent radius: Style.radiusM - color: Color.mSurfaceVariant + color: Color.mSurface visible: Settings.data.appLauncher.showIconBackground && !modelData.isImage } diff --git a/Modules/Panels/Launcher/LauncherListDelegate.qml b/Modules/Panels/Launcher/LauncherListDelegate.qml index 63f1d767f..aba61b5bb 100644 --- a/Modules/Panels/Launcher/LauncherListDelegate.qml +++ b/Modules/Panels/Launcher/LauncherListDelegate.qml @@ -57,7 +57,7 @@ NBox { Rectangle { anchors.fill: parent radius: Style.radiusXS - color: Color.mSurfaceVariant + color: Color.mSurface visible: Settings.data.appLauncher.showIconBackground && !modelData.isImage } From 02a3d74c241cc0550b638353de59f9b5edc3f07d Mon Sep 17 00:00:00 2001 From: Lemmy Date: Thu, 12 Mar 2026 00:18:03 -0400 Subject: [PATCH 16/20] feat(ncheckbox): allow custom labelSize --- Assets/settings-search-index.json | 12 ++++++++++++ Widgets/NCheckbox.qml | 2 ++ Widgets/NLabel.qml | 3 ++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Assets/settings-search-index.json b/Assets/settings-search-index.json index bf07197e0..03f4885ed 100644 --- a/Assets/settings-search-index.json +++ b/Assets/settings-search-index.json @@ -656,6 +656,18 @@ "Settings.data.network.bluetoothRssiPollingEnabled" ] }, + { + "labelKey": "common.auto-connect", + "descriptionKey": null, + "widget": "NCheckbox", + "tab": 16, + "tabLabel": "panels.connections.title", + "subTab": 1, + "subTabLabel": "common.bluetooth", + "visibleWhen": [ + "Settings.data.network.bluetoothAutoConnect" + ] + }, { "labelKey": "toast.airplane-mode.title", "descriptionKey": null, diff --git a/Widgets/NCheckbox.qml b/Widgets/NCheckbox.qml index 09ed49f7f..1f363a3b8 100644 --- a/Widgets/NCheckbox.qml +++ b/Widgets/NCheckbox.qml @@ -14,6 +14,7 @@ RowLayout { property color activeColor: Color.mPrimary property color activeOnColor: Color.mOnPrimary property int baseSize: Style.baseWidgetSize * 0.7 + property real labelSize: Style.fontSizeL signal toggled(bool checked) signal entered @@ -24,6 +25,7 @@ RowLayout { NLabel { label: root.label + labelSize: root.labelSize description: root.description visible: root.label !== "" || root.description !== "" } diff --git a/Widgets/NLabel.qml b/Widgets/NLabel.qml index 626a3709e..71073fca7 100644 --- a/Widgets/NLabel.qml +++ b/Widgets/NLabel.qml @@ -14,6 +14,7 @@ ColumnLayout { property color iconColor: Color.mOnSurface property bool showIndicator: false property string indicatorTooltip: "" + property real labelSize: Style.fontSizeL opacity: enabled ? 1.0 : 0.6 spacing: Style.marginXXS @@ -38,7 +39,7 @@ ColumnLayout { id: labelText Layout.fillWidth: true text: root.label - pointSize: Style.fontSizeL + pointSize: root.labelSize font.weight: Style.fontWeightSemiBold color: labelColor wrapMode: Text.WordWrap From 3cdd999664bfb922a8d389494e43bd570e63144c Mon Sep 17 00:00:00 2001 From: Lemmy Date: Thu, 12 Mar 2026 00:18:31 -0400 Subject: [PATCH 17/20] feat(bt): improve ui/ux for the auto-reconnect feature --- .../Tabs/Connections/BluetoothSubTab.qml | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/Modules/Panels/Settings/Tabs/Connections/BluetoothSubTab.qml b/Modules/Panels/Settings/Tabs/Connections/BluetoothSubTab.qml index 7db8d6319..00142478c 100644 --- a/Modules/Panels/Settings/Tabs/Connections/BluetoothSubTab.qml +++ b/Modules/Panels/Settings/Tabs/Connections/BluetoothSubTab.qml @@ -671,24 +671,14 @@ Item { icon: BluetoothService.getDeviceAutoConnect(modelData.address) ? "repeat" : "repeat-off" pointSize: Style.fontSizeXS color: BluetoothService.getDeviceAutoConnect(modelData.address) ? Color.mPrimary : Color.mOnSurface - Layout.alignment: Qt.AlignVCenter } - NText { - text: I18n.tr("common.auto-connect") - pointSize: Style.fontSizeXS - color: BluetoothService.getDeviceAutoConnect(modelData.address) ? Color.mOnSurface : Color.mOnSurfaceVariant - Layout.fillWidth: true - Layout.alignment: Qt.AlignVCenter - - MouseArea { - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onEntered: TooltipService.show(parent, BluetoothService.getDeviceAutoConnect(modelData.address) ? I18n.tr("tooltips.bluetooth-auto-connect-on") : I18n.tr("tooltips.bluetooth-auto-connect-off")) - onExited: TooltipService.hide() - onClicked: BluetoothService.setDeviceAutoConnect(modelData, !BluetoothService.getDeviceAutoConnect(modelData.address)) - } + NCheckbox { + label: I18n.tr("common.auto-connect") + labelSize: Style.fontSizeXS + baseSize: Style.baseWidgetSize * 0.6 + checked: BluetoothService.getDeviceAutoConnect(modelData.address) + onToggled: checked => BluetoothService.setDeviceAutoConnect(modelData, checked) } } } From d0b5052452a4abb01ffbbb547108dbf2adeeaa94 Mon Sep 17 00:00:00 2001 From: Lysec Date: Thu, 12 Mar 2026 10:07:55 +0100 Subject: [PATCH 18/20] fix(workspace): potential fix for SIGSEGV caused by re-entrant incubation --- Modules/Bar/Widgets/Workspace.qml | 7 ++++--- Services/Compositor/CompositorService.qml | 3 --- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Modules/Bar/Widgets/Workspace.qml b/Modules/Bar/Widgets/Workspace.qml index 7a5c3ef74..df48743af 100644 --- a/Modules/Bar/Widgets/Workspace.qml +++ b/Modules/Bar/Widgets/Workspace.qml @@ -700,13 +700,14 @@ Item { } } - Component.onCompleted: updateWindows() - onWorkspaceModelChanged: updateWindows() + // Deferred to avoid re-entrant incubation: when localWorkspaces.append() + Component.onCompleted: Qt.callLater(updateWindows) + onWorkspaceModelChanged: Qt.callLater(updateWindows) Connections { target: root function onWindowRevisionChanged() { - groupedContainer.updateWindows(); + Qt.callLater(groupedContainer.updateWindows); } } diff --git a/Services/Compositor/CompositorService.qml b/Services/Compositor/CompositorService.qml index eaff86edc..f9f7427ef 100644 --- a/Services/Compositor/CompositorService.qml +++ b/Services/Compositor/CompositorService.qml @@ -211,10 +211,7 @@ Singleton { }); backend.windowListChanged.connect(() => { - // Sync windows when they change syncWindows(); - // Forward the signal - windowListChanged(); }); // Property bindings - use automatic property change signal From 3ab57ce06d41c8029e5b58e1b9e4762f443e9bec Mon Sep 17 00:00:00 2001 From: Lysec Date: Thu, 12 Mar 2026 11:08:12 +0100 Subject: [PATCH 19/20] Release v4.6.7 --- Services/Noctalia/UpdateService.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Services/Noctalia/UpdateService.qml b/Services/Noctalia/UpdateService.qml index 012a4b7bb..4bcd87f50 100644 --- a/Services/Noctalia/UpdateService.qml +++ b/Services/Noctalia/UpdateService.qml @@ -12,7 +12,7 @@ Singleton { // Version properties readonly property string baseVersion: "4.6.7" - readonly property bool isDevelopment: true + readonly property bool isDevelopment: false readonly property string developmentSuffix: "-git" readonly property string currentVersion: `v${!isDevelopment ? baseVersion : baseVersion + developmentSuffix}` From ba03e4c3f7340a958d23a186576052fbdea79193 Mon Sep 17 00:00:00 2001 From: Lysec Date: Thu, 12 Mar 2026 11:10:06 +0100 Subject: [PATCH 20/20] Bumping version --- Services/Noctalia/UpdateService.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Services/Noctalia/UpdateService.qml b/Services/Noctalia/UpdateService.qml index 4bcd87f50..0f0473377 100644 --- a/Services/Noctalia/UpdateService.qml +++ b/Services/Noctalia/UpdateService.qml @@ -11,8 +11,8 @@ Singleton { id: root // Version properties - readonly property string baseVersion: "4.6.7" - readonly property bool isDevelopment: false + readonly property string baseVersion: "4.6.8" + readonly property bool isDevelopment: true readonly property string developmentSuffix: "-git" readonly property string currentVersion: `v${!isDevelopment ? baseVersion : baseVersion + developmentSuffix}`