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

This commit is contained in:
Turann_
2026-03-12 13:52:29 +03:00
committed by GitHub
37 changed files with 431 additions and 260 deletions
+2
View File
@@ -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",
+2
View File
@@ -309,6 +309,8 @@
"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-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",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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": "ワークスペースバッジを表示",
+2
View File
@@ -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": "작업 공간 배지 표시",
+2
View File
@@ -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",
+37
View File
@@ -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.<br>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} <b>framifrå</b> medverkaren vår!",
"contributors-description-plural": "Takk og ære til alle dei {count} <b>framifrå</b> 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 <b>{count} framifrå</b> 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",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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": "Показывать значок рабочего стола",
+2
View File
@@ -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",
+2
View File
@@ -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",
+2
View File
@@ -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": "Показати значок робочого столу",
+2
View File
@@ -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": "显示工作区徽章",
+2
View File
@@ -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": "顯示工作區標記",
+12
View File
@@ -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,
+1
View File
@@ -215,6 +215,7 @@
"hideUnoccupied": false,
"characterCount": 2,
"showApplications": false,
"showApplicationsHover": false,
"showLabelsOnlyWhenOccupied": true,
"colorizeIcons": false,
"unfocusedIconsOpacity": 1,
+27
View File
@@ -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") {
+2 -2
View File
@@ -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"];
+94 -25
View File
@@ -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
@@ -106,7 +107,6 @@ Item {
}
property bool isDestroying: false
property bool hovered: false
// Revision counter to force icon re-evaluation
property int iconRevision: 0
@@ -128,8 +128,34 @@ 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: workspaceHoverHandler
enabled: showApplications && showApplicationsHover
onHoveredChanged: {
if (hovered) {
hoverEval.stop();
isHovered = true;
} else {
hoverEval.restart();
}
}
}
Timer {
id: hoverEval
interval: 150
repeat: false
onTriggered: {
isHovered = workspaceHoverHandler.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,23 +284,27 @@ Item {
onScreenChanged: Qt.callLater(refreshWorkspaces)
onScreenNameChanged: Qt.callLater(refreshWorkspaces)
onHideUnoccupiedChanged: Qt.callLater(refreshWorkspaces)
onShowApplicationsChanged: Qt.callLater(refreshWorkspaces)
onAppVisibleChanged: {
if (appVisible) {
Qt.callLater(refreshWorkspaces);
}
}
Connections {
target: CompositorService
function onWorkspacesChanged() {
refreshWorkspaces();
Qt.callLater(refreshWorkspaces);
}
function onWindowListChanged() {
if (showApplications || showLabelsOnlyWhenOccupied) {
if (appVisible || showLabelsOnlyWhenOccupied) {
root.windowRevision++;
refreshWorkspaces();
Qt.callLater(refreshWorkspaces);
}
}
function onActiveWindowChanged() {
if (showApplications) {
if (appVisible) {
root.windowRevision++;
refreshWorkspaces();
Qt.callLater(refreshWorkspaces);
}
}
}
@@ -410,6 +440,15 @@ Item {
NPopupContextMenu {
id: contextMenu
onVisibleChanged: {
if (visible) {
hoverEval.stop();
root.isHovered = true;
} else {
hoverEval.restart();
}
}
model: {
var items = [];
if (root.selectedWindowId) {
@@ -486,7 +525,7 @@ Item {
Rectangle {
id: workspaceBackground
visible: !showApplications
visible: !appVisible
width: isVertical ? capsuleHeight : parent.width
height: isVertical ? parent.height : capsuleHeight
radius: Style.radiusM
@@ -557,7 +596,15 @@ Item {
spacing: spacingBetweenPills
x: horizontalPadding
y: 0
visible: !isVertical && !showApplications
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
@@ -592,7 +639,15 @@ Item {
spacing: spacingBetweenPills
x: 0
y: horizontalPadding
visible: isVertical && !showApplications
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
@@ -622,7 +677,7 @@ Item {
}
// ========================================
// Grouped mode (showApplications = true)
// Grouped mode (appVisible = true)
// ========================================
Component {
id: groupedWorkspaceDelegate
@@ -645,21 +700,26 @@ 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);
}
}
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 : 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 {
@@ -712,16 +772,19 @@ Item {
delegate: Item {
id: groupedTaskbarItem
property bool itemHovered: false
width: root.iconSize
height: root.iconSize
HoverHandler {
id: windowHoverHandler
}
IconImage {
id: groupedAppIcon
width: parent.width
height: parent.height
source: {
root.iconRevision; // Force re-evaluation when revision changes
return ThemeIcons.iconForAppId(modelData.appId?.toLowerCase());
@@ -733,13 +796,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)
}
@@ -773,11 +836,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();
}
}
@@ -906,7 +967,15 @@ Item {
Flow {
id: groupedGrid
visible: showApplications
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)
@@ -915,7 +984,7 @@ Item {
flow: root.isVertical ? Flow.TopToBottom : Flow.LeftToRight
Repeater {
model: showApplications ? localWorkspaces : null
model: appVisible ? localWorkspaces : null
delegate: groupedWorkspaceDelegate
}
}
+1 -18
View File
@@ -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
@@ -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
}
@@ -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
}
@@ -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) : "";
@@ -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")
+4 -159
View File
@@ -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,
@@ -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
@@ -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)
}
}
}
@@ -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
+1 -1
View File
@@ -11,7 +11,7 @@ Singleton {
id: root
// Version properties
readonly property string baseVersion: "4.6.7"
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}`
+1
View File
@@ -293,6 +293,7 @@ Singleton {
"hideUnoccupied": false,
"characterCount": 2,
"showApplications": false,
"showApplicationsHover": false,
"showLabelsOnlyWhenOccupied": true,
"colorizeIcons": false,
"unfocusedIconsOpacity": 1.0,
+158
View File
@@ -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;
}
}
+2
View File
@@ -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 !== ""
}
+2 -1
View File
@@ -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