Merge branch 'noctalia-dev:main' into pr/networking-refactor-pt2

This commit is contained in:
Turann_
2026-03-14 00:56:16 +03:00
committed by GitHub
44 changed files with 165 additions and 100 deletions
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "App-Launcher anzeigen",
"appearance-sit-on-frame-description": "Richten Sie das Dock innerhalb des Rahmenrands aus, anstatt es oben zu platzieren.",
"appearance-sit-on-frame-label": "Dock sitzt am Rahmen",
"appearance-type-attached": "Statisch",
"appearance-type-description": "Wählen Sie zwischen einer schwebenden Pillenform oder einer statischen, am Rand befestigten Leiste.",
"appearance-type-floating": "Schwebend",
"appearance-type-label": "Dock-Stil",
"appearance-type-static": "Statisch",
"enabled-description": "Dock vollständig anzeigen oder ausblenden.",
"enabled-label": "Dock aktivieren",
"monitors-desc": "Dock auf bestimmten Monitoren anzeigen. Standardmäßig werden alle angezeigt, wenn keine ausgewählt wurden.",
+1 -1
View File
@@ -1149,10 +1149,10 @@
"appearance-show-launcher-icon-label": "Show app launcher",
"appearance-sit-on-frame-description": "Align the dock inside the frame border instead of sitting on top.",
"appearance-sit-on-frame-label": "Dock sits on frame",
"appearance-type-attached": "Attached",
"appearance-type-description": "Choose between a floating pill or a static bar attached to the edge.",
"appearance-type-floating": "Floating",
"appearance-type-label": "Dock style",
"appearance-type-static": "Static",
"enabled-description": "Show or hide the dock entirely.",
"enabled-label": "Enable dock",
"monitors-desc": "Show dock on specific monitors. Defaults to all if none are chosen.",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "Mostrar lanzador de aplicaciones",
"appearance-sit-on-frame-description": "Alinear el dock dentro del borde del marco en lugar de que se superponga.",
"appearance-sit-on-frame-label": "El Dock se asienta en el marco",
"appearance-type-attached": "Estático",
"appearance-type-description": "Elige entre una barra flotante con forma de píldora o una barra estática anclada al borde.",
"appearance-type-floating": "Flotante",
"appearance-type-label": "Estilo del dock",
"appearance-type-static": "Estático",
"enabled-description": "Mostrar u ocultar el dock por completo.",
"enabled-label": "Habilitar dock",
"monitors-desc": "Mostrar el dock en monitores específicos. Por defecto, se muestra en todos si no se elige ninguno.",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "Afficher le Lanceur d'applications",
"appearance-sit-on-frame-description": "Aligner le dock à l'intérieur de la bordure du cadre au lieu qu'il se superpose.",
"appearance-sit-on-frame-label": "Le dock est sur le cadre",
"appearance-type-attached": "Statique",
"appearance-type-description": "Choisissez entre une barre flottante en forme de pilule ou une barre statique attachée au bord.",
"appearance-type-floating": "Flottant",
"appearance-type-label": "Style du dock",
"appearance-type-static": "Statique",
"enabled-description": "Afficher ou masquer complètement le dock.",
"enabled-label": "Activer le dock",
"monitors-desc": "Afficher le dock sur des écrans spécifiques. Par défaut, il s'affiche sur tous les écrans si aucun n'est sélectionné.",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "Alkalmazásindító megjelenítése",
"appearance-sit-on-frame-description": "Igazítsa a dokkot a keret szegélyén belülre, ahelyett, hogy a tetején ülne.",
"appearance-sit-on-frame-label": "A dokk a kereten ül",
"appearance-type-attached": "Statikus",
"appearance-type-description": "Lebegő, kapszula alakú sáv vagy statikus, a szélhez rögzített sáv.",
"appearance-type-floating": "Lebegő",
"appearance-type-label": "Dokk stílus",
"appearance-type-static": "Statikus",
"enabled-description": "A dokk teljes megjelenítése vagy elrejtése.",
"enabled-label": "Dokk engedélyezése",
"monitors-desc": "Dokk megjelenítése meghatározott monitorokon. Alapértelmezés szerint mindegyiken, ha nincs kiválasztva.",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "Mostra launcher app",
"appearance-sit-on-frame-description": "Allinea il dock dentro il bordo frame invece di posizionarlo sopra.",
"appearance-sit-on-frame-label": "Dock sul frame",
"appearance-type-attached": "Statico",
"appearance-type-description": "Scegli tra pill flottante o barra statica agganciata al bordo.",
"appearance-type-floating": "Flottante",
"appearance-type-label": "Stile dock",
"appearance-type-static": "Statico",
"enabled-description": "Mostra o nascondi completamente il dock.",
"enabled-label": "Abilita dock",
"monitors-desc": "Mostra dock su monitor specifici. Se non ne scegli nessuno, verranno usati tutti.",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "アプリランチャーを表示",
"appearance-sit-on-frame-description": "ドックをフレームの境界の内側に配置し、上部に重ならないようにします。",
"appearance-sit-on-frame-label": "ドックはフレームに配置",
"appearance-type-attached": "静的",
"appearance-type-description": "浮動するピル型、または端に固定された静的バーのどちらかを選択してください。",
"appearance-type-floating": "フローティング",
"appearance-type-label": "ドックスタイル",
"appearance-type-static": "静的",
"enabled-description": "ドックを完全に表示または非表示にします。",
"enabled-label": "ドックの有効化",
"monitors-desc": "ドックを表示するディスプレイを選択します。未選択の場合は全てに表示されます。",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "앱 런처 표시",
"appearance-sit-on-frame-description": "독을 프레임 테두리 내부에 정렬하고, 위에 놓이지 않도록 합니다.",
"appearance-sit-on-frame-label": "독은 프레임에 위치",
"appearance-type-attached": "정적",
"appearance-type-description": "플로팅 필 형태 또는 가장자리에 고정된 고정 바 중에서 선택하세요.",
"appearance-type-floating": "플로팅",
"appearance-type-label": "독 스타일",
"appearance-type-static": "정적",
"enabled-description": "독을 완전히 표시하거나 숨깁니다.",
"enabled-label": "독 활성화",
"monitors-desc": "특정 모니터에 독을 표시합니다. 선택하지 않으면 모든 모니터에 표시됩니다.",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "Toon app-starter",
"appearance-sit-on-frame-description": "Lijn het dock uit binnen de kadergrens, in plaats van erbovenop te liggen.",
"appearance-sit-on-frame-label": "Dock zit op het frame",
"appearance-type-attached": "Statisch",
"appearance-type-description": "Kies tussen een zwevende pilvorm of een statische balk die aan de rand is bevestigd.",
"appearance-type-floating": "Zwevend",
"appearance-type-label": "Dockstijl",
"appearance-type-static": "Statisch",
"enabled-description": "Dock geheel tonen of verbergen.",
"enabled-label": "Dock inschakelen",
"monitors-desc": "Dock op specifieke monitoren weergeven. Standaard op alle als er geen zijn gekozen.",
+1 -1
View File
@@ -1094,10 +1094,10 @@
"appearance-position-label": "Stad",
"appearance-sit-on-frame-description": "Set festepunktet i ramma heller enn å ha det på toppen.",
"appearance-sit-on-frame-label": "Festepunktet sit på ramma",
"appearance-type-attached": "Statisk",
"appearance-type-description": "Vel mellom flytande pille eller statisk oppgåveline fest til randa.",
"appearance-type-floating": "Flytande",
"appearance-type-label": "Festepunktstil",
"appearance-type-static": "Statisk",
"enabled-description": "Viser eller gøymer festepunktet heilt.",
"enabled-label": "Slå på festepunkt",
"monitors-desc": "Viser festepunktet på visse skjermar. Dersom du ikkje vel noko, viser det seg på alle.",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "Pokaż launcher aplikacji",
"appearance-sit-on-frame-description": "Wyrównaj dock wewnątrz ramki, zamiast umieszczać go na wierzchu.",
"appearance-sit-on-frame-label": "Dock znajduje się na ramce",
"appearance-type-attached": "Statyczny",
"appearance-type-description": "Wybierz pomiędzy pływającą pigułką a statycznym paskiem przymocowanym do krawędzi.",
"appearance-type-floating": "Pływający",
"appearance-type-label": "Styl docka",
"appearance-type-static": "Statyczny",
"enabled-description": "Pokaż lub całkowicie ukryj dok.",
"enabled-label": "Włącz dok",
"monitors-desc": "Pokaż dok na konkretnych monitorach. Domyślnie na wszystkich, jeśli żaden nie zostanie wybrany.",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "Mostrar lançador de aplicações",
"appearance-sit-on-frame-description": "Alinhe o dock dentro da borda do quadro em vez de ficar por cima.",
"appearance-sit-on-frame-label": "O dock fica no quadro",
"appearance-type-attached": "Estático",
"appearance-type-description": "Escolha entre uma pílula flutuante ou uma barra estática anexada à borda.",
"appearance-type-floating": "Flutuante",
"appearance-type-label": "Estilo do dock",
"appearance-type-static": "Estático",
"enabled-description": "Mostrar ou ocultar o dock completamente.",
"enabled-label": "Ativar dock",
"monitors-desc": "Mostrar dock em monitores específicos. O padrão é todos se nenhum for escolhido.",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "Показать панель запуска приложений",
"appearance-sit-on-frame-description": "Выровнять док внутри границы рамки, а не поверх нее.",
"appearance-sit-on-frame-label": "док располагается на рамке",
"appearance-type-attached": "Статический",
"appearance-type-description": "Выберите между плавающей пилюлей или статической панелью, прикрепленной к краю.",
"appearance-type-floating": "Плавающий",
"appearance-type-label": "Стиль дока",
"appearance-type-static": "Статический",
"enabled-description": "Показать или скрыть док целиком.",
"enabled-label": "Включить док",
"monitors-desc": "Показывать док на определённых мониторах. По умолчанию на всех, если ни один не выбран.",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "Visa appstartare",
"appearance-sit-on-frame-description": "Justera dockan innanför ramkanten istället för att ligga ovanpå.",
"appearance-sit-on-frame-label": "Dockan sitter på ramen",
"appearance-type-attached": "Statisk",
"appearance-type-description": "Välj mellan en flytande pillerform eller en statisk stapel fäst vid kanten.",
"appearance-type-floating": "Flytande",
"appearance-type-label": "Dockstil",
"appearance-type-static": "Statisk",
"enabled-description": "Visa eller dölj dockningsstationen helt.",
"enabled-label": "Aktivera dockningsstation",
"monitors-desc": "Visa dockningsstationen på specifika bildskärmar. Standardinställningen är alla om ingen är vald.",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "Uygulama başlatıcıyı göster",
"appearance-sit-on-frame-description": "Dock'u çerçevenin kenar boşluğunun içine hizalayın, üstüne oturmak yerine.",
"appearance-sit-on-frame-label": "Dock çerçevede yer alır",
"appearance-type-attached": "Statik",
"appearance-type-description": "Yüzen bir hap veya kenara bağlı sabit bir çubuk arasından seçim yapın.",
"appearance-type-floating": "Yüzen",
"appearance-type-label": "Dock stili",
"appearance-type-static": "Statik",
"enabled-description": "Docku tamamen gösterin veya gizleyin.",
"enabled-label": "Docku etkinleştir",
"monitors-desc": "Docku belirli ekranlarda gösterin. Hiçbiri seçilmezse varsayılan olarak tümünde gösterilir.",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "Показати запуск програм",
"appearance-sit-on-frame-description": "Вирівняйте док всередині межі рамки, а не поверх неї.",
"appearance-sit-on-frame-label": "Док розміщується на рамці",
"appearance-type-attached": "Статичний",
"appearance-type-description": "Виберіть між плаваючою пігулкою або статичною панеллю, прикріпленою до краю.",
"appearance-type-floating": "Плаваючий",
"appearance-type-label": "Стиль дока",
"appearance-type-static": "Статичний",
"enabled-description": "Показати або сховати док повністю.",
"enabled-label": "Увімкнути док",
"monitors-desc": "Показувати док на певних моніторах. За замовчуванням на всіх, якщо не вибрано.",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "显示应用启动器",
"appearance-sit-on-frame-description": "将停靠栏对齐在框架边框内,而不是位于顶部。",
"appearance-sit-on-frame-label": "停靠栏位于框架上",
"appearance-type-attached": "静态",
"appearance-type-description": "选择浮动药丸样式或附着在边缘的静态栏。",
"appearance-type-floating": "浮动",
"appearance-type-label": "Dock 样式",
"appearance-type-static": "静态",
"enabled-description": "完全显示或隐藏 Dock 栏。",
"enabled-label": "启用 Dock 栏",
"monitors-desc": "在特定显示器上显示 Dock 栏。如果未选择任何显示器,则默认在所有显示器上显示。",
+1 -1
View File
@@ -1151,10 +1151,10 @@
"appearance-show-launcher-icon-label": "顯示應用程式啟動器",
"appearance-sit-on-frame-description": "將停靠欄對齊在框架邊框內,而不是位於頂部。",
"appearance-sit-on-frame-label": "停靠欄位於框架上",
"appearance-type-attached": "靜態",
"appearance-type-description": "選擇浮動藥丸樣式或附著在邊緣的靜態列。",
"appearance-type-floating": "浮動",
"appearance-type-label": "Dock 樣式",
"appearance-type-static": "靜態",
"enabled-description": "顯示或完全隱藏 Dock",
"enabled-label": "啟用 Dock",
"monitors-desc": "只在特定的顯示器顯示 Dock, 如果全部取消勾選則會顯示在所有顯示器",
+1 -1
View File
@@ -849,7 +849,7 @@
"subTab": 0,
"subTabLabel": "common.appearance",
"visibleWhen": [
"Settings.data.dock.dockType === \"static\" && Settings.data.bar.barType === \"framed\""
"Settings.data.dock.dockType === \"attached\" && Settings.data.bar.barType === \"framed\""
]
},
{
+14
View File
@@ -0,0 +1,14 @@
import QtQuick
QtObject {
function migrate(adapter, logger, rawJson) {
logger.i("Settings", "Migrating settings to v58 (dock.dockType: static -> attached)");
if (rawJson && rawJson.dock && rawJson.dock.dockType === "static") {
adapter.dock.dockType = "attached";
logger.i("Settings", "Migrated dock.dockType: static -> attached");
}
return true;
}
}
+3 -1
View File
@@ -29,7 +29,8 @@ QtObject {
54: migration54Component,
55: migration55Component,
56: migration56Component,
57: migration57Component
57: migration57Component,
58: migration58Component
})
// Migration components
@@ -56,4 +57,5 @@ QtObject {
property Component migration55Component: Migration55 {}
property Component migration56Component: Migration56 {}
property Component migration57Component: Migration57 {}
property Component migration58Component: Migration58 {}
}
+2 -2
View File
@@ -25,7 +25,7 @@ Singleton {
- Default cache directory: ~/.cache/noctalia
*/
readonly property alias data: adapter // Used to access via Settings.data.xxx.yyy
readonly property int settingsVersion: 57
readonly property int settingsVersion: 58
property bool isDebug: Quickshell.env("NOCTALIA_DEBUG") === "1"
readonly property string shellName: "noctalia"
readonly property string configDir: Quickshell.env("NOCTALIA_CONFIG_DIR") || (Quickshell.env("XDG_CONFIG_HOME") || Quickshell.env("HOME") + "/.config") + "/" + shellName + "/"
@@ -543,7 +543,7 @@ Singleton {
property bool enabled: true
property string position: "bottom" // "top", "bottom", "left", "right"
property string displayMode: "auto_hide" // "always_visible", "auto_hide", "exclusive"
property string dockType: "floating" // "floating", "static"
property string dockType: "floating" // "floating", "attached"
property real backgroundOpacity: 1.0
property real floatingRatio: 1.0
property real size: 1
+1 -1
View File
@@ -12,7 +12,7 @@ Item {
property string icon: ""
property string text: ""
property string suffix: ""
property var tooltipText: ""
property var tooltipText
property bool autoHide: false
property bool forceOpen: false
property bool forceClose: false
+1 -1
View File
@@ -13,7 +13,7 @@ Item {
property string icon: ""
property string text: ""
property string suffix: ""
property var tooltipText: ""
property var tooltipText
property bool autoHide: false
property bool forceOpen: false
property bool forceClose: false
+1 -1
View File
@@ -13,7 +13,7 @@ Item {
property string icon: ""
property string text: ""
property string suffix: ""
property var tooltipText: ""
property var tooltipText
property bool autoHide: false
property bool forceOpen: false
property bool forceClose: false
+27 -2
View File
@@ -73,8 +73,33 @@ Item {
id: loader
anchors.fill: parent
asynchronous: false
// Include reloadCounter in the binding to force re-evaluation
active: root.checkWidgetExists() && (root.reloadCounter >= 0)
// Deferred activation to prevent re-entrant incubation crash:
// When ListModel.append() creates this delegate, the Repeater is mid-incubation.
// If this Loader activates synchronously (asynchronous: false) during delegate
// finalization, it triggers nested QQmlIncubatorPrivate::incubate which corrupts
// the V4 heap (SIGSEGV in QV4::Object::insertMember).
// Deferring to the next event loop iteration breaks the nesting.
property bool _ready: false
active: _ready && root.checkWidgetExists() && (root.reloadCounter >= 0)
Timer {
id: activateTimer
interval: 0
onTriggered: loader._ready = true
}
Component.onCompleted: activateTimer.start()
// Reset _ready when reloadCounter changes to force a deferred re-activation
Connections {
target: root
function onReloadCounterChanged() {
loader._ready = false;
activateTimer.restart();
}
}
sourceComponent: {
// Depend on reloadCounter to force re-fetch of component
var _ = root.reloadCounter;
+2 -2
View File
@@ -37,8 +37,8 @@ NIconButton {
baseSize: Style.getCapsuleHeightForScreen(screen?.name)
applyUiScale: false
customRadius: Style.radiusL
colorBg: Settings.data.nightLight.forced ? Color.mPrimary : Style.capsuleColor
colorFg: Settings.data.nightLight.forced ? Color.mOnPrimary : Color.resolveColorKey(iconColorKey)
colorBg: Settings.data.nightLight.enabled ? Color.mPrimary : Style.capsuleColor
colorFg: Settings.data.nightLight.enabled ? Color.mOnPrimary : Color.resolveColorKey(iconColorKey)
border.color: Style.capsuleBorderColor
border.width: Style.capsuleBorderWidth
+9 -9
View File
@@ -76,7 +76,7 @@ Loader {
readonly property string displayMode: Settings.data.dock.displayMode
readonly property bool autoHide: displayMode === "auto_hide"
readonly property bool exclusive: displayMode === "exclusive"
readonly property bool isStaticMode: Settings.data.dock.dockType === "static"
readonly property bool isAttachedMode: Settings.data.dock.dockType === "attached"
readonly property int hideDelay: 500
readonly property int showDelay: 100
readonly property int hideAnimationDuration: Math.max(0, Math.round(Style.animationFast / (Settings.data.dock.animationSpeed || 1.0)))
@@ -104,7 +104,7 @@ Loader {
readonly property real barMarginV: Settings.data.bar.floating ? Math.ceil(Settings.data.bar.marginVertical) : 0
readonly property int barHeight: Style.getBarHeightForScreen(modelData?.name)
readonly property bool staticPanelOpen: {
if (!isStaticMode)
if (!isAttachedMode)
return false;
var panel = getStaticDockPanel();
if (panel && panel.isPanelOpen !== undefined)
@@ -151,7 +151,7 @@ Loader {
return Math.max(0, Math.round((edgeSize - peekEdgeLength) / 2));
}
readonly property bool showDockIndicator: {
if (!Settings.data.dock.showDockIndicator || (!autoHide && !isStaticMode) || !hidden)
if (!Settings.data.dock.showDockIndicator || (!autoHide && !isAttachedMode) || !hidden)
return false;
return !staticPanelOpen;
}
@@ -639,13 +639,13 @@ Loader {
menuHovered = false;
}
if (autoHide && !dockHovered && !anyAppHovered && !peekHovered && !menuHovered) {
if (isStaticMode) {
if (isAttachedMode) {
const panel = getStaticDockPanel();
if (panel && (panel.menuHovered || (panel.currentContextMenu && panel.currentContextMenu.visible))) {
restart();
return;
}
if (panel && panel.isDockHovered) {
if (panel && (panel.isDockHovered || panel.dockHovered || panel.anyAppHovered)) {
restart();
return;
}
@@ -669,7 +669,7 @@ Loader {
interval: showDelay
onTriggered: {
if (autoHide) {
if (!isStaticMode) {
if (!isAttachedMode) {
dockLoaded = true; // Load dock immediately
}
hidden = false; // Then trigger show animation
@@ -725,7 +725,7 @@ Loader {
onEntered: {
peekHovered = true;
if (isStaticMode) {
if (isAttachedMode) {
if (dockItemCount <= 0)
return;
const panel = getStaticDockPanel();
@@ -741,7 +741,7 @@ Loader {
onExited: {
peekHovered = false;
showTimer.stop();
if (isStaticMode) {
if (isAttachedMode) {
// Start hideTimer which checks panel.isDockHovered before closing
if (!dockHovered && !anyAppHovered && !menuHovered) {
hideTimer.restart();
@@ -820,7 +820,7 @@ Loader {
Loader {
id: dockWindowLoader
active: Settings.data.dock.enabled && !isStaticMode && (barIsReady || !hasBar) && modelData && (Settings.data.dock.monitors.length === 0 || Settings.data.dock.monitors.includes(modelData.name)) && dockLoaded && ToplevelManager && (dockApps.length > 0)
active: Settings.data.dock.enabled && !isAttachedMode && (barIsReady || !hasBar) && modelData && (Settings.data.dock.monitors.length === 0 || Settings.data.dock.monitors.includes(modelData.name)) && dockLoaded && ToplevelManager && (dockApps.length > 0)
sourceComponent: PanelWindow {
id: dockWindow
+3 -3
View File
@@ -18,7 +18,7 @@ Item {
required property int extraLeft
required property int extraRight
property alias dockContainer: dockContainer
readonly property bool isStaticMode: Settings.data.dock.dockType === "static"
readonly property bool isAttachedMode: Settings.data.dock.dockType === "attached"
readonly property string tooltipDirection: dockRoot.dockPosition === "left" ? "right" : (dockRoot.dockPosition === "right" ? "left" : (dockRoot.dockPosition === "top" ? "bottom" : "top"))
Rectangle {
@@ -26,7 +26,7 @@ Item {
// For vertical dock, swap width and height logic
width: dockRoot.isVertical ? Math.round(dockRoot.iconSize * 1.5) : Math.min(dockLayout.implicitWidth + Style.marginXL, dockRoot.maxWidth)
height: dockRoot.isVertical ? Math.min(dockLayout.implicitHeight + Style.marginXL, dockRoot.maxHeight) : Math.round(dockRoot.iconSize * 1.5)
color: Qt.alpha(Color.mSurface, (isStaticMode ? 0 : Settings.data.dock.backgroundOpacity))
color: Qt.alpha(Color.mSurface, (isAttachedMode ? 0 : Settings.data.dock.backgroundOpacity))
// Anchor based on padding to achieve centering shift
anchors.horizontalCenter: extraLeft > 0 || extraRight > 0 ? undefined : parent.horizontalCenter
@@ -39,7 +39,7 @@ Item {
radius: Style.radiusL
border.width: Style.borderS
border.color: Qt.alpha(Color.mOutline, (isStaticMode ? 0 : Settings.data.dock.backgroundOpacity))
border.color: Qt.alpha(Color.mOutline, (isAttachedMode ? 0 : Settings.data.dock.backgroundOpacity))
MouseArea {
id: dockMouseArea
+1 -1
View File
@@ -265,7 +265,7 @@ PopupWindow {
} else if (action.execute) {
action.execute();
}
if (Settings.data.dock.dockType === "static") {
if (Settings.data.dock.dockType === "attached") {
const panel = PanelService.getPanel("staticDockPanel", root.screen, false);
if (panel)
panel.close();
+7 -2
View File
@@ -25,6 +25,8 @@ PanelWindow {
Component.onCompleted: {
Logger.d("BarContentWindow", "Bar content window created for screen:", barWindow.screen?.name);
if (!isHidden)
contentLoaded = true;
}
// Wayland layer configuration
@@ -144,8 +146,11 @@ PanelWindow {
right: barPosition === "right" || !barIsVertical
}
// Track if content should be loaded (stays true during fade-out animation)
property bool contentLoaded: !isHidden
// Track if content should be loaded (stays true during fade-out animation).
// Must NOT be a binding to isHidden on the first hide cycle the binding
// would flip contentLoaded false synchronously (before onIsHiddenChanged can
// start the unload timer), unmapping the Wayland surface mid-animation.
property bool contentLoaded: false
// Timer to delay unload until after fade animation
Timer {
@@ -11,7 +11,7 @@ NIconButtonHot {
enabled: ProgramCheckerService.wlsunsetAvailable
icon: Settings.data.nightLight.enabled ? (Settings.data.nightLight.forced ? "nightlight-forced" : "nightlight-on") : "nightlight-off"
hot: !Settings.data.nightLight.enabled || Settings.data.nightLight.forced
hot: Settings.data.nightLight.enabled
tooltipText: I18n.tr("common.night-light")
onClicked: {
@@ -6,7 +6,9 @@ import Quickshell.Services.Notifications
import Quickshell.Wayland
import qs.Commons
import qs.Modules.MainScreen
import qs.Modules.Panels.Settings
import qs.Services.System
import qs.Services.UI
import qs.Widgets
// Notification History panel
@@ -421,6 +423,16 @@ SmartPanel {
}
}
NIconButton {
icon: "settings"
tooltipText: I18n.tr("common.settings")
baseSize: Style.baseWidgetSize * 0.8
onClicked: {
SettingsPanelService.openToTab(SettingsPanel.Tab.Notifications, 0, screen);
root.close();
}
}
NIconButton {
icon: "close"
tooltipText: I18n.tr("common.close")
@@ -59,8 +59,8 @@ ColumnLayout {
"name": I18n.tr("panels.dock.appearance-type-floating")
},
{
"key": "static",
"name": I18n.tr("panels.dock.appearance-type-static")
"key": "attached",
"name": I18n.tr("panels.dock.appearance-type-attached")
}
]
currentKey: Settings.data.dock.dockType
@@ -96,7 +96,7 @@ ColumnLayout {
NToggle {
Layout.fillWidth: true
visible: Settings.data.dock.dockType === "static" && Settings.data.bar.barType === "framed"
visible: Settings.data.dock.dockType === "attached" && Settings.data.bar.barType === "framed"
label: I18n.tr("panels.dock.appearance-sit-on-frame-label")
description: I18n.tr("panels.dock.appearance-sit-on-frame-description")
checked: Settings.data.dock.sitOnFrame
+21 -13
View File
@@ -23,23 +23,31 @@ kitty)
;;
ghostty)
CONFIG_FILE="$HOME/.config/ghostty/config"
# Check if the config file exists before trying to modify it.
if [ -f "$CONFIG_FILE" ]; then
# Check if theme is already set to noctalia (flexible spacing)
if grep -qE "^theme\s*=\s*noctalia$" "$CONFIG_FILE"; then
: # Already correct
elif grep -qE "^theme\s*=" "$CONFIG_FILE"; then
# Replace existing theme line in-place
sed -i -E 's/^theme\s*=.*/theme = noctalia/' "$CONFIG_FILE"
else
# Add the new theme line to the end of the file
echo "theme = noctalia" >>"$CONFIG_FILE"
# Check both potential config files
CONFIG_FILES=("$HOME/.config/ghostty/config" "$HOME/.config/ghostty/config.ghostty")
FOUND_CONFIG=false
for CONFIG_FILE in "${CONFIG_FILES[@]}"; do
if [ -f "$CONFIG_FILE" ]; then
FOUND_CONFIG=true
# Check if theme is already set to noctalia (flexible spacing)
if grep -qE "^theme\s*=\s*noctalia$" "$CONFIG_FILE"; then
: # Already correct
elif grep -qE "^theme\s*=" "$CONFIG_FILE"; then
# Replace existing theme line in-place
sed -i -E 's/^theme\s*=.*/theme = noctalia/' "$CONFIG_FILE"
else
# Add the new theme line to the end of the file
echo "theme = noctalia" >>"$CONFIG_FILE"
fi
fi
done
if [ "$FOUND_CONFIG" = true ]; then
# Only signal if ghostty is running
pgrep -f ghostty >/dev/null && pkill -SIGUSR2 ghostty || true
else
echo "Error: ghostty config file not found at $CONFIG_FILE" >&2
echo "Error: No ghostty config file found at ${CONFIG_FILES[*]}" >&2
exit 1
fi
;;
+4 -4
View File
@@ -233,7 +233,7 @@ Singleton {
Process {
id: ddcProc
property list<var> ddcMonitors: []
command: ["ddcutil", "detect", "--sleep-multiplier=0.5"]
command: ["ddcutil", "detect", "--enable-dynamic-sleep", "--sleep-multiplier=0.5"]
stdout: StdioCollector {
onStreamFinished: {
var displays = text.trim().split("\n\n");
@@ -367,7 +367,7 @@ Singleton {
refreshProc.running = true;
} else if (monitor.isDdc && monitor.busNum !== "") {
// For DDC displays, get the current value
refreshProc.command = ["ddcutil", "-b", monitor.busNum, "--sleep-multiplier=0.05", "getvcp", "10", "--brief"];
refreshProc.command = ["ddcutil", "-b", monitor.busNum, "--enable-dynamic-sleep", "--sleep-multiplier=0.05", "getvcp", "10", "--brief"];
refreshProc.running = true;
} else if (monitor.isAppleDisplay) {
// For Apple displays, get the current value
@@ -516,7 +516,7 @@ Singleton {
var ddcValue = Math.round(value * monitor.maxBrightness);
var ddcBus = busNum;
Qt.callLater(() => {
setBrightnessProc.command = ["ddcutil", "-b", ddcBus, "--noverify", "--async", "--sleep-multiplier=0.05", "setvcp", "10", ddcValue];
setBrightnessProc.command = ["ddcutil", "-b", ddcBus, "--noverify", "--async", "--enable-dynamic-sleep", "--sleep-multiplier=0.05", "setvcp", "10", ddcValue];
setBrightnessProc.running = true;
});
} else if (!isDdc) {
@@ -538,7 +538,7 @@ Singleton {
initProc.command = ["asdbctl", "get"];
initProc.running = true;
} else if (isDdc && busNum !== "") {
initProc.command = ["ddcutil", "-b", busNum, "--sleep-multiplier=0.05", "getvcp", "10", "--brief"];
initProc.command = ["ddcutil", "-b", busNum, "--enable-dynamic-sleep", "--sleep-multiplier=0.05", "getvcp", "10", "--brief"];
initProc.running = true;
} else if (!isDdc) {
// Internal backlight: first try explicit output mapping, then fall back to first available.
+5 -5
View File
@@ -10,7 +10,7 @@ Rectangle {
// Public properties
property string text: ""
property string icon: ""
property string tooltipText
property var tooltipText
property color backgroundColor: Color.mPrimary
property color textColor: Color.mOnPrimary
property color hoverColor: Color.mHover
@@ -142,19 +142,19 @@ Rectangle {
onEntered: {
root.hovered = true;
root.entered();
if (tooltipText) {
if (tooltipText && (!Array.isArray(tooltipText) || tooltipText.length > 0)) {
TooltipService.show(root, root.tooltipText);
}
}
onExited: {
root.hovered = false;
root.exited();
if (tooltipText) {
if (tooltipText && (!Array.isArray(tooltipText) || tooltipText.length > 0)) {
TooltipService.hide();
}
}
onPressed: mouse => {
if (tooltipText) {
if (tooltipText && (!Array.isArray(tooltipText) || tooltipText.length > 0)) {
TooltipService.hide();
}
if (mouse.button === Qt.LeftButton) {
@@ -168,7 +168,7 @@ Rectangle {
onCanceled: {
root.hovered = false;
if (tooltipText) {
if (tooltipText && (!Array.isArray(tooltipText) || tooltipText.length > 0)) {
TooltipService.hide();
}
}
+3 -3
View File
@@ -13,7 +13,7 @@ Item {
property string suffix: "%"
property real contentScale: 1.0
property color fillColor: Color.mPrimary
property string tooltipText: ""
property var tooltipText
property string tooltipDirection: "top"
// Arc geometry constants
@@ -151,12 +151,12 @@ Item {
anchors.fill: parent
hoverEnabled: true
onEntered: {
if (root.tooltipText) {
if (root.tooltipText && (!Array.isArray(root.tooltipText) || root.tooltipText.length > 0)) {
TooltipService.show(root, root.tooltipText, root.tooltipDirection);
}
}
onExited: {
if (root.tooltipText) {
if (root.tooltipText && (!Array.isArray(root.tooltipText) || root.tooltipText.length > 0)) {
TooltipService.hide();
}
}
+4 -4
View File
@@ -11,7 +11,7 @@ Slider {
property var cutoutColor: Color.mSurface
property bool snapAlways: true
property real widthRatio: 0.7
property string tooltipText
property var tooltipText
property string tooltipDirection: "auto"
property bool hovering: false
property color topColor: "white"
@@ -212,14 +212,14 @@ Slider {
onEntered: {
root.hovering = true;
if (root.tooltipText) {
if (root.tooltipText && (!Array.isArray(root.tooltipText) || root.tooltipText.length > 0)) {
TooltipService.show(knob, root.tooltipText, root.tooltipDirection);
}
}
onExited: {
root.hovering = false;
if (root.tooltipText) {
if (root.tooltipText && (!Array.isArray(root.tooltipText) || root.tooltipText.length > 0)) {
TooltipService.hide();
}
}
@@ -229,7 +229,7 @@ Slider {
Connections {
target: root
function onPressedChanged() {
if (root.pressed && root.tooltipText) {
if (root.pressed && root.tooltipText && (!Array.isArray(root.tooltipText) || root.tooltipText.length > 0)) {
TooltipService.hide();
}
}
+4 -4
View File
@@ -11,7 +11,7 @@ Item {
property bool applyUiScale: true
property string icon
property string tooltipText
property var tooltipText
property string tooltipDirection: "auto"
property bool allowClickWhenDisabled: false
property bool handleWheel: false
@@ -96,20 +96,20 @@ Item {
hoverEnabled: true
onEntered: {
hovering = root.enabled ? true : false;
if (tooltipText) {
if (tooltipText && (!Array.isArray(tooltipText) || tooltipText.length > 0)) {
TooltipService.show(root, tooltipText, tooltipDirection);
}
root.entered();
}
onExited: {
hovering = false;
if (tooltipText) {
if (tooltipText && (!Array.isArray(tooltipText) || tooltipText.length > 0)) {
TooltipService.hide(root);
}
root.exited();
}
onClicked: mouse => {
if (tooltipText) {
if (tooltipText && (!Array.isArray(tooltipText) || tooltipText.length > 0)) {
TooltipService.hide(root);
}
if (!root.enabled && !allowClickWhenDisabled) {
+6 -6
View File
@@ -11,8 +11,8 @@ Rectangle {
// Public properties
property real baseSize: Style.baseWidgetSize
property bool applyUiScale: true
property string icon: ""
property string tooltipText: ""
property string icon
property var tooltipText
property string tooltipDirection: "auto"
property bool allowClickWhenDisabled: false
property bool hot: false
@@ -106,7 +106,7 @@ Rectangle {
onEntered: {
hovering = root.enabled ? true : false;
if (tooltipText) {
if (tooltipText && (!Array.isArray(tooltipText) || tooltipText.length > 0)) {
TooltipService.show(parent, tooltipText, tooltipDirection);
}
root.entered();
@@ -114,7 +114,7 @@ Rectangle {
onExited: {
hovering = false;
if (tooltipText) {
if (tooltipText && (!Array.isArray(tooltipText) || tooltipText.length > 0)) {
TooltipService.hide();
}
root.exited();
@@ -124,7 +124,7 @@ Rectangle {
if (root.enabled) {
root.pressed = true;
}
if (tooltipText) {
if (tooltipText && (!Array.isArray(tooltipText) || tooltipText.length > 0)) {
TooltipService.hide();
}
}
@@ -153,7 +153,7 @@ Rectangle {
root.hovering = false;
root.pressed = false;
root.scale = 1.0;
if (tooltipText) {
if (tooltipText && (!Array.isArray(tooltipText) || tooltipText.length > 0)) {
TooltipService.hide();
}
}
+4 -4
View File
@@ -7,7 +7,7 @@ Rectangle {
id: root
property bool show: false
property string tooltipText: ""
property var tooltipText
implicitWidth: root.show ? 6 * Style.uiScaleRatio : 0
implicitHeight: root.show ? 6 * Style.uiScaleRatio : 0
@@ -26,20 +26,20 @@ Rectangle {
}
MouseArea {
enabled: root.show && root.tooltipText !== ""
enabled: root.show && root.tooltipText && (!Array.isArray(root.tooltipText) || root.tooltipText.length > 0)
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.NoButton
cursorShape: Qt.PointingHandCursor
onEntered: {
if (root.tooltipText) {
if (root.tooltipText && (!Array.isArray(root.tooltipText) || root.tooltipText.length > 0)) {
TooltipService.show(root, root.tooltipText);
}
}
onExited: {
if (root.tooltipText) {
if (root.tooltipText && (!Array.isArray(root.tooltipText) || root.tooltipText.length > 0)) {
TooltipService.hide();
}
}
+4 -4
View File
@@ -11,7 +11,7 @@ Slider {
property var cutoutColor: Color.mSurface
property bool snapAlways: true
property real heightRatio: 0.7
property string tooltipText
property var tooltipText
property string tooltipDirection: "auto"
property bool hovering: false
@@ -226,14 +226,14 @@ Slider {
onEntered: {
root.hovering = true;
if (root.tooltipText) {
if (root.tooltipText && (!Array.isArray(root.tooltipText) || root.tooltipText.length > 0)) {
TooltipService.show(knob, root.tooltipText, root.tooltipDirection);
}
}
onExited: {
root.hovering = false;
if (root.tooltipText) {
if (root.tooltipText && (!Array.isArray(root.tooltipText) || root.tooltipText.length > 0)) {
TooltipService.hide();
}
}
@@ -243,7 +243,7 @@ Slider {
Connections {
target: root
function onPressedChanged() {
if (root.pressed && root.tooltipText) {
if (root.pressed && root.tooltipText && (!Array.isArray(root.tooltipText) || root.tooltipText.length > 0)) {
TooltipService.hide();
}
}
+4 -5
View File
@@ -8,11 +8,10 @@ import qs.Widgets
Rectangle {
id: root
// Public properties
// Public properties
property string text: ""
property string icon: ""
property string tooltipText: ""
property var tooltipText
property bool checked: false
property int tabIndex: 0
property real pointSize: Style.fontSizeM
@@ -94,7 +93,7 @@ Rectangle {
id: tooltipTimer
interval: 500
onTriggered: {
if (root.isHovered && root.tooltipText !== "") {
if (root.isHovered && root.tooltipText && (!Array.isArray(root.tooltipText) || root.tooltipText.length > 0)) {
TooltipService.show(root, root.tooltipText);
}
}
@@ -106,14 +105,14 @@ Rectangle {
cursorShape: Qt.PointingHandCursor
onEntered: {
root.isHovered = true;
if (root.tooltipText !== "") {
if (root.tooltipText && (!Array.isArray(root.tooltipText) || root.tooltipText.length > 0)) {
tooltipTimer.start();
}
}
onExited: {
root.isHovered = false;
tooltipTimer.stop();
if (root.tooltipText !== "") {
if (root.tooltipText && (!Array.isArray(root.tooltipText) || root.tooltipText.length > 0)) {
TooltipService.hide();
}
}