mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Merge branch 'noctalia-dev:main' into pr/networking-refactor-pt1
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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": "ワークスペースバッジを表示",
|
||||
|
||||
@@ -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": "작업 공간 배지 표시",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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": "Показывать значок рабочего стола",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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": "Показати значок робочого столу",
|
||||
|
||||
@@ -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": "显示工作区徽章",
|
||||
|
||||
@@ -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": "顯示工作區標記",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -215,6 +215,7 @@
|
||||
"hideUnoccupied": false,
|
||||
"characterCount": 2,
|
||||
"showApplications": false,
|
||||
"showApplicationsHover": false,
|
||||
"showLabelsOnlyWhenOccupied": true,
|
||||
"colorizeIcons": false,
|
||||
"unfocusedIconsOpacity": 1,
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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"];
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}`
|
||||
|
||||
@@ -293,6 +293,7 @@ Singleton {
|
||||
"hideUnoccupied": false,
|
||||
"characterCount": 2,
|
||||
"showApplications": false,
|
||||
"showApplicationsHover": false,
|
||||
"showLabelsOnlyWhenOccupied": true,
|
||||
"colorizeIcons": false,
|
||||
"unfocusedIconsOpacity": 1.0,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user