mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
Merge branch 'main' into main
This commit is contained in:
+2
-1
@@ -1,3 +1,4 @@
|
||||
.qmlls.ini
|
||||
.zed
|
||||
.idea
|
||||
.idea
|
||||
.vscode
|
||||
@@ -1,38 +1,38 @@
|
||||
{
|
||||
"dark": {
|
||||
"mPrimary": "#7aa2f7",
|
||||
"mOnPrimary": "#16161e",
|
||||
"mSecondary": "#bb9af7",
|
||||
"mOnSecondary": "#16161e",
|
||||
"mTertiary": "#9ece6a",
|
||||
"mOnTertiary": "#16161e",
|
||||
"mError": "#f7768e",
|
||||
"mOnError": "#16161e",
|
||||
"mSurface": "#1a1b26",
|
||||
"mOnSurface": "#c0caf5",
|
||||
"mSurfaceVariant": "#24283b",
|
||||
"mOnSurfaceVariant": "#9aa5ce",
|
||||
"mOutline": "#565f89",
|
||||
"mShadow": "#15161e",
|
||||
"mHover": "#9ece6a",
|
||||
"mOnHover": "#16161e"
|
||||
},
|
||||
"light": {
|
||||
"mPrimary": "#2e7de9",
|
||||
"mOnPrimary": "#e1e2e7",
|
||||
"mSecondary": "#9854f1",
|
||||
"mOnSecondary": "#e1e2e7",
|
||||
"mTertiary": "#587539",
|
||||
"mOnTertiary": "#e1e2e7",
|
||||
"mError": "#f52a65",
|
||||
"mOnError": "#e1e2e7",
|
||||
"mSurface": "#e1e2e7",
|
||||
"mOnSurface": "#3760bf",
|
||||
"mSurfaceVariant": "#d0d5e3",
|
||||
"mOnSurfaceVariant": "#6172b0",
|
||||
"mOutline": "#b4b5b9",
|
||||
"mShadow": "#a8aecb",
|
||||
"mHover": "#587539",
|
||||
"mOnHover": "#e1e2e7"
|
||||
}
|
||||
"dark": {
|
||||
"mPrimary": "#7aa2f7",
|
||||
"mOnPrimary": "#16161e",
|
||||
"mSecondary": "#bb9af7",
|
||||
"mOnSecondary": "#16161e",
|
||||
"mTertiary": "#9ece6a",
|
||||
"mOnTertiary": "#16161e",
|
||||
"mError": "#f7768e",
|
||||
"mOnError": "#16161e",
|
||||
"mSurface": "#1a1b26",
|
||||
"mOnSurface": "#c0caf5",
|
||||
"mSurfaceVariant": "#24283b",
|
||||
"mOnSurfaceVariant": "#9aa5ce",
|
||||
"mOutline": "#353D57",
|
||||
"mShadow": "#15161e",
|
||||
"mHover": "#9ece6a",
|
||||
"mOnHover": "#16161e"
|
||||
},
|
||||
"light": {
|
||||
"mPrimary": "#2e7de9",
|
||||
"mOnPrimary": "#e1e2e7",
|
||||
"mSecondary": "#9854f1",
|
||||
"mOnSecondary": "#e1e2e7",
|
||||
"mTertiary": "#587539",
|
||||
"mOnTertiary": "#e1e2e7",
|
||||
"mError": "#f52a65",
|
||||
"mOnError": "#e1e2e7",
|
||||
"mSurface": "#e1e2e7",
|
||||
"mOnSurface": "#3760bf",
|
||||
"mSurfaceVariant": "#d0d5e3",
|
||||
"mOnSurfaceVariant": "#6172b0",
|
||||
"mOutline": "#b4b5b9",
|
||||
"mShadow": "#a8aecb",
|
||||
"mHover": "#587539",
|
||||
"mOnHover": "#e1e2e7"
|
||||
}
|
||||
}
|
||||
|
||||
+504
-1665
File diff suppressed because it is too large
Load Diff
@@ -140,6 +140,13 @@
|
||||
"stream-description": "Geben Sie einen Befehl ein, der kontinuierlich ausgeführt werden soll."
|
||||
},
|
||||
"dynamic-text": "Dynamischer Text",
|
||||
"hide-mode": {
|
||||
"alwaysExpanded": "Immer erweitert",
|
||||
"description": "Steuert die Sichtbarkeit des Widgets, wenn der Befehl keine Ausgabe hat.",
|
||||
"expandWithOutput": "Mit Ausgabe erweitern",
|
||||
"label": "Ausblendmodus",
|
||||
"maxTransparent": "Maximal erweitert aber transparent"
|
||||
},
|
||||
"icon": {
|
||||
"description": "Symbol aus der Bibliothek auswählen.",
|
||||
"label": "Symbol"
|
||||
@@ -175,6 +182,10 @@
|
||||
"label": "Rechtsklick",
|
||||
"update-text": "Text beim Rechtsklick aktualisieren"
|
||||
},
|
||||
"show-icon": {
|
||||
"description": "Schaltet die Sichtbarkeit des Widget-Symbols um.",
|
||||
"label": "Symbol anzeigen"
|
||||
},
|
||||
"text-stream": {
|
||||
"description": "Gestreamte Zeilen aus dem Befehl werden als Text auf der Schaltfläche angezeigt.",
|
||||
"label": "Stream"
|
||||
@@ -343,6 +354,9 @@
|
||||
"description": "Breite der Fenstertitel in der Taskleiste festlegen (in Pixel).",
|
||||
"label": "Titelbreite",
|
||||
"reset-tooltip": "Titelbreite zurücksetzen"
|
||||
"show-pinned-apps": {
|
||||
"description": "Angeheftete Apps aus dem Dock in der Taskleiste anzeigen.",
|
||||
"label": "Angeheftete Apps anzeigen"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
@@ -359,6 +373,10 @@
|
||||
"drawer-enabled": {
|
||||
"description": "Wenn aktiviert, werden nicht angeheftete Tray-Elemente in einem Schubladen-Panel angezeigt. Wenn deaktiviert, werden alle Tray-Elemente inline angezeigt.",
|
||||
"label": "Schublade aktivieren"
|
||||
},
|
||||
"hide-passive": {
|
||||
"description": "Wenn aktiviert, werden Tray-Elemente mit dem Status \"Passiv\" ausgeblendet.",
|
||||
"label": "Passive Gegenstände ausblenden"
|
||||
}
|
||||
},
|
||||
"volume": {
|
||||
@@ -531,11 +549,12 @@
|
||||
"misc": "Verschiedenes",
|
||||
"network": "Netzwerk",
|
||||
"office": "Büro",
|
||||
"pinned": "Angeheftet",
|
||||
"system": "System",
|
||||
"webbrowser": "Webbrowser"
|
||||
},
|
||||
"pin": "An das Dock anheften",
|
||||
"unpin": "Vom Dock lösen"
|
||||
"pin": "Anheften",
|
||||
"unpin": "Lösen"
|
||||
},
|
||||
"lock-screen": {
|
||||
"authenticating": "Authentifizierung...",
|
||||
@@ -736,6 +755,9 @@
|
||||
"clipboard-loading": "Lade Zwischenablageverlauf...",
|
||||
"clipboard-loading-description": "Bitte warten",
|
||||
"clipboard-search-description": "Zwischenablageverlauf durchsuchen",
|
||||
"command": "Befehl",
|
||||
"command-description": "Shell-Befehle ausführen",
|
||||
"command-name": "Befehl",
|
||||
"emoji": "Emoji-Auswahl",
|
||||
"emoji-loading": "Lade Emojis...",
|
||||
"emoji-loading-description": "Bitte warten",
|
||||
@@ -1337,6 +1359,10 @@
|
||||
"description": "Theme-Farben auf Dock-App-Symbole anwenden (nur nicht fokussierte Apps).",
|
||||
"label": "Symbole einfärben"
|
||||
},
|
||||
"dead-opacity": {
|
||||
"description": "Die Deckkraft von App-Symbolen anpassen, die nicht ausgeführt werden.",
|
||||
"label": "Tote Opazität"
|
||||
},
|
||||
"display": {
|
||||
"always-visible": "Immer sichtbar",
|
||||
"auto-hide": "Automatisch ausblenden",
|
||||
@@ -1352,6 +1378,14 @@
|
||||
"description": "Gesamtgröße des Docks anpassen.",
|
||||
"label": "Dock-Größe"
|
||||
},
|
||||
"inactive-indicators": {
|
||||
"description": "Anzeige von Indikator-Pillen für alle Apps, nicht nur für die aktuell aktive.",
|
||||
"label": "Laufende Indikatoren"
|
||||
},
|
||||
"pinned-static": {
|
||||
"description": "Gepinnten App-Symbole immer in statischer Reihenfolge nach links schieben.",
|
||||
"label": "Statische angeheftete Apps"
|
||||
},
|
||||
"section": {
|
||||
"description": "Verhalten und Erscheinungsbild des Docks anpassen.",
|
||||
"label": "Erscheinungsbild"
|
||||
@@ -1513,6 +1547,10 @@
|
||||
"description": "Verhalten und Erscheinungsbild des Starters anpassen.",
|
||||
"label": "Erscheinungsbild"
|
||||
},
|
||||
"show-categories": {
|
||||
"description": "Kategorienregisterkarten zum Filtern von Anwendungen anzeigen.",
|
||||
"label": "Kategorien anzeigen"
|
||||
},
|
||||
"sort-by-usage": {
|
||||
"description": "Wenn aktiviert, erscheinen häufig gestartete Apps zuerst in der Liste.",
|
||||
"label": "Nach Häufigkeit sortieren"
|
||||
|
||||
@@ -140,6 +140,13 @@
|
||||
"stream-description": "Enter a command to run continuously."
|
||||
},
|
||||
"dynamic-text": "Dynamic text",
|
||||
"hide-mode": {
|
||||
"alwaysExpanded": "Always expanded",
|
||||
"description": "Controls widget visibility when the command has no output.",
|
||||
"expandWithOutput": "Expand when has output",
|
||||
"label": "Hide mode",
|
||||
"maxTransparent": "Max expanded but transparent"
|
||||
},
|
||||
"icon": {
|
||||
"description": "Select an icon from the library.",
|
||||
"label": "Icon"
|
||||
@@ -175,6 +182,10 @@
|
||||
"label": "Right click",
|
||||
"update-text": "Update displayed text on right-click"
|
||||
},
|
||||
"show-icon": {
|
||||
"description": "Toggles the visibility of the widget's icon.",
|
||||
"label": "Show icon"
|
||||
},
|
||||
"text-stream": {
|
||||
"description": "Streamed lines from the command will be displayed as text on the button.",
|
||||
"label": "Stream"
|
||||
@@ -343,6 +354,9 @@
|
||||
"description": "Set the width of window titles in the taskbar (in pixels).",
|
||||
"label": "Title width",
|
||||
"reset-tooltip": "Reset title width"
|
||||
"show-pinned-apps": {
|
||||
"description": "Show pinned apps from the dock in the taskbar.",
|
||||
"label": "Show pinned apps"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
@@ -359,6 +373,10 @@
|
||||
"drawer-enabled": {
|
||||
"description": "When enabled, unpinned tray items are shown in a drawer panel. When disabled, all tray items are shown inline.",
|
||||
"label": "Enable drawer"
|
||||
},
|
||||
"hide-passive": {
|
||||
"description": "When enabled, tray items with Passive status will be hidden.",
|
||||
"label": "Hide passive items"
|
||||
}
|
||||
},
|
||||
"volume": {
|
||||
@@ -531,11 +549,12 @@
|
||||
"misc": "Misc",
|
||||
"network": "Network",
|
||||
"office": "Office",
|
||||
"pinned": "Pinned",
|
||||
"system": "System",
|
||||
"webbrowser": "Web Browser"
|
||||
},
|
||||
"pin": "Pin to dock",
|
||||
"unpin": "Unpin from dock"
|
||||
"pin": "Pin",
|
||||
"unpin": "Unpin"
|
||||
},
|
||||
"lock-screen": {
|
||||
"authenticating": "Authenticating...",
|
||||
@@ -736,6 +755,9 @@
|
||||
"clipboard-loading": "Loading clipboard history...",
|
||||
"clipboard-loading-description": "Please wait",
|
||||
"clipboard-search-description": "Search clipboard history",
|
||||
"command": "Command",
|
||||
"command-description": "Run shell commands",
|
||||
"command-name": "Command",
|
||||
"emoji": "Emoji picker",
|
||||
"emoji-loading": "Loading emojis...",
|
||||
"emoji-loading-description": "Please wait",
|
||||
@@ -1337,6 +1359,10 @@
|
||||
"description": "Apply theme colors to dock app icons (non-focused apps only).",
|
||||
"label": "Colorize Icons"
|
||||
},
|
||||
"dead-opacity": {
|
||||
"description": "Adjust the opacity of app icons that are not running.",
|
||||
"label": "Dead Opacity"
|
||||
},
|
||||
"display": {
|
||||
"always-visible": "Always visible",
|
||||
"auto-hide": "Auto hide",
|
||||
@@ -1352,6 +1378,14 @@
|
||||
"description": "Adjust the overall size of the dock.",
|
||||
"label": "Dock size"
|
||||
},
|
||||
"inactive-indicators": {
|
||||
"description": "Display indicatator pills for all apps, not just the currently active one.",
|
||||
"label": "Running Indicators"
|
||||
},
|
||||
"pinned-static": {
|
||||
"description": "Always push pinned app icons to the left in static order.",
|
||||
"label": "Static Pinned Apps"
|
||||
},
|
||||
"section": {
|
||||
"description": "Customize the dock's behavior and appearance.",
|
||||
"label": "Appearance"
|
||||
@@ -1513,6 +1547,10 @@
|
||||
"description": "Customize the launcher's behavior and appearance.",
|
||||
"label": "Appearance"
|
||||
},
|
||||
"show-categories": {
|
||||
"description": "Show category tabs for filtering applications.",
|
||||
"label": "Show categories"
|
||||
},
|
||||
"sort-by-usage": {
|
||||
"description": "When enabled, frequently launched apps appear first in the list.",
|
||||
"label": "Sort by most used"
|
||||
|
||||
@@ -140,6 +140,13 @@
|
||||
"stream-description": "Introduce un comando para ejecutar continuamente."
|
||||
},
|
||||
"dynamic-text": "Texto dinámico",
|
||||
"hide-mode": {
|
||||
"alwaysExpanded": "Siempre expandido",
|
||||
"description": "Controla la visibilidad del widget cuando el comando no tiene salida.",
|
||||
"expandWithOutput": "Expandir cuando tiene salida",
|
||||
"label": "Modo de ocultar",
|
||||
"maxTransparent": "Máximo expandido pero transparente"
|
||||
},
|
||||
"icon": {
|
||||
"description": "Selecciona un icono de la biblioteca.",
|
||||
"label": "Icono"
|
||||
@@ -175,6 +182,10 @@
|
||||
"label": "Clic derecho",
|
||||
"update-text": "Actualizar el texto mostrado al hacer clic derecho"
|
||||
},
|
||||
"show-icon": {
|
||||
"description": "Alterna la visibilidad del icono del widget.",
|
||||
"label": "Mostrar icono"
|
||||
},
|
||||
"text-stream": {
|
||||
"description": "Las líneas transmitidas desde el comando se mostrarán como texto en el botón.",
|
||||
"label": "Transmisión"
|
||||
@@ -343,6 +354,9 @@
|
||||
"description": "Establecer el ancho de los títulos de ventanas en la barra de tareas (en píxeles).",
|
||||
"label": "Ancho del título",
|
||||
"reset-tooltip": "Restablecer ancho del título"
|
||||
"show-pinned-apps": {
|
||||
"description": "Mostrar las aplicaciones ancladas desde el dock en la barra de tareas.",
|
||||
"label": "Mostrar aplicaciones ancladas"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
@@ -359,6 +373,10 @@
|
||||
"drawer-enabled": {
|
||||
"description": "Cuando está habilitado, los elementos de la bandeja no anclados se muestran en un panel cajón. Cuando está deshabilitado, todos los elementos de la bandeja se muestran en línea.",
|
||||
"label": "Habilitar cajón"
|
||||
},
|
||||
"hide-passive": {
|
||||
"description": "Cuando está activado, los elementos de la bandeja con estado Pasivo se ocultarán.",
|
||||
"label": "Ocultar objetos pasivos"
|
||||
}
|
||||
},
|
||||
"volume": {
|
||||
@@ -531,11 +549,12 @@
|
||||
"misc": "Varios",
|
||||
"network": "Red",
|
||||
"office": "Oficina",
|
||||
"pinned": "Anclado",
|
||||
"system": "Sistema",
|
||||
"webbrowser": "Navegador web"
|
||||
},
|
||||
"pin": "Anclar al dock",
|
||||
"unpin": "Desanclar del dock"
|
||||
"pin": "Anclar",
|
||||
"unpin": "Desanclar"
|
||||
},
|
||||
"lock-screen": {
|
||||
"authenticating": "Autenticando...",
|
||||
@@ -736,6 +755,9 @@
|
||||
"clipboard-loading": "Cargando historial del portapapeles...",
|
||||
"clipboard-loading-description": "Por favor espera",
|
||||
"clipboard-search-description": "Buscar en el historial del portapapeles",
|
||||
"command": "Comando",
|
||||
"command-description": "Ejecutar comandos de shell",
|
||||
"command-name": "Comando",
|
||||
"emoji": "Selector de emojis",
|
||||
"emoji-loading": "Cargando emojis...",
|
||||
"emoji-loading-description": "Por favor espera",
|
||||
@@ -1337,6 +1359,10 @@
|
||||
"description": "Aplicar colores del tema a los iconos de aplicaciones del dock (solo aplicaciones no enfocadas).",
|
||||
"label": "Colorear iconos"
|
||||
},
|
||||
"dead-opacity": {
|
||||
"description": "Ajustar la opacidad de los iconos de las aplicaciones que no están en ejecución.",
|
||||
"label": "Opacidad Muerta"
|
||||
},
|
||||
"display": {
|
||||
"always-visible": "Siempre visible",
|
||||
"auto-hide": "Ocultar automáticamente",
|
||||
@@ -1352,6 +1378,14 @@
|
||||
"description": "Ajusta el tamaño general del Dock.",
|
||||
"label": "Tamaño del Dock"
|
||||
},
|
||||
"inactive-indicators": {
|
||||
"description": "Mostrar indicadores en forma de pastillas para todas las aplicaciones, no solo para la que está activa actualmente.",
|
||||
"label": "Indicadores de ejecución"
|
||||
},
|
||||
"pinned-static": {
|
||||
"description": "Siempre empuja los iconos de las aplicaciones ancladas a la izquierda en orden estático.",
|
||||
"label": "Aplicaciones ancladas estáticas"
|
||||
},
|
||||
"section": {
|
||||
"description": "Personaliza el comportamiento y la apariencia del dock.",
|
||||
"label": "Apariencia"
|
||||
@@ -1513,6 +1547,10 @@
|
||||
"description": "Personaliza el comportamiento y la apariencia del lanzador.",
|
||||
"label": "Apariencia"
|
||||
},
|
||||
"show-categories": {
|
||||
"description": "Mostrar pestañas de categorías para filtrar aplicaciones.",
|
||||
"label": "Mostrar categorías"
|
||||
},
|
||||
"sort-by-usage": {
|
||||
"description": "Cuando está activado, las aplicaciones más utilizadas aparecen primero en la lista.",
|
||||
"label": "Ordenar por más usados"
|
||||
|
||||
@@ -140,6 +140,13 @@
|
||||
"stream-description": "Entrez une commande à exécuter en continu."
|
||||
},
|
||||
"dynamic-text": "Texte dynamique",
|
||||
"hide-mode": {
|
||||
"alwaysExpanded": "Toujours étendu",
|
||||
"description": "Contrôle la visibilité du widget quand la commande n'a pas de sortie.",
|
||||
"expandWithOutput": "Étendre quand il y a une sortie",
|
||||
"label": "Mode masqué",
|
||||
"maxTransparent": "Étendu au maximum mais transparent"
|
||||
},
|
||||
"icon": {
|
||||
"description": "Sélectionnez une icône dans la bibliothèque.",
|
||||
"label": "Icône"
|
||||
@@ -175,6 +182,10 @@
|
||||
"label": "Clic droit",
|
||||
"update-text": "Mettre à jour le texte affiché lors d'un clic droit."
|
||||
},
|
||||
"show-icon": {
|
||||
"description": "Bascule la visibilité de l'icône du widget.",
|
||||
"label": "Afficher l'icône"
|
||||
},
|
||||
"text-stream": {
|
||||
"description": "Les lignes diffusées depuis la commande seront affichées sous forme de texte sur le bouton.",
|
||||
"label": "Flux"
|
||||
@@ -343,6 +354,9 @@
|
||||
"description": "Définir la largeur des titres de fenêtres dans la barre des tâches (en pixels).",
|
||||
"label": "Largeur du titre",
|
||||
"reset-tooltip": "Réinitialiser la largeur du titre"
|
||||
"show-pinned-apps": {
|
||||
"description": "Afficher les applications épinglées du dock dans la barre des tâches.",
|
||||
"label": "Afficher les applications épinglées"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
@@ -359,6 +373,10 @@
|
||||
"drawer-enabled": {
|
||||
"description": "Lorsqu'elle est activée, les éléments de la barre système non épinglés sont affichés dans un panneau tiroir. Lorsqu'elle est désactivée, tous les éléments de la barre système sont affichés en ligne.",
|
||||
"label": "Activer le tiroir"
|
||||
},
|
||||
"hide-passive": {
|
||||
"description": "Lorsque cette option est activée, les éléments de la barre d'état système ayant le statut Passif seront masqués.",
|
||||
"label": "Masquer les objets passifs"
|
||||
}
|
||||
},
|
||||
"volume": {
|
||||
@@ -531,11 +549,12 @@
|
||||
"misc": "Divers",
|
||||
"network": "Réseau",
|
||||
"office": "Bureau",
|
||||
"pinned": "Épinglé",
|
||||
"system": "Système",
|
||||
"webbrowser": "Navigateur web"
|
||||
},
|
||||
"pin": "Épingler au dock",
|
||||
"unpin": "Retirer du dock"
|
||||
"pin": "Épingler",
|
||||
"unpin": "Détacher"
|
||||
},
|
||||
"lock-screen": {
|
||||
"authenticating": "Authentification...",
|
||||
@@ -736,6 +755,9 @@
|
||||
"clipboard-loading": "Chargement de l'historique du presse-papiers...",
|
||||
"clipboard-loading-description": "Veuillez patienter",
|
||||
"clipboard-search-description": "Rechercher dans l'historique du presse-papiers",
|
||||
"command": "Commande",
|
||||
"command-description": "Exécuter des commandes shell",
|
||||
"command-name": "Commande",
|
||||
"emoji": "Sélecteur d'émojis",
|
||||
"emoji-loading": "Chargement des émojis...",
|
||||
"emoji-loading-description": "Veuillez patienter",
|
||||
@@ -1337,6 +1359,10 @@
|
||||
"description": "Appliquer les couleurs du thème aux icônes d'applications du dock (applications non focalisées uniquement).",
|
||||
"label": "Coloriser les icônes"
|
||||
},
|
||||
"dead-opacity": {
|
||||
"description": "Ajuster l'opacité des icônes d'applications qui ne sont pas en cours d'exécution.",
|
||||
"label": "Opacité morte"
|
||||
},
|
||||
"display": {
|
||||
"always-visible": "Toujours visible",
|
||||
"auto-hide": "Masquer automatiquement",
|
||||
@@ -1352,6 +1378,14 @@
|
||||
"description": "Ajuster la taille globale du Dock.",
|
||||
"label": "Taille du Dock"
|
||||
},
|
||||
"inactive-indicators": {
|
||||
"description": "Afficher les pastilles d'indicateur pour toutes les applications, pas seulement celle qui est active.",
|
||||
"label": "Indicateurs de fonctionnement"
|
||||
},
|
||||
"pinned-static": {
|
||||
"description": "Toujours pousser les icônes d'applications épinglées vers la gauche dans un ordre statique.",
|
||||
"label": "Applications épinglées statiques"
|
||||
},
|
||||
"section": {
|
||||
"description": "Personnalisez le comportement et l'apparence du dock.",
|
||||
"label": "Apparence"
|
||||
@@ -1513,6 +1547,10 @@
|
||||
"description": "Personnalisez le comportement et l'apparence du lanceur.",
|
||||
"label": "Apparence"
|
||||
},
|
||||
"show-categories": {
|
||||
"description": "Afficher les onglets de catégories pour filtrer les applications.",
|
||||
"label": "Afficher les catégories"
|
||||
},
|
||||
"sort-by-usage": {
|
||||
"description": "Lorsque cette option est activée, les applications fréquemment lancées apparaissent en premier dans la liste.",
|
||||
"label": "Trier par les plus utilisés"
|
||||
|
||||
@@ -140,6 +140,13 @@
|
||||
"stream-description": "継続的に実行するコマンドを入力します。"
|
||||
},
|
||||
"dynamic-text": "動的テキスト",
|
||||
"hide-mode": {
|
||||
"alwaysExpanded": "常に展開",
|
||||
"description": "コマンドが出力を持っていない場合のウィジェットの表示を制御します。",
|
||||
"expandWithOutput": "出力があるときに展開",
|
||||
"label": "非表示モード",
|
||||
"maxTransparent": "最大展開だが透過"
|
||||
},
|
||||
"icon": {
|
||||
"description": "ライブラリからアイコンを選択します。",
|
||||
"label": "アイコン"
|
||||
@@ -175,6 +182,10 @@
|
||||
"label": "右クリック",
|
||||
"update-text": "右クリック時に表示テキストを更新"
|
||||
},
|
||||
"show-icon": {
|
||||
"description": "ウィジェットのアイコンの表示を切り替えます。",
|
||||
"label": "アイコンを表示"
|
||||
},
|
||||
"text-stream": {
|
||||
"description": "コマンドからストリーミングされた行を、ボタン上のテキストとして表示します。",
|
||||
"label": "ストリーム"
|
||||
@@ -343,6 +354,9 @@
|
||||
"description": "タスクバーのウィンドウタイトルの幅を設定します(ピクセル単位)。",
|
||||
"label": "タイトル幅",
|
||||
"reset-tooltip": "タイトル幅をリセット"
|
||||
"show-pinned-apps": {
|
||||
"description": "ドックからピン留めされたアプリをタスクバーに表示する。",
|
||||
"label": "ピン留めされたアプリを表示"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
@@ -359,6 +373,10 @@
|
||||
"drawer-enabled": {
|
||||
"description": "有効にすると、ピン留めされていないトレイ項目をドロワーパネル内に表示します。\n無効にすると、すべての項目をインラインで表示します。",
|
||||
"label": "ドロワーを有効化"
|
||||
},
|
||||
"hide-passive": {
|
||||
"description": "有効にすると、非アクティブなステータスのトレイアイコンは非表示になります。",
|
||||
"label": "受動的なアイテムを隠す"
|
||||
}
|
||||
},
|
||||
"volume": {
|
||||
@@ -531,11 +549,12 @@
|
||||
"misc": "その他",
|
||||
"network": "ネットワーク",
|
||||
"office": "オフィス",
|
||||
"pinned": "ピン留め",
|
||||
"system": "システム",
|
||||
"webbrowser": "ウェブブラウザ"
|
||||
},
|
||||
"pin": "ドックにピン留め",
|
||||
"unpin": "ドックからピン留めを解除"
|
||||
"pin": "ピン留め",
|
||||
"unpin": "ピン留め解除"
|
||||
},
|
||||
"lock-screen": {
|
||||
"authenticating": "認証中...",
|
||||
@@ -736,6 +755,9 @@
|
||||
"clipboard-loading": "クリップボード履歴を読み込み中...",
|
||||
"clipboard-loading-description": "お待ちください",
|
||||
"clipboard-search-description": "クリップボード履歴を検索",
|
||||
"command": "コマンド",
|
||||
"command-description": "シェルコマンドを実行する",
|
||||
"command-name": "コマンド",
|
||||
"emoji": "絵文字選択",
|
||||
"emoji-loading": "絵文字を読み込み中...",
|
||||
"emoji-loading-description": "お待ちください",
|
||||
@@ -1337,6 +1359,10 @@
|
||||
"description": "ドックのアプリアイコンにテーマカラーを適用します(非フォーカス時のみ)。",
|
||||
"label": "テーマカラーの適用"
|
||||
},
|
||||
"dead-opacity": {
|
||||
"description": "実行されていないアプリのアイコンの不透明度を調整します。",
|
||||
"label": "死んだ不透明度"
|
||||
},
|
||||
"display": {
|
||||
"always-visible": "常に表示",
|
||||
"auto-hide": "自動的に隠す",
|
||||
@@ -1352,6 +1378,14 @@
|
||||
"description": "ドック全体のサイズを調整します。",
|
||||
"label": "ドックのサイズ"
|
||||
},
|
||||
"inactive-indicators": {
|
||||
"description": "現在アクティブなアプリだけでなく、すべてのアプリのインジケーターピルを表示する。",
|
||||
"label": "実行指標"
|
||||
},
|
||||
"pinned-static": {
|
||||
"description": "ピン留めされたアプリのアイコンは、常に静的な順序で左に寄せてください。",
|
||||
"label": "固定された静的アプリ"
|
||||
},
|
||||
"section": {
|
||||
"description": "ドックの動作と外観をカスタマイズします。",
|
||||
"label": "外観"
|
||||
@@ -1513,6 +1547,10 @@
|
||||
"description": "ランチャーの挙動と外観をカスタマイズします。",
|
||||
"label": "外観"
|
||||
},
|
||||
"show-categories": {
|
||||
"description": "アプリケーションをフィルタリングするためのカテゴリタブを表示します。",
|
||||
"label": "カテゴリを表示"
|
||||
},
|
||||
"sort-by-usage": {
|
||||
"description": "有効にすると、よく使うアプリがリストの上位に表示されます。",
|
||||
"label": "使用頻度順に並べ替え"
|
||||
|
||||
@@ -140,6 +140,13 @@
|
||||
"stream-description": "Voer een commando in dat continu wordt uitgevoerd."
|
||||
},
|
||||
"dynamic-text": "Dynamische tekst",
|
||||
"hide-mode": {
|
||||
"alwaysExpanded": "Altijd uitgeklapt",
|
||||
"description": "Bepaalt de zichtbaarheid van de widget wanneer het commando geen uitvoer heeft.",
|
||||
"expandWithOutput": "Uitklappen wanneer er uitvoer is",
|
||||
"label": "Verbergmodus",
|
||||
"maxTransparent": "Maximaal uitgeklapt maar transparant"
|
||||
},
|
||||
"icon": {
|
||||
"description": "Selecteer een pictogram uit de bibliotheek.",
|
||||
"label": "Pictogram"
|
||||
@@ -175,6 +182,10 @@
|
||||
"label": "Rechtermuisklik",
|
||||
"update-text": "Tekst bijwerken die wordt weergegeven bij rechtsklikken"
|
||||
},
|
||||
"show-icon": {
|
||||
"description": "Schakelt de zichtbaarheid van het widgetpictogram.",
|
||||
"label": "Pictogram weergeven"
|
||||
},
|
||||
"text-stream": {
|
||||
"description": "Gestreamde regels uit het commando worden als tekst op de knop weergegeven.",
|
||||
"label": "Stream"
|
||||
@@ -343,6 +354,9 @@
|
||||
"description": "Stel de breedte van venstertitels in de taakbalk in (in pixels).",
|
||||
"label": "Titelbreedte",
|
||||
"reset-tooltip": "Titelbreedte resetten"
|
||||
"show-pinned-apps": {
|
||||
"description": "Toon vastgemaakte apps van het dock in de taakbalk.",
|
||||
"label": "Toon vastgemaakte apps"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
@@ -359,6 +373,10 @@
|
||||
"drawer-enabled": {
|
||||
"description": "Indien ingeschakeld worden niet-vastgemaakte systeemvakitems in een lade weergegeven. Indien uitgeschakeld worden alle items inline getoond.",
|
||||
"label": "Lade inschakelen"
|
||||
},
|
||||
"hide-passive": {
|
||||
"description": "Indien ingeschakeld, worden tray-items met de status Passief verborgen.",
|
||||
"label": "Verberg passieve items"
|
||||
}
|
||||
},
|
||||
"volume": {
|
||||
@@ -531,11 +549,12 @@
|
||||
"misc": "Diversen",
|
||||
"network": "Netwerk",
|
||||
"office": "Kantoor",
|
||||
"pinned": "Vastgemaakt",
|
||||
"system": "Systeem",
|
||||
"webbrowser": "Webbrowser"
|
||||
},
|
||||
"pin": "Aan dock vastmaken",
|
||||
"unpin": "Van dock losmaken"
|
||||
"pin": "Vastmaken",
|
||||
"unpin": "Losmaken"
|
||||
},
|
||||
"lock-screen": {
|
||||
"authenticating": "Bezig met verifiëren...",
|
||||
@@ -736,6 +755,9 @@
|
||||
"clipboard-loading": "Klembordgeschiedenis laden...",
|
||||
"clipboard-loading-description": "Even geduld",
|
||||
"clipboard-search-description": "Zoek in klembordgeschiedenis",
|
||||
"command": "Commando",
|
||||
"command-description": "Shell-opdrachten uitvoeren",
|
||||
"command-name": "Commando",
|
||||
"emoji": "Emoji-kiezer",
|
||||
"emoji-loading": "Emoji's laden...",
|
||||
"emoji-loading-description": "Even geduld",
|
||||
@@ -1337,6 +1359,10 @@
|
||||
"description": "Pas themakleuren toe op dock-pictogrammen (alleen niet-focuste apps).",
|
||||
"label": "Pictogrammen inkleuren"
|
||||
},
|
||||
"dead-opacity": {
|
||||
"description": "Pas de transparantie aan van app-iconen die niet actief zijn.",
|
||||
"label": "Dode opaciteit"
|
||||
},
|
||||
"display": {
|
||||
"always-visible": "Altijd zichtbaar",
|
||||
"auto-hide": "Automatisch verbergen",
|
||||
@@ -1352,6 +1378,14 @@
|
||||
"description": "Pas de algehele grootte van de dock aan.",
|
||||
"label": "Grootte van de dock"
|
||||
},
|
||||
"inactive-indicators": {
|
||||
"description": "Toon indicatorpillen voor alle apps, niet alleen de actieve.",
|
||||
"label": "Lopende indicatoren"
|
||||
},
|
||||
"pinned-static": {
|
||||
"description": "Zet vastgemaakte app-pictogrammen altijd in statische volgorde aan de linkerkant.",
|
||||
"label": "Statische vastgezette apps"
|
||||
},
|
||||
"section": {
|
||||
"description": "Pas het gedrag en uiterlijk van de dock aan.",
|
||||
"label": "Uiterlijk"
|
||||
@@ -1513,6 +1547,10 @@
|
||||
"description": "Pas het gedrag en uiterlijk van de launcher aan.",
|
||||
"label": "Uiterlijk"
|
||||
},
|
||||
"show-categories": {
|
||||
"description": "Categorieën-tabbladen weergeven voor het filteren van applicaties.",
|
||||
"label": "Categorieën weergeven"
|
||||
},
|
||||
"sort-by-usage": {
|
||||
"description": "Indien ingeschakeld, verschijnen vaak gestarte apps bovenaan in de lijst.",
|
||||
"label": "Sorteren op meest gebruikt"
|
||||
|
||||
@@ -140,6 +140,13 @@
|
||||
"stream-description": "Insira um comando para executar continuamente."
|
||||
},
|
||||
"dynamic-text": "Texto dinâmico",
|
||||
"hide-mode": {
|
||||
"alwaysExpanded": "Sempre expandido",
|
||||
"description": "Controla a visibilidade do widget quando o comando não tem saída.",
|
||||
"expandWithOutput": "Expandir quando tem saída",
|
||||
"label": "Modo de ocultação",
|
||||
"maxTransparent": "Totalmente expandido mas transparente"
|
||||
},
|
||||
"icon": {
|
||||
"description": "Selecione um ícone da biblioteca.",
|
||||
"label": "Ícone"
|
||||
@@ -175,6 +182,10 @@
|
||||
"label": "Clique direito",
|
||||
"update-text": "Atualizar o texto exibido ao clicar com o botão direito."
|
||||
},
|
||||
"show-icon": {
|
||||
"description": "Alterna a visibilidade do ícone do widget.",
|
||||
"label": "Mostrar ícone"
|
||||
},
|
||||
"text-stream": {
|
||||
"description": "As linhas transmitidas do comando serão exibidas como texto no botão.",
|
||||
"label": "Transmissão"
|
||||
@@ -343,6 +354,9 @@
|
||||
"description": "Definir a largura dos títulos de janelas na barra de tarefas (em pixels).",
|
||||
"label": "Largura do título",
|
||||
"reset-tooltip": "Redefinir largura do título"
|
||||
"show-pinned-apps": {
|
||||
"description": "Mostrar aplicativos fixados do Dock na barra de tarefas.",
|
||||
"label": "Mostrar aplicativos fixados"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
@@ -359,6 +373,10 @@
|
||||
"drawer-enabled": {
|
||||
"description": "Quando habilitado, os itens da bandeja não fixados são exibidos em um painel gaveta. Quando desabilitado, todos os itens da bandeja são exibidos inline.",
|
||||
"label": "Habilitar gaveta"
|
||||
},
|
||||
"hide-passive": {
|
||||
"description": "Quando ativado, os itens da bandeja com status Passivo serão ocultados.",
|
||||
"label": "Ocultar itens passivos"
|
||||
}
|
||||
},
|
||||
"volume": {
|
||||
@@ -531,11 +549,12 @@
|
||||
"misc": "Diversos",
|
||||
"network": "Rede",
|
||||
"office": "Escritório",
|
||||
"pinned": "Fixado",
|
||||
"system": "Sistema",
|
||||
"webbrowser": "Navegador web"
|
||||
},
|
||||
"pin": "Fixar no dock",
|
||||
"unpin": "Desafixar do dock"
|
||||
"pin": "Fixar",
|
||||
"unpin": "Desafixar"
|
||||
},
|
||||
"lock-screen": {
|
||||
"authenticating": "Autenticando...",
|
||||
@@ -736,6 +755,9 @@
|
||||
"clipboard-loading": "Carregando histórico da área de transferência...",
|
||||
"clipboard-loading-description": "Por favor, aguarde",
|
||||
"clipboard-search-description": "Pesquisar no histórico da área de transferência",
|
||||
"command": "Comando",
|
||||
"command-description": "Executar comandos shell",
|
||||
"command-name": "Comando",
|
||||
"emoji": "Seletor de emojis",
|
||||
"emoji-loading": "Carregando emojis...",
|
||||
"emoji-loading-description": "Por favor, aguarde",
|
||||
@@ -1337,6 +1359,10 @@
|
||||
"description": "Aplicar cores do tema aos ícones de aplicativos da dock (apenas aplicativos não focados).",
|
||||
"label": "Colorir ícones"
|
||||
},
|
||||
"dead-opacity": {
|
||||
"description": "Ajustar a opacidade dos ícones de aplicativos que não estão em execução.",
|
||||
"label": "Opacidade Morta"
|
||||
},
|
||||
"display": {
|
||||
"always-visible": "Sempre visível",
|
||||
"auto-hide": "Ocultar automaticamente",
|
||||
@@ -1352,6 +1378,14 @@
|
||||
"description": "Ajustar o tamanho geral do Dock.",
|
||||
"label": "Tamanho do Dock"
|
||||
},
|
||||
"inactive-indicators": {
|
||||
"description": "Exibir indicadores de pílula para todos os aplicativos, não apenas para o aplicativo ativo no momento.",
|
||||
"label": "Indicadores de execução"
|
||||
},
|
||||
"pinned-static": {
|
||||
"description": "Sempre posicione os ícones de aplicativos fixados à esquerda em ordem estática.",
|
||||
"label": "Aplicativos Fixados Estaticamente"
|
||||
},
|
||||
"section": {
|
||||
"description": "Personalize o comportamento e a aparência da dock.",
|
||||
"label": "Aparência"
|
||||
@@ -1513,6 +1547,10 @@
|
||||
"description": "Personalize o comportamento e a aparência do lançador.",
|
||||
"label": "Aparência"
|
||||
},
|
||||
"show-categories": {
|
||||
"description": "Mostrar abas de categorias para filtrar aplicativos.",
|
||||
"label": "Mostrar categorias"
|
||||
},
|
||||
"sort-by-usage": {
|
||||
"description": "Quando ativado, os aplicativos mais usados aparecem primeiro na lista.",
|
||||
"label": "Ordenar por mais usados"
|
||||
|
||||
@@ -140,6 +140,13 @@
|
||||
"stream-description": "Введите команду для непрерывного выполнения."
|
||||
},
|
||||
"dynamic-text": "Динамический текст",
|
||||
"hide-mode": {
|
||||
"alwaysExpanded": "Всегда раскрыт",
|
||||
"description": "Управляет видимостью виджета, когда команда не имеет вывода.",
|
||||
"expandWithOutput": "Раскрывать при наличии вывода",
|
||||
"label": "Режим скрытия",
|
||||
"maxTransparent": "Максимально раскрыт, но прозрачный"
|
||||
},
|
||||
"icon": {
|
||||
"description": "Выберите иконку из библиотеки.",
|
||||
"label": "Иконка"
|
||||
@@ -175,6 +182,10 @@
|
||||
"label": "Клик правой кнопкой",
|
||||
"update-text": "Обновить отображаемый текст по правому клику"
|
||||
},
|
||||
"show-icon": {
|
||||
"description": "Переключает видимость иконки виджета.",
|
||||
"label": "Показать иконку"
|
||||
},
|
||||
"text-stream": {
|
||||
"description": "Потоковые строки из команды будут отображаться как текст на кнопке.",
|
||||
"label": "Поток"
|
||||
@@ -343,6 +354,9 @@
|
||||
"description": "Установить ширину заголовков окон на панели задач (в пикселях).",
|
||||
"label": "Ширина заголовка",
|
||||
"reset-tooltip": "Сбросить ширину заголовка"
|
||||
"show-pinned-apps": {
|
||||
"description": "Показывать закреплённые приложения из Dock на панели задач.",
|
||||
"label": "Показать закреплённые приложения"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
@@ -359,6 +373,10 @@
|
||||
"drawer-enabled": {
|
||||
"description": "Если включено, незакрепленные элементы трея отображаются во всплывающей панели. Если отключено, все элементы трея отображаются в строку.",
|
||||
"label": "Включить всплывающую панель"
|
||||
},
|
||||
"hide-passive": {
|
||||
"description": "Если включено, элементы в трее со статусом \"Пассивный\" будут скрыты.",
|
||||
"label": "Скрыть пассивные предметы"
|
||||
}
|
||||
},
|
||||
"volume": {
|
||||
@@ -531,11 +549,12 @@
|
||||
"misc": "Разное",
|
||||
"network": "Сеть",
|
||||
"office": "Офис",
|
||||
"pinned": "Закреплено",
|
||||
"system": "Система",
|
||||
"webbrowser": "Веб-браузер"
|
||||
},
|
||||
"pin": "Закрепить на панели",
|
||||
"unpin": "Открепить от панели"
|
||||
"pin": "Закрепить",
|
||||
"unpin": "Открепить"
|
||||
},
|
||||
"lock-screen": {
|
||||
"authenticating": "Аутентификация...",
|
||||
@@ -736,6 +755,9 @@
|
||||
"clipboard-loading": "Загрузка истории буфера обмена...",
|
||||
"clipboard-loading-description": "Пожалуйста, подождите",
|
||||
"clipboard-search-description": "Поиск в истории буфера обмена",
|
||||
"command": "Команда",
|
||||
"command-description": "Выполнять команды оболочки",
|
||||
"command-name": "Команда",
|
||||
"emoji": "Выбор эмодзи",
|
||||
"emoji-loading": "Загрузка эмодзи...",
|
||||
"emoji-loading-description": "Пожалуйста, подождите",
|
||||
@@ -1337,6 +1359,10 @@
|
||||
"description": "Применить цвета темы к иконкам приложений на панели (только для нефокусированных приложений).",
|
||||
"label": "Раскрасить иконки"
|
||||
},
|
||||
"dead-opacity": {
|
||||
"description": "Настройте прозрачность значков неактивных приложений.",
|
||||
"label": "Мёртвая непрозрачность"
|
||||
},
|
||||
"display": {
|
||||
"always-visible": "Всегда видимая",
|
||||
"auto-hide": "Автоматически скрывать",
|
||||
@@ -1352,6 +1378,14 @@
|
||||
"description": "Настройка общего размера панели приложений.",
|
||||
"label": "Размер панели"
|
||||
},
|
||||
"inactive-indicators": {
|
||||
"description": "Отображать индикаторы для всех приложений, а не только для активного.",
|
||||
"label": "Бегущие индикаторы"
|
||||
},
|
||||
"pinned-static": {
|
||||
"description": "Всегда перемещайте закреплённые значки приложений влево в статичном порядке.",
|
||||
"label": "Закреплённые статические приложения"
|
||||
},
|
||||
"section": {
|
||||
"description": "Настройка поведения и внешнего вида панели приложений.",
|
||||
"label": "Внешний вид"
|
||||
@@ -1513,6 +1547,10 @@
|
||||
"description": "Настройка поведения и внешнего вида запуска.",
|
||||
"label": "Внешний вид"
|
||||
},
|
||||
"show-categories": {
|
||||
"description": "Показывать вкладки категорий для фильтрации приложений.",
|
||||
"label": "Показывать категории"
|
||||
},
|
||||
"sort-by-usage": {
|
||||
"description": "Если включено, часто запускаемые приложения появляются в списке первыми.",
|
||||
"label": "Сортировать по частоте использования"
|
||||
|
||||
+185
-147
@@ -7,27 +7,27 @@
|
||||
"widget-settings": {
|
||||
"active-window": {
|
||||
"colorize-icons": {
|
||||
"description": "Aktif pencere ikonuna tema renklerini uygula.",
|
||||
"label": "İkonları Renklendir"
|
||||
"description": "Aktif pencere simgelerine tema renklerini uygula.",
|
||||
"label": "Simgeleri Renklendir"
|
||||
},
|
||||
"hide-mode": {
|
||||
"description": "Pencere aktif değilken widget'in nasıl davrandığını kontrol eder.",
|
||||
"description": "Pencere aktif değilken araç takımlarının nasıl davrandığını kontrol eder.",
|
||||
"label": "Gizleme modu"
|
||||
},
|
||||
"max-width": {
|
||||
"description": "Widget'in maksimum yatay boyutunu ayarlar. Widget daha kısa içerik için küçülecektir.",
|
||||
"label": "Maksimum Genişlik"
|
||||
"description": "Araç takımının en fazla yatay boyutunu ayarlar. Araç takımı daha kısa içerik için küçülecektir.",
|
||||
"label": "En Fazla Genişlik"
|
||||
},
|
||||
"scrolling-mode": {
|
||||
"description": "Uzun pencere başlıkları için metin kaydırmanın ne zaman etkinleştirileceğini kontrol et.",
|
||||
"label": "Kaydırma modu"
|
||||
},
|
||||
"show-app-icon": {
|
||||
"description": "Pencere başlığı yanında uygulama ikonunu göster.",
|
||||
"label": "Uygulama ikonunu göster"
|
||||
"description": "Pencere başlığı yanında uygulama simgesini göster.",
|
||||
"label": "Uygulama simgesini göster"
|
||||
},
|
||||
"use-fixed-width": {
|
||||
"description": "Etkinleştirildiğinde, widget dinamik olarak içeriğe göre ayarlamak yerine her zaman maksimum genişliği kullanır.",
|
||||
"description": "Etkinleştirildiğinde, araç takımı hareketli olarak içeriğe göre ayarlanmak yerine her zaman en fazla genişliği kullanır.",
|
||||
"label": "Sabit Genişlik Kullan"
|
||||
}
|
||||
},
|
||||
@@ -119,19 +119,19 @@
|
||||
"label": "Renklendirmeyi Etkinleştir"
|
||||
},
|
||||
"icon": {
|
||||
"description": "Kütüphaneden veya özel bir dosyadan bir ikon seçin.",
|
||||
"label": "İkon"
|
||||
"description": "Kütüphaneden veya özel bir dosyadan bir simge seçin.",
|
||||
"label": "Simge"
|
||||
},
|
||||
"select-custom-icon": "Özel bir ikon seç",
|
||||
"select-custom-icon": "Özel bir simge seç",
|
||||
"use-distro-logo": {
|
||||
"description": "Özel ikon yerine dağıtımınızın logosunu kullanın.",
|
||||
"label": "Dağıtım logosunu ikon yerine kullan"
|
||||
"description": "Özel simge yerine dağıtımınızın logosunu kullanın.",
|
||||
"label": "Dağıtım logosunu simge yerine kullan"
|
||||
}
|
||||
},
|
||||
"custom-button": {
|
||||
"browse": "Göz At",
|
||||
"collapse-condition": {
|
||||
"description": "Çıktı metni bu değerle eşleşirse buton daralacak.",
|
||||
"description": "Çıktı metni bu değerle eşleşirse düğme daralacak.",
|
||||
"label": "Daralma durumu"
|
||||
},
|
||||
"display-command-output": {
|
||||
@@ -139,31 +139,38 @@
|
||||
"label": "Komut Çıktısını Göster",
|
||||
"stream-description": "Sürekli çalıştırılacak bir komut girin."
|
||||
},
|
||||
"dynamic-text": "Dinamik metin",
|
||||
"dynamic-text": "Hareketli metin",
|
||||
"hide-mode": {
|
||||
"alwaysExpanded": "Her zaman geniş",
|
||||
"description": "Komutun çıktı vermemesi durumunda gerecin görünürlüğünü kontrol eder.",
|
||||
"expandWithOutput": "Çıktı olduğunda genişlet",
|
||||
"label": "Gizleme modu",
|
||||
"maxTransparent": "En büyük genişlik ama saydam"
|
||||
},
|
||||
"icon": {
|
||||
"description": "Kütüphaneden bir ikon seçin.",
|
||||
"label": "İkon"
|
||||
"description": "Kütüphaneden bir simge seçin.",
|
||||
"label": "Simge"
|
||||
},
|
||||
"left-click": {
|
||||
"description": "Butona sol tıklandığında yürütülecek komut.",
|
||||
"description": "Düğmeye sol tıklandığında yürütülecek komut.",
|
||||
"label": "Sol tıklama",
|
||||
"update-text": "Sol tıklamayla görüntülenen metni güncelle"
|
||||
},
|
||||
"max-text-length-horizontal": {
|
||||
"description": "Yatay çubukta gösterilecek maksimum karakter sayısı (metni gizlemek için 0)",
|
||||
"label": "Maks. metin uzunluğu (yatay)"
|
||||
"description": "Yatay çubukta gösterilecek en fazla karakter sayısı (metni gizlemek için 0)",
|
||||
"label": "En uzun metin uzunluğu (yatay)"
|
||||
},
|
||||
"max-text-length-vertical": {
|
||||
"description": "Dikey çubukta gösterilecek maksimum karakter sayısı (metni gizlemek için 0)",
|
||||
"label": "Maks. metin uzunluğu (dikey)"
|
||||
"description": "Dikey çubukta gösterilecek en fazla karakter sayısı (metni gizlemek için 0)",
|
||||
"label": "En uzun metin uzunluğu (dikey)"
|
||||
},
|
||||
"middle-click": {
|
||||
"description": "Butona orta tıklandığında yürütülecek komut.",
|
||||
"description": "Orta düğmeye tıklandığında yürütülecek komut.",
|
||||
"label": "Orta tıklama",
|
||||
"update-text": "Orta tıklamayla görüntülenen metni güncelle"
|
||||
},
|
||||
"parse-json": {
|
||||
"description": "Komut çıktısını metin ve ikon dinamik olarak ayarlamak için bir JSON nesnesi olarak ayrıştırın.",
|
||||
"description": "Komut çıktısını hareketli metin ve simge olarak ayarlamak için bir JSON nesnesi olarak ayrıştırın.",
|
||||
"label": "Çıktıyı JSON olarak ayrıştır"
|
||||
},
|
||||
"refresh-interval": {
|
||||
@@ -171,12 +178,16 @@
|
||||
"label": "Yenileme aralığı"
|
||||
},
|
||||
"right-click": {
|
||||
"description": "Butona sağ tıklandığında yürütülecek komut.",
|
||||
"description": "Sağ düğmeye tıklandığında yürütülecek komut.",
|
||||
"label": "Sağ tıklama",
|
||||
"update-text": "Sağ tıklamada görüntülenen metni güncelle"
|
||||
},
|
||||
"show-icon": {
|
||||
"description": "Takım aracının simgesinin görünürlüğünü değiştirir.",
|
||||
"label": "Simgeyi göster"
|
||||
},
|
||||
"text-stream": {
|
||||
"description": "Komuttan gelen akış satırları butonda metin olarak gösterilecektir.",
|
||||
"description": "Komuttan gelen akış satırları düğmede metin olarak gösterilecektir.",
|
||||
"label": "Akış"
|
||||
},
|
||||
"wheel": {
|
||||
@@ -210,26 +221,26 @@
|
||||
"lock-keys": {
|
||||
"browse": "Göz at",
|
||||
"show-caps-lock": {
|
||||
"description": "Caps Lock durumunu göster.",
|
||||
"label": "Caps Lock"
|
||||
"description": "Büyük Harf Kilidi düğmesi durumunu göster.",
|
||||
"label": "Büyük Harf Kilidi"
|
||||
},
|
||||
"show-num-lock": {
|
||||
"description": "Num Lock durumunu göster.",
|
||||
"label": "Num Lock"
|
||||
"description": "Sayı Kilidi durumunu göster.",
|
||||
"label": "Sayı Kilidi"
|
||||
},
|
||||
"show-scroll-lock": {
|
||||
"description": "Scroll Lock durumunu göster.",
|
||||
"label": "Scroll Lock"
|
||||
"description": "Kaydırma Kilidi durumunu göster.",
|
||||
"label": "Kaydırma Kilidi"
|
||||
}
|
||||
},
|
||||
"media-mini": {
|
||||
"hide-mode": {
|
||||
"description": "Medya çalınmadığında widget'in nasıl davrandığını kontrol eder.",
|
||||
"description": "Ortam çalınmadığında araç takımının nasıl davrandığını kontrol eder.",
|
||||
"label": "Gizleme modu"
|
||||
},
|
||||
"max-width": {
|
||||
"description": "Widget'in maksimum yatay boyutunu ayarlar. Widget daha kısa içerik için küçülecektir.",
|
||||
"label": "Maksimum Genişlik"
|
||||
"description": "Araç takımının en fazla yatay boyutunu ayarlar. Araç takımı daha kısa içerik için küçülecektir.",
|
||||
"label": "En Fazla Genişlik"
|
||||
},
|
||||
"no-active-player": "Etkin çalar yok",
|
||||
"scrolling-mode": {
|
||||
@@ -237,7 +248,7 @@
|
||||
"label": "Kaydırma modu"
|
||||
},
|
||||
"show-album-art": {
|
||||
"description": "Şu anda çalan parçanın albüm kapak sanatını göster.",
|
||||
"description": "Şu anda çalan parçanın albüm kapağını göster.",
|
||||
"label": "Albüm kapağını göster"
|
||||
},
|
||||
"show-artist-first": {
|
||||
@@ -253,11 +264,11 @@
|
||||
"label": "Görselleştiriciyi göster"
|
||||
},
|
||||
"use-fixed-width": {
|
||||
"description": "Etkinleştirildiğinde, widget dinamik olarak içerik göre ayarlamak yerine her zaman maksimum genişliği kullanır.",
|
||||
"description": "Etkinleştirildiğinde, araç takımını hareketli olarak içeriğe göre ayarlamak yerine her zaman en fazla genişliği kullanır.",
|
||||
"label": "Sabit Genişlik Kullan"
|
||||
},
|
||||
"visualizer-type": {
|
||||
"description": "Gösterilecek ses görselleştirici stilini seçin.",
|
||||
"description": "Gösterilecek ses görselleştirici biçemini seçin.",
|
||||
"label": "Görselleştirici türü"
|
||||
}
|
||||
},
|
||||
@@ -278,8 +289,8 @@
|
||||
}
|
||||
},
|
||||
"section-editor": {
|
||||
"placeholder": "Eklenecek bir widget seçin...",
|
||||
"search-placeholder": "Widget ara..."
|
||||
"placeholder": "Eklenecek bir araç takımı seçin...",
|
||||
"search-placeholder": "Araç takımı ara..."
|
||||
},
|
||||
"spacer": {
|
||||
"width": {
|
||||
@@ -289,12 +300,12 @@
|
||||
},
|
||||
"system-monitor": {
|
||||
"cpu-temperature": {
|
||||
"description": "Mevcut CPU sıcaklık okumalarını gösterir.",
|
||||
"label": "CPU sıcaklığı"
|
||||
"description": "Mevcut işlemci sıcaklık okumalarını gösterir.",
|
||||
"label": "İşlemci sıcaklığı"
|
||||
},
|
||||
"cpu-usage": {
|
||||
"description": "Mevcut CPU kullanım yüzdesini göster.",
|
||||
"label": "CPU kullanımı"
|
||||
"description": "Mevcut işlemci kullanım yüzdesini göster.",
|
||||
"label": "İşlemci kullanımı"
|
||||
},
|
||||
"disk-path": {
|
||||
"description": "İzlenecek disk bağlama noktasını seçin.",
|
||||
@@ -305,7 +316,7 @@
|
||||
"label": "Bellek yüzde olarak"
|
||||
},
|
||||
"memory-usage": {
|
||||
"description": "Mevcut RAM kullanım bilgilerini göster.",
|
||||
"description": "Mevcut bellek kullanım bilgilerini göster.",
|
||||
"label": "Bellek kullanımı"
|
||||
},
|
||||
"network-traffic": {
|
||||
@@ -319,11 +330,11 @@
|
||||
},
|
||||
"taskbar": {
|
||||
"colorize-icons": {
|
||||
"description": "Görev çubuğu ikonlarına tema renklerini uygula.",
|
||||
"label": "İkonları Renklendir"
|
||||
"description": "Görev çubuğu simgelerine tema renklerini uygula.",
|
||||
"label": "Simgeleri Renklendir"
|
||||
},
|
||||
"hide-mode": {
|
||||
"description": "Eşleşen pencere olmadığında widget'in nasıl davrandığını kontrol eder.",
|
||||
"description": "Eşleşen pencere olmadığında araç takımının nasıl davrandığını kontrol eder.",
|
||||
"label": "Gizleme modu"
|
||||
},
|
||||
"only-active-workspaces": {
|
||||
@@ -343,6 +354,9 @@
|
||||
"description": "Görev çubuğundaki pencere başlıklarının genişliğini ayarla (piksel olarak).",
|
||||
"label": "Başlık genişliği",
|
||||
"reset-tooltip": "Başlık genişliğini sıfırla"
|
||||
"show-pinned-apps": {
|
||||
"description": "Dock'taki sabitlenmiş uygulamaları görev çubuğunda göster.",
|
||||
"label": "Sabitlenmiş uygulamaları göster"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
@@ -353,12 +367,16 @@
|
||||
},
|
||||
"tray": {
|
||||
"colorize-icons": {
|
||||
"description": "Tepsi ikonlarına tema renklerini uygula.",
|
||||
"label": "İkonları Renklendir"
|
||||
"description": "Tepsi simgelerine tema renklerini uygula.",
|
||||
"label": "Simgeleri Renklendir"
|
||||
},
|
||||
"drawer-enabled": {
|
||||
"description": "Etkinleştirildiğinde, sabitlenmemiş tepsi öğeleri bir çekmece panelinde gösterilir. Devre dışı bırakıldığında, tüm tepsi öğeleri satır içi gösterilir.",
|
||||
"label": "Çekmeceyi Etkinleştir"
|
||||
},
|
||||
"hide-passive": {
|
||||
"description": "Etkinleştirildiğinde, Pasif durumdaki tepsi öğeleri gizlenir.",
|
||||
"label": "Pasif öğeleri gizle"
|
||||
}
|
||||
},
|
||||
"volume": {
|
||||
@@ -429,8 +447,8 @@
|
||||
"timer": {
|
||||
"countdown": "Geri sayım",
|
||||
"duration": "Süre",
|
||||
"hours": "h",
|
||||
"minutes": "m",
|
||||
"hours": "S",
|
||||
"minutes": "d",
|
||||
"pause": "Duraklat",
|
||||
"reset": "Sıfırla",
|
||||
"seconds": "s",
|
||||
@@ -488,23 +506,23 @@
|
||||
"cycle-visualizer": "Döngü görselleştirici",
|
||||
"disable-bluetooth": "Bluetooth'u kapat",
|
||||
"disable-dnd": "Rahatsız Etmeyin'i Kapat",
|
||||
"disable-wifi": "Wi-Fi'ı kapat",
|
||||
"disable-wifi": "Kablosuz Bağlantıyı kapat",
|
||||
"disconnect-vpn": "{name} bağlantısını kes",
|
||||
"enable-bluetooth": "Bluetooth'u etkinleştir",
|
||||
"enable-dnd": "Rahatsız Etmeyin'i Etkinleştir",
|
||||
"enable-wifi": "Wi-Fi'ı etkinleştir",
|
||||
"enable-wifi": "Kablosuz Bağlantıyı etkinleştir",
|
||||
"next": "Sonraki",
|
||||
"open-calendar": "Takvimi aç",
|
||||
"open-display-settings": "Ekran ayarları",
|
||||
"open-launcher": "Başlatıcıyı aç",
|
||||
"open-mixer": "Ses mikseri",
|
||||
"open-mixer": "Ses Karıştırıcısı",
|
||||
"open-settings": "Ayarları aç",
|
||||
"pause": "Duraklat",
|
||||
"play": "Oynat",
|
||||
"previous": "Önceki",
|
||||
"random-wallpaper": "Rastgele duvar kağıdı",
|
||||
"toggle-mute": "Sesi kapat/aç",
|
||||
"widget-settings": "Araç ayarları"
|
||||
"widget-settings": "Araç takımı ayarları"
|
||||
},
|
||||
"dock": {
|
||||
"menu": {
|
||||
@@ -522,7 +540,7 @@
|
||||
"launcher": {
|
||||
"categories": {
|
||||
"all": "Tümü",
|
||||
"audiovideo": "Ses ve Video",
|
||||
"audiovideo": "Ses ve Görüntü",
|
||||
"chat": "Sohbet",
|
||||
"development": "Geliştirme",
|
||||
"education": "Eğitim",
|
||||
@@ -531,11 +549,12 @@
|
||||
"misc": "Çeşitli",
|
||||
"network": "Ağ",
|
||||
"office": "Ofis",
|
||||
"pinned": "Sabitlendi",
|
||||
"system": "Sistem",
|
||||
"webbrowser": "Web tarayıcı"
|
||||
"webbrowser": "Tarayıcı"
|
||||
},
|
||||
"pin": "Dock'a sabitle",
|
||||
"unpin": "Dock'dan sabitlemeyi kaldır"
|
||||
"pin": "Sabitle",
|
||||
"unpin": "Sabitlemeyi kaldır"
|
||||
},
|
||||
"lock-screen": {
|
||||
"authenticating": "Doğrulanıyor...",
|
||||
@@ -575,7 +594,7 @@
|
||||
"comfortable": "Rahat",
|
||||
"compact": "Sıkı",
|
||||
"default": "Varsayılan",
|
||||
"mini": "Mini"
|
||||
"mini": "Ufak"
|
||||
},
|
||||
"position": {
|
||||
"bottom": "Alt",
|
||||
@@ -663,7 +682,7 @@
|
||||
"quality": {
|
||||
"high": "Yüksek",
|
||||
"medium": "Orta",
|
||||
"ultra": "Ultra",
|
||||
"ultra": "Aşırı",
|
||||
"very-high": "Çok yüksek"
|
||||
},
|
||||
"sources": {
|
||||
@@ -672,7 +691,7 @@
|
||||
}
|
||||
},
|
||||
"scrolling-modes": {
|
||||
"always": "Her Kaydır",
|
||||
"always": "Her Zaman Kaydır",
|
||||
"hover": "Üzerine Gelince Kaydır",
|
||||
"never": "Asla Kaydırma"
|
||||
},
|
||||
@@ -736,6 +755,9 @@
|
||||
"clipboard-loading": "Panoya geçmişi yükleniyor...",
|
||||
"clipboard-loading-description": "Lütfen bekleyin",
|
||||
"clipboard-search-description": "Panoya geçmişini ara",
|
||||
"command": "Komut",
|
||||
"command-description": "Kabuk komutlarını çalıştır",
|
||||
"command-name": "Komut",
|
||||
"emoji": "Emoji seçici",
|
||||
"emoji-loading": "Emojiler yükleniyor...",
|
||||
"emoji-loading-description": "Lütfen bekleyin",
|
||||
@@ -805,17 +827,17 @@
|
||||
},
|
||||
"wifi": {
|
||||
"label": {
|
||||
"disconnected": "Wi-Fi Bağlantısı Kesik",
|
||||
"disconnected": "Kablosuz Bağlantı Kesik",
|
||||
"ethernet": "Ethernet",
|
||||
"wifi": "Wi-Fi"
|
||||
"wifi": "Kablosuz Bağlantı"
|
||||
},
|
||||
"tooltip": {
|
||||
"action": "Wi-Fi"
|
||||
"action": "Kablosuz Bağlantı"
|
||||
}
|
||||
}
|
||||
},
|
||||
"session-menu": {
|
||||
"action-in-seconds": "{action} in {seconds} seconds...",
|
||||
"action-in-seconds": "{seconds} saniyede {action}...",
|
||||
"hibernate": "Hazırda Bekletme",
|
||||
"lock": "Kilitle",
|
||||
"lock-and-suspend": "Kilitle ve Askıya Al",
|
||||
@@ -864,8 +886,8 @@
|
||||
}
|
||||
},
|
||||
"external-mixer": {
|
||||
"description": "Harici ses mikseri özelliği etkinleştirilirken başlatılacak komutu veya uygulama yolunu girin.",
|
||||
"label": "Harici Ses Mikseri Komutu",
|
||||
"description": "Harici ses karıştırıcısı özelliği etkinleştirilirken başlatılacak komutu veya uygulama yolunu girin.",
|
||||
"label": "Harici Ses Karıştırıcısı Komutu",
|
||||
"placeholder": "pwvucontrol || pavucontrol"
|
||||
},
|
||||
"media": {
|
||||
@@ -888,19 +910,19 @@
|
||||
"label": "Kaydırma hızı"
|
||||
},
|
||||
"scrolling-title": {
|
||||
"description": "Uzun medya başlıkları için sürekli kaydırmayı etkinleştirin",
|
||||
"description": "Uzun ortam başlıkları için sürekli kaydırmayı etkinleştirin",
|
||||
"label": "Kayan başlık"
|
||||
},
|
||||
"section": {
|
||||
"description": "Tercih ettiğiniz ve yoksayacağınız medya uygulamalarını ayarlayın.",
|
||||
"label": "Medya oynatıcılar"
|
||||
"description": "Tercih ettiğiniz ve yoksayacağınız ortam uygulamalarını ayarlayın.",
|
||||
"label": "Ortam oynatıcıları"
|
||||
},
|
||||
"visualizer-quality": {
|
||||
"description": "Yüksek kalite daha fazla GPU kaynağı kullanır.",
|
||||
"description": "Yüksek kalite ekran kartını daha fazla kullanır.",
|
||||
"label": "Görselleştirme kalitesi"
|
||||
},
|
||||
"visualizer-type": {
|
||||
"description": "Medya oynatımı için bir görselleştirme türü seçin",
|
||||
"description": "Ortam oynatımı için bir görselleştirme türü seçin",
|
||||
"label": "Görselleştirme türü"
|
||||
}
|
||||
},
|
||||
@@ -939,23 +961,23 @@
|
||||
"bar": {
|
||||
"appearance": {
|
||||
"background-opacity": {
|
||||
"description": "Barın arka plan opaklığını ayarlayın.",
|
||||
"description": "Araç çubuğu arka plan opaklığını ayarlayın.",
|
||||
"label": "Arka plan opaklığı"
|
||||
},
|
||||
"capsule-opacity": {
|
||||
"description": "Kapsül gösterildiğinde widget arka planlarının saydamlık seviyesini ayarla.",
|
||||
"description": "Kapsül gösterildiğinde araç takımı arka planlarının saydamlık seviyesini ayarla.",
|
||||
"label": "Kapsül saydamlığı"
|
||||
},
|
||||
"density": {
|
||||
"description": "Sıkı veya geniş bir görünüm için barın dolgusunu ayarlayın.",
|
||||
"label": "Bar yoğunluğu"
|
||||
"description": "Sıkı veya geniş bir görünüm için araç çubuğu dolgusunu ayarlayın.",
|
||||
"label": "Araç Çubuğu yoğunluğu"
|
||||
},
|
||||
"floating": {
|
||||
"description": "Barı yüzen bir 'hap' olarak görüntüler. Not: Bu, ekran köşelerini kenarlara taşıyacaktır.",
|
||||
"label": "Yüzen bar"
|
||||
"description": "Araç çubuğunu yüzen bir 'kapsül' olarak görüntüler. Not: Bu, ekran köşelerini kenarlara taşıyacaktır.",
|
||||
"label": "Yüzen Araç Çubuğu"
|
||||
},
|
||||
"margins": {
|
||||
"description": "Yüzen barın etrafındaki kenar boşluklarını ayarlayın.",
|
||||
"description": "Yüzen araç çubuğunun etrafındaki kenar boşluklarını ayarlayın.",
|
||||
"horizontal": "Yatay",
|
||||
"label": "Kenar boşlukları",
|
||||
"vertical": "Dikey"
|
||||
@@ -965,25 +987,25 @@
|
||||
"label": "Dış köşeler"
|
||||
},
|
||||
"position": {
|
||||
"description": "Barı ekranda nereye yerleştireceğinizi seçin.",
|
||||
"label": "Bar konumu"
|
||||
"description": "Araç çubuğunu ekranda nereye yerleştireceğinizi seçin.",
|
||||
"label": "Araç Çubuğu konumu"
|
||||
},
|
||||
"section": {
|
||||
"description": "Barın görünümünü ve konumunu özelleştirin.",
|
||||
"description": "Araç çubuğunun görünümünü ve konumunu özelleştirin.",
|
||||
"label": "Görünüm"
|
||||
},
|
||||
"show-capsule": {
|
||||
"description": "Widget arka planlarını göster.",
|
||||
"description": "Araç takımı arka planlarını göster.",
|
||||
"label": "Kapsülü göster"
|
||||
}
|
||||
},
|
||||
"monitors": {
|
||||
"section": {
|
||||
"description": "Barı belirli ekranlarda gösterin. Hiçbiri seçilmezse varsayılan olarak tümünde gösterilir.",
|
||||
"description": "Araç çubuğunu belirli ekranlarda gösterin. Hiçbiri seçilmezse varsayılan olarak tümünde gösterilir.",
|
||||
"label": "Ekran görüntüsü"
|
||||
}
|
||||
},
|
||||
"title": "Bar",
|
||||
"title": "Araç Çubuğu",
|
||||
"tray": {
|
||||
"back": "Geri",
|
||||
"blacklist": {
|
||||
@@ -996,8 +1018,8 @@
|
||||
},
|
||||
"widgets": {
|
||||
"section": {
|
||||
"description": "Widget'ları sıralarını değiştirmek için sürükleyin. Widget'ları bölümler arasında aktarmak veya kaldırmak için sağ tıklama menüsünü kullanın.",
|
||||
"label": "Widget konumlandırma"
|
||||
"description": "Araç takımları sıralarını değiştirmek için sürükleyin. Araç takımlarını bölümler arasında aktarmak veya kaldırmak için sağ tıklama menüsünü kullanın.",
|
||||
"label": "Araç takımlarını konumlandırma"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1030,7 +1052,7 @@
|
||||
"description": "Işık ve koyu mod arasında otomatik geçişi etkinleştirir.",
|
||||
"label": "Koyu mod zamanlaması",
|
||||
"location": "Konum",
|
||||
"manual": "Manuel",
|
||||
"manual": "El ile",
|
||||
"off": "Kapalı"
|
||||
},
|
||||
"switch": {
|
||||
@@ -1169,7 +1191,7 @@
|
||||
}
|
||||
},
|
||||
"ui": {
|
||||
"description": "Masaüstü ortamı ve UI araç seti temalandırma.",
|
||||
"description": "Masaüstü ortamı ve kullanıcı arabilirimi araç seti temalandırma.",
|
||||
"gtk": {
|
||||
"description": "{filepath} dosyasına yaz"
|
||||
},
|
||||
@@ -1187,16 +1209,16 @@
|
||||
"control-center": {
|
||||
"cards": {
|
||||
"section": {
|
||||
"description": "Kontrol Merkezi'nde hangi kontrollerin ve hangi sırada görüneceğini özelleştirin.",
|
||||
"description": "Kontrol merkezinde hangi kontrollerin ve hangi sırada görüneceğini özelleştirin.",
|
||||
"label": "Kartlar"
|
||||
}
|
||||
},
|
||||
"position": {
|
||||
"description": "Kontrol Merkezi paneli açıldığında nerede görüneceğini seçin.",
|
||||
"description": "Kontrol merkezi paneli açıldığında nerede görüneceğini seçin.",
|
||||
"label": "Konum"
|
||||
},
|
||||
"section": {
|
||||
"description": "Kontrol Merkezi paneli konumunu ve davranışını yapılandırın.",
|
||||
"description": "Kontrol merkezi paneli konumunu ve davranışını yapılandırın.",
|
||||
"label": "Görünüm"
|
||||
},
|
||||
"shortcuts": {
|
||||
@@ -1219,15 +1241,15 @@
|
||||
"label": "Simge"
|
||||
},
|
||||
"on-clicked": {
|
||||
"description": "Düğmeye sol tıklandığında yürütülecek komut.",
|
||||
"description": "Farenin sol tuşuna tıklandığında yürütülecek komut.",
|
||||
"label": "Sol Tık Komutu"
|
||||
},
|
||||
"on-middle-clicked": {
|
||||
"description": "Orta tuşa tıklandığında çalıştırılacak komut.",
|
||||
"description": "Farenin orta tuşuna tıklandığında çalıştırılacak komut.",
|
||||
"label": "Orta Tıklama Komutu"
|
||||
},
|
||||
"on-right-clicked": {
|
||||
"description": "Düğmeye sağ tıklandığında çalıştırılacak komut.",
|
||||
"description": "Farenin sağ tuşuna tıklandığında çalıştırılacak komut.",
|
||||
"label": "Sağ Tık Komutu"
|
||||
},
|
||||
"on-state-command": {
|
||||
@@ -1255,8 +1277,8 @@
|
||||
"cancel": "İptal"
|
||||
},
|
||||
"section": {
|
||||
"description": "Widget'ları sürükleyerek sıralarını değiştirebilirsiniz. Widget'ları bölümler arasında aktarmak veya kaldırmak için sağ tıklama menüsünü kullanın.",
|
||||
"label": "Kısayol widget'ları"
|
||||
"description": "Araç takımlarını sürükleyerek sıralarını değiştirebilirsiniz. Araç takımlarını bölümler arasında aktarmak veya kaldırmak için sağ tıklama menüsünü kullanın.",
|
||||
"label": "Kısayol Araç Takımları"
|
||||
},
|
||||
"sectionLeft": "Sol",
|
||||
"sectionRight": "Sağ"
|
||||
@@ -1326,52 +1348,64 @@
|
||||
"dock": {
|
||||
"appearance": {
|
||||
"background-opacity": {
|
||||
"description": "Dock'un arka plan opaklığını ayarlayın.",
|
||||
"description": "Rıhtımın arka plan opaklığını ayarlayın.",
|
||||
"label": "Arka plan opaklığı"
|
||||
},
|
||||
"border-radius": {
|
||||
"description": "Dock'un kenar yarıçapını ayarla.",
|
||||
"description": "Rıhtımın kenar yarıçapını ayarla.",
|
||||
"label": "Kenar yarıçapı"
|
||||
},
|
||||
"colorize-icons": {
|
||||
"description": "Dock uygulama simgelerine tema renklerini uygulayın (sadece odaklanılmamış uygulamalar).",
|
||||
"description": "Rıhtım uygulama simgelerine tema renklerini uygulayın (sadece odaklanılmamış uygulamalar).",
|
||||
"label": "Simgeleri Renklendir"
|
||||
},
|
||||
"dead-opacity": {
|
||||
"description": "Çalışmayan uygulama simgelerinin opaklığını ayarlayın.",
|
||||
"label": "Ölü Opaklık"
|
||||
},
|
||||
"display": {
|
||||
"always-visible": "Her zaman görünür",
|
||||
"auto-hide": "Otomatik gizle",
|
||||
"description": "Dock'un nasıl davranacağını seçin.",
|
||||
"description": "Rıhtımın nasıl davranacağını seçin.",
|
||||
"exclusive": "Özel",
|
||||
"label": "Görüntüleme"
|
||||
},
|
||||
"floating-distance": {
|
||||
"description": "Dock ile ekran kenarı arasındaki mesafeyi ayarlayın.",
|
||||
"label": "Dock yüzen mesafesi"
|
||||
"description": "Rıhtım ile ekran kenarı arasındaki mesafeyi ayarlayın.",
|
||||
"label": "Rıhtım yüzen mesafesi"
|
||||
},
|
||||
"icon-size": {
|
||||
"description": "Dock'un genel boyutunu ayarlayın.",
|
||||
"label": "Dock boyutu"
|
||||
"description": "Rıhtımın genel boyutunu ayarlayın.",
|
||||
"label": "Rıhtım boyutu"
|
||||
},
|
||||
"inactive-indicators": {
|
||||
"description": "Tüm uygulamalar için, sadece etkin olan için değil, gösterge haplarını göster.",
|
||||
"label": "Çalışan Göstergeler"
|
||||
},
|
||||
"pinned-static": {
|
||||
"description": "Sabit sırada, sabitlenmiş uygulama simgelerini her zaman sola itin.",
|
||||
"label": "Sabitlenmiş Statik Uygulamalar"
|
||||
},
|
||||
"section": {
|
||||
"description": "Dock'un davranışını ve görünümünü özelleştirin.",
|
||||
"description": "Rıhtımın davranışını ve görünümünü özelleştirin.",
|
||||
"label": "Görünüm"
|
||||
}
|
||||
},
|
||||
"enabled": {
|
||||
"description": "Dock'u tamamen gösterin veya gizleyin",
|
||||
"label": "Dock'u etkinleştir"
|
||||
"description": "Rıhtımı tamamen gösterin veya gizleyin",
|
||||
"label": "Rıhtımı etkinleştir"
|
||||
},
|
||||
"monitors": {
|
||||
"only-same-output": {
|
||||
"description": "Sadece dock'un bulunduğu çıktıdaki uygulamaları gösterin.",
|
||||
"description": "Sadece rıhtımın bulunduğu çıktıdaki uygulamaları gösterin.",
|
||||
"label": "Sadece aynı çıktıdaki uygulamalar"
|
||||
},
|
||||
"section": {
|
||||
"description": "Dock'u belirli ekranlarda gösterin. Hiçbiri seçilmezse varsayılan olarak tümünde gösterilir.",
|
||||
"description": "Rıhtımı belirli ekranlarda gösterin. Hiçbiri seçilmezse varsayılan olarak tümünde gösterilir.",
|
||||
"label": "Ekran görüntüsü"
|
||||
}
|
||||
},
|
||||
"title": "Dock"
|
||||
"title": "Rıhtım"
|
||||
},
|
||||
"general": {
|
||||
"fonts": {
|
||||
@@ -1440,7 +1474,7 @@
|
||||
"label": "Ekran köşelerini göster"
|
||||
},
|
||||
"solid-black": {
|
||||
"description": "Bar arka plan rengi yerine tam siyah kullan.",
|
||||
"description": "Araç çubuğu arka plan rengi yerine tam siyah kullan.",
|
||||
"label": "Siyah köşeler"
|
||||
}
|
||||
},
|
||||
@@ -1513,6 +1547,10 @@
|
||||
"description": "Başlatıcının davranışını ve görünümünü özelleştirin.",
|
||||
"label": "Görünüm"
|
||||
},
|
||||
"show-categories": {
|
||||
"description": "Uygulamaları filtrelemek için kategori sekmelerini göster.",
|
||||
"label": "Kategorileri göster"
|
||||
},
|
||||
"sort-by-usage": {
|
||||
"description": "Etkinleştirildiğinde, sıkça başlatılan uygulamalar listede ilk olarak görünür.",
|
||||
"label": "En çok kullanılana göre sırala"
|
||||
@@ -1545,7 +1583,7 @@
|
||||
},
|
||||
"date-time": {
|
||||
"12hour-format": {
|
||||
"description": "Zamanı kilit ekranında ve takvimde 12 saatlik formatta gösterir. Çubuk saatinin kendi ayarları vardır.",
|
||||
"description": "Zamanı kilit ekranında ve takvimde 12 saatlik formatta gösterir. Araç çubuğu saatinin kendi ayarları vardır.",
|
||||
"label": "12 saatlik zaman formatını kullan"
|
||||
},
|
||||
"first-day-of-week": {
|
||||
@@ -1558,7 +1596,7 @@
|
||||
"label": "Tarih & Saat"
|
||||
},
|
||||
"show-events": {
|
||||
"description": "Takvim panelinde etkinlikleri göster.",
|
||||
"description": "Takvim panelindeki etkinlikleri göster.",
|
||||
"label": "Takvim etkinliklerini göster"
|
||||
},
|
||||
"use-analog": {
|
||||
@@ -1588,8 +1626,8 @@
|
||||
"label": "Hava durumunu etkinleştir"
|
||||
},
|
||||
"fahrenheit": {
|
||||
"description": "Sıcaklığı Celsius yerine Fahrenheit cinsinden gösterin.",
|
||||
"label": "Sıcaklığı Fahrenheit (°F) cinsinden göster"
|
||||
"description": "Sıcaklığı santigrat yerine fahrenhayt cinsinden gösterin.",
|
||||
"label": "Sıcaklığı fahrenhayt (°F) cinsinden göster"
|
||||
},
|
||||
"section": {
|
||||
"description": "Tercih ettiğiniz sıcaklık birimini seçin.",
|
||||
@@ -1607,7 +1645,7 @@
|
||||
},
|
||||
"lock-screen": {
|
||||
"compact-lockscreen": {
|
||||
"description": "Sadece giriş girdisini ve sistem kontrollerini göster, hava durumu ve ortam medya widget'larını gizle.",
|
||||
"description": "Sadece giriş girdisini ve sistem kontrollerini göster, hava durumu ve ortam araç takımlarını gizle.",
|
||||
"label": "Kompakt ekran kilidi"
|
||||
},
|
||||
"lock-on-suspend": {
|
||||
@@ -1625,11 +1663,11 @@
|
||||
"label": "Bluetooth'u Etkinleştir"
|
||||
},
|
||||
"section": {
|
||||
"description": "Wi-Fi ve Bluetooth bağlantılarını yönetin."
|
||||
"description": "Kablosuz ve Bluetooth bağlantılarını yönetin."
|
||||
},
|
||||
"title": "Ağ",
|
||||
"wifi": {
|
||||
"label": "Wi-Fi'yi Etkinleştir"
|
||||
"label": "Kablosuz Bağlantıyı Etkinleştir"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
@@ -1755,7 +1793,7 @@
|
||||
"label": "Giriş sesi"
|
||||
},
|
||||
"lockkey": {
|
||||
"description": "Caps Lock, Num Lock veya Scroll Lock değiştirildiğinde OSD'yi göster.",
|
||||
"description": "Büyük Harf Kilidi, Sayı Kilidi veya Kaydırma Kilidi değiştirildiğinde OSD'yi göster.",
|
||||
"label": "Kilit tuşları"
|
||||
},
|
||||
"section": {
|
||||
@@ -1841,7 +1879,7 @@
|
||||
"audio": {
|
||||
"audio-codec": {
|
||||
"description": "En iyi performans ve en küçük ses boyutu için Opus önerilir.",
|
||||
"label": "Ses codec"
|
||||
"label": "Ses çözücüsü"
|
||||
},
|
||||
"audio-source": {
|
||||
"description": "Kayıt sırasında yakalanacak ses kaynağı.",
|
||||
@@ -1864,7 +1902,7 @@
|
||||
},
|
||||
"select-output-folder": "Çıktı klasörünü seç",
|
||||
"show-cursor": {
|
||||
"description": "Video fare imlecini kaydedin.",
|
||||
"description": "Görüntü fare imlecini kaydedin.",
|
||||
"label": "İmleci göster"
|
||||
}
|
||||
},
|
||||
@@ -1879,20 +1917,20 @@
|
||||
"label": "Kare hızı"
|
||||
},
|
||||
"section": {
|
||||
"description": "Video kaydı seçeneklerini yapılandırın.",
|
||||
"label": "Video ayarları"
|
||||
"description": "Görüntü kaydı seçeneklerini yapılandırın.",
|
||||
"label": "Görüntü ayarları"
|
||||
},
|
||||
"video-codec": {
|
||||
"description": "h264 en yaygın codec'tir.",
|
||||
"label": "Video codec"
|
||||
"description": "h264 en yaygın çözücüdür.",
|
||||
"label": "Görüntü çözücüsü"
|
||||
},
|
||||
"video-quality": {
|
||||
"description": "Daha yüksek kalite daha büyük dosya boyutları ile sonuçlanır.",
|
||||
"label": "Video kalitesi"
|
||||
"label": "Görüntü kalitesi"
|
||||
},
|
||||
"video-source": {
|
||||
"description": "Portal önerilir, eğer artefaktlar alırsanız Ekranı deneyin.",
|
||||
"label": "Video kaynağı"
|
||||
"label": "Görüntü kaynağı"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1949,7 +1987,7 @@
|
||||
"label": "Kritik Eşiği"
|
||||
},
|
||||
"cpu-section": {
|
||||
"label": "CPU Kullanımı"
|
||||
"label": "İşlemci Kullanımı"
|
||||
},
|
||||
"cpu-warning-threshold": {
|
||||
"label": "Uyarı Eşiği"
|
||||
@@ -2000,10 +2038,10 @@
|
||||
"label": "Uyarı Eşiği"
|
||||
},
|
||||
"temperature-section": {
|
||||
"label": "CPU Sıcaklığı"
|
||||
"label": "İşlemci Sıcaklığı"
|
||||
},
|
||||
"thresholds-section": {
|
||||
"description": "Her sistem metriği için uyarı/kritik eşiklerini ve yoklama aralıklarını ayarlayın.",
|
||||
"description": "Her sistem ölçüsü için uyarı/kritik eşiklerini ve yoklama aralıklarını ayarlayın.",
|
||||
"label": "Eşikler"
|
||||
},
|
||||
"title": "Sistem İzleme",
|
||||
@@ -2022,7 +2060,7 @@
|
||||
},
|
||||
"animation-disable": {
|
||||
"description": "Daha hızlı ve daha duyarlı bir deneyim için tüm animasyonları devre dışı bırakın.",
|
||||
"label": "UI Animasyonlarını Devre Dışı Bırak"
|
||||
"label": "Kullanıcı Arayüzü Animasyonlarını Devre Dışı Bırak"
|
||||
},
|
||||
"animation-speed": {
|
||||
"description": "Genel animasyon hızını ayarlar.",
|
||||
@@ -2049,7 +2087,7 @@
|
||||
"reset": "Karartılmış masaüstü opaklığını sıfırla"
|
||||
},
|
||||
"panel-background-opacity": {
|
||||
"description": "Tüm paneller için arka plan opaklığını ayarlayın (Launcher, Control Center, Ayarlar vb.).",
|
||||
"description": "Tüm paneller için arka plan opaklığını ayarlayın (Başlatıcı, Kontrol Merkezi, Ayarlar vb.).",
|
||||
"label": "Panel arka plan opaklığı"
|
||||
},
|
||||
"panels-attached-to-bar": {
|
||||
@@ -2183,7 +2221,7 @@
|
||||
},
|
||||
"customize": {
|
||||
"header": "Deneyiminizi özelleştirin",
|
||||
"subheader": "Bar konumunu, yoğunluğunu, ölçeğini ve daha fazlasını ayarlayın."
|
||||
"subheader": "Araç çubuğu konumunu, yoğunluğunu, ölçeğini ve daha fazlasını ayarlayın."
|
||||
},
|
||||
"wallpaper": {
|
||||
"choose-dir": "Duvar kağıdı görüntülerinizi içeren bir dizin seçin",
|
||||
@@ -2269,8 +2307,8 @@
|
||||
"opened": "Ko-fi sayfası tarayıcınızda açıldı"
|
||||
},
|
||||
"missing-control-center": {
|
||||
"description": "Kontrol Merkezi widget'ı çubuktan kaldırıldı. Çubuktan tekrar erişmek için widget'ı yeniden eklemeniz gerekecek. Çubuğa sağ tıklayarak da açabilirsiniz.",
|
||||
"label": "Son Kontrol Merkezi widget'ı kaldırıldı"
|
||||
"description": "Kontrol Merkezi araç takımı araç çubuğundan kaldırıldı. Araç çubuğundan tekrar erişmek için araç takımını yeniden eklemeniz gerekecek. Araç çubuğuna sağ tıklayarak da açabilirsiniz.",
|
||||
"label": "Son Kontrol Merkezi araç takımı kaldırıldı"
|
||||
},
|
||||
"night-light": {
|
||||
"disabled": "Devre dışı",
|
||||
@@ -2323,7 +2361,7 @@
|
||||
}
|
||||
},
|
||||
"tooltips": {
|
||||
"add-widget": "Widget ekle",
|
||||
"add-widget": "Araç takımı ekle",
|
||||
"bluetooth-devices": "Bluetooth cihazları",
|
||||
"brightness-at": "Parlaklık: %{brightness}",
|
||||
"cancel-timer": "Zamanlayıcı",
|
||||
@@ -2347,7 +2385,7 @@
|
||||
"keyboard-layout": "{layout} klavye düzeni",
|
||||
"list-view": "Liste görünümü",
|
||||
"manage-vpn": "VPN bağlantıları",
|
||||
"manage-wifi": "Wi-Fi",
|
||||
"manage-wifi": "Kablosuz Bağlantı",
|
||||
"microphone-volume-at": "Mikrofon sesi: %{volume}",
|
||||
"move-to-center-section": "Orta bölüm",
|
||||
"move-to-left-section": "Sol bölüm",
|
||||
@@ -2376,7 +2414,7 @@
|
||||
"refresh-devices": "Cihazları yenile",
|
||||
"refresh-wallhaven": "Wallhaven sonuçlarını yenile",
|
||||
"refresh-wallpaper-list": "Duvar kağıdı listesini yenile",
|
||||
"remove-widget": "Widget kaldır",
|
||||
"remove-widget": "Araç takımını kaldır",
|
||||
"screen-recorder-not-installed": "Ekran kaydedici (yüklü değil)",
|
||||
"search": "Ara",
|
||||
"search-close": "Aramayı kapat",
|
||||
@@ -2389,7 +2427,7 @@
|
||||
"up": "Üst dizin",
|
||||
"volume-at": "Çıkış sesi: %{volume}",
|
||||
"wallpaper-selector": "Duvar kağıdı seçici",
|
||||
"widget-settings": "Widget ayarları"
|
||||
"widget-settings": "Araç takımı ayarları"
|
||||
},
|
||||
"wallpaper": {
|
||||
"configure-directory": "Resimler içeren duvar kağıdı dizininizi yapılandırın.",
|
||||
@@ -2566,21 +2604,21 @@
|
||||
"available-networks": "Kullanılabilir Ağlar",
|
||||
"connect": "Bağlan",
|
||||
"connected": "Bağlı",
|
||||
"disabled": "Wi-Fi devre dışı",
|
||||
"disabled": "Kablosuz Bağlantı devre dışı",
|
||||
"disconnect": "Bağlantıyı kes",
|
||||
"disconnecting": "Bağlantı kesiliyor...",
|
||||
"enable-message": "Mevcut ağları görmek için Wi-Fi'yi etkinleştirin.",
|
||||
"enter-password": "Şifre girin...",
|
||||
"enable-message": "Mevcut ağları görmek için kablosuz bağlantıyı etkinleştirin.",
|
||||
"enter-password": "Parola girin...",
|
||||
"forget": "Unut",
|
||||
"forget-network": "Bu ağı unut?",
|
||||
"forgetting": "Unutuluyor...",
|
||||
"known-networks": "Bilinen Ağlar",
|
||||
"no-networks": "Ağ bulunamadı",
|
||||
"password": "Şifre",
|
||||
"password": "Parola",
|
||||
"saved": "Kaydedildi",
|
||||
"scan-again": "Yeniden tara",
|
||||
"searching": "Yakındaki ağlar aranıyor...",
|
||||
"title": "Wi-Fi"
|
||||
"title": "Kablosuz Bağlantı"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +140,13 @@
|
||||
"stream-description": "Введіть команду для безперервного запуску."
|
||||
},
|
||||
"dynamic-text": "Динамічний текст",
|
||||
"hide-mode": {
|
||||
"alwaysExpanded": "Завжди розширено",
|
||||
"description": "Контролює видимість віджета, коли команда не має виведення.",
|
||||
"expandWithOutput": "Розширити, якщо є виведення",
|
||||
"label": "Режим приховування",
|
||||
"maxTransparent": "Максимально розширено, але прозоро"
|
||||
},
|
||||
"icon": {
|
||||
"description": "Вибрати значок з бібліотеки.",
|
||||
"label": "Значок"
|
||||
@@ -175,6 +182,10 @@
|
||||
"label": "Правий клік",
|
||||
"update-text": "Оновити текст, що відображається, при натисканні правою кнопкою миші"
|
||||
},
|
||||
"show-icon": {
|
||||
"description": "Перемикає видимість значка віджета.",
|
||||
"label": "Показати значок"
|
||||
},
|
||||
"text-stream": {
|
||||
"description": "Потокові рядки з команди відображатимуться як текст на кнопці.",
|
||||
"label": "Потік"
|
||||
@@ -343,6 +354,9 @@
|
||||
"description": "Встановити ширину заголовків вікон на панелі завдань (у пікселях).",
|
||||
"label": "Ширина заголовка",
|
||||
"reset-tooltip": "Скинути ширину заголовка"
|
||||
"show-pinned-apps": {
|
||||
"description": "Показувати закріплені програми з док-панелі на панелі завдань.",
|
||||
"label": "Показати закріплені програми"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
@@ -359,6 +373,10 @@
|
||||
"drawer-enabled": {
|
||||
"description": "Коли увімкнено, не закріплені елементи трея відображаються на панелі ящика. Коли вимкнено, всі елементи трея відображаються в рядку.",
|
||||
"label": "Увімкнути висувну панель"
|
||||
},
|
||||
"hide-passive": {
|
||||
"description": "Якщо ввімкнено, елементи в треї зі статусом \"Пасивний\" будуть приховані.",
|
||||
"label": "Приховати пасивні предмети"
|
||||
}
|
||||
},
|
||||
"volume": {
|
||||
@@ -531,11 +549,12 @@
|
||||
"misc": "Різне",
|
||||
"network": "Мережа",
|
||||
"office": "Офіс",
|
||||
"pinned": "Закріплено",
|
||||
"system": "Система",
|
||||
"webbrowser": "Веб-браузер"
|
||||
},
|
||||
"pin": "Закріпити в доці",
|
||||
"unpin": "Відкріпити з доку"
|
||||
"pin": "Закріпити",
|
||||
"unpin": "Відкріпити"
|
||||
},
|
||||
"lock-screen": {
|
||||
"authenticating": "Автентифікація...",
|
||||
@@ -736,6 +755,9 @@
|
||||
"clipboard-loading": "Завантаження історії буфера обміну...",
|
||||
"clipboard-loading-description": "Зачекайте, будь ласка",
|
||||
"clipboard-search-description": "Пошук в історії буфера обміну",
|
||||
"command": "Команда",
|
||||
"command-description": "Виконати команди оболонки",
|
||||
"command-name": "Команда",
|
||||
"emoji": "Обрати емодзі",
|
||||
"emoji-loading": "Завантаження емодзі...",
|
||||
"emoji-loading-description": "Зачекайте, будь ласка",
|
||||
@@ -1337,6 +1359,10 @@
|
||||
"description": "Застосувати кольори теми до значків застосункiв у доці (тільки неактивні застосунки).",
|
||||
"label": "Розфарбувати значки"
|
||||
},
|
||||
"dead-opacity": {
|
||||
"description": "Відрегулюйте прозорість іконок програм, які не запущені.",
|
||||
"label": "Мертва непрозорість"
|
||||
},
|
||||
"display": {
|
||||
"always-visible": "Завжди видимий",
|
||||
"auto-hide": "Автоприховування",
|
||||
@@ -1352,6 +1378,14 @@
|
||||
"description": "Налаштуйте загальний розмір дока.",
|
||||
"label": "Розмір дока"
|
||||
},
|
||||
"inactive-indicators": {
|
||||
"description": "Відображати індикатори-пігулки для всіх програм, а не лише для поточної активної.",
|
||||
"label": "Індикатори бігу"
|
||||
},
|
||||
"pinned-static": {
|
||||
"description": "Завжди закріплюйте значки програм ліворуч у статичному порядку.",
|
||||
"label": "Статично закріплені програми"
|
||||
},
|
||||
"section": {
|
||||
"description": "Налаштуйте поведінку та зовнішній вигляд дока.",
|
||||
"label": "Зовнішній вигляд"
|
||||
@@ -1513,6 +1547,10 @@
|
||||
"description": "Налаштуйте поведінку та зовнішній вигляд лаунчера.",
|
||||
"label": "Зовнішній вигляд"
|
||||
},
|
||||
"show-categories": {
|
||||
"description": "Показувати вкладки категорій для фільтрації додатків.",
|
||||
"label": "Показувати категорії"
|
||||
},
|
||||
"sort-by-usage": {
|
||||
"description": "Коли увімкнено, часто використовувані застосунки з'являються першими в списку.",
|
||||
"label": "Сортувати за використанням"
|
||||
|
||||
@@ -140,6 +140,13 @@
|
||||
"stream-description": "输入一个要持续运行的命令。"
|
||||
},
|
||||
"dynamic-text": "动态文本",
|
||||
"hide-mode": {
|
||||
"alwaysExpanded": "始终展开",
|
||||
"description": "控制命令无输出时小部件的可见性。",
|
||||
"expandWithOutput": "有输出时展开",
|
||||
"label": "隐藏模式",
|
||||
"maxTransparent": "最大展开但透明"
|
||||
},
|
||||
"icon": {
|
||||
"description": "从库中选择图标。",
|
||||
"label": "图标"
|
||||
@@ -175,6 +182,10 @@
|
||||
"label": "右键点击",
|
||||
"update-text": "右键单击时更新显示的文本"
|
||||
},
|
||||
"show-icon": {
|
||||
"description": "切换小部件图标的可见性。",
|
||||
"label": "显示图标"
|
||||
},
|
||||
"text-stream": {
|
||||
"description": "来自命令的流式输出行将作为文本显示在按钮上。",
|
||||
"label": "流"
|
||||
@@ -343,6 +354,9 @@
|
||||
"description": "设置任务栏中窗口标题的宽度(以像素为单位)。",
|
||||
"label": "标题宽度",
|
||||
"reset-tooltip": "重置标题宽度"
|
||||
"show-pinned-apps": {
|
||||
"description": "在任务栏中显示 Dock 上固定的应用。",
|
||||
"label": "显示已置顶的应用"
|
||||
}
|
||||
},
|
||||
"taskbar-grouped": {
|
||||
@@ -359,6 +373,10 @@
|
||||
"drawer-enabled": {
|
||||
"description": "启用时,未固定的托盘项显示在抽屉面板中。禁用时,所有托盘项都内联显示。",
|
||||
"label": "启用抽屉"
|
||||
},
|
||||
"hide-passive": {
|
||||
"description": "启用后,将隐藏状态为“被动”的托盘图标。",
|
||||
"label": "隐藏被动物品"
|
||||
}
|
||||
},
|
||||
"volume": {
|
||||
@@ -531,11 +549,12 @@
|
||||
"misc": "杂项",
|
||||
"network": "网络",
|
||||
"office": "办公室",
|
||||
"pinned": "已固定",
|
||||
"system": "系统",
|
||||
"webbrowser": "网页浏览器"
|
||||
},
|
||||
"pin": "固定到 Dock",
|
||||
"unpin": "从 Dock 取消固定"
|
||||
"pin": "固定",
|
||||
"unpin": "取消固定"
|
||||
},
|
||||
"lock-screen": {
|
||||
"authenticating": "正在验证...",
|
||||
@@ -736,6 +755,9 @@
|
||||
"clipboard-loading": "正在加载剪贴板历史记录...",
|
||||
"clipboard-loading-description": "请稍候",
|
||||
"clipboard-search-description": "搜索剪贴板历史记录",
|
||||
"command": "命令",
|
||||
"command-description": "运行 shell 命令",
|
||||
"command-name": "命令",
|
||||
"emoji": "表情符号选择器",
|
||||
"emoji-loading": "正在加载表情符号...",
|
||||
"emoji-loading-description": "请稍候",
|
||||
@@ -1337,6 +1359,10 @@
|
||||
"description": "将主题颜色应用到 Dock 应用图标(仅限非聚焦应用)。",
|
||||
"label": "着色图标"
|
||||
},
|
||||
"dead-opacity": {
|
||||
"description": "调整未运行的应用程序图标的不透明度。",
|
||||
"label": "死亡不透明度"
|
||||
},
|
||||
"display": {
|
||||
"always-visible": "始终可见",
|
||||
"auto-hide": "自动隐藏",
|
||||
@@ -1352,6 +1378,14 @@
|
||||
"description": "调整 Dock 的整体大小。",
|
||||
"label": "Dock 大小"
|
||||
},
|
||||
"inactive-indicators": {
|
||||
"description": "为所有应用显示指示器小药丸,而不仅仅是当前活跃的应用。",
|
||||
"label": "运行指标"
|
||||
},
|
||||
"pinned-static": {
|
||||
"description": "始终将固定的应用图标按静态顺序推到左侧。",
|
||||
"label": "静态固定应用"
|
||||
},
|
||||
"section": {
|
||||
"description": "自定义 Dock 的行为和外观。",
|
||||
"label": "外观"
|
||||
@@ -1513,6 +1547,10 @@
|
||||
"description": "自定义启动器的行为和外观。",
|
||||
"label": "外观"
|
||||
},
|
||||
"show-categories": {
|
||||
"description": "显示用于筛选应用程序的类别标签。",
|
||||
"label": "显示类别"
|
||||
},
|
||||
"sort-by-usage": {
|
||||
"description": "启用后,经常启动的应用程序将显示在列表首位。",
|
||||
"label": "按使用频率排序"
|
||||
|
||||
@@ -175,7 +175,8 @@
|
||||
"terminalCommand": "xterm -e",
|
||||
"customLaunchPrefixEnabled": false,
|
||||
"customLaunchPrefix": "",
|
||||
"viewMode": "list"
|
||||
"viewMode": "list",
|
||||
"showCategories": true
|
||||
},
|
||||
"controlCenter": {
|
||||
"position": "close_to_bar_button",
|
||||
@@ -377,9 +378,6 @@
|
||||
"manualSunrise": "06:30",
|
||||
"manualSunset": "18:30"
|
||||
},
|
||||
"changelog": {
|
||||
"lastSeenVersion": ""
|
||||
},
|
||||
"hooks": {
|
||||
"enabled": false,
|
||||
"wallpaperChange": "",
|
||||
|
||||
@@ -129,6 +129,10 @@ Singleton {
|
||||
"settings-system-monitor": "activity",
|
||||
"bluetooth": "bluetooth",
|
||||
"bt-device-generic": "bluetooth",
|
||||
"bt-device-gamepad": "device-gamepad-2",
|
||||
"bt-device-microphone": "microphone",
|
||||
"bt-device-headset": "headset",
|
||||
"bt-device-earbuds": "device-airpods",
|
||||
"bt-device-headphones": "headphones",
|
||||
"bt-device-mouse": "mouse-2",
|
||||
"bt-device-keyboard": "bluetooth",
|
||||
|
||||
@@ -346,6 +346,7 @@ Singleton {
|
||||
property string customLaunchPrefix: ""
|
||||
// View mode: "list" or "grid"
|
||||
property string viewMode: "list"
|
||||
property bool showCategories: true
|
||||
}
|
||||
|
||||
// control center
|
||||
@@ -439,6 +440,10 @@ Singleton {
|
||||
// Desktop entry IDs pinned to the dock (e.g., "org.kde.konsole", "firefox.desktop")
|
||||
property list<string> pinnedApps: []
|
||||
property bool colorizeIcons: false
|
||||
|
||||
property bool pinnedStatic: false
|
||||
property bool inactiveIndicators: false
|
||||
property double deadOpacity: 0.6
|
||||
}
|
||||
|
||||
// network
|
||||
@@ -570,10 +575,6 @@ Singleton {
|
||||
property string manualSunset: "18:30"
|
||||
}
|
||||
|
||||
property JsonObject changelog: JsonObject {
|
||||
property string lastSeenVersion: ""
|
||||
}
|
||||
|
||||
// hooks
|
||||
property JsonObject hooks: JsonObject {
|
||||
property bool enabled: false
|
||||
|
||||
@@ -27,6 +27,7 @@ Item {
|
||||
|
||||
// Effective shown state (true if hovered/animated open or forced)
|
||||
readonly property bool revealed: !forceClose && (forceOpen || showPill)
|
||||
readonly property bool hasIcon: root.icon !== ""
|
||||
|
||||
signal shown
|
||||
signal hidden
|
||||
@@ -68,7 +69,14 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
width: collapseToIcon ? pillHeight : pillHeight + Math.max(0, pill.width - pillOverlap)
|
||||
width: {
|
||||
if (collapseToIcon) {
|
||||
return hasIcon ? pillHeight : 0;
|
||||
}
|
||||
var overlap = hasIcon ? pillOverlap : 0;
|
||||
var baseWidth = hasIcon ? pillHeight : 0;
|
||||
return baseWidth + Math.max(0, pill.width - overlap);
|
||||
}
|
||||
height: pillHeight
|
||||
|
||||
Connections {
|
||||
@@ -103,8 +111,11 @@ Item {
|
||||
width: revealed ? pillMaxWidth : 1
|
||||
height: pillHeight
|
||||
|
||||
x: oppositeDirection ? (iconCircle.x + iconCircle.width / 2) : // Opens right
|
||||
(iconCircle.x + iconCircle.width / 2) - width // Opens left
|
||||
x: {
|
||||
if (!hasIcon)
|
||||
return 0;
|
||||
return oppositeDirection ? (iconCircle.x + iconCircle.width / 2) : (iconCircle.x + iconCircle.width / 2) - width;
|
||||
}
|
||||
|
||||
opacity: revealed ? Style.opacityFull : Style.opacityNone
|
||||
color: Color.transparent // Make pill background transparent to avoid double opacity
|
||||
@@ -119,6 +130,9 @@ Item {
|
||||
id: textItem
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
x: {
|
||||
if (!hasIcon)
|
||||
return (parent.width - width) / 2;
|
||||
|
||||
// Better text horizontal centering
|
||||
var centerX = (parent.width - width) / 2;
|
||||
var offset = oppositeDirection ? Style.marginXS : -Style.marginXS;
|
||||
@@ -155,7 +169,7 @@ Item {
|
||||
|
||||
Rectangle {
|
||||
id: iconCircle
|
||||
width: pillHeight
|
||||
width: hasIcon ? pillHeight : 0
|
||||
height: pillHeight
|
||||
radius: Math.min(Style.radiusL, width / 2)
|
||||
color: Color.transparent // Make icon background transparent to avoid double opacity
|
||||
|
||||
@@ -52,6 +52,7 @@ Item {
|
||||
|
||||
// Effective shown state (true if animated open or forced, but not if force closed)
|
||||
readonly property bool revealed: !forceClose && (forceOpen || showPill)
|
||||
readonly property bool hasIcon: root.icon !== ""
|
||||
|
||||
// Always prioritize hover color, then the custom one and finally the fallback color
|
||||
readonly property color bgColor: hovered ? Color.mHover : (customBackgroundColor.a > 0) ? customBackgroundColor : Style.capsuleColor
|
||||
@@ -77,7 +78,18 @@ Item {
|
||||
|
||||
// For vertical bars: width is just icon size, height includes pill space
|
||||
width: buttonSize
|
||||
height: collapseToIcon ? buttonSize : (revealed ? (buttonSize + maxPillHeight - pillOverlap) : buttonSize)
|
||||
height: {
|
||||
if (collapseToIcon) {
|
||||
return hasIcon ? buttonSize : 0;
|
||||
}
|
||||
if (revealed) {
|
||||
var overlap = hasIcon ? pillOverlap : 0;
|
||||
var baseHeight = hasIcon ? buttonSize : 0;
|
||||
return baseHeight + Math.max(0, maxPillHeight - overlap);
|
||||
}
|
||||
// Fallback to buttonSize in idle state to remain clickable
|
||||
return buttonSize;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
@@ -92,9 +104,11 @@ Item {
|
||||
Rectangle {
|
||||
id: pillBackground
|
||||
width: buttonSize
|
||||
height: collapseToIcon ? buttonSize : (revealed ? (buttonSize + maxPillHeight - pillOverlap) : buttonSize)
|
||||
height: root.height
|
||||
radius: Style.radiusM
|
||||
color: root.bgColor
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
@@ -112,7 +126,11 @@ Item {
|
||||
|
||||
// Position based on direction - center the pill relative to the icon
|
||||
x: 0
|
||||
y: openUpward ? (iconCircle.y + iconCircle.height / 2 - height) : (iconCircle.y + iconCircle.height / 2)
|
||||
y: {
|
||||
if (!hasIcon)
|
||||
return 0;
|
||||
return openUpward ? (iconCircle.y + iconCircle.height / 2 - height) : (iconCircle.y + iconCircle.height / 2);
|
||||
}
|
||||
|
||||
opacity: revealed ? Style.opacityFull : Style.opacityNone
|
||||
color: Color.transparent // Make pill background transparent to avoid double opacity
|
||||
@@ -129,7 +147,7 @@ Item {
|
||||
id: textItem
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.verticalCenterOffset: openDownward ? Style.marginXXS : -Style.marginXXS
|
||||
anchors.verticalCenterOffset: hasIcon ? (openDownward ? Style.marginXXS : -Style.marginXXS) : 0
|
||||
rotation: rotateText ? -90 : 0
|
||||
text: root.text + root.suffix
|
||||
family: Settings.data.ui.fontFixed
|
||||
|
||||
@@ -305,6 +305,17 @@ PopupWindow {
|
||||
|
||||
// PIN / UNPIN
|
||||
Rectangle {
|
||||
visible: {
|
||||
if (widgetSection === "" || widgetIndex < 0)
|
||||
return false;
|
||||
var widgets = Settings.data.bar.widgets[widgetSection];
|
||||
if (!widgets || widgetIndex >= widgets.length)
|
||||
return false;
|
||||
var widgetSettings = widgets[widgetIndex];
|
||||
if (!widgetSettings)
|
||||
return false;
|
||||
return widgetSettings.drawerEnabled ?? false;
|
||||
}
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: 28
|
||||
color: pinUnpinMouseArea.containsMouse ? Qt.alpha(Color.mPrimary, 0.2) : Qt.alpha(Color.mPrimary, 0.08)
|
||||
|
||||
@@ -52,6 +52,83 @@ Item {
|
||||
readonly property string textCollapse: widgetSettings.textCollapse !== undefined ? widgetSettings.textCollapse : (widgetMetadata.textCollapse || "")
|
||||
readonly property bool parseJson: widgetSettings.parseJson !== undefined ? widgetSettings.parseJson : (widgetMetadata.parseJson || false)
|
||||
readonly property bool hasExec: (leftClickExec || rightClickExec || middleClickExec || (wheelMode === "unified" && wheelExec) || (wheelMode === "separate" && (wheelUpExec || wheelDownExec)))
|
||||
readonly property bool showIcon: (widgetSettings.showIcon !== undefined) ? widgetSettings.showIcon : true
|
||||
readonly property string hideMode: widgetSettings.hideMode || "alwaysExpanded"
|
||||
readonly property bool hasOutput: _dynamicText !== ""
|
||||
readonly property bool shouldForceOpen: textStream && (hideMode === "alwaysExpanded" || hideMode === "maxTransparent")
|
||||
|
||||
readonly property bool _useNewHideLogic: textCommand && textCommand.length > 0 && textStream
|
||||
readonly property bool _useTextCommandLogic: textCommand && textCommand.length > 0 && textStream
|
||||
|
||||
readonly property bool _pillVisible: {
|
||||
if (!_useTextCommandLogic) {
|
||||
return true;
|
||||
}
|
||||
if (hideMode === "alwaysExpanded" || hideMode === "maxTransparent") {
|
||||
return true;
|
||||
}
|
||||
var hasActualIcon = (_dynamicIcon !== "" || customIcon !== "");
|
||||
return hasOutput || (showIcon && hasActualIcon);
|
||||
}
|
||||
|
||||
readonly property real _pillOpacity: {
|
||||
if (!_useTextCommandLogic) {
|
||||
return 1.0;
|
||||
}
|
||||
if (hideMode === "maxTransparent" && !hasOutput) {
|
||||
return 0.0;
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
readonly property bool _pillForceOpen: {
|
||||
if (!_useTextCommandLogic) {
|
||||
return _dynamicText !== "" || (textStream && currentMaxTextLength > 0);
|
||||
}
|
||||
if (currentMaxTextLength <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hideMode === "alwaysExpanded" || hideMode === "maxTransparent") {
|
||||
return true;
|
||||
}
|
||||
return hasOutput;
|
||||
}
|
||||
|
||||
readonly property string _pillIcon: {
|
||||
if (!_useTextCommandLogic) {
|
||||
if (textCommand && textCommand.length > 0 && showIcon) {
|
||||
return _dynamicIcon !== "" ? _dynamicIcon : customIcon;
|
||||
} else if (!(textCommand && textCommand.length > 0)) {
|
||||
return _dynamicIcon !== "" ? _dynamicIcon : customIcon;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
if (!showIcon)
|
||||
return "";
|
||||
var actualIcon = _dynamicIcon !== "" ? _dynamicIcon : customIcon;
|
||||
if (hideMode === "expandWithOutput" && actualIcon === "") {
|
||||
return "question-mark";
|
||||
}
|
||||
return actualIcon;
|
||||
}
|
||||
|
||||
readonly property string _pillText: {
|
||||
if (!_useTextCommandLogic) {
|
||||
return (!isVerticalBar || currentMaxTextLength > 0) ? _dynamicText : "";
|
||||
}
|
||||
if (currentMaxTextLength <= 0) {
|
||||
return "";
|
||||
}
|
||||
if (hasOutput) {
|
||||
return _dynamicText;
|
||||
}
|
||||
if (hideMode === "expandWithOutput") {
|
||||
return "";
|
||||
}
|
||||
return " ".repeat(currentMaxTextLength);
|
||||
}
|
||||
|
||||
implicitWidth: pill.width
|
||||
implicitHeight: pill.height
|
||||
@@ -59,14 +136,17 @@ Item {
|
||||
BarPill {
|
||||
id: pill
|
||||
|
||||
visible: _pillVisible
|
||||
opacity: _pillOpacity
|
||||
screen: root.screen
|
||||
oppositeDirection: BarService.getPillDirection(root)
|
||||
icon: _dynamicIcon !== "" ? _dynamicIcon : customIcon
|
||||
text: (!isVerticalBar || currentMaxTextLength > 0) ? _dynamicText : ""
|
||||
icon: _pillIcon
|
||||
text: _pillText
|
||||
density: Settings.data.bar.density
|
||||
rotateText: isVerticalBar && currentMaxTextLength > 0
|
||||
autoHide: false
|
||||
forceOpen: _dynamicText !== ""
|
||||
forceOpen: _pillForceOpen
|
||||
|
||||
tooltipText: {
|
||||
var tooltipLines = [];
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ Item {
|
||||
anchors.fill: parent
|
||||
visible: showProgressRing
|
||||
progress: MediaService.trackLength > 0 ? MediaService.currentPosition / MediaService.trackLength : 0
|
||||
lineWidth: 2.5 * scaling
|
||||
lineWidth: 2 * scaling
|
||||
}
|
||||
|
||||
Item {
|
||||
|
||||
+221
-44
@@ -42,6 +42,7 @@ Rectangle {
|
||||
readonly property bool onlyActiveWorkspaces: (widgetSettings.onlyActiveWorkspaces !== undefined) ? widgetSettings.onlyActiveWorkspaces : widgetMetadata.onlyActiveWorkspaces
|
||||
readonly property bool showTitle: isVerticalBar ? false : (widgetSettings.showTitle !== undefined) ? widgetSettings.showTitle : widgetMetadata.showTitle
|
||||
readonly property int titleWidth: (widgetSettings.titleWidth !== undefined) ? widgetSettings.titleWidth : widgetMetadata.titleWidth
|
||||
readonly property bool showPinnedApps: (widgetSettings.showPinnedApps !== undefined) ? widgetSettings.showPinnedApps : widgetMetadata.showPinnedApps
|
||||
|
||||
// Context menu state
|
||||
property var selectedWindow: null
|
||||
@@ -50,6 +51,149 @@ Rectangle {
|
||||
|
||||
// Hover state
|
||||
property var hoveredWindowId: ""
|
||||
// Combined model of running windows and pinned apps
|
||||
property var combinedModel: []
|
||||
|
||||
// Helper function to normalize app IDs for case-insensitive matching
|
||||
function normalizeAppId(appId) {
|
||||
if (!appId || typeof appId !== 'string')
|
||||
return "";
|
||||
return appId.toLowerCase().trim();
|
||||
}
|
||||
|
||||
// Helper function to check if an app ID matches a pinned app (case-insensitive)
|
||||
function isAppIdPinned(appId, pinnedApps) {
|
||||
if (!appId || !pinnedApps || pinnedApps.length === 0)
|
||||
return false;
|
||||
const normalizedId = normalizeAppId(appId);
|
||||
return pinnedApps.some(pinnedId => normalizeAppId(pinnedId) === normalizedId);
|
||||
}
|
||||
|
||||
// Helper function to get app name from desktop entry
|
||||
function getAppNameFromDesktopEntry(appId) {
|
||||
if (!appId)
|
||||
return appId;
|
||||
|
||||
try {
|
||||
if (typeof DesktopEntries !== 'undefined' && DesktopEntries.heuristicLookup) {
|
||||
const entry = DesktopEntries.heuristicLookup(appId);
|
||||
if (entry && entry.name) {
|
||||
return entry.name;
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof DesktopEntries !== 'undefined' && DesktopEntries.byId) {
|
||||
const entry = DesktopEntries.byId(appId);
|
||||
if (entry && entry.name) {
|
||||
return entry.name;
|
||||
}
|
||||
}
|
||||
} catch (e)
|
||||
// Fall through to return original appId
|
||||
{}
|
||||
|
||||
// Return original appId if we can't find a desktop entry
|
||||
return appId;
|
||||
}
|
||||
|
||||
// Function to update the combined model
|
||||
function updateCombinedModel() {
|
||||
const runningWindows = [];
|
||||
const pinnedApps = Settings.data.dock.pinnedApps || [];
|
||||
const processedAppIds = new Set();
|
||||
|
||||
// First pass: Add all running windows
|
||||
try {
|
||||
const total = CompositorService.windows.count || 0;
|
||||
const activeIds = CompositorService.getActiveWorkspaces().map(function (ws) {
|
||||
return ws.id;
|
||||
});
|
||||
|
||||
for (var i = 0; i < total; i++) {
|
||||
var w = CompositorService.windows.get(i);
|
||||
if (!w)
|
||||
continue;
|
||||
var passOutput = (!onlySameOutput) || (w.output == screen?.name);
|
||||
var passWorkspace = (!onlyActiveWorkspaces) || (activeIds.includes(w.workspaceId));
|
||||
if (passOutput && passWorkspace) {
|
||||
const isPinned = isAppIdPinned(w.appId, pinnedApps);
|
||||
runningWindows.push({
|
||||
"type": isPinned ? "pinned-running" : "running",
|
||||
"window": w,
|
||||
"appId": w.appId,
|
||||
"title": w.title || getAppNameFromDesktopEntry(w.appId)
|
||||
});
|
||||
processedAppIds.add(normalizeAppId(w.appId));
|
||||
}
|
||||
}
|
||||
} catch (e)
|
||||
// Ignore errors
|
||||
{}
|
||||
|
||||
// Second pass: Add non-running pinned apps (only if showPinnedApps is enabled)
|
||||
if (showPinnedApps) {
|
||||
pinnedApps.forEach(pinnedAppId => {
|
||||
const normalizedPinnedId = normalizeAppId(pinnedAppId);
|
||||
if (!processedAppIds.has(normalizedPinnedId)) {
|
||||
const appName = getAppNameFromDesktopEntry(pinnedAppId);
|
||||
runningWindows.push({
|
||||
"type": "pinned",
|
||||
"window": null,
|
||||
"appId": pinnedAppId,
|
||||
"title": appName
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
combinedModel = runningWindows;
|
||||
updateHasWindow();
|
||||
}
|
||||
|
||||
// Function to launch a pinned app
|
||||
function launchPinnedApp(appId) {
|
||||
if (!appId)
|
||||
return;
|
||||
|
||||
try {
|
||||
const app = DesktopEntries.byId(appId);
|
||||
|
||||
if (Settings.data.appLauncher.customLaunchPrefixEnabled && Settings.data.appLauncher.customLaunchPrefix) {
|
||||
// Use custom launch prefix
|
||||
const prefix = Settings.data.appLauncher.customLaunchPrefix.split(" ");
|
||||
|
||||
if (app.runInTerminal) {
|
||||
const terminal = Settings.data.appLauncher.terminalCommand.split(" ");
|
||||
const command = prefix.concat(terminal.concat(app.command));
|
||||
Quickshell.execDetached(command);
|
||||
} else {
|
||||
const command = prefix.concat(app.command);
|
||||
Quickshell.execDetached(command);
|
||||
}
|
||||
} else if (Settings.data.appLauncher.useApp2Unit && app.id) {
|
||||
Logger.d("Taskbar", `Using app2unit for: ${app.id}`);
|
||||
if (app.runInTerminal)
|
||||
Quickshell.execDetached(["app2unit", "--", app.id + ".desktop"]);
|
||||
else
|
||||
Quickshell.execDetached(["app2unit", "--"].concat(app.command));
|
||||
} else {
|
||||
// Fallback logic when app2unit is not used
|
||||
if (app.runInTerminal) {
|
||||
Logger.d("Taskbar", "Executing terminal app manually: " + app.name);
|
||||
const terminal = Settings.data.appLauncher.terminalCommand.split(" ");
|
||||
const command = terminal.concat(app.command);
|
||||
Quickshell.execDetached(command);
|
||||
} else if (app.execute) {
|
||||
// Default execution for GUI apps
|
||||
app.execute();
|
||||
} else {
|
||||
Logger.w("Taskbar", `Could not launch: ${app.name}. No valid launch method.`);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
Logger.e("Taskbar", "Failed to launch app: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
NPopupContextMenu {
|
||||
id: contextMenu
|
||||
@@ -95,41 +239,31 @@ Rectangle {
|
||||
}
|
||||
|
||||
function updateHasWindow() {
|
||||
try {
|
||||
var total = CompositorService.windows.count || 0;
|
||||
var activeIds = CompositorService.getActiveWorkspaces().map(function (ws) {
|
||||
return ws.id;
|
||||
});
|
||||
var found = false;
|
||||
for (var i = 0; i < total; i++) {
|
||||
var w = CompositorService.windows.get(i);
|
||||
if (!w)
|
||||
continue;
|
||||
var passOutput = (!onlySameOutput) || (w.output == screen.name);
|
||||
var passWorkspace = (!onlyActiveWorkspaces) || (activeIds.includes(w.workspaceId));
|
||||
if (passOutput && passWorkspace) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
hasWindow = found;
|
||||
} catch (e) {
|
||||
hasWindow = false;
|
||||
}
|
||||
// Check if we have any items in the combined model (windows or pinned apps)
|
||||
hasWindow = combinedModel.length > 0;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: CompositorService
|
||||
function onWindowListChanged() {
|
||||
updateHasWindow();
|
||||
updateCombinedModel();
|
||||
}
|
||||
function onWorkspaceChanged() {
|
||||
updateHasWindow();
|
||||
updateCombinedModel();
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: updateHasWindow()
|
||||
onScreenChanged: updateHasWindow()
|
||||
Connections {
|
||||
target: Settings.data.dock
|
||||
function onPinnedAppsChanged() {
|
||||
updateCombinedModel();
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
updateCombinedModel();
|
||||
}
|
||||
onScreenChanged: updateCombinedModel()
|
||||
|
||||
// "visible": Always Visible, "hidden": Hide When Empty, "transparent": Transparent When Empty
|
||||
visible: hideMode !== "hidden" || hasWindow
|
||||
@@ -164,15 +298,16 @@ Rectangle {
|
||||
columnSpacing: isVerticalBar ? 0 : Style.marginXXS
|
||||
|
||||
Repeater {
|
||||
model: CompositorService.windows
|
||||
model: root.combinedModel
|
||||
delegate: Item {
|
||||
id: taskbarItem
|
||||
required property var modelData
|
||||
property ShellScreen screen: root.screen
|
||||
|
||||
visible: (!onlySameOutput || modelData.output === screen?.name) && (!onlyActiveWorkspaces || CompositorService.getActiveWorkspaces().map(function (ws) {
|
||||
return ws.id;
|
||||
}).includes(modelData.workspaceId))
|
||||
readonly property bool isRunning: modelData.window !== null
|
||||
readonly property bool isPinned: modelData.type === "pinned" || modelData.type === "pinned-running"
|
||||
readonly property bool isFocused: isRunning && modelData.window && modelData.window.isFocused
|
||||
readonly property bool isPinnedRunning: isPinned && isRunning && !isFocused
|
||||
|
||||
readonly property bool isHovered: root.hoveredWindowId === modelData.id
|
||||
readonly property real itemSpacing: Style.marginS
|
||||
@@ -200,6 +335,29 @@ Rectangle {
|
||||
duration: Style.animationFast
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
height: parent.height
|
||||
source: ThemeIcons.iconForAppId(modelData.appId)
|
||||
smooth: true
|
||||
asynchronous: true
|
||||
// Opacity: Focused (1.0) > Pinned Running (0.7) > Regular Running (0.6) > Just Pinned (0.4)
|
||||
opacity: isFocused ? Style.opacityFull : (isPinnedRunning ? 0.7 : (isRunning ? 0.6 : 0.4))
|
||||
|
||||
// For pinned apps that aren't running: use a muted color to indicate not running
|
||||
// For other apps: use standard colorization if enabled
|
||||
layer.enabled: (isPinned && !isRunning) || (root.widgetSettings.colorizeIcons !== false && !isFocused)
|
||||
layer.effect: ShaderEffect {
|
||||
property color targetColor: {
|
||||
// Pinned but not running: use a muted/desaturated color to indicate not running
|
||||
if (isPinned && !isRunning) {
|
||||
// Use a muted secondary or outline color
|
||||
return Settings.data.colorSchemes.darkMode ? Qt.darker(Color.mSecondary, 1.3) : Qt.lighter(Color.mSecondary, 1.5);
|
||||
}
|
||||
// Standard colorization for other cases
|
||||
return Settings.data.colorSchemes.darkMode ? Color.mOnSurface : Color.mSurfaceVariant;
|
||||
}
|
||||
property real colorizeMode: 0.0 // Dock mode (grayscale)
|
||||
|
||||
fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,6 +426,16 @@ Rectangle {
|
||||
color: titleFgColor
|
||||
opacity: Style.opacityFull
|
||||
}
|
||||
// Active indicator (focused window)
|
||||
Rectangle {
|
||||
id: iconBackground
|
||||
anchors.bottomMargin: -2
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 4
|
||||
height: 4
|
||||
color: isFocused ? Color.mPrimary : Color.transparent
|
||||
radius: Math.min(Style.radiusXXS, width / 2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,33 +447,42 @@ Rectangle {
|
||||
preventStealing: true
|
||||
|
||||
onPressed: function (mouse) {
|
||||
if (!taskbarItem.modelData)
|
||||
if (!modelData)
|
||||
return;
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
try {
|
||||
CompositorService.focusWindow(taskbarItem.modelData);
|
||||
} catch (error) {
|
||||
Logger.e("Taskbar", "Failed to activate toplevel: " + error);
|
||||
if (isRunning && modelData.window) {
|
||||
// Running app - focus it
|
||||
try {
|
||||
CompositorService.focusWindow(modelData.window);
|
||||
} catch (error) {
|
||||
Logger.e("Taskbar", "Failed to activate toplevel: " + error);
|
||||
}
|
||||
} else if (isPinned) {
|
||||
// Pinned app not running - launch it
|
||||
root.launchPinnedApp(modelData.appId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: function (mouse) {
|
||||
if (!taskbarItem.modelData)
|
||||
if (!modelData)
|
||||
return;
|
||||
if (mouse.button === Qt.RightButton) {
|
||||
mouse.accepted = true;
|
||||
TooltipService.hide();
|
||||
root.selectedWindow = taskbarItem.modelData;
|
||||
root.selectedAppName = CompositorService.getCleanAppName(taskbarItem.modelData.appId, taskbarItem.modelData.title);
|
||||
// Only show context menu for running apps
|
||||
if (isRunning && modelData.window) {
|
||||
root.selectedWindow = modelData.window;
|
||||
root.selectedAppName = CompositorService.getCleanAppName(modelData.appId, modelData.title);
|
||||
|
||||
// Store position and size for timer callback
|
||||
const globalPos = taskbarItem.mapToItem(root, 0, 0);
|
||||
contextMenuOpenTimer.globalX = globalPos.x;
|
||||
contextMenuOpenTimer.globalY = globalPos.y;
|
||||
contextMenuOpenTimer.itemWidth = taskbarItem.width;
|
||||
contextMenuOpenTimer.itemHeight = taskbarItem.height;
|
||||
contextMenuOpenTimer.restart();
|
||||
// Store position and size for timer callback
|
||||
const globalPos = taskbarItem.mapToItem(root, 0, 0);
|
||||
contextMenuOpenTimer.globalX = globalPos.x;
|
||||
contextMenuOpenTimer.globalY = globalPos.y;
|
||||
contextMenuOpenTimer.itemWidth = taskbarItem.width;
|
||||
contextMenuOpenTimer.itemHeight = taskbarItem.height;
|
||||
contextMenuOpenTimer.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
onEntered: {
|
||||
|
||||
@@ -21,7 +21,7 @@ Rectangle {
|
||||
// Get shared popup menu window from PanelService (reactive to trigger changes)
|
||||
readonly property var popupMenuWindow: {
|
||||
// Reference trigger to force re-evaluation
|
||||
var _ = popupMenuUpdateTrigger;
|
||||
var popupMenuUpdateTriggerRef = popupMenuUpdateTrigger;
|
||||
return PanelService.getPopupMenuWindow(screen);
|
||||
}
|
||||
|
||||
@@ -61,12 +61,10 @@ Rectangle {
|
||||
property list<string> blacklist: widgetSettings.blacklist || widgetMetadata.blacklist || [] // Read from settings
|
||||
property list<string> pinned: widgetSettings.pinned || widgetMetadata.pinned || [] // Pinned items (shown inline)
|
||||
property bool drawerEnabled: widgetSettings.drawerEnabled !== undefined ? widgetSettings.drawerEnabled : (widgetMetadata.drawerEnabled !== undefined ? widgetMetadata.drawerEnabled : true) // Enable drawer panel
|
||||
property bool hidePassive: widgetSettings.hidePassive !== undefined ? widgetSettings.hidePassive : true // Hide passive status items
|
||||
property var filteredItems: [] // Items to show inline (pinned)
|
||||
property var dropdownItems: [] // Items to show in drawer (unpinned)
|
||||
|
||||
// Debounce timer for updateFilteredItems to prevent excessive calls
|
||||
// when multiple events (e.g., SystemTray changes, settings saves)
|
||||
// trigger it in rapid succession, reducing redundant processing.
|
||||
Timer {
|
||||
id: updateDebounceTimer
|
||||
interval: 100 // milliseconds
|
||||
@@ -75,6 +73,43 @@ Rectangle {
|
||||
onTriggered: _performFilteredItemsUpdate()
|
||||
}
|
||||
|
||||
readonly property var statusSignature: {
|
||||
if (!SystemTray.items || !SystemTray.items.values) {
|
||||
return "";
|
||||
}
|
||||
var sig = "";
|
||||
var items = SystemTray.items.values;
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
if (item) {
|
||||
// Direct property access creates reactive binding
|
||||
var s = item.status;
|
||||
sig += (item.id || i) + ":" + (s !== undefined ? s : -1);
|
||||
}
|
||||
}
|
||||
// Trigger update when signature changes (status changed)
|
||||
if (root.hidePassive) {
|
||||
Qt.callLater(root.updateFilteredItems);
|
||||
}
|
||||
return sig;
|
||||
}
|
||||
Repeater {
|
||||
id: statusConnectionsRepeater
|
||||
model: SystemTray.items && SystemTray.items.values ? SystemTray.items.values : []
|
||||
|
||||
delegate: Item {
|
||||
Connections {
|
||||
target: modelData
|
||||
enabled: modelData !== null && modelData !== undefined
|
||||
function onStatusChanged() {
|
||||
if (root.hidePassive) {
|
||||
root.updateFilteredItems();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _performFilteredItemsUpdate() {
|
||||
let newItems = [];
|
||||
if (SystemTray.items && SystemTray.items.values) {
|
||||
@@ -87,6 +122,11 @@ Rectangle {
|
||||
|
||||
const title = item.tooltipTitle || item.name || item.id || "";
|
||||
|
||||
// Skip passive items if hidePassive is enabled
|
||||
if (root.hidePassive && item.status !== undefined && (item.status === SystemTray.Passive || item.status === 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if blacklisted
|
||||
let isBlacklisted = false;
|
||||
if (root.blacklist && root.blacklist.length > 0) {
|
||||
@@ -159,7 +199,6 @@ Rectangle {
|
||||
if (!str || !rule) {
|
||||
return false;
|
||||
}
|
||||
//Logger.d("Tray", "wildCardMatch - Input str:", str, "rule:", rule)
|
||||
|
||||
// First, convert '*' to a placeholder to preserve it, then escape other special regex characters
|
||||
// Use a unique placeholder that won't appear in normal strings
|
||||
@@ -172,11 +211,9 @@ Rectangle {
|
||||
// Add ^ and $ to match the entire string
|
||||
pattern = '^' + pattern + '$';
|
||||
|
||||
//Logger.d("Tray", "wildCardMatch - Generated pattern:", pattern)
|
||||
try {
|
||||
const regex = new RegExp(pattern, 'i');
|
||||
// 'i' for case-insensitive
|
||||
//Logger.d("Tray", "wildCardMatch - Regex test result:", regex.test(str))
|
||||
return regex.test(str);
|
||||
} catch (e) {
|
||||
Logger.w("Tray", "Invalid regex pattern for wildcard match:", rule, e.message);
|
||||
@@ -211,6 +248,7 @@ Rectangle {
|
||||
target: SystemTray.items
|
||||
function onValuesChanged() {
|
||||
root.updateFilteredItems();
|
||||
// Repeater will automatically update when items change
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,10 +259,14 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
// Watch for hidePassive changes to update filtering immediately
|
||||
onHidePassiveChanged: {
|
||||
root.updateFilteredItems();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
root.updateFilteredItems(); // Initial update
|
||||
}
|
||||
|
||||
visible: filteredItems.length > 0 || dropdownItems.length > 0
|
||||
implicitWidth: isVertical ? Style.capsuleHeight : Math.round(trayFlow.implicitWidth)
|
||||
implicitHeight: isVertical ? Math.round(trayFlow.implicitHeight) : Style.capsuleHeight
|
||||
|
||||
+41
-35
@@ -146,43 +146,49 @@ Loader {
|
||||
const combined = [];
|
||||
const processedAppIds = new Set();
|
||||
|
||||
// Strategy: Maintain app positions as much as possible
|
||||
// 1. First pass: Add all running apps (both pinned and non-pinned) in their current order
|
||||
runningApps.forEach(toplevel => {
|
||||
if (toplevel && toplevel.appId && !(Settings.data.dock.onlySameOutput && toplevel.screens && !toplevel.screens.includes(modelData))) {
|
||||
const isPinned = isAppIdPinned(toplevel.appId, pinnedApps);
|
||||
const appType = isPinned ? "pinned-running" : "running";
|
||||
//push an app onto combined with the given appType
|
||||
function pushApp(appType, toplevel, appId, title) {
|
||||
if (!processedAppIds.has(appId) && !(toplevel && Settings.data.dock.onlySameOutput && toplevel.screens && !toplevel.screens.includes(modelData))) {
|
||||
combined.push({
|
||||
"type": appType,
|
||||
"toplevel": toplevel,
|
||||
"appId": appId,
|
||||
"title": title
|
||||
});
|
||||
processedAppIds.add(appId);
|
||||
}
|
||||
}
|
||||
|
||||
// Use desktop entry name if title is "Loading..." or empty
|
||||
let appTitle = toplevel.title;
|
||||
if (!appTitle || appTitle === "Loading..." || appTitle.trim() === "") {
|
||||
appTitle = getAppNameFromDesktopEntry(toplevel.appId);
|
||||
function pushRunning(first) {
|
||||
runningApps.forEach(toplevel => {
|
||||
if (toplevel) {
|
||||
pushApp((first && pinnedApps.includes(toplevel.appId)) ? "pinned-running" : "running", toplevel, toplevel.appId, toplevel.title);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
combined.push({
|
||||
"type": appType,
|
||||
"toplevel": toplevel,
|
||||
"appId": toplevel.appId,
|
||||
"title": appTitle
|
||||
});
|
||||
processedAppIds.add(normalizeAppId(toplevel.appId));
|
||||
}
|
||||
});
|
||||
function pushPinned() {
|
||||
pinnedApps.forEach(pinnedAppId => {
|
||||
var toplevel = null;
|
||||
for (var app of runningApps) {
|
||||
if (app.appId === pinnedAppId) {
|
||||
toplevel = app;
|
||||
}
|
||||
}
|
||||
pushApp(toplevel ? "pinned-running" : "pinned", toplevel, pinnedAppId, toplevel ? toplevel.title : pinnedAppId);
|
||||
});
|
||||
}
|
||||
|
||||
// 2. Second pass: Add non-running pinned apps at the end
|
||||
pinnedApps.forEach(pinnedAppId => {
|
||||
const normalizedPinnedId = normalizeAppId(pinnedAppId);
|
||||
if (!processedAppIds.has(normalizedPinnedId)) {
|
||||
// Pinned app that is not running - get name from desktop entry
|
||||
const appName = getAppNameFromDesktopEntry(pinnedAppId);
|
||||
combined.push({
|
||||
"type": "pinned",
|
||||
"toplevel": null,
|
||||
"appId": pinnedAppId,
|
||||
"title": appName
|
||||
});
|
||||
}
|
||||
});
|
||||
//if pinnedStatic then push all pinned and then all remaining running apps
|
||||
if (Settings.data.dock.pinnedStatic) {
|
||||
pushPinned();
|
||||
pushRunning(false);
|
||||
|
||||
//else add all running apps and then remaining pinned apps
|
||||
} else {
|
||||
pushRunning(true);
|
||||
pushPinned();
|
||||
}
|
||||
|
||||
dockApps = combined;
|
||||
}
|
||||
@@ -455,7 +461,7 @@ Loader {
|
||||
cache: true
|
||||
|
||||
// Dim pinned apps that aren't running
|
||||
opacity: appButton.isRunning ? 1.0 : 0.6
|
||||
opacity: appButton.isRunning ? 1.0 : Settings.data.dock.deadOpacity
|
||||
|
||||
scale: appButton.hovered ? 1.15 : 1.0
|
||||
|
||||
@@ -657,7 +663,7 @@ Loader {
|
||||
|
||||
// Active indicator
|
||||
Rectangle {
|
||||
visible: isActive
|
||||
visible: Settings.data.dock.inactiveIndicators ? isRunning : isActive
|
||||
width: iconSize * 0.2
|
||||
height: iconSize * 0.1
|
||||
color: Color.mPrimary
|
||||
|
||||
@@ -32,11 +32,11 @@ PopupWindow {
|
||||
visible: false
|
||||
|
||||
// Hidden text element for measuring text width
|
||||
Text {
|
||||
NText {
|
||||
id: textMeasure
|
||||
visible: false
|
||||
font.pointSize: Style.fontSizeS
|
||||
font.family: "Sans Serif" // Match your NText font if different
|
||||
pointSize: Style.fontSizeS
|
||||
family: "Sans Serif" // Match your NText font if different
|
||||
wrapMode: Text.NoWrap
|
||||
elide: Text.ElideNone
|
||||
}
|
||||
@@ -67,7 +67,7 @@ PopupWindow {
|
||||
}
|
||||
}
|
||||
// Apply a reasonable minimum width (like 120px)
|
||||
menuContentWidth = Math.max(120, maxWidth);
|
||||
menuContentWidth = Math.max(120, Math.ceil(maxWidth));
|
||||
}
|
||||
|
||||
function initItems() {
|
||||
|
||||
@@ -33,8 +33,8 @@ PanelWindow {
|
||||
readonly property string barPosition: Settings.data.bar.position || "top"
|
||||
readonly property bool barIsVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property bool barFloating: Settings.data.bar.floating || false
|
||||
readonly property real barMarginH: Math.round(barFloating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0)
|
||||
readonly property real barMarginV: Math.round(barFloating ? Settings.data.bar.marginVertical * Style.marginXL : 0)
|
||||
readonly property real barMarginH: Math.ceil(barFloating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0)
|
||||
readonly property real barMarginV: Math.ceil(barFloating ? Settings.data.bar.marginVertical * Style.marginXL : 0)
|
||||
|
||||
// Anchor to the bar's edge
|
||||
anchors {
|
||||
|
||||
@@ -17,8 +17,8 @@ PanelWindow {
|
||||
readonly property string barPosition: Settings.data.bar.position || "top"
|
||||
readonly property bool barIsVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property bool barFloating: Settings.data.bar.floating || false
|
||||
readonly property real barMarginH: barFloating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
|
||||
readonly property real barMarginV: barFloating ? Settings.data.bar.marginVertical * Style.marginXL : 0
|
||||
readonly property real barMarginH: barFloating ? Math.ceil(Settings.data.bar.marginHorizontal * Style.marginXL) : 0
|
||||
readonly property real barMarginV: barFloating ? Math.ceil(Settings.data.bar.marginVertical * Style.marginXL) : 0
|
||||
|
||||
// Invisible - just reserves space
|
||||
color: "transparent"
|
||||
@@ -45,9 +45,9 @@ PanelWindow {
|
||||
// Vertical bar: reserve bar height + margin on the anchored edge only
|
||||
if (barFloating) {
|
||||
// For left bar, reserve left margin; for right bar, reserve right margin
|
||||
return Style.barHeight + barMarginH;
|
||||
return Style.barHeight + barMarginH + 1;
|
||||
}
|
||||
return Style.barHeight;
|
||||
return Style.barHeight + 1;
|
||||
}
|
||||
return 0; // Auto-width when left/right anchors are true
|
||||
}
|
||||
@@ -57,9 +57,9 @@ PanelWindow {
|
||||
// Horizontal bar: reserve bar height + margin on the anchored edge only
|
||||
if (barFloating) {
|
||||
// For top bar, reserve top margin; for bottom bar, reserve bottom margin
|
||||
return Style.barHeight + barMarginV;
|
||||
return Style.barHeight + barMarginV + 1;
|
||||
}
|
||||
return Style.barHeight;
|
||||
return Style.barHeight + 1;
|
||||
}
|
||||
return 0; // Auto-height when top/bottom anchors are true
|
||||
}
|
||||
|
||||
@@ -325,8 +325,8 @@ PanelWindow {
|
||||
readonly property string barPosition: Settings.data.bar.position || "top"
|
||||
readonly property bool barIsVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property bool barFloating: Settings.data.bar.floating || false
|
||||
readonly property real barMarginH: barFloating ? Math.round(Settings.data.bar.marginHorizontal * Style.marginXL) : 0
|
||||
readonly property real barMarginV: barFloating ? Math.round(Settings.data.bar.marginVertical * Style.marginXL) : 0
|
||||
readonly property real barMarginH: barFloating ? Math.ceil(Settings.data.bar.marginHorizontal * Style.marginXL) : 0
|
||||
readonly property real barMarginV: barFloating ? Math.ceil(Settings.data.bar.marginVertical * Style.marginXL) : 0
|
||||
readonly property real attachmentOverlap: 1 // Attachment overlap to fix hairline gap with fractional scaling
|
||||
|
||||
// Expose bar dimensions directly on this Item for BarBackground
|
||||
@@ -419,167 +419,100 @@ PanelWindow {
|
||||
// ========================================
|
||||
// These shortcuts delegate to the opened panel's handler functions
|
||||
// Panels can implement: onEscapePressed, onTabPressed, onBackTabPressed,
|
||||
// onUpPressed, onDownPressed, onReturnPressed
|
||||
|
||||
// onUpPressed, onDownPressed, onReturnPressed, etc...
|
||||
Shortcut {
|
||||
sequence: "Escape"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onEscapePressed) {
|
||||
PanelService.openedPanel.onEscapePressed();
|
||||
} else if (PanelService.openedPanel) {
|
||||
PanelService.openedPanel.close();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onEscapePressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onEscapePressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Tab"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onTabPressed) {
|
||||
PanelService.openedPanel.onTabPressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onTabPressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onTabPressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Backtab"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onBackTabPressed) {
|
||||
PanelService.openedPanel.onBackTabPressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onBackTabPressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onBackTabPressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Up"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onUpPressed) {
|
||||
PanelService.openedPanel.onUpPressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onUpPressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onUpPressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Down"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onDownPressed) {
|
||||
PanelService.openedPanel.onDownPressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onDownPressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onDownPressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Return"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onReturnPressed) {
|
||||
PanelService.openedPanel.onReturnPressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onReturnPressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onReturnPressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Left"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onLeftPressed) {
|
||||
PanelService.openedPanel.onLeftPressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onLeftPressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onLeftPressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Right"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onRightPressed) {
|
||||
PanelService.openedPanel.onRightPressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onRightPressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onRightPressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Home"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onHomePressed) {
|
||||
PanelService.openedPanel.onHomePressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onHomePressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onHomePressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "End"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onEndPressed) {
|
||||
PanelService.openedPanel.onEndPressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onEndPressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onEndPressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "PgUp"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onPageUpPressed) {
|
||||
PanelService.openedPanel.onPageUpPressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onPageUpPressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onPageUpPressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "PgDown"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onPageDownPressed) {
|
||||
PanelService.openedPanel.onPageDownPressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onPageDownPressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onPageDownPressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Ctrl+J"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onCtrlJPressed) {
|
||||
PanelService.openedPanel.onCtrlJPressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onCtrlJPressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onCtrlJPressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Ctrl+K"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onCtrlKPressed) {
|
||||
PanelService.openedPanel.onCtrlKPressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onCtrlKPressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onCtrlKPressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Ctrl+N"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onCtrlNPressed) {
|
||||
PanelService.openedPanel.onCtrlNPressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onCtrlNPressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onCtrlNPressed()
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Ctrl+P"
|
||||
enabled: root.isPanelOpen
|
||||
onActivated: {
|
||||
if (PanelService.openedPanel && PanelService.openedPanel.onCtrlPPressed) {
|
||||
PanelService.openedPanel.onCtrlPPressed();
|
||||
}
|
||||
}
|
||||
enabled: root.isPanelOpen && (PanelService.openedPanel.onCtrlPPressed !== undefined)
|
||||
onActivated: PanelService.openedPanel.onCtrlPPressed()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,43 +63,27 @@ Item {
|
||||
property bool closeWatchdogActive: false
|
||||
property bool openWatchdogActive: false
|
||||
|
||||
// Cached animation direction - set when panel opens, doesn't change during animation
|
||||
// These are computed once when opening and used for the entire open/close cycle
|
||||
property bool cachedAnimateFromTop: false
|
||||
property bool cachedAnimateFromBottom: false
|
||||
property bool cachedAnimateFromLeft: false
|
||||
property bool cachedAnimateFromRight: false
|
||||
property bool cachedShouldAnimateWidth: false
|
||||
property bool cachedShouldAnimateHeight: false
|
||||
|
||||
// Close with escape key
|
||||
property bool closeWithEscape: true
|
||||
|
||||
property bool exclusiveKeyboard: true
|
||||
|
||||
// Keyboard event handlers - override these in specific panels to handle shortcuts
|
||||
// Keyboard event handler
|
||||
// These are called from MainScreen's centralized shortcuts
|
||||
// override these in specific panels to handle shortcuts
|
||||
function onEscapePressed() {
|
||||
if (closeWithEscape)
|
||||
close();
|
||||
}
|
||||
function onTabPressed() {
|
||||
}
|
||||
function onBackTabPressed() {
|
||||
}
|
||||
function onUpPressed() {
|
||||
}
|
||||
function onDownPressed() {
|
||||
}
|
||||
function onLeftPressed() {
|
||||
}
|
||||
function onRightPressed() {
|
||||
}
|
||||
function onReturnPressed() {
|
||||
}
|
||||
function onHomePressed() {
|
||||
}
|
||||
function onEndPressed() {
|
||||
}
|
||||
function onPageUpPressed() {
|
||||
}
|
||||
function onPageDownPressed() {
|
||||
}
|
||||
function onCtrlJPressed() {
|
||||
}
|
||||
function onCtrlKPressed() {
|
||||
}
|
||||
|
||||
// Expose panel region for background rendering
|
||||
readonly property var panelRegion: panelContent.geometryPlaceholder
|
||||
@@ -107,8 +91,8 @@ Item {
|
||||
readonly property string barPosition: Settings.data.bar.position
|
||||
readonly property bool barIsVertical: barPosition === "left" || barPosition === "right"
|
||||
readonly property bool barFloating: Settings.data.bar.floating
|
||||
readonly property real barMarginH: barFloating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
|
||||
readonly property real barMarginV: barFloating ? Settings.data.bar.marginVertical * Style.marginXL : 0
|
||||
readonly property real barMarginH: barFloating ? Math.ceil(Settings.data.bar.marginHorizontal * Style.marginXL) : 0
|
||||
readonly property real barMarginV: barFloating ? Math.ceil(Settings.data.bar.marginVertical * Style.marginXL) : 0
|
||||
|
||||
// Check if bar should be visible on this screen
|
||||
readonly property bool barShouldShow: {
|
||||
@@ -124,14 +108,14 @@ Item {
|
||||
readonly property bool hasExplicitVerticalAnchor: panelAnchorVerticalCenter || panelAnchorTop || panelAnchorBottom
|
||||
|
||||
// Effective anchor properties (depend on allowAttach)
|
||||
// These are true when:
|
||||
// 1. Explicitly anchored, OR
|
||||
// These are true when allowAttach is enabled AND:
|
||||
// 1. Explicitly anchored to that edge, OR
|
||||
// 2. Using button position and bar is on that edge, OR
|
||||
// 3. Attached to bar with no explicit anchors (default centering behavior)
|
||||
readonly property bool effectivePanelAnchorTop: panelAnchorTop || (useButtonPosition && barPosition === "top") || (panelContent.allowAttach && !hasExplicitVerticalAnchor && barPosition === "top" && !barIsVertical)
|
||||
readonly property bool effectivePanelAnchorBottom: panelAnchorBottom || (useButtonPosition && barPosition === "bottom") || (panelContent.allowAttach && !hasExplicitVerticalAnchor && barPosition === "bottom" && !barIsVertical)
|
||||
readonly property bool effectivePanelAnchorLeft: panelAnchorLeft || (useButtonPosition && barPosition === "left") || (panelContent.allowAttach && !hasExplicitHorizontalAnchor && barPosition === "left" && barIsVertical)
|
||||
readonly property bool effectivePanelAnchorRight: panelAnchorRight || (useButtonPosition && barPosition === "right") || (panelContent.allowAttach && !hasExplicitHorizontalAnchor && barPosition === "right" && barIsVertical)
|
||||
// 3. No explicit anchors and bar is on that edge (default centering behavior)
|
||||
readonly property bool effectivePanelAnchorTop: panelContent.allowAttach && (panelAnchorTop || (useButtonPosition && barPosition === "top") || (!hasExplicitVerticalAnchor && barPosition === "top" && !barIsVertical))
|
||||
readonly property bool effectivePanelAnchorBottom: panelContent.allowAttach && (panelAnchorBottom || (useButtonPosition && barPosition === "bottom") || (!hasExplicitVerticalAnchor && barPosition === "bottom" && !barIsVertical))
|
||||
readonly property bool effectivePanelAnchorLeft: panelContent.allowAttach && (panelAnchorLeft || (useButtonPosition && barPosition === "left") || (!hasExplicitHorizontalAnchor && barPosition === "left" && barIsVertical))
|
||||
readonly property bool effectivePanelAnchorRight: panelContent.allowAttach && (panelAnchorRight || (useButtonPosition && barPosition === "right") || (!hasExplicitHorizontalAnchor && barPosition === "right" && barIsVertical))
|
||||
|
||||
signal opened
|
||||
signal closed
|
||||
@@ -347,36 +331,44 @@ Item {
|
||||
} else {
|
||||
calculatedX = (root.width - panelWidth) / 2;
|
||||
}
|
||||
} else if (root.effectivePanelAnchorRight) {
|
||||
if (panelContent.allowAttach && root.barIsVertical && root.barPosition === "right") {
|
||||
var rightBarEdge = root.width - root.barMarginH - Style.barHeight;
|
||||
calculatedX = rightBarEdge - panelWidth;
|
||||
} else if (panelContent.allowAttach) {
|
||||
// Account for corner inset when bar is floating, horizontal, AND panel is on same edge as bar
|
||||
var panelOnSameEdgeAsBar = (root.barPosition === "top" && root.effectivePanelAnchorTop) || (root.barPosition === "bottom" && root.effectivePanelAnchorBottom);
|
||||
if (!root.barIsVertical && root.barFloating && panelOnSameEdgeAsBar) {
|
||||
var rightCornerInset = Style.radiusL * 2;
|
||||
calculatedX = root.width - root.barMarginH - rightCornerInset - panelWidth;
|
||||
} else if (root.panelAnchorRight) {
|
||||
// Use raw panelAnchorRight for positioning decision
|
||||
if (root.effectivePanelAnchorRight) {
|
||||
// Attached: snap to edge/bar
|
||||
if (root.barIsVertical && root.barPosition === "right") {
|
||||
var rightBarEdge = root.width - root.barMarginH - Style.barHeight;
|
||||
calculatedX = rightBarEdge - panelWidth;
|
||||
} else {
|
||||
calculatedX = root.width - panelWidth;
|
||||
var panelOnSameEdgeAsBar = (root.barPosition === "top" && root.effectivePanelAnchorTop) || (root.barPosition === "bottom" && root.effectivePanelAnchorBottom);
|
||||
if (!root.barIsVertical && root.barFloating && panelOnSameEdgeAsBar) {
|
||||
var rightCornerInset = Style.radiusL * 2;
|
||||
calculatedX = root.width - root.barMarginH - rightCornerInset - panelWidth;
|
||||
} else {
|
||||
calculatedX = root.width - panelWidth;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Not attached: position at right with margin
|
||||
calculatedX = root.width - panelWidth - Style.marginL;
|
||||
}
|
||||
} else if (root.effectivePanelAnchorLeft) {
|
||||
if (panelContent.allowAttach && root.barIsVertical && root.barPosition === "left") {
|
||||
var leftBarEdge = root.barMarginH + Style.barHeight;
|
||||
calculatedX = leftBarEdge;
|
||||
} else if (panelContent.allowAttach) {
|
||||
// Account for corner inset when bar is floating, horizontal, AND panel is on same edge as bar
|
||||
var panelOnSameEdgeAsBar = (root.barPosition === "top" && root.effectivePanelAnchorTop) || (root.barPosition === "bottom" && root.effectivePanelAnchorBottom);
|
||||
if (!root.barIsVertical && root.barFloating && panelOnSameEdgeAsBar) {
|
||||
var leftCornerInset = Style.radiusL * 2;
|
||||
calculatedX = root.barMarginH + leftCornerInset;
|
||||
} else if (root.panelAnchorLeft) {
|
||||
// Use raw panelAnchorLeft for positioning decision
|
||||
if (root.effectivePanelAnchorLeft) {
|
||||
// Attached: snap to edge/bar
|
||||
if (root.barIsVertical && root.barPosition === "left") {
|
||||
var leftBarEdge = root.barMarginH + Style.barHeight;
|
||||
calculatedX = leftBarEdge;
|
||||
} else {
|
||||
calculatedX = 0;
|
||||
var panelOnSameEdgeAsBar = (root.barPosition === "top" && root.effectivePanelAnchorTop) || (root.barPosition === "bottom" && root.effectivePanelAnchorBottom);
|
||||
if (!root.barIsVertical && root.barFloating && panelOnSameEdgeAsBar) {
|
||||
var leftCornerInset = Style.radiusL * 2;
|
||||
calculatedX = root.barMarginH + leftCornerInset;
|
||||
} else {
|
||||
calculatedX = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Not attached: position at left with margin
|
||||
calculatedX = Style.marginL;
|
||||
}
|
||||
} else {
|
||||
@@ -496,17 +488,23 @@ Item {
|
||||
} else {
|
||||
calculatedY = (root.height - panelHeight) / 2;
|
||||
}
|
||||
} else if (root.effectivePanelAnchorTop) {
|
||||
if (panelContent.allowAttach) {
|
||||
calculatedY = 0;
|
||||
} else if (root.panelAnchorTop) {
|
||||
// Use raw panelAnchorTop for positioning decision
|
||||
if (root.effectivePanelAnchorTop) {
|
||||
// Attached: snap to edge/bar
|
||||
calculatedY = root.barPosition === "top" ? root.barMarginV + Style.barHeight : 0;
|
||||
} else {
|
||||
// Not attached: position at top with margin
|
||||
var topBarOffset = (root.barPosition === "top") ? barOffset : 0;
|
||||
calculatedY = topBarOffset + Style.marginL;
|
||||
}
|
||||
} else if (root.effectivePanelAnchorBottom) {
|
||||
if (panelContent.allowAttach) {
|
||||
calculatedY = root.height - panelHeight;
|
||||
} else if (root.panelAnchorBottom) {
|
||||
// Use raw panelAnchorBottom for positioning decision
|
||||
if (root.effectivePanelAnchorBottom) {
|
||||
// Attached: snap to edge/bar
|
||||
calculatedY = root.barPosition === "bottom" ? root.height - root.barMarginV - Style.barHeight - panelHeight : root.height - panelHeight;
|
||||
} else {
|
||||
// Not attached: position at bottom with margin
|
||||
var bottomBarOffset = (root.barPosition === "bottom") ? barOffset : 0;
|
||||
calculatedY = root.height - panelHeight - bottomBarOffset - Style.marginL;
|
||||
}
|
||||
@@ -794,10 +792,20 @@ Item {
|
||||
return true;
|
||||
}
|
||||
// Attached to vertical bar (left/right) - don't animate from top
|
||||
if (panelContent.allowAttachToBar && root.barIsVertical && (root.effectivePanelAnchorLeft || root.effectivePanelAnchorRight)) {
|
||||
// Only if panel is on the SAME side as the bar
|
||||
var attachedToVerticalBar = panelContent.allowAttachToBar && root.barIsVertical && ((root.effectivePanelAnchorLeft && root.barPosition === "left") || (root.effectivePanelAnchorRight && root.barPosition === "right"));
|
||||
if (attachedToVerticalBar) {
|
||||
return false;
|
||||
}
|
||||
// Default: animate from top
|
||||
// Panel anchored to left/right edge - animate from that edge instead
|
||||
if (root.panelAnchorLeft || root.panelAnchorRight) {
|
||||
return false;
|
||||
}
|
||||
// Attached to top edge
|
||||
if (panelContent.allowAttach && root.panelAnchorTop) {
|
||||
return true;
|
||||
}
|
||||
// Default: animate from top (for floating panels)
|
||||
return true;
|
||||
}
|
||||
// Panel is visible - use calculated positions
|
||||
@@ -829,7 +837,13 @@ Item {
|
||||
}
|
||||
readonly property bool animateFromLeft: {
|
||||
if (!root.isPanelVisible) {
|
||||
if (panelContent.allowAttachToBar && root.effectivePanelAnchorLeft && root.barIsVertical) {
|
||||
// Attached to vertical bar on left - must verify bar is actually on left
|
||||
if (panelContent.allowAttachToBar && root.effectivePanelAnchorLeft && root.barIsVertical && root.barPosition === "left") {
|
||||
return true;
|
||||
}
|
||||
// Panel anchored to left edge - animate from left
|
||||
// Takes precedence over top/bottom when bar is vertical
|
||||
if (root.panelAnchorLeft) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -850,7 +864,13 @@ Item {
|
||||
}
|
||||
readonly property bool animateFromRight: {
|
||||
if (!root.isPanelVisible) {
|
||||
if (panelContent.allowAttachToBar && root.effectivePanelAnchorRight && root.barIsVertical) {
|
||||
// Attached to vertical bar on right - must verify bar is actually on right
|
||||
if (panelContent.allowAttachToBar && root.effectivePanelAnchorRight && root.barIsVertical && root.barPosition === "right") {
|
||||
return true;
|
||||
}
|
||||
// Panel anchored to right edge - animate from right
|
||||
// Takes precedence over top/bottom when bar is vertical
|
||||
if (root.panelAnchorRight) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -873,6 +893,7 @@ Item {
|
||||
// Determine animation axis based on which edge is closest
|
||||
// Priority: horizontal edges (top/bottom) take precedence over vertical edges (left/right)
|
||||
// This prevents diagonal animations when panel is attached to a corner
|
||||
// Use reactive values here - they're evaluated BEFORE isPanelVisible becomes true
|
||||
readonly property bool shouldAnimateWidth: !shouldAnimateHeight && (animateFromLeft || animateFromRight)
|
||||
readonly property bool shouldAnimateHeight: animateFromTop || animateFromBottom
|
||||
|
||||
@@ -901,23 +922,21 @@ Item {
|
||||
|
||||
x: {
|
||||
// Offset x to make panel grow/shrink from the appropriate edge
|
||||
if (animateFromRight) {
|
||||
// Use CACHED values to prevent recalculation during animation
|
||||
if (root.cachedAnimateFromRight && root.cachedShouldAnimateWidth) {
|
||||
// Keep the RIGHT edge fixed at its target position
|
||||
if (isPanelVisible || isClosing) {
|
||||
var targetRightEdge = targetX + targetWidth;
|
||||
return targetRightEdge - width;
|
||||
}
|
||||
var targetRightEdge = targetX + targetWidth;
|
||||
return targetRightEdge - width;
|
||||
}
|
||||
return targetX;
|
||||
}
|
||||
y: {
|
||||
// Offset y to make panel grow/shrink from the appropriate edge
|
||||
if (animateFromBottom) {
|
||||
// Use CACHED values to prevent recalculation during animation
|
||||
if (root.cachedAnimateFromBottom && root.cachedShouldAnimateHeight) {
|
||||
// Keep the BOTTOM edge fixed at its target position
|
||||
if (isPanelVisible || isClosing) {
|
||||
var targetBottomEdge = targetY + targetHeight;
|
||||
return targetBottomEdge - height;
|
||||
}
|
||||
var targetBottomEdge = targetY + targetHeight;
|
||||
return targetBottomEdge - height;
|
||||
}
|
||||
return targetY;
|
||||
}
|
||||
@@ -1158,6 +1177,15 @@ Item {
|
||||
// Mark dimensions as initialized to enable animations
|
||||
panelBackground.dimensionsInitialized = true;
|
||||
|
||||
// Cache animation direction BEFORE isPanelVisible becomes true
|
||||
// This locks in the direction for the entire open/close cycle
|
||||
root.cachedAnimateFromTop = panelBackground.animateFromTop;
|
||||
root.cachedAnimateFromBottom = panelBackground.animateFromBottom;
|
||||
root.cachedAnimateFromLeft = panelBackground.animateFromLeft;
|
||||
root.cachedAnimateFromRight = panelBackground.animateFromRight;
|
||||
root.cachedShouldAnimateWidth = panelBackground.shouldAnimateWidth;
|
||||
root.cachedShouldAnimateHeight = panelBackground.shouldAnimateHeight;
|
||||
|
||||
// Make panel visible, now only the intended dimension will animate
|
||||
root.isPanelVisible = true;
|
||||
opacityTrigger.start();
|
||||
|
||||
@@ -67,28 +67,28 @@ Variants {
|
||||
readonly property int barOffsetTop: {
|
||||
if (barPos !== "top")
|
||||
return 0;
|
||||
const floatMarginV = isFloating ? Settings.data.bar.marginVertical * Style.marginXL : 0;
|
||||
const floatMarginV = isFloating ? Math.ceil(Settings.data.bar.marginVertical * Style.marginXL) : 0;
|
||||
return Style.barHeight + floatMarginV;
|
||||
}
|
||||
|
||||
readonly property int barOffsetBottom: {
|
||||
if (barPos !== "bottom")
|
||||
return 0;
|
||||
const floatMarginV = isFloating ? Settings.data.bar.marginVertical * Style.marginXL : 0;
|
||||
const floatMarginV = isFloating ? Math.ceil(Settings.data.bar.marginVertical * Style.marginXL) : 0;
|
||||
return Style.barHeight + floatMarginV;
|
||||
}
|
||||
|
||||
readonly property int barOffsetLeft: {
|
||||
if (barPos !== "left")
|
||||
return 0;
|
||||
const floatMarginH = isFloating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0;
|
||||
const floatMarginH = isFloating ? Math.ceil(Settings.data.bar.marginHorizontal * Style.marginXL) : 0;
|
||||
return Style.barHeight + floatMarginH;
|
||||
}
|
||||
|
||||
readonly property int barOffsetRight: {
|
||||
if (barPos !== "right")
|
||||
return 0;
|
||||
const floatMarginH = isFloating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0;
|
||||
const floatMarginH = isFloating ? Math.ceil(Settings.data.bar.marginHorizontal * Style.marginXL) : 0;
|
||||
return Style.barHeight + floatMarginH;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -419,7 +419,7 @@ Variants {
|
||||
let base = Style.marginM;
|
||||
if (Settings.data.bar.position === position) {
|
||||
const isVertical = position === "top" || position === "bottom";
|
||||
const floatExtra = Settings.data.bar.floating ? (isVertical ? Settings.data.bar.marginVertical : Settings.data.bar.marginHorizontal) * Style.marginXL : 0;
|
||||
const floatExtra = Math.ceil(Settings.data.bar.floating ? (isVertical ? Settings.data.bar.marginVertical : Settings.data.bar.marginHorizontal) * Style.marginXL : 0);
|
||||
return Style.barHeight + base + floatExtra;
|
||||
}
|
||||
return base;
|
||||
|
||||
@@ -22,6 +22,19 @@ SmartPanel {
|
||||
preferredWidth: Math.round(420 * Style.uiScaleRatio)
|
||||
preferredHeight: Math.round(420 * Style.uiScaleRatio)
|
||||
|
||||
Component.onCompleted: {
|
||||
var vol = AudioService.volume;
|
||||
localOutputVolume = (vol !== undefined && !isNaN(vol)) ? vol : 0;
|
||||
var inputVol = AudioService.inputVolume;
|
||||
localInputVolume = (inputVol !== undefined && !isNaN(inputVol)) ? inputVol : 0;
|
||||
if (AudioService.sink) {
|
||||
lastSinkId = AudioService.sink.id;
|
||||
}
|
||||
if (AudioService.source) {
|
||||
lastSourceId = AudioService.source.id;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset local volume when device changes - use current device's volume
|
||||
Connections {
|
||||
target: AudioService
|
||||
@@ -31,7 +44,8 @@ SmartPanel {
|
||||
if (newSinkId !== lastSinkId) {
|
||||
lastSinkId = newSinkId;
|
||||
// Immediately set local volume to current device's volume
|
||||
localOutputVolume = AudioService.volume;
|
||||
var vol = AudioService.volume;
|
||||
localOutputVolume = (vol !== undefined && !isNaN(vol)) ? vol : 0;
|
||||
}
|
||||
} else {
|
||||
lastSinkId = -1;
|
||||
@@ -48,7 +62,8 @@ SmartPanel {
|
||||
if (newSourceId !== lastSourceId) {
|
||||
lastSourceId = newSourceId;
|
||||
// Immediately set local volume to current device's volume
|
||||
localInputVolume = AudioService.inputVolume;
|
||||
var vol = AudioService.inputVolume;
|
||||
localInputVolume = (vol !== undefined && !isNaN(vol)) ? vol : 0;
|
||||
}
|
||||
} else {
|
||||
lastSourceId = -1;
|
||||
@@ -62,7 +77,8 @@ SmartPanel {
|
||||
target: AudioService
|
||||
function onVolumeChanged() {
|
||||
if (!localOutputVolumeChanging && AudioService.sink && AudioService.sink.id === lastSinkId) {
|
||||
localOutputVolume = AudioService.volume;
|
||||
var vol = AudioService.volume;
|
||||
localOutputVolume = (vol !== undefined && !isNaN(vol)) ? vol : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,7 +87,8 @@ SmartPanel {
|
||||
target: AudioService.sink?.audio ? AudioService.sink?.audio : null
|
||||
function onVolumeChanged() {
|
||||
if (!localOutputVolumeChanging && AudioService.sink && AudioService.sink.id === lastSinkId) {
|
||||
localOutputVolume = AudioService.volume;
|
||||
var vol = AudioService.volume;
|
||||
localOutputVolume = (vol !== undefined && !isNaN(vol)) ? vol : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,7 +97,8 @@ SmartPanel {
|
||||
target: AudioService
|
||||
function onInputVolumeChanged() {
|
||||
if (!localInputVolumeChanging && AudioService.source && AudioService.source.id === lastSourceId) {
|
||||
localInputVolume = AudioService.inputVolume;
|
||||
var vol = AudioService.inputVolume;
|
||||
localInputVolume = (vol !== undefined && !isNaN(vol)) ? vol : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,7 +107,8 @@ SmartPanel {
|
||||
target: AudioService.source?.audio ? AudioService.source?.audio : null
|
||||
function onVolumeChanged() {
|
||||
if (!localInputVolumeChanging && AudioService.source && AudioService.source.id === lastSourceId) {
|
||||
localInputVolume = AudioService.inputVolume;
|
||||
var vol = AudioService.inputVolume;
|
||||
localInputVolume = (vol !== undefined && !isNaN(vol)) ? vol : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -228,8 +247,8 @@ SmartPanel {
|
||||
value: localOutputVolume
|
||||
stepSize: 0.01
|
||||
heightRatio: 0.5
|
||||
onMoved: value => localOutputVolume = value
|
||||
onPressedChanged: (pressed, value) => localOutputVolumeChanging = pressed
|
||||
onMoved: localOutputVolume = value
|
||||
onPressedChanged: localOutputVolumeChanging = pressed
|
||||
text: Math.round(localOutputVolume * 100) + "%"
|
||||
Layout.bottomMargin: Style.marginM
|
||||
}
|
||||
@@ -285,8 +304,8 @@ SmartPanel {
|
||||
value: localInputVolume
|
||||
stepSize: 0.01
|
||||
heightRatio: 0.5
|
||||
onMoved: value => localInputVolume = value
|
||||
onPressedChanged: (pressed, value) => localInputVolumeChanging = pressed
|
||||
onMoved: localInputVolume = value
|
||||
onPressedChanged: localInputVolumeChanging = pressed
|
||||
text: Math.round(localInputVolume * 100) + "%"
|
||||
Layout.bottomMargin: Style.marginM
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ SmartPanel {
|
||||
}
|
||||
|
||||
// Target columns, but actual columns may vary based on available width
|
||||
// Account for NTabBar margins (Style.marginXS on each side) to match category tabs width
|
||||
// Account for NTabBar margins to match category tabs width
|
||||
readonly property int targetGridColumns: 5
|
||||
readonly property int gridContentWidth: listPanelWidth - (2 * Style.marginXS)
|
||||
readonly property int gridCellSize: Math.floor((gridContentWidth - ((targetGridColumns - 1) * Style.marginS)) / targetGridColumns)
|
||||
@@ -87,7 +87,7 @@ SmartPanel {
|
||||
var currentIndex = emojiPlugin.categories.indexOf(emojiPlugin.selectedCategory);
|
||||
var nextIndex = (currentIndex + 1) % emojiPlugin.categories.length;
|
||||
emojiPlugin.selectCategory(emojiPlugin.categories[nextIndex]);
|
||||
} else if ((activePlugin === null || activePlugin === appsPlugin) && appsPlugin.isBrowsingMode && !root.searchText.startsWith(">")) {
|
||||
} else if ((activePlugin === null || activePlugin === appsPlugin) && appsPlugin.isBrowsingMode && !root.searchText.startsWith(">") && Settings.data.appLauncher.showCategories) {
|
||||
// In apps browsing mode (no search), Tab navigates between categories
|
||||
var availableCategories = appsPlugin.availableCategories || ["all"];
|
||||
var currentIndex = availableCategories.indexOf(appsPlugin.selectedCategory);
|
||||
@@ -103,7 +103,7 @@ SmartPanel {
|
||||
var currentIndex = emojiPlugin.categories.indexOf(emojiPlugin.selectedCategory);
|
||||
var previousIndex = ((currentIndex - 1) % emojiPlugin.categories.length + emojiPlugin.categories.length) % emojiPlugin.categories.length;
|
||||
emojiPlugin.selectCategory(emojiPlugin.categories[previousIndex]);
|
||||
} else if ((activePlugin === null || activePlugin === appsPlugin) && appsPlugin.isBrowsingMode && !root.searchText.startsWith(">")) {
|
||||
} else if ((activePlugin === null || activePlugin === appsPlugin) && appsPlugin.isBrowsingMode && !root.searchText.startsWith(">") && Settings.data.appLauncher.showCategories) {
|
||||
var availableCategories = appsPlugin.availableCategories || ["all"];
|
||||
var currentIndex = availableCategories.indexOf(appsPlugin.selectedCategory);
|
||||
var previousIndex = ((currentIndex - 1) % availableCategories.length + availableCategories.length) % availableCategories.length;
|
||||
@@ -320,6 +320,14 @@ SmartPanel {
|
||||
}
|
||||
}
|
||||
|
||||
CommandPlugin {
|
||||
id: cmdPlugin
|
||||
Component.onCompleted: {
|
||||
registerPlugin(this);
|
||||
Logger.d("Launcher", "Registered: CommandPlugin");
|
||||
}
|
||||
}
|
||||
|
||||
EmojiPlugin {
|
||||
id: emojiPlugin
|
||||
Component.onCompleted: {
|
||||
@@ -648,6 +656,7 @@ SmartPanel {
|
||||
id: emojiCategoryTabs
|
||||
visible: root.activePlugin === emojiPlugin && emojiPlugin.isBrowsingMode
|
||||
Layout.fillWidth: true
|
||||
margins: Style.marginM
|
||||
property int computedCurrentIndex: {
|
||||
if (visible && emojiPlugin.categories) {
|
||||
return emojiPlugin.categories.indexOf(emojiPlugin.selectedCategory);
|
||||
@@ -690,8 +699,9 @@ SmartPanel {
|
||||
// App category tabs (shown when browsing apps without search)
|
||||
NTabBar {
|
||||
id: appCategoryTabs
|
||||
visible: (root.activePlugin === null || root.activePlugin === appsPlugin) && appsPlugin.isBrowsingMode && !root.searchText.startsWith(">")
|
||||
visible: (root.activePlugin === null || root.activePlugin === appsPlugin) && appsPlugin.isBrowsingMode && !root.searchText.startsWith(">") && Settings.data.appLauncher.showCategories
|
||||
Layout.fillWidth: true
|
||||
margins: Style.marginM
|
||||
property int computedCurrentIndex: {
|
||||
if (visible && appsPlugin.availableCategories) {
|
||||
return appsPlugin.availableCategories.indexOf(appsPlugin.selectedCategory);
|
||||
|
||||
@@ -15,11 +15,12 @@ Item {
|
||||
// Category support
|
||||
property string selectedCategory: "all"
|
||||
property bool isBrowsingMode: false
|
||||
property var categories: ["all", "AudioVideo", "Chat", "Development", "Education", "Game", "Graphics", "Network", "Office", "System", "Misc", "WebBrowser"]
|
||||
property var categories: ["all", "Pinned", "AudioVideo", "Chat", "Development", "Education", "Game", "Graphics", "Network", "Office", "System", "Misc", "WebBrowser"]
|
||||
property var availableCategories: ["all"] // Reactive property for available categories
|
||||
|
||||
property var categoryIcons: ({
|
||||
"all": "apps",
|
||||
"Pinned": "pin",
|
||||
"AudioVideo": "music",
|
||||
"Chat": "message-circle",
|
||||
"Development": "code",
|
||||
@@ -38,6 +39,7 @@ Item {
|
||||
function getCategoryName(category) {
|
||||
const names = {
|
||||
"all": I18n.tr("launcher.categories.all"),
|
||||
"Pinned": I18n.tr("launcher.categories.pinned"),
|
||||
"AudioVideo": I18n.tr("launcher.categories.audiovideo"),
|
||||
"Chat": I18n.tr("launcher.categories.chat"),
|
||||
"Development": I18n.tr("launcher.categories.development"),
|
||||
@@ -200,11 +202,33 @@ Item {
|
||||
return "Misc";
|
||||
}
|
||||
|
||||
// Helper function to normalize app IDs for case-insensitive matching
|
||||
function normalizeAppId(appId) {
|
||||
if (!appId || typeof appId !== 'string')
|
||||
return "";
|
||||
return appId.toLowerCase().trim();
|
||||
}
|
||||
|
||||
// Helper function to check if an app is pinned
|
||||
function isAppPinned(app) {
|
||||
if (!app)
|
||||
return false;
|
||||
const pinnedApps = Settings.data.dock.pinnedApps || [];
|
||||
const appId = getAppKey(app);
|
||||
const normalizedId = normalizeAppId(appId);
|
||||
return pinnedApps.some(pinnedId => normalizeAppId(pinnedId) === normalizedId);
|
||||
}
|
||||
|
||||
function appMatchesCategory(app, category) {
|
||||
// Check if app matches the selected category
|
||||
if (category === "all")
|
||||
return true;
|
||||
|
||||
// Handle Pinned category separately
|
||||
if (category === "Pinned") {
|
||||
return isAppPinned(app);
|
||||
}
|
||||
|
||||
// Get the primary category for this app (first matching standard category)
|
||||
const primaryCategory = getAppCategory(app);
|
||||
|
||||
@@ -241,6 +265,19 @@ Item {
|
||||
let hasAudioVideo = false;
|
||||
let hasEducation = false;
|
||||
let hasSystem = false;
|
||||
let hasPinned = false;
|
||||
|
||||
// Check if there are any pinned apps
|
||||
const pinnedApps = Settings.data.dock.pinnedApps || [];
|
||||
if (pinnedApps.length > 0) {
|
||||
// Verify that at least one pinned app exists in entries
|
||||
for (let app of entries) {
|
||||
if (isAppPinned(app)) {
|
||||
hasPinned = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let app of entries) {
|
||||
const appCategories = getAppCategories(app);
|
||||
@@ -257,6 +294,13 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
const result = ["all"];
|
||||
|
||||
// Add Pinned category first if there are pinned apps
|
||||
if (hasPinned) {
|
||||
result.push("Pinned");
|
||||
}
|
||||
|
||||
if (hasAudioVideo) {
|
||||
categorySet.add("AudioVideo");
|
||||
}
|
||||
@@ -267,9 +311,8 @@ Item {
|
||||
categorySet.add("System");
|
||||
}
|
||||
|
||||
const result = ["all"];
|
||||
for (let cat of root.categories) {
|
||||
if (cat !== "all" && cat !== "Misc" && categorySet.has(cat)) {
|
||||
if (cat !== "all" && cat !== "Pinned" && cat !== "Misc" && categorySet.has(cat)) {
|
||||
result.push(cat);
|
||||
}
|
||||
}
|
||||
@@ -308,6 +351,27 @@ Item {
|
||||
availableCategories = getAvailableCategories();
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Settings.data.dock
|
||||
function onPinnedAppsChanged() {
|
||||
const wasViewingPinned = selectedCategory === "Pinned";
|
||||
updateAvailableCategories();
|
||||
|
||||
// If we were viewing Pinned category and it's no longer available, switch to "all"
|
||||
if (wasViewingPinned && !availableCategories.includes("Pinned")) {
|
||||
selectedCategory = "all";
|
||||
}
|
||||
|
||||
// Update results if we're currently viewing the Pinned category
|
||||
if (selectedCategory === "Pinned" && launcher) {
|
||||
launcher.updateResults();
|
||||
} else if (wasViewingPinned && selectedCategory === "all" && launcher) {
|
||||
// Also update results when switching to "all"
|
||||
launcher.updateResults();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getExecutableName(app) {
|
||||
if (!app)
|
||||
return "";
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
|
||||
Item {
|
||||
property var launcher: null
|
||||
property string name: I18n.tr("plugins.command")
|
||||
|
||||
function handleCommand(query) {
|
||||
return query.startsWith(">cmd");
|
||||
}
|
||||
|
||||
function commands() {
|
||||
return [
|
||||
{
|
||||
"name": ">cmd",
|
||||
"description": I18n.tr("plugins.command-description"),
|
||||
"icon": "utilities-terminal",
|
||||
"isImage": false,
|
||||
"onActivate": function () {
|
||||
launcher.setSearchText(">cmd ");
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
function getResults(query) {
|
||||
if (!query.startsWith(">cmd"))
|
||||
return [];
|
||||
|
||||
let expression = query.substring(4).trim();
|
||||
return [
|
||||
{
|
||||
"name": I18n.tr("plugins.command-name"),
|
||||
"description": I18n.tr("plugins.command-description"),
|
||||
"icon": "utilities-terminal",
|
||||
"isImage": false,
|
||||
"onActivate": function () {
|
||||
launcher.close();
|
||||
Quickshell.execDetached(["sh", "-c", expression]);
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -123,6 +123,38 @@ SmartPanel {
|
||||
id: notificationRect
|
||||
color: Color.transparent
|
||||
|
||||
// Calculate content height based on header + tabs (if visible) + content
|
||||
property real headerHeight: headerBox.implicitHeight
|
||||
property real tabsHeight: tabsBox.visible ? tabsBox.implicitHeight + Style.marginS : 0
|
||||
property real contentHeight: {
|
||||
if (NotificationService.historyList.count === 0) {
|
||||
return emptyState.implicitHeight;
|
||||
}
|
||||
// Calculate actual height of visible notifications
|
||||
var totalHeight = 0;
|
||||
var count = NotificationService.historyList.count;
|
||||
var visibleCount = 0;
|
||||
for (var i = 0; i < count; i++) {
|
||||
var item = NotificationService.historyList.get(i);
|
||||
if (item && root.isInCurrentRange(item.timestamp)) {
|
||||
visibleCount++;
|
||||
}
|
||||
}
|
||||
// Estimate: each notification is roughly 100-150px, use conservative estimate
|
||||
var avgNotificationHeight = 120 * Style.uiScaleRatio;
|
||||
totalHeight = visibleCount * avgNotificationHeight + (visibleCount - 1) * Style.marginM;
|
||||
return totalHeight;
|
||||
}
|
||||
property real calculatedHeight: headerHeight + tabsHeight + contentHeight + (Style.marginL * 2) + (Style.marginM * 2)
|
||||
property real contentPreferredHeight: {
|
||||
if (NotificationService.historyList.count === 0) {
|
||||
// Empty state: smaller height
|
||||
return Math.min(root.preferredHeight, 280 * Style.uiScaleRatio);
|
||||
}
|
||||
// Clamp between minimum (280) and maximum (540)
|
||||
return Math.max(280 * Style.uiScaleRatio, Math.min(root.preferredHeight, calculatedHeight));
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: mainColumn
|
||||
anchors.fill: parent
|
||||
@@ -131,6 +163,7 @@ SmartPanel {
|
||||
|
||||
// Header section
|
||||
NBox {
|
||||
id: headerBox
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: headerRow.implicitHeight + (Style.marginM * 2)
|
||||
|
||||
@@ -183,6 +216,7 @@ SmartPanel {
|
||||
|
||||
// Time range tabs ([All] / [Today] / [Yesterday] / [Earlier])
|
||||
NBox {
|
||||
id: tabsBox
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginS
|
||||
implicitHeight: timeTabs.implicitHeight + (Style.marginS * 2)
|
||||
@@ -237,6 +271,7 @@ SmartPanel {
|
||||
|
||||
// Empty state when no notifications
|
||||
ColumnLayout {
|
||||
id: emptyState
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
@@ -276,201 +311,205 @@ SmartPanel {
|
||||
}
|
||||
}
|
||||
|
||||
// Notification list
|
||||
NScrollView {
|
||||
id: scrollView
|
||||
// Notification list container with gradient overlay
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
||||
clip: true
|
||||
visible: NotificationService.historyList.count > 0
|
||||
|
||||
// Track which notification is expanded
|
||||
property string expandedId: ""
|
||||
NScrollView {
|
||||
id: scrollView
|
||||
anchors.fill: parent
|
||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
ScrollBar.vertical.policy: ScrollBar.AsNeeded
|
||||
clip: true
|
||||
|
||||
contentWidth: availableWidth
|
||||
// Track which notification is expanded
|
||||
property string expandedId: ""
|
||||
|
||||
Column {
|
||||
width: scrollView.width
|
||||
spacing: Style.marginM
|
||||
contentWidth: availableWidth
|
||||
|
||||
Repeater {
|
||||
model: NotificationService.historyList
|
||||
Column {
|
||||
width: scrollView.width
|
||||
spacing: Style.marginM
|
||||
|
||||
delegate: Item {
|
||||
id: notificationDelegate
|
||||
width: parent.width
|
||||
visible: root.isInCurrentRange(model.timestamp)
|
||||
height: visible ? contentColumn.height + (Style.marginM * 2) : 0
|
||||
Repeater {
|
||||
model: NotificationService.historyList
|
||||
|
||||
property string notificationId: model.id
|
||||
property bool isExpanded: scrollView.expandedId === notificationId
|
||||
property bool canExpand: summaryText.truncated || bodyText.truncated
|
||||
delegate: Item {
|
||||
id: notificationDelegate
|
||||
width: parent.width
|
||||
visible: root.isInCurrentRange(model.timestamp)
|
||||
height: visible ? contentColumn.height + (Style.marginM * 2) : 0
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: Style.radiusM
|
||||
color: Color.mSurfaceVariant
|
||||
border.color: Qt.alpha(Color.mOutline, Style.opacityMedium)
|
||||
border.width: Style.borderS
|
||||
property string notificationId: model.id
|
||||
property bool isExpanded: scrollView.expandedId === notificationId
|
||||
property bool canExpand: summaryText.truncated || bodyText.truncated
|
||||
|
||||
Behavior on color {
|
||||
enabled: !Settings.data.general.animationDisabled
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
radius: Style.radiusM
|
||||
color: Color.mSurfaceVariant
|
||||
border.color: Qt.alpha(Color.mOutline, Style.opacityMedium)
|
||||
border.width: Style.borderS
|
||||
|
||||
Behavior on color {
|
||||
enabled: !Settings.data.general.animationDisabled
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Click to expand/collapse
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: Style.baseWidgetSize
|
||||
enabled: notificationDelegate.canExpand
|
||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: {
|
||||
if (scrollView.expandedId === notificationId) {
|
||||
scrollView.expandedId = "";
|
||||
} else {
|
||||
scrollView.expandedId = notificationId;
|
||||
// Click to expand/collapse
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: Style.baseWidgetSize
|
||||
enabled: notificationDelegate.canExpand
|
||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: {
|
||||
if (scrollView.expandedId === notificationId) {
|
||||
scrollView.expandedId = "";
|
||||
} else {
|
||||
scrollView.expandedId = notificationId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: contentColumn
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: Style.marginM
|
||||
spacing: Style.marginM
|
||||
|
||||
Row {
|
||||
width: parent.width
|
||||
Column {
|
||||
id: contentColumn
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: Style.marginM
|
||||
spacing: Style.marginM
|
||||
|
||||
// Icon
|
||||
NImageRounded {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: Math.round(40 * Style.uiScaleRatio)
|
||||
height: Math.round(40 * Style.uiScaleRatio)
|
||||
radius: Math.min(Style.radiusL, width / 2)
|
||||
imagePath: model.cachedImage || model.originalImage || ""
|
||||
borderColor: Color.transparent
|
||||
borderWidth: 0
|
||||
fallbackIcon: "bell"
|
||||
fallbackIconSize: 24
|
||||
}
|
||||
Row {
|
||||
width: parent.width
|
||||
spacing: Style.marginM
|
||||
|
||||
// Content
|
||||
Column {
|
||||
width: parent.width - Math.round(40 * Style.uiScaleRatio) - Style.marginM - Style.baseWidgetSize
|
||||
spacing: Style.marginXS
|
||||
// Icon
|
||||
NImageRounded {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: Math.round(40 * Style.uiScaleRatio)
|
||||
height: Math.round(40 * Style.uiScaleRatio)
|
||||
radius: Math.min(Style.radiusL, width / 2)
|
||||
imagePath: model.cachedImage || model.originalImage || ""
|
||||
borderColor: Color.transparent
|
||||
borderWidth: 0
|
||||
fallbackIcon: "bell"
|
||||
fallbackIconSize: 24
|
||||
}
|
||||
|
||||
// Header row with app name and timestamp
|
||||
Row {
|
||||
width: parent.width
|
||||
spacing: Style.marginS
|
||||
// Content
|
||||
Column {
|
||||
width: parent.width - Math.round(40 * Style.uiScaleRatio) - Style.marginM - Style.baseWidgetSize
|
||||
spacing: Style.marginXS
|
||||
|
||||
// Urgency indicator
|
||||
Rectangle {
|
||||
width: 6
|
||||
height: 6
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
radius: 3
|
||||
visible: model.urgency !== 1
|
||||
color: {
|
||||
if (model.urgency === 2)
|
||||
return Color.mError;
|
||||
else if (model.urgency === 0)
|
||||
return Color.mOnSurfaceVariant;
|
||||
else
|
||||
return Color.transparent;
|
||||
// Header row with app name and timestamp
|
||||
Row {
|
||||
width: parent.width
|
||||
spacing: Style.marginS
|
||||
|
||||
// Urgency indicator
|
||||
Rectangle {
|
||||
width: 6
|
||||
height: 6
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
radius: 3
|
||||
visible: model.urgency !== 1
|
||||
color: {
|
||||
if (model.urgency === 2)
|
||||
return Color.mError;
|
||||
else if (model.urgency === 0)
|
||||
return Color.mOnSurfaceVariant;
|
||||
else
|
||||
return Color.transparent;
|
||||
}
|
||||
}
|
||||
|
||||
NText {
|
||||
text: model.appName || "Unknown App"
|
||||
pointSize: Style.fontSizeXS
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mSecondary
|
||||
}
|
||||
|
||||
NText {
|
||||
textFormat: Text.PlainText
|
||||
text: " " + Time.formatRelativeTime(model.timestamp)
|
||||
pointSize: Style.fontSizeXXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
// Summary
|
||||
NText {
|
||||
text: model.appName || "Unknown App"
|
||||
pointSize: Style.fontSizeXS
|
||||
font.weight: Style.fontWeightBold
|
||||
color: Color.mSecondary
|
||||
}
|
||||
|
||||
NText {
|
||||
textFormat: Text.PlainText
|
||||
text: " " + Time.formatRelativeTime(model.timestamp)
|
||||
pointSize: Style.fontSizeXXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
||||
// Summary
|
||||
NText {
|
||||
id: summaryText
|
||||
width: parent.width
|
||||
text: model.summary || I18n.tr("general.no-summary")
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: Font.Medium
|
||||
color: Color.mOnSurface
|
||||
textFormat: Text.PlainText
|
||||
wrapMode: Text.Wrap
|
||||
maximumLineCount: notificationDelegate.isExpanded ? 999 : 2
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
// Body
|
||||
NText {
|
||||
id: bodyText
|
||||
width: parent.width
|
||||
text: model.body || ""
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mOnSurfaceVariant
|
||||
textFormat: Text.PlainText
|
||||
wrapMode: Text.Wrap
|
||||
maximumLineCount: notificationDelegate.isExpanded ? 999 : 3
|
||||
elide: Text.ElideRight
|
||||
visible: text.length > 0
|
||||
}
|
||||
|
||||
// Expand indicator
|
||||
Row {
|
||||
width: parent.width
|
||||
visible: !notificationDelegate.isExpanded && notificationDelegate.canExpand
|
||||
spacing: Style.marginXS
|
||||
|
||||
Item {
|
||||
width: parent.width - expandText.width - expandIcon.width - Style.marginXS
|
||||
height: 1
|
||||
}
|
||||
|
||||
NText {
|
||||
id: expandText
|
||||
text: I18n.tr("notifications.panel.click-to-expand") || "Click to expand"
|
||||
pointSize: Style.fontSizeXS
|
||||
color: Color.mPrimary
|
||||
id: summaryText
|
||||
width: parent.width
|
||||
text: model.summary || I18n.tr("general.no-summary")
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: Font.Medium
|
||||
color: Color.mOnSurface
|
||||
textFormat: Text.PlainText
|
||||
wrapMode: Text.Wrap
|
||||
maximumLineCount: notificationDelegate.isExpanded ? 999 : 2
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
NIcon {
|
||||
id: expandIcon
|
||||
icon: "chevron-down"
|
||||
// Body
|
||||
NText {
|
||||
id: bodyText
|
||||
width: parent.width
|
||||
text: model.body || ""
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mPrimary
|
||||
color: Color.mOnSurfaceVariant
|
||||
textFormat: Text.PlainText
|
||||
wrapMode: Text.Wrap
|
||||
maximumLineCount: notificationDelegate.isExpanded ? 999 : 3
|
||||
elide: Text.ElideRight
|
||||
visible: text.length > 0
|
||||
}
|
||||
|
||||
// Expand indicator
|
||||
Row {
|
||||
width: parent.width
|
||||
visible: !notificationDelegate.isExpanded && notificationDelegate.canExpand
|
||||
spacing: Style.marginXS
|
||||
|
||||
Item {
|
||||
width: parent.width - expandText.width - expandIcon.width - Style.marginXS
|
||||
height: 1
|
||||
}
|
||||
|
||||
NText {
|
||||
id: expandText
|
||||
text: I18n.tr("notifications.panel.click-to-expand") || "Click to expand"
|
||||
pointSize: Style.fontSizeXS
|
||||
color: Color.mPrimary
|
||||
font.weight: Font.Medium
|
||||
}
|
||||
|
||||
NIcon {
|
||||
id: expandIcon
|
||||
icon: "chevron-down"
|
||||
pointSize: Style.fontSizeS
|
||||
color: Color.mPrimary
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete button
|
||||
NIconButton {
|
||||
icon: "trash"
|
||||
tooltipText: I18n.tr("tooltips.delete-notification")
|
||||
baseSize: Style.baseWidgetSize * 0.7
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
// Delete button
|
||||
NIconButton {
|
||||
icon: "trash"
|
||||
tooltipText: I18n.tr("tooltips.delete-notification")
|
||||
baseSize: Style.baseWidgetSize * 0.7
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
onClicked: {
|
||||
NotificationService.removeFromHistory(notificationId);
|
||||
onClicked: {
|
||||
NotificationService.removeFromHistory(notificationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -478,6 +517,27 @@ SmartPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Overlay gradient to smooth the hard cut due to scrolling at the bottom (only visible when scrollable)
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Color.transparent
|
||||
visible: scrollView.ScrollBar.vertical && scrollView.ScrollBar.vertical.size < 1.0
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0.0
|
||||
color: Color.transparent
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.85
|
||||
color: Color.transparent
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: Qt.alpha(Color.mSurface, 0.95)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,14 @@ SmartPanel {
|
||||
// Reference to the plugin content loader (set when panel content is created)
|
||||
property var contentLoader: null
|
||||
|
||||
// Pass through anchor properties from plugin panel content
|
||||
panelAnchorHorizontalCenter: pluginInstance?.panelAnchorHorizontalCenter ?? false
|
||||
panelAnchorVerticalCenter: pluginInstance?.panelAnchorVerticalCenter ?? false
|
||||
panelAnchorTop: pluginInstance?.panelAnchorTop ?? false
|
||||
panelAnchorBottom: pluginInstance?.panelAnchorBottom ?? false
|
||||
panelAnchorLeft: pluginInstance?.panelAnchorLeft ?? false
|
||||
panelAnchorRight: pluginInstance?.panelAnchorRight ?? false
|
||||
|
||||
// Panel content is dynamically loaded
|
||||
panelContent: Component {
|
||||
Item {
|
||||
|
||||
@@ -18,7 +18,7 @@ ColumnLayout {
|
||||
property bool valueUseDistroLogo: widgetData.useDistroLogo !== undefined ? widgetData.useDistroLogo : widgetMetadata.useDistroLogo
|
||||
property string valueCustomIconPath: widgetData.customIconPath !== undefined ? widgetData.customIconPath : ""
|
||||
property bool valueEnableColorization: widgetData.enableColorization || false
|
||||
property string valueColorizeSystemIcon: widgetData.colorizeSystemIcon !== undefined ? widgetData.colorizeSystemIcon : (widgetMetadata.colorizeSystemIcon !== undefined ? widgetMetadata.colorizeSystemIcon : "none")
|
||||
property string valueColorizeSystemIcon: widgetData.colorizeSystemIcon !== undefined ? widgetData.colorizeSystemIcon : widgetMetadata.colorizeSystemIcon
|
||||
|
||||
function saveSettings() {
|
||||
var settings = Object.assign({}, widgetData || {});
|
||||
|
||||
@@ -18,6 +18,8 @@ ColumnLayout {
|
||||
property bool valueParseJson: widgetData.parseJson !== undefined ? widgetData.parseJson : widgetMetadata.parseJson
|
||||
property int valueMaxTextLengthHorizontal: widgetData?.maxTextLength?.horizontal ?? widgetMetadata?.maxTextLength?.horizontal
|
||||
property int valueMaxTextLengthVertical: widgetData?.maxTextLength?.vertical ?? widgetMetadata?.maxTextLength?.vertical
|
||||
property string valueHideMode: (widgetData.hideMode !== undefined) ? widgetData.hideMode : widgetMetadata.hideMode
|
||||
property bool valueShowIcon: (widgetData.showIcon !== undefined) ? widgetData.showIcon : widgetMetadata.showIcon
|
||||
|
||||
function saveSettings() {
|
||||
var settings = Object.assign({}, widgetData || {});
|
||||
@@ -39,6 +41,8 @@ ColumnLayout {
|
||||
settings.textCollapse = textCollapseInput.text;
|
||||
settings.textStream = valueTextStream;
|
||||
settings.parseJson = valueParseJson;
|
||||
settings.showIcon = valueShowIcon;
|
||||
settings.hideMode = valueHideMode;
|
||||
settings.maxTextLength = {
|
||||
"horizontal": valueMaxTextLengthHorizontal,
|
||||
"vertical": valueMaxTextLengthVertical
|
||||
@@ -88,6 +92,15 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
id: showIconToggle
|
||||
label: I18n.tr("bar.widget-settings.custom-button.show-icon.label", "Show icon")
|
||||
description: I18n.tr("bar.widget-settings.custom-button.show-icon.description", "Toggles the visibility of the widget's icon.")
|
||||
checked: valueShowIcon
|
||||
onToggled: checked => valueShowIcon = checked
|
||||
visible: textCommandInput.text !== ""
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: Style.marginM
|
||||
|
||||
@@ -166,7 +179,7 @@ ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.custom-button.wheel-mode-separate.label", "Separate wheel commands")
|
||||
description: I18n.tr("bar.widget-settings.custom-button.wheel-mode-separate.description", "Enable separate commands for wheel up and down")
|
||||
property bool internalChecked: (widgetData?.wheelMode || widgetMetadata?.wheelMode || "unified") === "separate"
|
||||
property bool internalChecked: (widgetData?.wheelMode || widgetMetadata?.wheelMode) === "separate"
|
||||
checked: internalChecked
|
||||
onToggled: checked => {
|
||||
internalChecked = checked;
|
||||
@@ -188,7 +201,7 @@ ColumnLayout {
|
||||
label: I18n.tr("bar.widget-settings.custom-button.wheel.label")
|
||||
description: I18n.tr("bar.widget-settings.custom-button.wheel.description")
|
||||
placeholderText: I18n.tr("placeholders.enter-command")
|
||||
text: widgetData?.wheelExec || widgetMetadata?.wheelExec || ""
|
||||
text: widgetData?.wheelExec || widgetMetadata?.wheelExec
|
||||
}
|
||||
|
||||
NToggle {
|
||||
@@ -217,7 +230,7 @@ ColumnLayout {
|
||||
label: I18n.tr("bar.widget-settings.custom-button.wheel-up.label")
|
||||
description: I18n.tr("bar.widget-settings.custom-button.wheel-up.description")
|
||||
placeholderText: I18n.tr("placeholders.enter-command")
|
||||
text: widgetData?.wheelUpExec || widgetMetadata?.wheelUpExec || ""
|
||||
text: widgetData?.wheelUpExec || widgetMetadata?.wheelUpExec
|
||||
}
|
||||
|
||||
NToggle {
|
||||
@@ -227,7 +240,7 @@ ColumnLayout {
|
||||
Layout.bottomMargin: Style.marginS
|
||||
onEntered: TooltipService.show(wheelUpUpdateText, I18n.tr("bar.widget-settings.custom-button.wheel.update-text"), "auto")
|
||||
onExited: TooltipService.hide()
|
||||
checked: (widgetData?.wheelUpUpdateText !== undefined) ? widgetData.wheelUpUpdateText : (widgetMetadata?.wheelUpUpdateText ?? false)
|
||||
checked: (widgetData?.wheelUpUpdateText !== undefined) ? widgetData.wheelUpUpdateText : widgetMetadata?.wheelUpUpdateText
|
||||
onToggled: isChecked => checked = isChecked
|
||||
}
|
||||
}
|
||||
@@ -241,7 +254,7 @@ ColumnLayout {
|
||||
label: I18n.tr("bar.widget-settings.custom-button.wheel-down.label")
|
||||
description: I18n.tr("bar.widget-settings.custom-button.wheel-down.description")
|
||||
placeholderText: I18n.tr("placeholders.enter-command")
|
||||
text: widgetData?.wheelDownExec || widgetMetadata?.wheelDownExec || ""
|
||||
text: widgetData?.wheelDownExec || widgetMetadata?.wheelDownExec
|
||||
}
|
||||
|
||||
NToggle {
|
||||
@@ -251,7 +264,7 @@ ColumnLayout {
|
||||
Layout.bottomMargin: Style.marginS
|
||||
onEntered: TooltipService.show(wheelDownUpdateText, I18n.tr("bar.widget-settings.custom-button.wheel.update-text"), "auto")
|
||||
onExited: TooltipService.hide()
|
||||
checked: (widgetData?.wheelDownUpdateText !== undefined) ? widgetData.wheelDownUpdateText : (widgetMetadata?.wheelDownUpdateText ?? false)
|
||||
checked: (widgetData?.wheelDownUpdateText !== undefined) ? widgetData.wheelDownUpdateText : widgetMetadata?.wheelDownUpdateText
|
||||
onToggled: isChecked => checked = isChecked
|
||||
}
|
||||
}
|
||||
@@ -325,9 +338,32 @@ ColumnLayout {
|
||||
visible: !valueTextStream
|
||||
label: I18n.tr("bar.widget-settings.custom-button.refresh-interval.label")
|
||||
description: I18n.tr("bar.widget-settings.custom-button.refresh-interval.description")
|
||||
placeholderText: String(widgetMetadata.textIntervalMs || 3000)
|
||||
placeholderText: String(widgetMetadata.textIntervalMs)
|
||||
text: widgetData && widgetData.textIntervalMs !== undefined ? String(widgetData.textIntervalMs) : ""
|
||||
}
|
||||
|
||||
NComboBox {
|
||||
id: hideModeComboBox
|
||||
label: I18n.tr("bar.widget-settings.custom-button.hide-mode.label", "Hide mode")
|
||||
description: I18n.tr("bar.widget-settings.custom-button.hide-mode.description", "Controls widget visibility when the command has no output.")
|
||||
model: [
|
||||
{
|
||||
name: I18n.tr("bar.widget-settings.custom-button.hide-mode.alwaysExpanded", "Always expanded"),
|
||||
key: "alwaysExpanded"
|
||||
},
|
||||
{
|
||||
name: I18n.tr("bar.widget-settings.custom-button.hide-mode.expandWithOutput", "Expand when has output"),
|
||||
key: "expandWithOutput"
|
||||
},
|
||||
{
|
||||
name: I18n.tr("bar.widget-settings.custom-button.hide-mode.maxTransparent", "Max expanded but transparent"),
|
||||
key: "maxTransparent"
|
||||
}
|
||||
]
|
||||
currentKey: valueHideMode
|
||||
onSelected: key => valueHideMode = key
|
||||
visible: textCommandInput.text !== "" && valueTextStream == true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ ColumnLayout {
|
||||
// Local state
|
||||
property string valueHideMode: "hidden" // Default to 'Hide When Empty'
|
||||
// Deprecated: hideWhenIdle now folded into hideMode = "idle"
|
||||
property bool valueHideWhenIdle: widgetData.hideWhenIdle !== undefined ? widgetData.hideWhenIdle : (widgetMetadata.hideWhenIdle !== undefined ? widgetMetadata.hideWhenIdle : false)
|
||||
property bool valueHideWhenIdle: widgetData.hideWhenIdle !== undefined ? widgetData.hideWhenIdle : widgetMetadata.hideWhenIdle
|
||||
property bool valueShowAlbumArt: widgetData.showAlbumArt !== undefined ? widgetData.showAlbumArt : widgetMetadata.showAlbumArt
|
||||
property bool valueShowArtistFirst: widgetData.showArtistFirst !== undefined ? widgetData.showArtistFirst : widgetMetadata.showArtistFirst
|
||||
property bool valueShowVisualizer: widgetData.showVisualizer !== undefined ? widgetData.showVisualizer : widgetMetadata.showVisualizer
|
||||
|
||||
@@ -21,6 +21,7 @@ ColumnLayout {
|
||||
property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons
|
||||
property bool valueShowTitle: isVerticalBar ? false : widgetData.showTitle !== undefined ? widgetData.showTitle : widgetMetadata.showTitle
|
||||
property int valueTitleWidth: widgetData.titleWidth !== undefined ? widgetData.titleWidth : widgetMetadata.titleWidth
|
||||
property bool valueShowPinnedApps: widgetData.showPinnedApps !== undefined ? widgetData.showPinnedApps : widgetMetadata.showPinnedApps
|
||||
|
||||
Component.onCompleted: {
|
||||
if (widgetData && widgetData.hideMode !== undefined) {
|
||||
@@ -38,6 +39,7 @@ ColumnLayout {
|
||||
settings.colorizeIcons = valueColorizeIcons;
|
||||
settings.showTitle = valueShowTitle;
|
||||
settings.titleWidth = parseInt(titleWidthInput.text) || widgetMetadata.titleWidth;
|
||||
settings.showPinnedApps = valueShowPinnedApps;
|
||||
return settings;
|
||||
}
|
||||
|
||||
@@ -104,5 +106,9 @@ ColumnLayout {
|
||||
description: I18n.tr("bar.widget-settings.taskbar.title-width.description")
|
||||
text: widgetData.titleWidth || widgetMetadata.titleWidth
|
||||
placeholderText: I18n.tr("placeholders.enter-width-pixels")
|
||||
label: I18n.tr("bar.widget-settings.taskbar.show-pinned-apps.label")
|
||||
description: I18n.tr("bar.widget-settings.taskbar.show-pinned-apps.description")
|
||||
checked: root.valueShowPinnedApps
|
||||
onToggled: checked => root.valueShowPinnedApps = checked
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,8 @@ ColumnLayout {
|
||||
// Local state
|
||||
property var localBlacklist: widgetData.blacklist || []
|
||||
property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons
|
||||
property bool valueDrawerEnabled: widgetData.drawerEnabled !== undefined ? widgetData.drawerEnabled : (widgetMetadata.drawerEnabled !== undefined ? widgetMetadata.drawerEnabled : true)
|
||||
property bool valueDrawerEnabled: widgetData.drawerEnabled !== undefined ? widgetData.drawerEnabled : widgetMetadata.drawerEnabled
|
||||
property bool valueHidePassive: widgetData.hidePassive !== undefined ? widgetData.hidePassive : widgetMetadata.hidePassive
|
||||
|
||||
ListModel {
|
||||
id: blacklistModel
|
||||
@@ -46,6 +47,14 @@ ColumnLayout {
|
||||
onToggled: checked => root.valueDrawerEnabled = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
Layout.fillWidth: true
|
||||
label: I18n.tr("bar.widget-settings.tray.hide-passive.label")
|
||||
description: I18n.tr("bar.widget-settings.tray.hide-passive.description")
|
||||
checked: root.valueHidePassive
|
||||
onToggled: checked => root.valueHidePassive = checked
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS
|
||||
@@ -150,6 +159,7 @@ ColumnLayout {
|
||||
settings.blacklist = newBlacklist;
|
||||
settings.colorizeIcons = root.valueColorizeIcons;
|
||||
settings.drawerEnabled = root.valueDrawerEnabled;
|
||||
settings.hidePassive = root.valueHidePassive;
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ ColumnLayout {
|
||||
property bool enableOnStateLogic: (widgetData && widgetData.enableOnStateLogic !== undefined) ? widgetData.enableOnStateLogic : widgetMetadata.enableOnStateLogic
|
||||
|
||||
Component.onCompleted: {
|
||||
stateChecksJson = (widgetData && widgetData.stateChecksJson !== undefined) ? widgetData.stateChecksJson : widgetMetadata.stateChecksJson || "[]";
|
||||
stateChecksJson = (widgetData && widgetData.stateChecksJson !== undefined) ? widgetData.stateChecksJson : widgetMetadata.stateChecksJson;
|
||||
try {
|
||||
var initialChecks = JSON.parse(stateChecksJson);
|
||||
if (initialChecks && Array.isArray(initialChecks)) {
|
||||
|
||||
@@ -19,8 +19,8 @@ SmartPanel {
|
||||
readonly property bool attachToBar: Settings.data.ui.settingsPanelAttachToBar
|
||||
readonly property string barPosition: Settings.data.bar.position
|
||||
readonly property bool barFloating: Settings.data.bar.floating
|
||||
readonly property real barMarginH: barFloating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
|
||||
readonly property real barMarginV: barFloating ? Settings.data.bar.marginVertical * Style.marginXL : 0
|
||||
readonly property real barMarginH: barFloating ? Math.ceil(Settings.data.bar.marginHorizontal * Style.marginXL) : 0
|
||||
readonly property real barMarginV: barFloating ? Math.ceil(Settings.data.bar.marginVertical * Style.marginXL) : 0
|
||||
|
||||
forceAttachToBar: attachToBar
|
||||
panelAnchorHorizontalCenter: attachToBar ? (barPosition === "top" || barPosition === "bottom") : true
|
||||
@@ -440,91 +440,118 @@ SmartPanel {
|
||||
border.width: Style.borderS
|
||||
radius: Style.radiusM
|
||||
|
||||
NListView {
|
||||
id: sidebarList
|
||||
Item {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginS
|
||||
model: root.tabsModel
|
||||
spacing: Style.marginXS
|
||||
currentIndex: root.currentTabIndex
|
||||
verticalPolicy: ScrollBar.AsNeeded
|
||||
|
||||
delegate: Rectangle {
|
||||
id: tabItem
|
||||
width: sidebarList.verticalScrollBarActive ? sidebarList.width - sidebarList.scrollBarWidth - Style.marginXS : sidebarList.width
|
||||
height: tabEntryRow.implicitHeight + Style.marginS * 2
|
||||
radius: Style.radiusS
|
||||
color: selected ? Color.mPrimary : (tabItem.hovering ? Color.mHover : Color.transparent)
|
||||
readonly property bool selected: index === root.currentTabIndex
|
||||
property bool hovering: false
|
||||
property color tabTextColor: selected ? Color.mOnPrimary : (tabItem.hovering ? Color.mOnHover : Color.mOnSurface)
|
||||
NListView {
|
||||
id: sidebarList
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.marginS
|
||||
model: root.tabsModel
|
||||
spacing: Style.marginXS
|
||||
currentIndex: root.currentTabIndex
|
||||
verticalPolicy: ScrollBar.AsNeeded
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
delegate: Rectangle {
|
||||
id: tabItem
|
||||
width: sidebarList.verticalScrollBarActive ? sidebarList.width - sidebarList.scrollBarWidth - Style.marginXS : sidebarList.width
|
||||
height: tabEntryRow.implicitHeight + Style.marginS * 2
|
||||
radius: Style.radiusS
|
||||
color: selected ? Color.mPrimary : (tabItem.hovering ? Color.mHover : Color.transparent)
|
||||
readonly property bool selected: index === root.currentTabIndex
|
||||
property bool hovering: false
|
||||
property color tabTextColor: selected ? Color.mOnPrimary : (tabItem.hovering ? Color.mOnHover : Color.mOnSurface)
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on tabTextColor {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: tabEntryRow
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Style.marginS
|
||||
anchors.rightMargin: Style.marginS
|
||||
spacing: Style.marginM
|
||||
|
||||
// Tab icon
|
||||
NIcon {
|
||||
icon: modelData.icon
|
||||
color: tabTextColor
|
||||
pointSize: Style.fontSizeXL
|
||||
}
|
||||
|
||||
// Tab label
|
||||
NText {
|
||||
text: I18n.tr(modelData.label)
|
||||
color: tabTextColor
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: Style.fontWeightBold
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onEntered: tabItem.hovering = true
|
||||
onExited: tabItem.hovering = false
|
||||
onCanceled: tabItem.hovering = false
|
||||
onClicked: root.currentTabIndex = index
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== root.currentTabIndex) {
|
||||
root.currentTabIndex = currentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on tabTextColor {
|
||||
ColorAnimation {
|
||||
duration: Style.animationFast
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentTabIndexChanged() {
|
||||
if (sidebarList.currentIndex !== root.currentTabIndex) {
|
||||
sidebarList.currentIndex = root.currentTabIndex;
|
||||
sidebarList.positionViewAtIndex(root.currentTabIndex, ListView.Contain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: tabEntryRow
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Style.marginS
|
||||
anchors.rightMargin: Style.marginS
|
||||
spacing: Style.marginM
|
||||
|
||||
// Tab icon
|
||||
NIcon {
|
||||
icon: modelData.icon
|
||||
color: tabTextColor
|
||||
pointSize: Style.fontSizeXL
|
||||
}
|
||||
|
||||
// Tab label
|
||||
NText {
|
||||
text: I18n.tr(modelData.label)
|
||||
color: tabTextColor
|
||||
pointSize: Style.fontSizeM
|
||||
font.weight: Style.fontWeightBold
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onEntered: tabItem.hovering = true
|
||||
onExited: tabItem.hovering = false
|
||||
onCanceled: tabItem.hovering = false
|
||||
onClicked: root.currentTabIndex = index
|
||||
}
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex !== root.currentTabIndex) {
|
||||
root.currentTabIndex = currentIndex;
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentTabIndexChanged() {
|
||||
if (sidebarList.currentIndex !== root.currentTabIndex) {
|
||||
sidebarList.currentIndex = root.currentTabIndex;
|
||||
sidebarList.positionViewAtIndex(root.currentTabIndex, ListView.Contain);
|
||||
// Overlay gradient for sidebar scrolling (only visible when scrollable)
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Style.borderS
|
||||
radius: Style.radiusM
|
||||
color: Color.transparent
|
||||
visible: sidebarList.verticalScrollBarActive
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0.0
|
||||
color: Color.transparent
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.95
|
||||
color: Color.transparent
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: Color.mSurfaceVariant
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -633,6 +660,27 @@ SmartPanel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Overlay gradient for content scrolling (only visible when scrollable)
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: Color.transparent
|
||||
visible: root.activeScrollView && root.activeScrollView.ScrollBar.vertical && root.activeScrollView.ScrollBar.vertical.size < 1.0
|
||||
gradient: Gradient {
|
||||
GradientStop {
|
||||
position: 0.0
|
||||
color: Color.transparent
|
||||
}
|
||||
GradientStop {
|
||||
position: 0.95
|
||||
color: Color.transparent
|
||||
}
|
||||
GradientStop {
|
||||
position: 1.0
|
||||
color: Qt.alpha(Color.mSurfaceVariant, 0.95)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -530,4 +530,10 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL
|
||||
Layout.bottomMargin: Style.marginL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ ColumnLayout {
|
||||
stepSize: 0.01
|
||||
value: Settings.data.bar.marginHorizontal
|
||||
onMoved: value => Settings.data.bar.marginHorizontal = value
|
||||
text: Math.round(Settings.data.bar.marginHorizontal * 100) + "%"
|
||||
text: Math.ceil(Settings.data.bar.marginHorizontal * 100) + "%"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -933,4 +933,10 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL
|
||||
Layout.bottomMargin: Style.marginL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import qs.Commons
|
||||
import qs.Services.Compositor
|
||||
import qs.Services.Hardware
|
||||
import qs.Services.Location
|
||||
import qs.Services.UI
|
||||
import qs.Widgets
|
||||
|
||||
ColumnLayout {
|
||||
@@ -372,6 +373,7 @@ ColumnLayout {
|
||||
// Manual scheduling
|
||||
ColumnLayout {
|
||||
spacing: Style.marginS
|
||||
Layout.fillWidth: true
|
||||
visible: Settings.data.nightLight.enabled && !Settings.data.nightLight.autoSchedule && !Settings.data.nightLight.forced
|
||||
|
||||
NLabel {
|
||||
@@ -379,14 +381,16 @@ ColumnLayout {
|
||||
description: I18n.tr("settings.display.night-light.manual-schedule.description")
|
||||
}
|
||||
|
||||
// Sunrise time
|
||||
RowLayout {
|
||||
Layout.fillWidth: false
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS
|
||||
|
||||
NText {
|
||||
text: I18n.tr("settings.display.night-light.manual-schedule.sunrise")
|
||||
pointSize: Style.fontSizeM
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
NComboBox {
|
||||
@@ -394,17 +398,20 @@ ColumnLayout {
|
||||
currentKey: Settings.data.nightLight.manualSunrise
|
||||
placeholder: I18n.tr("settings.display.night-light.manual-schedule.select-start")
|
||||
onSelected: key => Settings.data.nightLight.manualSunrise = key
|
||||
minimumWidth: 120
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: 20
|
||||
}
|
||||
// Sunset time
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Style.marginS
|
||||
|
||||
NText {
|
||||
text: I18n.tr("settings.display.night-light.manual-schedule.sunset")
|
||||
pointSize: Style.fontSizeM
|
||||
color: Color.mOnSurfaceVariant
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
NComboBox {
|
||||
@@ -412,7 +419,7 @@ ColumnLayout {
|
||||
currentKey: Settings.data.nightLight.manualSunset
|
||||
placeholder: I18n.tr("settings.display.night-light.manual-schedule.select-stop")
|
||||
onSelected: key => Settings.data.nightLight.manualSunset = key
|
||||
minimumWidth: 120
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,25 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
visible: Settings.data.dock.enabled
|
||||
spacing: Style.marginXXS
|
||||
Layout.fillWidth: true
|
||||
NLabel {
|
||||
label: I18n.tr("settings.dock.appearance.dead-opacity.label")
|
||||
description: I18n.tr("settings.dock.appearance.dead-opacity.description")
|
||||
}
|
||||
NValueSlider {
|
||||
Layout.fillWidth: true
|
||||
from: 0
|
||||
to: 1
|
||||
stepSize: 0.01
|
||||
value: Settings.data.dock.deadOpacity
|
||||
onMoved: value => Settings.data.dock.deadOpacity = value
|
||||
text: Math.floor(Settings.data.dock.deadOpacity * 100) + "%"
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
visible: Settings.data.dock.enabled
|
||||
spacing: Style.marginXXS
|
||||
@@ -121,6 +140,22 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
|
||||
NToggle {
|
||||
visible: Settings.data.dock.enabled
|
||||
label: I18n.tr("settings.dock.appearance.inactive-indicators.label")
|
||||
description: I18n.tr("settings.dock.appearance.inactive-indicators.description")
|
||||
checked: Settings.data.dock.inactiveIndicators
|
||||
onToggled: checked => Settings.data.dock.inactiveIndicators = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
visible: Settings.data.dock.enabled
|
||||
label: I18n.tr("settings.dock.appearance.pinned-static.label")
|
||||
description: I18n.tr("settings.dock.appearance.pinned-static.description")
|
||||
checked: Settings.data.dock.pinnedStatic
|
||||
onToggled: checked => Settings.data.dock.pinnedStatic = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
visible: Settings.data.dock.enabled
|
||||
label: I18n.tr("settings.dock.monitors.only-same-output.label")
|
||||
@@ -183,7 +218,6 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
NDivider {
|
||||
visible: Settings.data.dock.enabled
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL
|
||||
Layout.bottomMargin: Style.marginL
|
||||
|
||||
@@ -93,4 +93,10 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL
|
||||
Layout.bottomMargin: Style.marginL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,13 @@ ColumnLayout {
|
||||
onToggled: checked => Settings.data.appLauncher.viewMode = checked ? "grid" : "list"
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("settings.launcher.settings.show-categories.label")
|
||||
description: I18n.tr("settings.launcher.settings.show-categories.description")
|
||||
checked: Settings.data.appLauncher.showCategories
|
||||
onToggled: checked => Settings.data.appLauncher.showCategories = checked
|
||||
}
|
||||
|
||||
NToggle {
|
||||
label: I18n.tr("settings.launcher.settings.clipboard-history.label")
|
||||
description: I18n.tr("settings.launcher.settings.clipboard-history.description")
|
||||
|
||||
@@ -235,4 +235,10 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL
|
||||
Layout.bottomMargin: Style.marginL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,16 @@ ColumnLayout {
|
||||
// Track which plugins are currently updating
|
||||
property var updatingPlugins: ({})
|
||||
|
||||
function stripAuthorEmail(author) {
|
||||
if (!author)
|
||||
return "";
|
||||
var lastBracket = author.lastIndexOf("<");
|
||||
if (lastBracket >= 0) {
|
||||
return author.substring(0, lastBracket).trim();
|
||||
}
|
||||
return author;
|
||||
}
|
||||
|
||||
// Check for updates when tab becomes visible
|
||||
onVisibleChanged: {
|
||||
if (visible && PluginService.pluginsFullyLoaded) {
|
||||
@@ -152,7 +162,7 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
NText {
|
||||
text: modelData.author
|
||||
text: stripAuthorEmail(modelData.author)
|
||||
font.pointSize: Style.fontSizeXXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
@@ -473,7 +483,7 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
NText {
|
||||
text: modelData.author
|
||||
text: stripAuthorEmail(modelData.author)
|
||||
font.pointSize: Style.fontSizeXXS
|
||||
color: Color.mOnSurfaceVariant
|
||||
}
|
||||
@@ -525,6 +535,12 @@ ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL
|
||||
Layout.bottomMargin: Style.marginL
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
// Dialogs
|
||||
// ------------------------------
|
||||
|
||||
@@ -269,4 +269,10 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL
|
||||
Layout.bottomMargin: Style.marginL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,4 +510,10 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL
|
||||
Layout.bottomMargin: Style.marginL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,4 +468,10 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.marginL
|
||||
Layout.bottomMargin: Style.marginL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ SmartPanel {
|
||||
// Read widget settings for reactivity
|
||||
readonly property var widgetSettings: {
|
||||
// Reference settingsVersion to force recalculation when it changes
|
||||
var _ = root.settingsVersion;
|
||||
var settingsVersionRef = root.settingsVersion;
|
||||
if (widgetSection === "" || widgetIndex < 0)
|
||||
return {};
|
||||
var widgets = Settings.data.bar.widgets[widgetSection];
|
||||
@@ -39,6 +39,7 @@ SmartPanel {
|
||||
|
||||
// Read pinned list directly from settings for reactivity
|
||||
readonly property var pinnedList: widgetSettings.pinned || []
|
||||
readonly property bool hidePassive: widgetSettings.hidePassive !== undefined ? widgetSettings.hidePassive : true
|
||||
|
||||
function wildCardMatch(str, rule) {
|
||||
if (!str || !rule)
|
||||
@@ -72,9 +73,20 @@ SmartPanel {
|
||||
// Dynamic sizing based on item count
|
||||
// Show items that are NOT pinned (unpinned items go to drawer)
|
||||
readonly property var trayValuesAll: (SystemTray.items && SystemTray.items.values) ? SystemTray.items.values : []
|
||||
readonly property var trayValues: trayValuesAll.filter(function (it) {
|
||||
return !root.isPinned(it);
|
||||
})
|
||||
// Explicitly reference hidePassive to ensure reactivity
|
||||
readonly property var trayValues: {
|
||||
// Reference hidePassive to ensure dependency tracking
|
||||
var hidePassiveRef = root.hidePassive;
|
||||
return trayValuesAll.filter(function (it) {
|
||||
if (!it)
|
||||
return false;
|
||||
// Filter out passive items if hidePassive is enabled
|
||||
if (root.hidePassive && it.status !== undefined && (it.status === SystemTray.Passive || it.status === 0)) {
|
||||
return false;
|
||||
}
|
||||
return !root.isPinned(it);
|
||||
});
|
||||
}
|
||||
readonly property int itemCount: trayValues.length
|
||||
readonly property int maxColumns: 8
|
||||
readonly property real cellSize: Math.round(Style.capsuleHeight * 0.65)
|
||||
@@ -111,7 +123,7 @@ SmartPanel {
|
||||
// Get the trayMenu window and loader from PanelService (reactive to trigger changes)
|
||||
readonly property var popupMenuWindow: {
|
||||
// Reference trigger to force re-evaluation
|
||||
var _ = popupMenuUpdateTrigger;
|
||||
var popupMenuUpdateTriggerRef = popupMenuUpdateTrigger;
|
||||
return PanelService.getPopupMenuWindow(screen);
|
||||
}
|
||||
|
||||
|
||||
@@ -148,28 +148,28 @@ Item {
|
||||
readonly property int barOffsetTop: {
|
||||
if (barPos !== "top")
|
||||
return 0;
|
||||
const floatMarginV = isFloating ? Settings.data.bar.marginVertical * Style.marginXL : 0;
|
||||
const floatMarginV = isFloating ? Math.ceil(Settings.data.bar.marginVertical * Style.marginXL) : 0;
|
||||
return Style.barHeight + floatMarginV;
|
||||
}
|
||||
|
||||
readonly property int barOffsetBottom: {
|
||||
if (barPos !== "bottom")
|
||||
return 0;
|
||||
const floatMarginV = isFloating ? Settings.data.bar.marginVertical * Style.marginXL : 0;
|
||||
const floatMarginV = isFloating ? Math.ceil(Settings.data.bar.marginVertical * Style.marginXL) : 0;
|
||||
return Style.barHeight + floatMarginV;
|
||||
}
|
||||
|
||||
readonly property int barOffsetLeft: {
|
||||
if (barPos !== "left")
|
||||
return 0;
|
||||
const floatMarginH = isFloating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0;
|
||||
const floatMarginH = isFloating ? Math.ceil(Settings.data.bar.marginHorizontal * Style.marginXL) : 0;
|
||||
return Style.barHeight + floatMarginH;
|
||||
}
|
||||
|
||||
readonly property int barOffsetRight: {
|
||||
if (barPos !== "right")
|
||||
return 0;
|
||||
const floatMarginH = isFloating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0;
|
||||
const floatMarginH = isFloating ? Math.ceil(Settings.data.bar.marginHorizontal * Style.marginXL) : 0;
|
||||
return Style.barHeight + floatMarginH;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
@@ -21,19 +20,32 @@ Singleton {
|
||||
|
||||
var command = buildCommand();
|
||||
|
||||
// Compare with previous command to avoid unecessary restart
|
||||
// Compare with previous command to avoid unnecessary restart
|
||||
if (JSON.stringify(command) !== JSON.stringify(lastCommand)) {
|
||||
lastCommand = command;
|
||||
runner.command = command;
|
||||
|
||||
// Set running to false so it may restarts below if still enabled
|
||||
// Set running to false so it may restart below if still enabled
|
||||
runner.running = false;
|
||||
}
|
||||
|
||||
runner.running = params.enabled;
|
||||
}
|
||||
|
||||
function parseTime(timeStr) {
|
||||
var parts = timeStr.split(':');
|
||||
return {
|
||||
hour: parseInt(parts[0]),
|
||||
minute: parseInt(parts[1])
|
||||
};
|
||||
}
|
||||
|
||||
function timeToMinutes(timeObj) {
|
||||
return timeObj.hour * 60 + timeObj.minute;
|
||||
}
|
||||
|
||||
function buildCommand() {
|
||||
var cmd = ["wlsunset"];
|
||||
|
||||
if (params.forced) {
|
||||
// Force immediate full night temperature regardless of time
|
||||
// Keep distinct day/night temps but set times so we're effectively always in "night"
|
||||
@@ -48,25 +60,79 @@ Singleton {
|
||||
if (params.autoSchedule) {
|
||||
cmd.push("-l", `${LocationService.stableLatitude}`, "-L", `${LocationService.stableLongitude}`);
|
||||
} else {
|
||||
// Manual schedule - we need to handle the edge case at midnight
|
||||
var now = new Date();
|
||||
var currentMinutes = now.getHours() * 60 + now.getMinutes();
|
||||
|
||||
var sunrise = parseTime(params.manualSunrise);
|
||||
var sunset = parseTime(params.manualSunset);
|
||||
var sunriseMinutes = timeToMinutes(sunrise);
|
||||
var sunsetMinutes = timeToMinutes(sunset);
|
||||
|
||||
// Determine if we're currently in night period
|
||||
var inNightPeriod = false;
|
||||
if (sunsetMinutes < sunriseMinutes) {
|
||||
// Normal case: sunset before sunrise (e.g., 20:00 to 06:00)
|
||||
inNightPeriod = currentMinutes >= sunsetMinutes || currentMinutes < sunriseMinutes;
|
||||
} else {
|
||||
// Edge case: sunset after sunrise (e.g., 06:00 to 20:00 means night is inverted)
|
||||
inNightPeriod = currentMinutes >= sunsetMinutes && currentMinutes < sunriseMinutes;
|
||||
}
|
||||
|
||||
// Always pass times as-is - wlsunset handles day transitions
|
||||
cmd.push("-S", params.manualSunrise);
|
||||
cmd.push("-s", params.manualSunset);
|
||||
}
|
||||
cmd.push("-d", 60 * 15); // 15min progressive fade at sunset/sunrise
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
// Timer to restart wlsunset at midnight (only for manual schedule)
|
||||
// This ensures it recalculates times for the new day without visible flicker
|
||||
Timer {
|
||||
id: midnightTimer
|
||||
running: false
|
||||
repeat: false
|
||||
|
||||
function scheduleNextMidnight() {
|
||||
if (!params.enabled || params.autoSchedule || params.forced) {
|
||||
running = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var now = new Date();
|
||||
var midnight = new Date(now);
|
||||
midnight.setHours(24, 0, 1, 0); // Next midnight + 1 second
|
||||
|
||||
var msUntilMidnight = midnight.getTime() - now.getTime();
|
||||
interval = msUntilMidnight;
|
||||
running = true;
|
||||
|
||||
Logger.i("NightLight", "Scheduled midnight restart in", Math.floor(msUntilMidnight / 1000), "seconds");
|
||||
}
|
||||
|
||||
onTriggered: {
|
||||
Logger.i("NightLight", "Midnight reached - restarting wlsunset");
|
||||
apply();
|
||||
scheduleNextMidnight();
|
||||
}
|
||||
}
|
||||
|
||||
// Observe setting changes and location readiness
|
||||
Connections {
|
||||
target: Settings.data.nightLight
|
||||
function onEnabledChanged() {
|
||||
apply();
|
||||
midnightTimer.scheduleNextMidnight();
|
||||
// Toast: night light toggled
|
||||
const enabled = !!Settings.data.nightLight.enabled;
|
||||
ToastService.showNotice(I18n.tr("settings.display.night-light.section.label"), enabled ? I18n.tr("toast.night-light.enabled") : I18n.tr("toast.night-light.disabled"), enabled ? "nightlight-on" : "nightlight-off");
|
||||
}
|
||||
function onForcedChanged() {
|
||||
apply();
|
||||
midnightTimer.scheduleNextMidnight();
|
||||
if (Settings.data.nightLight.enabled) {
|
||||
ToastService.showNotice(I18n.tr("settings.display.night-light.section.label"), Settings.data.nightLight.forced ? I18n.tr("toast.night-light.forced") : I18n.tr("toast.night-light.normal"), Settings.data.nightLight.forced ? "nightlight-forced" : "nightlight-on");
|
||||
}
|
||||
@@ -77,6 +143,16 @@ Singleton {
|
||||
function onDayTempChanged() {
|
||||
apply();
|
||||
}
|
||||
function onAutoScheduleChanged() {
|
||||
apply();
|
||||
midnightTimer.scheduleNextMidnight();
|
||||
}
|
||||
function onManualSunriseChanged() {
|
||||
apply();
|
||||
}
|
||||
function onManualSunsetChanged() {
|
||||
apply();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
@@ -88,6 +164,10 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
midnightTimer.scheduleNextMidnight();
|
||||
}
|
||||
|
||||
// Foreground process runner
|
||||
Process {
|
||||
id: runner
|
||||
|
||||
@@ -105,28 +105,39 @@ Singleton {
|
||||
|
||||
var name = (device.name || device.deviceName || "").toLowerCase();
|
||||
var icon = (device.icon || "").toLowerCase();
|
||||
if (icon.includes("headset") || icon.includes("audio") || name.includes("headphone") || name.includes("airpod") || name.includes("headset") || name.includes("arctis")) {
|
||||
if (icon.includes("controller") || icon.includes("gamepad") || name.includes("controller") || name.includes("gamepad")) {
|
||||
return "bt-device-gamepad";
|
||||
}
|
||||
if (icon.includes("microphone") || name.includes("microphone")) {
|
||||
return "bt-device-microphone";
|
||||
}
|
||||
if (name.includes("pod") || name.includes("bud") || name.includes("minor")) {
|
||||
return "bt-device-earbuds";
|
||||
}
|
||||
if (icon.includes("headset") || name.includes("arctis") || name.includes("headset") || name.includes("major")) {
|
||||
return "bt-device-headset";
|
||||
}
|
||||
if (icon.includes("headphone") || name.includes("headphone")) {
|
||||
return "bt-device-headphones";
|
||||
}
|
||||
|
||||
if (icon.includes("mouse") || name.includes("mouse")) {
|
||||
return "bt-device-mouse";
|
||||
}
|
||||
if (icon.includes("keyboard") || name.includes("keyboard")) {
|
||||
return "bt-device-keyboard";
|
||||
}
|
||||
if (icon.includes("phone") || name.includes("phone") || name.includes("iphone") || name.includes("android") || name.includes("samsung")) {
|
||||
return "bt-device-phone";
|
||||
}
|
||||
if (icon.includes("watch") || name.includes("watch")) {
|
||||
return "bt-device-watch";
|
||||
}
|
||||
if (icon.includes("speaker") || name.includes("speaker")) {
|
||||
if (icon.includes("speaker") || name.includes("speaker") || name.includes("audio") || name.includes("sound")) {
|
||||
return "bt-device-speaker";
|
||||
}
|
||||
if (icon.includes("display") || name.includes("tv")) {
|
||||
return "bt-device-tv";
|
||||
}
|
||||
if (icon.includes("phone") || name.includes("phone") || name.includes("iphone") || name.includes("android") || name.includes("samsung")) {
|
||||
return "bt-device-phone";
|
||||
}
|
||||
return "bt-device-generic";
|
||||
}
|
||||
|
||||
|
||||
@@ -344,7 +344,7 @@ Singleton {
|
||||
}
|
||||
|
||||
// Enable a plugin
|
||||
function enablePlugin(pluginId) {
|
||||
function enablePlugin(pluginId, skipAddToBar) {
|
||||
if (PluginRegistry.isPluginEnabled(pluginId)) {
|
||||
Logger.w("PluginService", "Plugin already enabled:", pluginId);
|
||||
return true;
|
||||
@@ -358,11 +358,13 @@ Singleton {
|
||||
PluginRegistry.setPluginEnabled(pluginId, true);
|
||||
loadPlugin(pluginId);
|
||||
|
||||
// Add plugin widget to bar if it provides one
|
||||
var manifest = PluginRegistry.getPluginManifest(pluginId);
|
||||
if (manifest && manifest.entryPoints && manifest.entryPoints.barWidget) {
|
||||
var widgetId = "plugin:" + pluginId;
|
||||
addWidgetToBar(widgetId, "right"); // Default to right section
|
||||
// Add plugin widget to bar if it provides one (unless we're restoring from backup)
|
||||
if (!skipAddToBar) {
|
||||
var manifest = PluginRegistry.getPluginManifest(pluginId);
|
||||
if (manifest && manifest.entryPoints && manifest.entryPoints.barWidget) {
|
||||
var widgetId = "plugin:" + pluginId;
|
||||
addWidgetToBar(widgetId, "right"); // Default to right section
|
||||
}
|
||||
}
|
||||
|
||||
updatePluginInAvailable(pluginId, {
|
||||
@@ -994,15 +996,16 @@ Singleton {
|
||||
if (success) {
|
||||
Logger.i("PluginService", "Plugin updated successfully:", pluginId);
|
||||
|
||||
// Restore bar layout
|
||||
// Re-enable the plugin first, so the new component is registered
|
||||
// Skip adding to bar since we'll restore the layout from backup
|
||||
enablePlugin(pluginId, true);
|
||||
|
||||
// Then restore bar layout (so BarWidgetLoaders can find the new component)
|
||||
Settings.data.bar.widgets.left = barBackup.left;
|
||||
Settings.data.bar.widgets.center = barBackup.center;
|
||||
Settings.data.bar.widgets.right = barBackup.right;
|
||||
Logger.d("PluginService", "Restored bar layout");
|
||||
|
||||
// Re-enable the plugin
|
||||
enablePlugin(pluginId);
|
||||
|
||||
// Remove from updates list
|
||||
var updates = Object.assign({}, root.pluginUpdates);
|
||||
delete updates[pluginId];
|
||||
@@ -1062,12 +1065,10 @@ Singleton {
|
||||
|
||||
// If this slot is empty, use it
|
||||
if (panel.currentPluginId === "") {
|
||||
// Open the panel first so the loader gets created
|
||||
// Set the pluginId first - when panel opens and panelContent loads,
|
||||
// Component.onCompleted will call loadPluginPanel automatically
|
||||
panel.currentPluginId = pluginId;
|
||||
panel.open();
|
||||
// Wait a brief moment for the panel to be fully created
|
||||
Qt.callLater(function () {
|
||||
panel.loadPluginPanel(pluginId);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1077,10 +1078,10 @@ Singleton {
|
||||
var panel1 = PanelService.getPanel("pluginPanel1", screen);
|
||||
if (panel1) {
|
||||
panel1.unloadPluginPanel();
|
||||
// Set the pluginId first - when panel opens and panelContent loads,
|
||||
// Component.onCompleted will call loadPluginPanel automatically
|
||||
panel1.currentPluginId = pluginId;
|
||||
panel1.open();
|
||||
Qt.callLater(function () {
|
||||
panel1.loadPluginPanel(pluginId);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,8 @@ Singleton {
|
||||
"CustomButton": {
|
||||
"allowUserSettings": true,
|
||||
"icon": "heart",
|
||||
"showIcon": true,
|
||||
"hideMode": "alwaysExpanded",
|
||||
"leftClickExec": "",
|
||||
"leftClickUpdateText": false,
|
||||
"rightClickExec": "",
|
||||
@@ -205,6 +207,7 @@ Singleton {
|
||||
"colorizeIcons": false,
|
||||
"showTitle": false,
|
||||
"titleWidth": 120
|
||||
"showPinnedApps": true
|
||||
},
|
||||
"TaskbarGrouped": {
|
||||
"allowUserSettings": true,
|
||||
|
||||
@@ -478,6 +478,7 @@ NBox {
|
||||
MouseArea {
|
||||
id: flowDragArea
|
||||
anchors.fill: parent
|
||||
anchors.margins: -20 * Style.uiScaleRatio // Buffer zone to prevent premature cancel
|
||||
z: -1
|
||||
|
||||
acceptedButtons: Qt.LeftButton
|
||||
@@ -618,6 +619,28 @@ NBox {
|
||||
|
||||
onPositionChanged: mouse => {
|
||||
if (draggedIndex !== -1 && potentialDrag) {
|
||||
// Check if mouse is too far outside the actual parent bounds
|
||||
const buffer = 30 * Style.uiScaleRatio;
|
||||
const isOutside = mouse.x < -buffer || mouse.x > parent.width + buffer || mouse.y < -buffer || mouse.y > parent.height + buffer;
|
||||
|
||||
if (isOutside && (dragStarted || potentialDrag)) {
|
||||
// Cancel drag if mouse is too far outside
|
||||
if (potentialDrag) {
|
||||
root.dragPotentialEnded();
|
||||
}
|
||||
dragStarted = false;
|
||||
potentialDrag = false;
|
||||
draggedIndex = -1;
|
||||
draggedWidget = null;
|
||||
dropTargetIndex = -1;
|
||||
draggedModelData = null;
|
||||
preventStealing = false;
|
||||
dropIndicator.opacity = 0;
|
||||
pulseAnimation.running = false;
|
||||
dragGhost.width = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
const deltaX = mouse.x - startPos.x;
|
||||
const deltaY = mouse.y - startPos.y;
|
||||
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
||||
@@ -669,10 +692,23 @@ NBox {
|
||||
}
|
||||
|
||||
onExited: {
|
||||
if (dragStarted) {
|
||||
// Hide drop indicator when mouse leaves, but keep ghost visible
|
||||
if (dragStarted || potentialDrag) {
|
||||
// Cancel drag when mouse leaves the area
|
||||
if (potentialDrag) {
|
||||
root.dragPotentialEnded();
|
||||
}
|
||||
|
||||
// Reset everything
|
||||
dragStarted = false;
|
||||
potentialDrag = false;
|
||||
draggedIndex = -1;
|
||||
draggedWidget = null;
|
||||
dropTargetIndex = -1;
|
||||
draggedModelData = null;
|
||||
preventStealing = false;
|
||||
dropIndicator.opacity = 0;
|
||||
pulseAnimation.running = false;
|
||||
dragGhost.width = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -9,19 +9,20 @@ Rectangle {
|
||||
|
||||
// Public properties
|
||||
property int currentIndex: 0
|
||||
property int spacing: Style.marginS
|
||||
property real spacing: Style.marginS
|
||||
property real margins: Style.marginXS
|
||||
default property alias content: tabRow.children
|
||||
|
||||
// Styling
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: Style.baseWidgetSize
|
||||
implicitHeight: Style.baseWidgetSize + (margins * 2)
|
||||
color: Color.mSurfaceVariant
|
||||
radius: Style.iRadiusS
|
||||
|
||||
RowLayout {
|
||||
id: tabRow
|
||||
anchors.fill: parent
|
||||
anchors.margins: 0
|
||||
anchors.margins: margins
|
||||
spacing: root.spacing
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user