diff --git a/.github/funding.yml b/.github/funding.yml
new file mode 100644
index 00000000..ae4a88c0
--- /dev/null
+++ b/.github/funding.yml
@@ -0,0 +1 @@
+ko_fi: lysec
\ No newline at end of file
diff --git a/.zed/settings.json b/.zed/settings.json
deleted file mode 100644
index 5f7d4f63..00000000
--- a/.zed/settings.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "languages": {
- "QML": {
- "format_on_save": "on",
- "formatter": {
- "external": {
- "command": "qmlfmt",
- "arguments": ["-e", "-b", "360", "-t", "2", "-i", "2"]
- }
- }
- }
- }
-}
diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json
index 6ba6381a..e04f43ed 100644
--- a/Assets/Translations/de.json
+++ b/Assets/Translations/de.json
@@ -13,32 +13,6 @@
},
"select-avatar": "Avatar-Bild auswählen"
},
- "ui": {
- "section": {
- "label": "Benutzeroberfläche",
- "description": "Passen Sie das Aussehen, die Haptik und das Verhalten der Oberfläche an."
- },
- "tooltips": {
- "label": "Tooltips anzeigen",
- "description": "Tooltips in der gesamten Benutzeroberfläche aktivieren oder deaktivieren."
- },
- "dim-desktop": {
- "label": "Desktop abdunkeln",
- "description": "Desktop abdunkeln, wenn Panels oder Menüs geöffnet sind."
- },
- "border-radius": {
- "label": "Eckenradius",
- "description": "Steuert die Rundung der Ecken von Fenstern, Buttons und anderen Elementen."
- },
- "animation-speed": {
- "label": "Animationsgeschwindigkeit",
- "description": "Globale Animationsgeschwindigkeit anpassen."
- },
- "animation-disable": {
- "label": "UI-Animationen deaktivieren",
- "description": "Alle Animationen für eine schnellere, reaktionsschnellere Erfahrung deaktivieren."
- }
- },
"screen-corners": {
"section": {
"label": "Bildschirmecken",
@@ -54,7 +28,8 @@
},
"radius": {
"label": "Bildschirmecken-Radius",
- "description": "Rundung der Bildschirmecken anpassen."
+ "description": "Rundung der Bildschirmecken anpassen.",
+ "reset": "Eckenradius des Bildschirms zurücksetzen"
}
},
"fonts": {
@@ -83,33 +58,6 @@
}
},
"reset-scaling": "Skalierung zurücksetzen"
- },
- "control-center": {
- "title": "Kontrollzentrum",
- "section": {
- "label": "Kontrollzentrum",
- "description": "Konfigurieren Sie die Positionierung und das Verhalten des Kontrollzentrum-Panels."
- },
- "position": {
- "label": "Position",
- "description": "Wählen Sie, wo das Kontrollzentrum-Panel beim Öffnen erscheint."
- },
- "quickSettingsStyle": {
- "section": {
- "label": "Schnelleinstellungen-Stil",
- "description": "Passen Sie das Aussehen und Verhalten der Schnelleinstellungen im Kontrollzentrum an."
- },
- "style": {
- "label": "Schnelleinstellungen-Stil",
- "description": "Wählen Sie den visuellen Stil für Schnelleinstellungs-Schalter und -Steuerungen."
- }
- },
- "widgets": {
- "section": {
- "label": "Widgets",
- "description": "Konfigurieren und verwalten Sie Kontrollzentrum-Widgets und deren Anzeigeoptionen."
- }
- }
}
},
"audio": {
@@ -196,11 +144,9 @@
"monitors": {
"section": {
"label": "Monitor-spezifische Einstellungen",
- "description": "Skalierung und Helligkeit für jeden Bildschirm anpassen."
+ "description": "Helligkeitseinstellungen für jedes Display anpassen."
},
- "scale": "Skalierung",
"brightness": "Helligkeit",
- "reset-scaling": "Skalierung zurücksetzen",
"brightness-step": {
"label": "Helligkeits-Schrittgröße",
"description": "Schrittgröße für Helligkeitsänderungen anpassen (Mausrad und Tastenkombinationen)."
@@ -318,6 +264,10 @@
"floating-distance": {
"label": "Dock-Schwebeabstand",
"description": "Schwebeabstand vom Bildschirmrand anpassen."
+ },
+ "colorize-icons": {
+ "label": "Symbole einfärben",
+ "description": "Theme-Farben auf Dock-App-Symbole anwenden (nur nicht fokussierte Apps)."
}
},
"monitors": {
@@ -430,6 +380,10 @@
"label": "Bildschirmanzeige aktivieren",
"description": "Lautstärke- und Helligkeitsänderungen in Echtzeit anzeigen."
},
+ "always-on-top": {
+ "label": "Immer im Vordergrund",
+ "description": "Bildschirmanzeige über Vollbildfenstern und anderen Ebenen anzeigen."
+ },
"location": {
"label": "Position",
"description": "Wo Bildschirmanzeigen erscheinen."
@@ -734,29 +688,8 @@
"description": "Ein Dankeschön an unseren {count} großartigen Mitwirkenden!",
"description_plural": "Ein Dankeschön an unsere {count} großartigen Mitwirkenden!"
}
- }
- },
- "control-center": {
- "title": "Kontrollzentrum",
- "quickSettingsStyle": {
- "section": {
- "label": "Schnelleinstellungen-Stil",
- "description": "Passen Sie das Aussehen und Verhalten der Schnelleinstellungen im Kontrollzentrum an."
- },
- "style": {
- "label": "Schnelleinstellungen-Stil",
- "description": "Wählen Sie den visuellen Stil für Schnelleinstellungs-Schalter und -Steuerungen."
- }
},
- "widgets": {
- "section": {
- "label": "Widgets",
- "description": "Konfigurieren und verwalten Sie Kontrollzentrum-Widgets und deren Anzeigeoptionen."
- }
- },
- "quickSettings": {
- "sectionName": "Schnelleinstellungen"
- }
+ "support": "Unterstützen Sie uns"
},
"hooks": {
"title": "Hooks",
@@ -790,6 +723,69 @@
"description": "• Hintergrundbild-Hook: $1 = Hintergrundbild-Pfad, $2 = Bildschirmname\n• Theme-Wechsel-Hook: $1 = true/false (Dunkelmodus-Status)"
}
}
+ },
+ "control-center": {
+ "position": {
+ "description": "Wählen Sie aus, wo das Kontrollzentrum angezeigt wird, wenn es geöffnet wird.",
+ "label": "Position"
+ },
+ "section": {
+ "description": "Konfigurieren Sie die Positionierung und das Verhalten des Control Center-Panels.",
+ "label": "Aussehen"
+ },
+ "title": "Kontrollzentrum",
+ "cards": {
+ "section": {
+ "description": "Passen Sie an, welche Steuerelemente im Kontrollzentrum angezeigt werden und in welcher Reihenfolge.",
+ "label": "Karten"
+ }
+ },
+ "shortcuts": {
+ "section": {
+ "description": "Konfigurieren und verwalten Sie die Verknüpfungs-Widgets.",
+ "label": "Widgets für Kurzbefehle"
+ },
+ "sectionLeft": "Links",
+ "sectionRight": "Richtig"
+ }
+ },
+ "user-interface": {
+ "animation-disable": {
+ "description": "Deaktivieren Sie alle Animationen für eine schnellere und reaktionsfreudigere Erfahrung.",
+ "label": "UI-Animationen deaktivieren"
+ },
+ "animation-speed": {
+ "description": "Globale Animationsgeschwindigkeit anpassen.",
+ "label": "Animationsgeschwindigkeit",
+ "reset": "Animationsgeschwindigkeit zurücksetzen"
+ },
+ "border-radius": {
+ "description": "Steuert die Eckenrundung von Fenstern, Schaltflächen und anderen Elementen.",
+ "label": "Eckenradius",
+ "reset": "Rahmenradius zurücksetzen"
+ },
+ "compact-lockscreen": {
+ "description": "Zeige nur die Login-Eingabe und Systemsteuerung, blende Wetter- und Medien-Widgets aus.",
+ "label": "Kompakter Sperrbildschirm"
+ },
+ "dim-desktop": {
+ "description": "Den Desktop abdunkeln, wenn Bedienfelder oder Menüs geöffnet sind.",
+ "label": "Dim Desktop"
+ },
+ "scaling": {
+ "description": "Ändert die Größe der allgemeinen Benutzeroberfläche, mit Ausnahme der Leiste.",
+ "label": "Oberflächenskalierung",
+ "reset-scaling": "Schnittstellenskalierung zurücksetzen"
+ },
+ "section": {
+ "description": "Passen Sie das Aussehen, die Haptik und das Verhalten der Benutzeroberfläche an.",
+ "label": "Aussehen"
+ },
+ "title": "Benutzeroberfläche",
+ "tooltips": {
+ "description": "Tooltips in der gesamten Benutzeroberfläche aktivieren oder deaktivieren.",
+ "label": "Tooltips anzeigen"
+ }
}
},
"general": {
@@ -910,9 +906,9 @@
"search-placeholder": "Widgets suchen..."
},
"active-window": {
- "auto-hide": {
- "label": "Automatisch ausblenden",
- "description": "Widget automatisch ausblenden, wenn kein Fenster aktiv ist."
+ "hide-mode": {
+ "label": "Ausblendmodus",
+ "description": "Steuert das Verhalten des Widgets, wenn kein Fenster aktiv ist."
},
"show-app-icon": {
"label": "App-Symbol anzeigen",
@@ -925,6 +921,10 @@
"width": {
"description": "Steuert die horizontale Größe des Widgets.",
"label": "Widget-Breite"
+ },
+ "colorize-icons": {
+ "label": "Symbole einfärben",
+ "description": "Theme-Farben auf das aktive Fenster-Symbol anwenden."
}
},
"system-monitor": {
@@ -1055,9 +1055,9 @@
}
},
"media-mini": {
- "auto-hide": {
- "label": "Automatisch ausblenden",
- "description": "Widget automatisch ausblenden, wenn keine Medien abgespielt werden."
+ "hide-mode": {
+ "label": "Ausblendmodus",
+ "description": "Steuert das Verhalten des Widgets, wenn keine Medien abgespielt werden."
},
"show-album-art": {
"label": "Albumcover anzeigen",
@@ -1118,6 +1118,16 @@
"only-same-output": {
"label": "Nur vom gleichen Bildschirm",
"description": "Zeige nur Apps vom dem Bildschirm an, wo sich die Taskbar befindet."
+ },
+ "colorize-icons": {
+ "label": "Symbole einfärben",
+ "description": "Theme-Farben auf Taskbar-Symbole anwenden."
+ }
+ },
+ "tray": {
+ "colorize-icons": {
+ "label": "Symbole einfärben",
+ "description": "Theme-Farben auf Tray-Symbole anwenden."
}
}
}
@@ -1287,7 +1297,8 @@
"density": {
"compact": "Kompakt",
"default": "Standard",
- "comfortable": "Bequem"
+ "comfortable": "Bequem",
+ "mini": "Mini"
}
},
"launcher": {
@@ -1376,6 +1387,11 @@
"microphone-input": "Mikrofon-Eingabe",
"both": "System-Ausgabe + Mikrofon-Eingabe"
}
+ },
+ "hide-modes": {
+ "hidden": "Ausblenden, wenn leer",
+ "transparent": "Transparent, wenn leer",
+ "visible": "Immer sichtbar"
}
},
"session-menu": {
@@ -1568,6 +1584,9 @@
"enabled": "Aktiviert",
"disabled": "Deaktiviert"
},
+ "kofi": {
+ "opened": "Ko-fi-Seite in Ihrem Browser geöffnet"
+ },
"do-not-disturb": {
"enabled": "'Nicht stören' aktiviert",
"disabled": "'Nicht stören' deaktiviert",
diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json
index 361903a8..3819ebbc 100644
--- a/Assets/Translations/en.json
+++ b/Assets/Translations/en.json
@@ -13,32 +13,6 @@
},
"select-avatar": "Select avatar image"
},
- "ui": {
- "section": {
- "label": "User interface",
- "description": "Customize the look, feel, and behavior of the interface."
- },
- "tooltips": {
- "label": "Show tooltips",
- "description": "Enable or disable tooltips throughout the interface."
- },
- "dim-desktop": {
- "label": "Dim desktop",
- "description": "Dim the desktop when panels or menus are open."
- },
- "border-radius": {
- "label": "Border radius",
- "description": "Controls the corner roundness of windows, buttons, and other elements."
- },
- "animation-speed": {
- "label": "Animation speed",
- "description": "Adjust global animation speed."
- },
- "animation-disable": {
- "label": "Disable UI Animations",
- "description": "Disable all animations for a faster, more responsive experience."
- }
- },
"screen-corners": {
"section": {
"label": "Screen corners",
@@ -54,7 +28,8 @@
},
"radius": {
"label": "Screen corners radius",
- "description": "Adjust the rounded corners of the screen."
+ "description": "Adjust the rounded corners of the screen.",
+ "reset": "Reset screen corners radius"
}
},
"fonts": {
@@ -83,34 +58,8 @@
"description": "Increase or decrease the size of the monospaced text."
}
}
- },
- "control-center": {
- "title": "Control Center",
- "section": {
- "label": "Control Center",
- "description": "Configure the Control Center panel positioning and behavior."
- },
- "position": {
- "label": "Position",
- "description": "Choose where the Control Center panel appears when opened."
- },
- "quickSettingsStyle": {
- "section": {
- "label": "Quick Settings Style",
- "description": "Customize the appearance and behavior of quick settings in the Control Center."
- },
- "style": {
- "label": "Quick Settings Style",
- "description": "Choose the visual style for quick settings toggles and controls."
- }
- },
- "widgets": {
- "section": {
- "label": "Widgets",
- "description": "Configure and manage Control Center widgets and their display options."
- }
- }
}
+
},
"audio": {
"title": "Audio",
@@ -196,11 +145,9 @@
"monitors": {
"section": {
"label": "Per-monitor settings",
- "description": "Adjust scaling and brightness for each display."
+ "description": "Adjust settings brightness for each display."
},
- "scale": "Scale",
"brightness": "Brightness",
- "reset-scaling": "Reset scaling",
"brightness-step": {
"label": "Brightness step size",
"description": "Adjust the step size for brightness changes (scroll wheel and keyboard shortcuts)."
@@ -318,6 +265,10 @@
"floating-distance": {
"label": "Dock floating distance",
"description": "Adjust the floating distance from the screen edge."
+ },
+ "colorize-icons": {
+ "label": "Colorize Icons",
+ "description": "Apply theme colors to dock app icons (non-focused apps only)."
}
},
"monitors": {
@@ -430,6 +381,10 @@
"label": "Enable on screen display",
"description": "Show volume and brightness changes in real-time."
},
+ "always-on-top": {
+ "label": "Always on top",
+ "description": "Display OSD above fullscreen windows and other layers."
+ },
"location": {
"label": "Location",
"description": "Where on-screen displays appear."
@@ -734,29 +689,8 @@
"description": "Shout-out to our {count} awesome contributor!",
"description_plural": "Shout-out to our {count} awesome contributors!"
}
- }
- },
- "control-center": {
- "title": "Control Center",
- "quickSettingsStyle": {
- "section": {
- "label": "Quick Settings Style",
- "description": "Customize the appearance and behavior of quick settings in the Control Center."
- },
- "style": {
- "label": "Quick Settings Style",
- "description": "Choose the visual style for quick settings toggles and controls."
- }
},
- "widgets": {
- "section": {
- "label": "Widgets",
- "description": "Configure and manage Control Center widgets and their display options."
- }
- },
- "quickSettings": {
- "sectionName": "Quick Settings"
- }
+ "support": "Support us"
},
"hooks": {
"title": "Hooks",
@@ -790,6 +724,69 @@
"description": "• Wallpaper Hook: $1 = wallpaper path, $2 = screen name\n• Theme Toggle Hook: $1 = true/false (dark mode state)"
}
}
+ },
+ "control-center": {
+ "title": "Control Center",
+ "section": {
+ "label": "Appearance",
+ "description": "Configure the Control Center panel positioning and behavior."
+ },
+ "position": {
+ "label": "Position",
+ "description": "Choose where the Control Center panel appears when opened."
+ },
+ "cards": {
+ "section": {
+ "label": "Cards",
+ "description": "Customize which controls appear in the Control Center and in what order."
+ }
+ },
+ "shortcuts": {
+ "section": {
+ "label": "Shortcuts widgets",
+ "description": "Configure and manage the shortcuts widgets."
+ },
+ "sectionLeft": "Left",
+ "sectionRight": "Right"
+ }
+ },
+ "user-interface": {
+ "title": "User interface",
+ "section": {
+ "label": "Appearance",
+ "description": "Customize the look, feel, and behavior of the interface."
+ },
+ "tooltips": {
+ "label": "Show tooltips",
+ "description": "Enable or disable tooltips throughout the interface."
+ },
+ "scaling": {
+ "label": "Interface scaling",
+ "description": "Changes the size of the general user interface, excluding the bar.",
+ "reset-scaling": "Reset interface scaling"
+ },
+ "dim-desktop": {
+ "label": "Dim desktop",
+ "description": "Dim the desktop when panels or menus are open."
+ },
+ "compact-lockscreen": {
+ "label": "Compact lock screen",
+ "description": "Show only the login input and system controls, hiding weather and media widgets."
+ },
+ "border-radius": {
+ "label": "Border radius",
+ "description": "Controls the corner roundness of windows, buttons, and other elements.",
+ "reset": "Reset border radius"
+ },
+ "animation-speed": {
+ "label": "Animation speed",
+ "description": "Adjust global animation speed.",
+ "reset": "Reset animation speed"
+ },
+ "animation-disable": {
+ "label": "Disable UI Animations",
+ "description": "Disable all animations for a faster, more responsive experience."
+ }
}
},
"widgets": {
@@ -893,9 +890,9 @@
"search-placeholder": "Search widget..."
},
"active-window": {
- "auto-hide": {
- "label": "Hide automatically",
- "description": "Automatically hide the widget when no window is active."
+ "hide-mode": {
+ "label": "Hiding mode",
+ "description": "Controls how the widget behaves when no window is active."
},
"show-app-icon": {
"label": "Show app icon",
@@ -908,6 +905,10 @@
"width": {
"label": "Widget Width",
"description": "Controls the horizontal size of the widget."
+ },
+ "colorize-icons": {
+ "label": "Colorize Icons",
+ "description": "Apply theme colors to active window icon."
}
},
"system-monitor": {
@@ -1038,9 +1039,9 @@
}
},
"media-mini": {
- "auto-hide": {
- "label": "Hide automatically",
- "description": "Automatically hide the widget when no media is playing."
+ "hide-mode": {
+ "label": "Hiding mode",
+ "description": "Controls how the widget behaves when no media is playing."
},
"show-album-art": {
"label": "Show album art",
@@ -1101,6 +1102,16 @@
"only-same-output": {
"label": "Only from same output",
"description": "Show only apps from the output where the bar is located."
+ },
+ "colorize-icons": {
+ "label": "Colorize Icons",
+ "description": "Apply theme colors to taskbar icons."
+ }
+ },
+ "tray": {
+ "colorize-icons": {
+ "label": "Colorize Icons",
+ "description": "Apply theme colors to tray icons."
}
}
}
@@ -1268,6 +1279,7 @@
"right": "Right"
},
"density": {
+ "mini": "Mini",
"compact": "Compact",
"default": "Default",
"comfortable": "Comfortable"
@@ -1336,6 +1348,11 @@
"hover": "Scroll On Hover",
"never": "Never Scroll"
},
+ "hide-modes": {
+ "visible": "Always Visible",
+ "hidden": "Hide When Empty",
+ "transparent": "Transparent When Empty"
+ },
"frame-rates": {
"fps": "{fps} FPS"
},
@@ -1540,6 +1557,9 @@
"enabled": "Enabled",
"disabled": "Disabled"
},
+ "kofi": {
+ "opened": "Ko-fi page opened in your browser"
+ },
"do-not-disturb": {
"enabled": "'Do not disturb' enabled",
"disabled": "'Do not disturb' disabled",
diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json
index 08d7aac8..cc8f14a3 100644
--- a/Assets/Translations/es.json
+++ b/Assets/Translations/es.json
@@ -13,32 +13,6 @@
},
"select-avatar": "Seleccionar imagen de avatar"
},
- "ui": {
- "section": {
- "label": "Interfaz de usuario",
- "description": "Personaliza la apariencia, sensación y comportamiento de la interfaz."
- },
- "tooltips": {
- "label": "Mostrar tooltips",
- "description": "Activar o desactivar tooltips en toda la interfaz."
- },
- "dim-desktop": {
- "label": "Atenuar escritorio",
- "description": "Atenúa el escritorio cuando los paneles o menús están abiertos."
- },
- "border-radius": {
- "label": "Radio del borde",
- "description": "Controla la redondez de las esquinas de ventanas, botones y otros elementos."
- },
- "animation-speed": {
- "label": "Velocidad de la animación",
- "description": "Ajusta la velocidad de la animación global."
- },
- "animation-disable": {
- "label": "Desactivar animaciones de UI",
- "description": "Desactivar todas las animaciones para una experiencia más rápida y responsiva."
- }
- },
"screen-corners": {
"section": {
"label": "Esquinas de la pantalla",
@@ -54,7 +28,8 @@
},
"radius": {
"label": "Radio de las esquinas de la pantalla",
- "description": "Ajusta las esquinas redondeadas de la pantalla."
+ "description": "Ajusta las esquinas redondeadas de la pantalla.",
+ "reset": "Restablecer el radio de las esquinas de la pantalla"
}
},
"fonts": {
@@ -83,33 +58,6 @@
}
},
"reset-scaling": "Restablecer la escala"
- },
- "control-center": {
- "title": "Centro de control",
- "section": {
- "label": "Centro de control",
- "description": "Configurar el posicionamiento y comportamiento del panel del centro de control."
- },
- "position": {
- "label": "Posición",
- "description": "Elige dónde aparece el panel del centro de control cuando se abre."
- },
- "quickSettingsStyle": {
- "section": {
- "label": "Estilo de configuración rápida",
- "description": "Personaliza la apariencia y el comportamiento de las configuraciones rápidas en el centro de control."
- },
- "style": {
- "label": "Estilo de configuración rápida",
- "description": "Elige el estilo visual para los interruptores y controles de configuración rápida."
- }
- },
- "widgets": {
- "section": {
- "label": "Widgets",
- "description": "Configura y gestiona los widgets del centro de control y sus opciones de visualización."
- }
- }
}
},
"audio": {
@@ -196,11 +144,9 @@
"monitors": {
"section": {
"label": "Configuración por monitor",
- "description": "Ajusta la escala y el brillo para cada pantalla."
+ "description": "Ajustar el brillo de la configuración para cada pantalla."
},
- "scale": "Escala",
"brightness": "Brillo",
- "reset-scaling": "Restablecer escala",
"brightness-step": {
"label": "Tamaño del paso de brillo",
"description": "Ajusta el tamaño del paso para los cambios de brillo (rueda de desplazamiento y atajos de teclado)."
@@ -318,6 +264,10 @@
"floating-distance": {
"label": "Distancia de flotación del dock",
"description": "Ajusta la distancia de flotación desde el borde de la pantalla."
+ },
+ "colorize-icons": {
+ "label": "Colorear iconos",
+ "description": "Aplicar colores del tema a los iconos de aplicaciones del dock (solo aplicaciones no enfocadas)."
}
},
"monitors": {
@@ -430,6 +380,10 @@
"label": "Activar visualización en pantalla",
"description": "Mostrar cambios de volumen y brillo en tiempo real."
},
+ "always-on-top": {
+ "label": "Siempre encima",
+ "description": "Mostrar OSD por encima de ventanas de pantalla completa y otras capas."
+ },
"location": {
"label": "Ubicación",
"description": "Dónde aparece la visualización en pantalla."
@@ -734,29 +688,8 @@
"description": "¡Un saludo a nuestro increíble colaborador número {count}!",
"description_plural": "¡Un saludo a nuestros {count} increíbles colaboradores!"
}
- }
- },
- "control-center": {
- "title": "Centro de control",
- "quickSettingsStyle": {
- "section": {
- "label": "Estilo de configuración rápida",
- "description": "Personaliza la apariencia y el comportamiento de las configuraciones rápidas en el centro de control."
- },
- "style": {
- "label": "Estilo de configuración rápida",
- "description": "Elige el estilo visual para los interruptores y controles de configuración rápida."
- }
},
- "widgets": {
- "section": {
- "label": "Widgets",
- "description": "Configura y gestiona los widgets del centro de control y sus opciones de visualización."
- }
- },
- "quickSettings": {
- "sectionName": "Ajustes rápidos"
- }
+ "support": "Apóyanos"
},
"hooks": {
"title": "Hooks",
@@ -790,6 +723,69 @@
"description": "• Hook de fondo de pantalla: $1 = ruta del fondo de pantalla, $2 = nombre de la pantalla\n• Hook de cambio de tema: $1 = true/false (estado del modo oscuro)"
}
}
+ },
+ "control-center": {
+ "position": {
+ "description": "Elige dónde aparece el panel del Centro de control cuando se abre.",
+ "label": "Posición"
+ },
+ "section": {
+ "description": "Configurar el posicionamiento y el comportamiento del panel del Centro de control.",
+ "label": "Apariencia"
+ },
+ "title": "Centro de control",
+ "cards": {
+ "section": {
+ "description": "Personaliza qué controles aparecen en el Centro de control y en qué orden.",
+ "label": "Tarjetas"
+ }
+ },
+ "shortcuts": {
+ "section": {
+ "description": "Configurar y administrar los widgets de accesos directos.",
+ "label": "Widgets de accesos directos"
+ },
+ "sectionLeft": "Izquierda",
+ "sectionRight": "Derecha"
+ }
+ },
+ "user-interface": {
+ "animation-disable": {
+ "description": "Desactiva todas las animaciones para una experiencia más rápida y con mayor capacidad de respuesta.",
+ "label": "Desactivar animaciones de la interfaz de usuario"
+ },
+ "animation-speed": {
+ "description": "Ajustar la velocidad global de la animación.",
+ "label": "Velocidad de animación",
+ "reset": "Restablecer la velocidad de la animación"
+ },
+ "border-radius": {
+ "description": "Controla la redondez de las esquinas de las ventanas, los botones y otros elementos.",
+ "label": "Radio de borde",
+ "reset": "Restablecer el radio del borde"
+ },
+ "compact-lockscreen": {
+ "description": "Mostrar solo el campo de inicio de sesión y los controles del sistema, ocultando los widgets del clima y multimedia.",
+ "label": "Pantalla de bloqueo compacta"
+ },
+ "dim-desktop": {
+ "description": "Atenuar el escritorio cuando los paneles o menús estén abiertos.",
+ "label": "Dim escritorio"
+ },
+ "scaling": {
+ "description": "Cambia el tamaño de la interfaz de usuario general, excluyendo la barra.",
+ "label": "Escalado de la interfaz",
+ "reset-scaling": "Restablecer el escalado de la interfaz"
+ },
+ "section": {
+ "description": "Personaliza la apariencia, el ambiente y el comportamiento de la interfaz.",
+ "label": "Apariencia"
+ },
+ "title": "Interfaz de usuario",
+ "tooltips": {
+ "description": "Activar o desactivar los avisos emergentes en toda la interfaz.",
+ "label": "Mostrar sugerencias"
+ }
}
},
"widgets": {
@@ -893,9 +889,9 @@
"search-placeholder": "Buscar widgets..."
},
"active-window": {
- "auto-hide": {
- "label": "Ocultar automáticamente",
- "description": "Ocultar automáticamente el widget cuando no hay ventana activa."
+ "hide-mode": {
+ "label": "Modo de ocultación",
+ "description": "Controla el comportamiento del widget cuando no hay ventana activa."
},
"show-app-icon": {
"label": "Mostrar icono de la aplicación",
@@ -908,6 +904,10 @@
"width": {
"description": "Controla el tamaño horizontal del widget.",
"label": "Ancho del widget"
+ },
+ "colorize-icons": {
+ "label": "Colorear iconos",
+ "description": "Aplicar colores del tema al icono de la ventana activa."
}
},
"system-monitor": {
@@ -1038,9 +1038,9 @@
}
},
"media-mini": {
- "auto-hide": {
- "label": "Ocultar automáticamente",
- "description": "Ocultar automáticamente el widget cuando no se está reproduciendo ningún medio."
+ "hide-mode": {
+ "label": "Modo de ocultación",
+ "description": "Controla el comportamiento del widget cuando no se está reproduciendo ningún medio."
},
"show-album-art": {
"label": "Mostrar arte del álbum",
@@ -1101,6 +1101,16 @@
"only-same-output": {
"description": "Muestra solo las aplicaciones del resultado donde se encuentra la barra.",
"label": "Solo de la misma salida"
+ },
+ "colorize-icons": {
+ "label": "Colorear iconos",
+ "description": "Aplicar colores del tema a los iconos de la barra de tareas."
+ }
+ },
+ "tray": {
+ "colorize-icons": {
+ "label": "Colorear iconos",
+ "description": "Aplicar colores del tema a los iconos de la bandeja del sistema."
}
}
}
@@ -1270,7 +1280,8 @@
"density": {
"compact": "Compacta",
"default": "Predeterminada",
- "comfortable": "Cómoda"
+ "comfortable": "Cómoda",
+ "mini": "Mini"
}
},
"launcher": {
@@ -1359,6 +1370,11 @@
"microphone-input": "Entrada del micrófono",
"both": "Salida del sistema + entrada del micrófono"
}
+ },
+ "hide-modes": {
+ "hidden": "Ocultar cuando esté vacío",
+ "transparent": "Transparente cuando está vacío",
+ "visible": "Siempre visible"
}
},
"session-menu": {
@@ -1540,6 +1556,9 @@
"enabled": "Activado",
"disabled": "Desactivado"
},
+ "kofi": {
+ "opened": "Página de Ko-fi abierta en tu navegador"
+ },
"do-not-disturb": {
"enabled": "'No molestar' activado",
"disabled": "'No molestar' desactivado",
diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json
index 5f7bec3a..9cb02955 100644
--- a/Assets/Translations/fr.json
+++ b/Assets/Translations/fr.json
@@ -13,32 +13,6 @@
},
"select-avatar": "Sélectionner une image d'avatar"
},
- "ui": {
- "section": {
- "label": "Interface utilisateur",
- "description": "Personnalisez l'apparence, l'ergonomie et le comportement de l'interface."
- },
- "tooltips": {
- "label": "Afficher les tooltips",
- "description": "Activer ou désactiver les tooltips dans toute l'interface."
- },
- "dim-desktop": {
- "label": "Assombrir le bureau",
- "description": "Assombrir le bureau lorsque des panneaux ou des menus sont ouverts."
- },
- "border-radius": {
- "label": "Rayon de bordure",
- "description": "Contrôle l'arrondi des coins des fenêtres, des boutons et d'autres éléments."
- },
- "animation-speed": {
- "label": "Vitesse d'animation",
- "description": "Ajustez la vitesse globale des animations."
- },
- "animation-disable": {
- "label": "Désactiver les animations de l'interface",
- "description": "Désactiver toutes les animations pour une expérience plus rapide et réactive."
- }
- },
"screen-corners": {
"section": {
"label": "Coins de l'écran",
@@ -54,7 +28,8 @@
},
"radius": {
"label": "Rayon des coins de l'écran",
- "description": "Ajustez l'arrondi des coins de l'écran."
+ "description": "Ajustez l'arrondi des coins de l'écran.",
+ "reset": "Réinitialiser le rayon des coins de l'écran"
}
},
"fonts": {
@@ -83,33 +58,6 @@
}
},
"reset-scaling": "Réinitialiser l'échelle"
- },
- "control-center": {
- "title": "Centre de contrôle",
- "section": {
- "label": "Centre de contrôle",
- "description": "Configurer le positionnement et le comportement du panneau du centre de contrôle."
- },
- "position": {
- "label": "Position",
- "description": "Choisissez où apparaît le panneau du centre de contrôle lors de l'ouverture."
- },
- "quickSettingsStyle": {
- "section": {
- "label": "Style des paramètres rapides",
- "description": "Personnalisez l'apparence et le comportement des paramètres rapides dans le centre de contrôle."
- },
- "style": {
- "label": "Style des paramètres rapides",
- "description": "Choisissez le style visuel pour les commutateurs et contrôles des paramètres rapides."
- }
- },
- "widgets": {
- "section": {
- "label": "Widgets",
- "description": "Configurez et gérez les widgets du centre de contrôle et leurs options d'affichage."
- }
- }
}
},
"audio": {
@@ -196,11 +144,9 @@
"monitors": {
"section": {
"label": "Paramètres par moniteur",
- "description": "Ajustez la mise à l'échelle et la luminosité pour chaque écran."
+ "description": "Ajustez la luminosité pour chaque écran."
},
- "scale": "Mise à l'échelle",
"brightness": "Luminosité",
- "reset-scaling": "Réinitialiser la mise à l'échelle",
"brightness-step": {
"label": "Incrément de luminosité",
"description": "Ajustez l'incrément pour les changements de luminosité (molette de la souris et raccourcis clavier)."
@@ -318,6 +264,10 @@
"floating-distance": {
"label": "Distance de flottaison du dock",
"description": "Ajustez la distance de flottaison par rapport au bord de l'écran."
+ },
+ "colorize-icons": {
+ "label": "Coloriser les icônes",
+ "description": "Appliquer les couleurs du thème aux icônes d'applications du dock (applications non focalisées uniquement)."
}
},
"monitors": {
@@ -430,6 +380,10 @@
"label": "Activer l'affichage à l'écran",
"description": "Afficher en temps réel les changements de volume et de luminosité."
},
+ "always-on-top": {
+ "label": "Toujours au premier plan",
+ "description": "Afficher l'OSD au-dessus des fenêtres plein écran et autres couches."
+ },
"location": {
"label": "Emplacement",
"description": "Emplacement des affichages à l'écran."
@@ -734,29 +688,8 @@
"description": "Un grand merci à notre {count} super contributeur !",
"description_plural": "Un grand merci à nos {count} super contributeurs !"
}
- }
- },
- "control-center": {
- "title": "Centre de contrôle",
- "quickSettingsStyle": {
- "section": {
- "label": "Style des paramètres rapides",
- "description": "Personnalisez l'apparence et le comportement des paramètres rapides dans le centre de contrôle."
- },
- "style": {
- "label": "Style des paramètres rapides",
- "description": "Choisissez le style visuel pour les commutateurs et contrôles des paramètres rapides."
- }
},
- "widgets": {
- "section": {
- "label": "Widgets",
- "description": "Configurez et gérez les widgets du centre de contrôle et leurs options d'affichage."
- }
- },
- "quickSettings": {
- "sectionName": "Paramètres rapides"
- }
+ "support": "Soutenez-nous"
},
"hooks": {
"title": "Hooks",
@@ -790,6 +723,69 @@
"description": "• Hook Fond d'écran : $1 = chemin du fond d'écran, $2 = nom de l'écran\n• Hook de bascule de thème : $1 = true/false (état du mode sombre)"
}
}
+ },
+ "control-center": {
+ "position": {
+ "description": "Choisissez où le panneau du Centre de contrôle apparaît lorsqu'il est ouvert.",
+ "label": "Position"
+ },
+ "section": {
+ "description": "Configurer le positionnement et le comportement du panneau du Centre de contrôle.",
+ "label": "Apparence"
+ },
+ "title": "Centre de contrôle",
+ "cards": {
+ "section": {
+ "description": "Personnalisez les commandes qui apparaissent dans le Centre de contrôle et leur ordre d'affichage.",
+ "label": "Cartes"
+ }
+ },
+ "shortcuts": {
+ "section": {
+ "description": "Configurer et gérer les widgets de raccourcis.",
+ "label": "Widgets de raccourcis"
+ },
+ "sectionLeft": "Gauche",
+ "sectionRight": "Droite"
+ }
+ },
+ "user-interface": {
+ "animation-disable": {
+ "description": "Désactiver toutes les animations pour une expérience plus rapide et plus réactive.",
+ "label": "Désactiver les animations de l'interface utilisateur"
+ },
+ "animation-speed": {
+ "description": "Ajuster la vitesse globale de l'animation.",
+ "label": "Vitesse d'animation",
+ "reset": "Réinitialiser la vitesse de l'animation"
+ },
+ "border-radius": {
+ "description": "Contrôle l'arrondi des angles des fenêtres, des boutons et d'autres éléments.",
+ "label": "Rayon de bordure",
+ "reset": "Réinitialiser le rayon de la bordure"
+ },
+ "compact-lockscreen": {
+ "description": "Afficher uniquement le champ de saisie de connexion et les commandes système, en masquant les widgets météo et multimédia.",
+ "label": "Écran de verrouillage compact"
+ },
+ "dim-desktop": {
+ "description": "Atténuer le bureau lorsque des panneaux ou des menus sont ouverts.",
+ "label": "Dim bureau"
+ },
+ "scaling": {
+ "description": "Modifie la taille de l'interface utilisateur générale, à l'exception de la barre.",
+ "label": "Mise à l'échelle de l'interface",
+ "reset-scaling": "Réinitialiser l'échelle de l'interface"
+ },
+ "section": {
+ "description": "Personnaliser l'apparence, l'ergonomie et le comportement de l'interface.",
+ "label": "Apparence"
+ },
+ "title": "Interface utilisateur",
+ "tooltips": {
+ "description": "Activer ou désactiver les info-bulles dans toute l'interface.",
+ "label": "Afficher les infobulles"
+ }
}
},
"widgets": {
@@ -901,13 +897,17 @@
"label": "Mode de défilement",
"description": "Contrôler quand le défilement de texte est activé pour les titres de fenêtre longs."
},
- "auto-hide": {
- "label": "Masquer automatiquement",
- "description": "Masquer automatiquement le widget quand aucune fenêtre n'est active."
+ "hide-mode": {
+ "label": "Mode de masquage",
+ "description": "Contrôle le comportement du widget lorsqu'aucune fenêtre n'est active."
},
"width": {
"description": "Contrôle la taille horizontale du widget.",
"label": "Largeur du widget"
+ },
+ "colorize-icons": {
+ "label": "Coloriser les icônes",
+ "description": "Appliquer les couleurs du thème à l'icône de la fenêtre active."
}
},
"system-monitor": {
@@ -1054,9 +1054,9 @@
"label": "Mode de défilement",
"description": "Contrôler quand le défilement de texte est activé pour les titres de piste longs."
},
- "auto-hide": {
- "label": "Masquer automatiquement",
- "description": "Masquer automatiquement le widget quand aucun média n'est en cours de lecture."
+ "hide-mode": {
+ "label": "Mode de masquage",
+ "description": "Contrôle le comportement du widget lorsqu'aucun média n'est en cours de lecture."
},
"no-active-player": "Aucun lecteur actif"
},
@@ -1101,6 +1101,16 @@
"only-same-output": {
"description": "Afficher uniquement les applications de la sortie où la barre est située.",
"label": "Seulement à partir de la même sortie"
+ },
+ "colorize-icons": {
+ "label": "Coloriser les icônes",
+ "description": "Appliquer les couleurs du thème aux icônes de la barre des tâches."
+ }
+ },
+ "tray": {
+ "colorize-icons": {
+ "label": "Coloriser les icônes",
+ "description": "Appliquer les couleurs du thème aux icônes de la barre système."
}
}
}
@@ -1270,7 +1280,8 @@
"density": {
"compact": "Compact",
"default": "Défaut",
- "comfortable": "Confortable"
+ "comfortable": "Confortable",
+ "mini": "Mini"
}
},
"launcher": {
@@ -1359,6 +1370,11 @@
"microphone-input": "Entrée microphone",
"both": "Sortie système + entrée microphone"
}
+ },
+ "hide-modes": {
+ "hidden": "Masquer si vide",
+ "transparent": "Transparent quand vide",
+ "visible": "Toujours visible"
}
},
"session-menu": {
@@ -1540,6 +1556,9 @@
"enabled": "Activé",
"disabled": "Désactivé"
},
+ "kofi": {
+ "opened": "Page Ko-fi ouverte dans votre navigateur"
+ },
"do-not-disturb": {
"enabled": "'Ne pas déranger' activé",
"disabled": "'Ne pas déranger' désactivé",
diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json
index e46f67cb..2b90a189 100644
--- a/Assets/Translations/pt.json
+++ b/Assets/Translations/pt.json
@@ -13,32 +13,6 @@
},
"select-avatar": "Selecionar imagem de avatar"
},
- "ui": {
- "section": {
- "label": "Interface do usuário",
- "description": "Personalize a aparência, a sensação e o comportamento da interface."
- },
- "tooltips": {
- "label": "Mostrar tooltips",
- "description": "Ativar ou desativar tooltips em toda a interface."
- },
- "dim-desktop": {
- "label": "Escurecer área de trabalho",
- "description": "Escurece a área de trabalho quando painéis ou menus estão abertos."
- },
- "border-radius": {
- "label": "Raio da borda",
- "description": "Controla o arredondamento dos cantos de janelas, botões e outros elementos."
- },
- "animation-speed": {
- "label": "Velocidade da animação",
- "description": "Ajuste a velocidade global da animação."
- },
- "animation-disable": {
- "label": "Desativar animações da interface",
- "description": "Desativar todas as animações para uma experiência mais rápida e responsiva."
- }
- },
"screen-corners": {
"section": {
"label": "Cantos da tela",
@@ -54,7 +28,8 @@
},
"radius": {
"label": "Raio dos cantos da tela",
- "description": "Ajuste os cantos arredondados da tela."
+ "description": "Ajuste os cantos arredondados da tela.",
+ "reset": "Redefinir raio dos cantos da tela"
}
},
"fonts": {
@@ -83,33 +58,6 @@
}
},
"reset-scaling": "Redefinir escala"
- },
- "control-center": {
- "title": "Centro de controle",
- "section": {
- "label": "Centro de controle",
- "description": "Configurar o posicionamento e comportamento do painel do centro de controle."
- },
- "position": {
- "label": "Posição",
- "description": "Escolha onde o painel do centro de controle aparece quando aberto."
- },
- "quickSettingsStyle": {
- "section": {
- "label": "Estilo de configurações rápidas",
- "description": "Personalize a aparência e o comportamento das configurações rápidas no centro de controle."
- },
- "style": {
- "label": "Estilo de configurações rápidas",
- "description": "Escolha o estilo visual para os interruptores e controles de configurações rápidas."
- }
- },
- "widgets": {
- "section": {
- "label": "Widgets",
- "description": "Configure e gerencie os widgets do centro de controle e suas opções de exibição."
- }
- }
}
},
"audio": {
@@ -196,11 +144,9 @@
"monitors": {
"section": {
"label": "Configurações por monitor",
- "description": "Ajuste a escala e o brilho para cada tela."
+ "description": "Ajustar o brilho das configurações para cada tela."
},
- "scale": "Escala",
"brightness": "Brilho",
- "reset-scaling": "Redefinir escala",
"brightness-step": {
"label": "Tamanho do passo do brilho",
"description": "Ajuste o tamanho do passo para alterações de brilho (roda do mouse e atalhos de teclado)."
@@ -318,6 +264,10 @@
"floating-distance": {
"label": "Distância de flutuação da dock",
"description": "Ajuste a distância de flutuação da borda da tela."
+ },
+ "colorize-icons": {
+ "label": "Colorir ícones",
+ "description": "Aplicar cores do tema aos ícones de aplicativos da dock (apenas aplicativos não focados)."
}
},
"monitors": {
@@ -700,29 +650,8 @@
"description": "Agradecimentos ao nosso incrível colaborador!",
"description_plural": "Agradecimentos aos nossos {count} incríveis colaboradores!"
}
- }
- },
- "control-center": {
- "title": "Centro de controle",
- "quickSettingsStyle": {
- "section": {
- "label": "Estilo de configurações rápidas",
- "description": "Personalize a aparência e o comportamento das configurações rápidas no centro de controle."
- },
- "style": {
- "label": "Estilo de configurações rápidas",
- "description": "Escolha o estilo visual para os interruptores e controles de configurações rápidas."
- }
},
- "widgets": {
- "section": {
- "label": "Widgets",
- "description": "Configure e gerencie os widgets do centro de controle e suas opções de exibição."
- }
- },
- "quickSettings": {
- "sectionName": "Configurações rápidas"
- }
+ "support": "Apoie-nos"
},
"hooks": {
"title": "Hooks",
@@ -770,6 +699,10 @@
"label": "Ativar exibição na tela",
"description": "Mostrar alterações de volume e brilho em tempo real."
},
+ "always-on-top": {
+ "label": "Sempre no topo",
+ "description": "Exibir OSD acima de janelas em tela cheia e outras camadas."
+ },
"location": {
"label": "Localização",
"description": "Onde a exibição na tela aparece."
@@ -790,6 +723,69 @@
"description": "Mostrar a OSD em monitores específicos. Padrão é todos se nenhum for escolhido."
}
}
+ },
+ "control-center": {
+ "position": {
+ "description": "Escolha onde o painel da Central de Controle aparece quando aberto.",
+ "label": "Posição"
+ },
+ "section": {
+ "description": "Configurar o posicionamento e o comportamento do painel da Central de Controle.",
+ "label": "Aparência"
+ },
+ "title": "Central de Controle",
+ "cards": {
+ "section": {
+ "description": "Personalize quais controles aparecem na Central de Controle e em que ordem.",
+ "label": "Cartas"
+ }
+ },
+ "shortcuts": {
+ "section": {
+ "description": "Configure e gerencie os widgets de atalhos.",
+ "label": "Widgets de atalhos"
+ },
+ "sectionLeft": "Esquerda",
+ "sectionRight": "Direito/Certo/À direita"
+ }
+ },
+ "user-interface": {
+ "animation-disable": {
+ "description": "Desative todas as animações para uma experiência mais rápida e responsiva.",
+ "label": "Desativar animações da interface do usuário"
+ },
+ "animation-speed": {
+ "description": "Ajustar a velocidade global da animação.",
+ "label": "Velocidade da animação",
+ "reset": "Redefinir velocidade da animação"
+ },
+ "border-radius": {
+ "description": "Controla o arredondamento dos cantos de janelas, botões e outros elementos.",
+ "label": "Raio da borda",
+ "reset": "Redefinir raio da borda"
+ },
+ "compact-lockscreen": {
+ "description": "Mostrar apenas a entrada de login e os controles do sistema, ocultando widgets de clima e mídia.",
+ "label": "Tela de bloqueio compacta"
+ },
+ "dim-desktop": {
+ "description": "Escurecer a área de trabalho quando painéis ou menus estiverem abertos.",
+ "label": "Dim área de trabalho"
+ },
+ "scaling": {
+ "description": "Altera o tamanho da interface geral do usuário, excluindo a barra.",
+ "label": "Escalonamento da interface",
+ "reset-scaling": "Redefinir escala da interface"
+ },
+ "section": {
+ "description": "Personalize a aparência, a sensação e o comportamento da interface.",
+ "label": "Aparência"
+ },
+ "title": "Interface do usuário",
+ "tooltips": {
+ "description": "Ativar ou desativar dicas de ferramentas em toda a interface.",
+ "label": "Mostrar dicas de ferramenta"
+ }
}
},
"widgets": {
@@ -893,9 +889,9 @@
"search-placeholder": "Pesquisar widgets..."
},
"active-window": {
- "auto-hide": {
- "label": "Ocultar automaticamente",
- "description": "Ocultar automaticamente o widget quando nenhuma janela está ativa."
+ "hide-mode": {
+ "label": "Modo de ocultação",
+ "description": "Controla o comportamento do widget quando nenhuma janela está ativa."
},
"show-app-icon": {
"label": "Mostrar ícone do aplicativo",
@@ -908,6 +904,10 @@
"width": {
"description": "Controla o tamanho horizontal do widget.",
"label": "Largura do Widget"
+ },
+ "colorize-icons": {
+ "label": "Colorir ícones",
+ "description": "Aplicar cores do tema ao ícone da janela ativa."
}
},
"system-monitor": {
@@ -1038,9 +1038,9 @@
}
},
"media-mini": {
- "auto-hide": {
- "label": "Ocultar automaticamente",
- "description": "Ocultar automaticamente o widget quando nenhuma mídia está sendo reproduzida."
+ "hide-mode": {
+ "label": "Modo de ocultação",
+ "description": "Controla o comportamento do widget quando nenhuma mídia está sendo reproduzida."
},
"show-album-art": {
"label": "Mostrar arte do álbum",
@@ -1101,6 +1101,16 @@
"only-same-output": {
"description": "Mostrar apenas os aplicativos da saída onde a barra está localizada.",
"label": "Apenas da mesma saída"
+ },
+ "colorize-icons": {
+ "label": "Colorir ícones",
+ "description": "Aplicar cores do tema aos ícones da barra de tarefas."
+ }
+ },
+ "tray": {
+ "colorize-icons": {
+ "label": "Colorir ícones",
+ "description": "Aplicar cores do tema aos ícones da bandeja do sistema."
}
}
}
@@ -1311,7 +1321,8 @@
"density": {
"compact": "Compacta",
"default": "Padrão",
- "comfortable": "Confortável"
+ "comfortable": "Confortável",
+ "mini": "Mini"
}
},
"display-mode": {
@@ -1359,6 +1370,11 @@
"microphone-input": "Entrada do microfone",
"both": "Saída do sistema + entrada do microfone"
}
+ },
+ "hide-modes": {
+ "hidden": "Ocultar Quando Vazio",
+ "transparent": "Transparente quando vazio",
+ "visible": "Sempre Visível"
}
},
"session-menu": {
@@ -1540,6 +1556,9 @@
"enabled": "Ativado",
"disabled": "Desativado"
},
+ "kofi": {
+ "opened": "Página do Ko-fi aberta no seu navegador"
+ },
"do-not-disturb": {
"enabled": "'Não perturbe' ativado",
"disabled": "'Não perturbe' desativado",
diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json
index c6ff1c0f..88758343 100644
--- a/Assets/Translations/zh-CN.json
+++ b/Assets/Translations/zh-CN.json
@@ -13,32 +13,6 @@
},
"select-avatar": "选择头像图片"
},
- "ui": {
- "section": {
- "label": "用户界面",
- "description": "自定义界面的外观、风格和行为。"
- },
- "tooltips": {
- "label": "显示工具提示",
- "description": "在整个界面中启用或禁用工具提示。"
- },
- "dim-desktop": {
- "label": "调暗桌面",
- "description": "当面板或菜单打开时调暗桌面。"
- },
- "border-radius": {
- "label": "边框圆角",
- "description": "控制窗口、按钮及其他元素的边角圆度。"
- },
- "animation-speed": {
- "label": "动画速度",
- "description": "调整全局动画速度。"
- },
- "animation-disable": {
- "label": "关闭动画",
- "description": "禁用所有动画效果,以获得更快速、更灵敏的体验。"
- }
- },
"screen-corners": {
"section": {
"label": "屏幕边角",
@@ -54,7 +28,8 @@
},
"radius": {
"label": "屏幕边角半径",
- "description": "调整屏幕圆角的弧度。"
+ "description": "调整屏幕圆角的弧度。",
+ "reset": "重置屏幕圆角半径"
}
},
"fonts": {
@@ -83,33 +58,6 @@
"description": "增大或减小等宽文本的尺寸"
}
}
- },
- "control-center": {
- "title": "控制中心",
- "section": {
- "label": "控制中心",
- "description": "配置控制中心面板的定位和行为。"
- },
- "position": {
- "label": "位置",
- "description": "选择控制中心面板打开时出现的位置。"
- },
- "quickSettingsStyle": {
- "section": {
- "label": "快速设置样式",
- "description": "自定义控制中心中快速设置的外观和行为。"
- },
- "style": {
- "label": "快速设置样式",
- "description": "选择快速设置开关和控件的视觉样式。"
- }
- },
- "widgets": {
- "section": {
- "label": "小部件",
- "description": "配置和管理控制中心小部件及其显示选项。"
- }
- }
}
},
"audio": {
@@ -196,11 +144,9 @@
"monitors": {
"section": {
"label": "显示器设置",
- "description": "调整每个显示器的缩放比例和亮度。"
+ "description": "调整每个显示器的亮度设置。"
},
- "scale": "缩放比例",
"brightness": "亮度",
- "reset-scaling": "重置缩放",
"brightness-step": {
"label": "亮度步长",
"description": "调整亮度变化的步长(滚轮和键盘快捷键)。"
@@ -318,6 +264,10 @@
"floating-distance": {
"label": "Dock 浮动距离",
"description": "调整距离屏幕边缘的浮动距离。"
+ },
+ "colorize-icons": {
+ "label": "着色图标",
+ "description": "将主题颜色应用到 Dock 应用图标(仅限非聚焦应用)。"
}
},
"monitors": {
@@ -430,6 +380,10 @@
"label": "启用屏幕显示",
"description": "实时显示音量与亮度变化。"
},
+ "always-on-top": {
+ "label": "始终置顶",
+ "description": "在全屏窗口和其他图层之上显示OSD。"
+ },
"location": {
"label": "位置",
"description": "屏幕显示出现的位置。"
@@ -734,29 +688,8 @@
"description": "向我们 {count} 位超棒的贡献者致敬!",
"description_plural": "向我们 {count} 位超棒的贡献者致敬!"
}
- }
- },
- "control-center": {
- "title": "控制中心",
- "quickSettingsStyle": {
- "section": {
- "label": "快速设置样式",
- "description": "自定义控制中心中快速设置的外观和行为。"
- },
- "style": {
- "label": "快速设置样式",
- "description": "选择快速设置开关和控件的视觉样式。"
- }
},
- "widgets": {
- "section": {
- "label": "小部件",
- "description": "配置和管理控制中心小部件及其显示选项。"
- }
- },
- "quickSettings": {
- "sectionName": "快速设置"
- }
+ "support": "支持我们"
},
"hooks": {
"title": "钩子",
@@ -790,6 +723,69 @@
"description": "• 壁纸钩子: $1 = 壁纸路径, $2 = 屏幕名称\n• 主题切换钩子: $1 = true/false (深色模式状态)"
}
}
+ },
+ "control-center": {
+ "position": {
+ "description": "选择打开控制中心时面板出现的位置。",
+ "label": "位置"
+ },
+ "section": {
+ "description": "配置控制中心面板的位置和行为。",
+ "label": "外观"
+ },
+ "title": "控制中心",
+ "cards": {
+ "section": {
+ "description": "自定义在控制中心显示的控制项及其顺序。",
+ "label": "卡片"
+ }
+ },
+ "shortcuts": {
+ "section": {
+ "description": "配置和管理快捷方式小部件。",
+ "label": "快捷方式小部件"
+ },
+ "sectionLeft": "左",
+ "sectionRight": "右"
+ }
+ },
+ "user-interface": {
+ "animation-disable": {
+ "description": "禁用所有动画以获得更快、更流畅的体验。",
+ "label": "禁用 UI 动画"
+ },
+ "animation-speed": {
+ "description": "调整全局动画速度。",
+ "label": "动画速度",
+ "reset": "重置动画速度"
+ },
+ "border-radius": {
+ "description": "控制窗口、按钮和其他元素的圆角程度。",
+ "label": "边框半径",
+ "reset": "重置边框半径"
+ },
+ "compact-lockscreen": {
+ "description": "仅显示登录输入和系统控制,隐藏天气和媒体小部件。",
+ "label": "紧凑型锁屏"
+ },
+ "dim-desktop": {
+ "description": "当面板或菜单打开时,桌面变暗。",
+ "label": "昏暗的桌面"
+ },
+ "scaling": {
+ "description": "更改通用用户界面大小,不包括栏。",
+ "label": "界面缩放",
+ "reset-scaling": "重置界面缩放"
+ },
+ "section": {
+ "description": "自定义界面的外观、感觉和行为。",
+ "label": "外观"
+ },
+ "title": "用户界面",
+ "tooltips": {
+ "description": "启用或禁用整个界面的工具提示。",
+ "label": "显示工具提示"
+ }
}
},
"widgets": {
@@ -893,9 +889,9 @@
"search-placeholder": "搜索小部件..."
},
"active-window": {
- "auto-hide": {
- "label": "自动隐藏",
- "description": "当没有活动窗口时自动隐藏小部件。"
+ "hide-mode": {
+ "label": "隐藏模式",
+ "description": "控制当没有活动窗口时小部件的行为。"
},
"show-app-icon": {
"label": "显示应用图标",
@@ -908,6 +904,10 @@
"width": {
"description": "控制小部件的水平尺寸。",
"label": "小部件宽度"
+ },
+ "colorize-icons": {
+ "label": "着色图标",
+ "description": "将主题颜色应用到活动窗口图标。"
}
},
"system-monitor": {
@@ -1038,9 +1038,9 @@
}
},
"media-mini": {
- "auto-hide": {
- "label": "自动隐藏",
- "description": "当没有媒体播放时自动隐藏小部件。"
+ "hide-mode": {
+ "label": "隐藏模式",
+ "description": "控制当没有媒体播放时小部件的行为。"
},
"show-album-art": {
"label": "显示专辑封面",
@@ -1101,6 +1101,16 @@
"only-same-output": {
"label": "仅显示同屏幕",
"description": "仅显示任务栏所在屏幕上的应用程序"
+ },
+ "colorize-icons": {
+ "label": "着色图标",
+ "description": "将主题颜色应用到任务栏图标。"
+ }
+ },
+ "tray": {
+ "colorize-icons": {
+ "label": "着色图标",
+ "description": "将主题颜色应用到系统托盘图标。"
}
}
}
@@ -1270,7 +1280,8 @@
"density": {
"compact": "紧凑",
"default": "默认",
- "comfortable": "舒适"
+ "comfortable": "舒适",
+ "mini": "迷你"
}
},
"launcher": {
@@ -1359,6 +1370,11 @@
"microphone-input": "麦克风输入",
"both": "系统输出 + 麦克风输入"
}
+ },
+ "hide-modes": {
+ "hidden": "当为空时隐藏",
+ "transparent": "空时透明",
+ "visible": "始终可见"
}
},
"session-menu": {
@@ -1540,6 +1556,9 @@
"enabled": "已启用",
"disabled": "已禁用"
},
+ "kofi": {
+ "opened": "Ko-fi页面已在您的浏览器中打开"
+ },
"do-not-disturb": {
"enabled": "'勿扰模式'已启用",
"disabled": "'勿扰模式'已禁用",
diff --git a/Assets/settings-default.json b/Assets/settings-default.json
index 7f9e9a9f..63418a1b 100644
--- a/Assets/settings-default.json
+++ b/Assets/settings-default.json
@@ -61,10 +61,12 @@
"dimDesktop": true,
"showScreenCorners": false,
"forceBlackScreenCorners": false,
+ "scaleRatio": 1,
"radiusRatio": 1,
"screenRadiusRatio": 1,
"animationSpeed": 1,
- "animationDisabled": false
+ "animationDisabled": false,
+ "compactLockScreen": false
},
"location": {
"name": "Tokyo",
@@ -109,9 +111,8 @@
},
"controlCenter": {
"position": "close_to_bar_button",
- "quickSettingsStyle": "compact",
- "widgets": {
- "quickSettings": [
+ "shortcuts": {
+ "left": [
{
"id": "WiFi"
},
@@ -119,19 +120,49 @@
"id": "Bluetooth"
},
{
- "id": "Notifications"
+ "id": "ScreenRecorder"
},
{
- "id": "ScreenRecorder"
+ "id": "WallpaperSelector"
+ }
+ ],
+ "right": [
+ {
+ "id": "Notifications"
},
{
"id": "PowerProfile"
},
{
- "id": "WallpaperSelector"
+ "id": "KeepAwake"
+ },
+ {
+ "id": "NightLight"
}
]
- }
+ },
+ "cards": [
+ {
+ "enabled": true,
+ "id": "profile-card"
+ },
+ {
+ "enabled": true,
+ "id": "shortcuts-card"
+ },
+ {
+ "enabled": true,
+ "id": "audio-card"
+ },
+ {
+ "enabled": true,
+ "id": "weather-card"
+ },
+ {
+ "enabled": true,
+ "id": "media-sysmon-card"
+ }
+ ]
},
"dock": {
"displayMode": "always_visible",
@@ -139,7 +170,8 @@
"floatingRatio": 1,
"onlySameOutput": true,
"monitors": [],
- "pinnedApps": []
+ "pinnedApps": [],
+ "colorizeIcons": false
},
"network": {
"wifiEnabled": true
@@ -159,7 +191,8 @@
"enabled": true,
"location": "top_right",
"monitors": [],
- "autoHideMs": 2000
+ "autoHideMs": 2000,
+ "alwaysOnTop": false
},
"audio": {
"volumeStep": 5,
@@ -174,7 +207,6 @@
"fontFixed": "DejaVu Sans Mono",
"fontDefaultScale": 1,
"fontFixedScale": 1,
- "monitorsScaling": [],
"idleInhibitorEnabled": false,
"tooltipsEnabled": true
},
@@ -191,6 +223,7 @@
"templates": {
"gtk": false,
"qt": false,
+ "kcolorscheme": false,
"kitty": false,
"ghostty": false,
"foot": false,
diff --git a/Bin/dev/i18n-json-check.sh b/Bin/dev/i18n-json.sh
similarity index 99%
rename from Bin/dev/i18n-json-check.sh
rename to Bin/dev/i18n-json.sh
index a847d66c..0db1585b 100755
--- a/Bin/dev/i18n-json-check.sh
+++ b/Bin/dev/i18n-json.sh
@@ -123,13 +123,13 @@ EOF
# Make API call to Gemini
local api_url="https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${api_key}"
- print_color $BLUE " API URL: $api_url" >&2
+ # print_color $BLUE " API URL: $api_url" >&2
local response=$(curl -s -X POST "$api_url" \
-H "Content-Type: application/json" \
-d "$request_body" 2>/dev/null)
- print_color $BLUE " API Response: $response" >&2
+ # print_color $BLUE " API Response: $response" >&2
# Extract the translation from response - try multiple parsing approaches
local translation=$(echo "$response" | jq -r '.candidates[0].content.parts[0].text // .text // empty' 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
diff --git a/Commons/Settings.qml b/Commons/Settings.qml
index a9ff52c9..167254db 100644
--- a/Commons/Settings.qml
+++ b/Commons/Settings.qml
@@ -162,10 +162,6 @@ Singleton {
"id": "Tray"
}, {
"id": "NotificationHistory"
- }, {
- "id": "WiFi"
- }, {
- "id": "Bluetooth"
}, {
"id": "Battery"
}, {
@@ -186,10 +182,12 @@ Singleton {
property bool dimDesktop: true
property bool showScreenCorners: false
property bool forceBlackScreenCorners: false
+ property real scaleRatio: 1.0
property real radiusRatio: 1.0
property real screenRadiusRatio: 1.0
property real animationSpeed: 1.0
property bool animationDisabled: false
+ property bool compactLockScreen: false
}
// location
@@ -246,23 +244,43 @@ Singleton {
property JsonObject controlCenter: JsonObject {
// Position: close_to_bar_button, center, top_left, top_right, bottom_left, bottom_right, bottom_center, top_center
property string position: "close_to_bar_button"
- property string quickSettingsStyle: "compact" // "compact", "classic", or "modern"
- property JsonObject widgets
- widgets: JsonObject {
- property list quickSettings: [{
+ property JsonObject shortcuts
+ shortcuts: JsonObject {
+ property list left: [{
"id": "WiFi"
}, {
"id": "Bluetooth"
- }, {
- "id": "Notifications"
}, {
"id": "ScreenRecorder"
- }, {
- "id": "PowerProfile"
}, {
"id": "WallpaperSelector"
}]
+ property list right: [{
+ "id": "Notifications"
+ }, {
+ "id": "PowerProfile"
+ }, {
+ "id": "KeepAwake"
+ }, {
+ "id": "NightLight"
+ }]
}
+ property list cards: [{
+ "id": "profile-card",
+ "enabled": true
+ }, {
+ "id": "shortcuts-card",
+ "enabled": true
+ }, {
+ "id": "audio-card",
+ "enabled": true
+ }, {
+ "id": "weather-card",
+ "enabled": true
+ }, {
+ "id": "media-sysmon-card",
+ "enabled": true
+ }]
}
// dock
@@ -274,6 +292,7 @@ Singleton {
property list monitors: []
// Desktop entry IDs pinned to the dock (e.g., "org.kde.konsole", "firefox.desktop")
property list pinnedApps: []
+ property bool colorizeIcons: false
}
// network
@@ -300,6 +319,7 @@ Singleton {
property string location: "top_right"
property list monitors: []
property int autoHideMs: 2000
+ property bool alwaysOnTop: false
}
// audio
@@ -318,7 +338,6 @@ Singleton {
property string fontFixed: "DejaVu Sans Mono"
property real fontDefaultScale: 1.0
property real fontFixedScale: 1.0
- property list monitorsScaling: []
property bool idleInhibitorEnabled: false
property bool tooltipsEnabled: true
}
@@ -375,6 +394,23 @@ Singleton {
}
}
+ // -----------------------------------------------------
+ // Function to preprocess paths by expanding "~" to user's home directory
+ function preprocessPath(path) {
+ if (typeof path !== "string" || path === "") {
+ return path
+ }
+
+ // Expand "~" to user's home directory
+ if (path.startsWith("~/")) {
+ return Quickshell.env("HOME") + path.substring(1)
+ } else if (path === "~") {
+ return Quickshell.env("HOME")
+ }
+
+ return path
+ }
+
// -----------------------------------------------------
// Public function to trigger immediate settings saving
function saveImmediate() {
diff --git a/Commons/Style.qml b/Commons/Style.qml
index ab09232f..aaad6128 100644
--- a/Commons/Style.qml
+++ b/Commons/Style.qml
@@ -29,27 +29,25 @@ Singleton {
property int fontWeightBold: 700
// Radii
- property int radiusXXS: 4 * Settings.data.general.radiusRatio
- property int radiusXS: 8 * Settings.data.general.radiusRatio
- property int radiusS: 12 * Settings.data.general.radiusRatio
- property int radiusM: 16 * Settings.data.general.radiusRatio
- property int radiusL: 20 * Settings.data.general.radiusRatio
-
- //screen Radii
- property int screenRadius: 20 * Settings.data.general.screenRadiusRatio
+ property int radiusXXS: Math.round(4 * Settings.data.general.radiusRatio)
+ property int radiusXS: Math.round(8 * Settings.data.general.radiusRatio)
+ property int radiusS: Math.round(12 * Settings.data.general.radiusRatio)
+ property int radiusM: Math.round(16 * Settings.data.general.radiusRatio)
+ property int radiusL: Math.round(20 * Settings.data.general.radiusRatio)
+ property int screenRadius: Math.round(20 * Settings.data.general.screenRadiusRatio)
// Border
- property int borderS: 1
- property int borderM: 2
- property int borderL: 3
+ property int borderS: Math.round(1 * uiScaleRatio)
+ property int borderM: Math.round(2 * uiScaleRatio)
+ property int borderL: Math.round(3 * uiScaleRatio)
// Margins (for margins and spacing)
- property int marginXXS: 2
- property int marginXS: 4
- property int marginS: 8
- property int marginM: 12
- property int marginL: 16
- property int marginXL: 24
+ property int marginXXS: Math.round(2 * uiScaleRatio)
+ property int marginXS: Math.round(4 * uiScaleRatio)
+ property int marginS: Math.round(6 * uiScaleRatio)
+ property int marginM: Math.round(9 * uiScaleRatio)
+ property int marginL: Math.round(13 * uiScaleRatio)
+ property int marginXL: Math.round(18 * uiScaleRatio)
// Opacity
property real opacityNone: 0.0
@@ -70,31 +68,39 @@ Singleton {
property int tooltipDelayLong: 1200
property int pillDelay: 500
- // Settings widgets base size
+ // Widgets base size
property real baseWidgetSize: 33
property real sliderWidth: 200
+ property real uiScaleRatio: Settings.data.general.scaleRatio
+
// Bar Dimensions
property real barHeight: {
- if (Settings.data.bar.density === "compact") {
+ switch (Settings.data.bar.density) {
+ case "mini":
+ return (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? 22 : 20
+ case "compact":
return (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? 27 : 25
- }
- if (Settings.data.bar.density === "default") {
- return (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? 33 : 31
- }
- if (Settings.data.bar.density === "comfortable") {
+ case "comfortable":
return (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? 39 : 37
+ default:
+
+ case "default":
+ return (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? 33 : 31
}
}
property real capsuleHeight: {
- if (Settings.data.bar.density === "compact") {
+ switch (Settings.data.bar.density) {
+ case "mini":
+ return barHeight * 1.0
+ case "compact":
return barHeight * 0.85
- }
- if (Settings.data.bar.density === "default") {
- return barHeight * 0.82
- }
- if (Settings.data.bar.density === "comfortable") {
+ case "comfortable":
return barHeight * 0.73
+ default:
+
+ case "default":
+ return barHeight * 0.82
}
}
}
diff --git a/Commons/TablerIcons.qml b/Commons/TablerIcons.qml
index 39743adb..3522e30d 100644
--- a/Commons/TablerIcons.qml
+++ b/Commons/TablerIcons.qml
@@ -101,7 +101,9 @@ Singleton {
"brightness-low": "brightness-down-filled",
"brightness-high": "brightness-up-filled",
"settings-general": "adjustments-horizontal",
- "settings-bar": "capsule-horizontal",
+ "settings-bar": "crop-16-9",
+ "settings-user-interface": "layout-board",
+ "settings-control-center": "adjustments-horizontal",
"settings-dock": "layout-bottombar",
"settings-launcher": "rocket",
"settings-audio": "device-speaker",
diff --git a/Modules/Background/ScreenCorners.qml b/Modules/Background/ScreenCorners.qml
index c8302ca6..7ddda724 100644
--- a/Modules/Background/ScreenCorners.qml
+++ b/Modules/Background/ScreenCorners.qml
@@ -16,21 +16,11 @@ Loader {
id: root
required property ShellScreen modelData
- property real scaling: ScalingService.getScreenScale(screen)
screen: modelData
property color cornerColor: Settings.data.general.forceBlackScreenCorners ? Qt.rgba(0, 0, 0, 1) : Qt.alpha(Color.mSurface, Settings.data.bar.backgroundOpacity)
- property real cornerRadius: Style.screenRadius * scaling
- property real cornerSize: Style.screenRadius * scaling
-
- Connections {
- target: ScalingService
- function onScaleChanged(screenName, scale) {
- if (screenName === screen.name) {
- scaling = scale
- }
- }
- }
+ property real cornerRadius: Style.screenRadius
+ property real cornerSize: Style.screenRadius
color: Color.transparent
@@ -48,10 +38,10 @@ Loader {
margins {
// When bar is floating, corners should be at screen edges (no margins)
// When bar is not floating, respect bar margins as before
- top: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "top" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
- bottom: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "bottom" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
- left: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "left" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
- right: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "right" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
+ top: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "top" && Settings.data.bar.backgroundOpacity > 0 ? Style.barHeight : 0
+ bottom: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "bottom" && Settings.data.bar.backgroundOpacity > 0 ? Style.barHeight : 0
+ left: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "left" && Settings.data.bar.backgroundOpacity > 0 ? Style.barHeight : 0
+ right: !Settings.data.bar.floating && BarService.isVisible && ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "right" && Settings.data.bar.backgroundOpacity > 0 ? Style.barHeight : 0
}
mask: Region {}
diff --git a/Modules/Bar/Bar.qml b/Modules/Bar/Bar.qml
index 701d71c1..8cc33280 100644
--- a/Modules/Bar/Bar.qml
+++ b/Modules/Bar/Bar.qml
@@ -105,8 +105,8 @@ Variants {
// When auto-hide is enabled, actually toggle window visibility after animations
visible: root.autoHide ? root.barWindowVisible : true
- implicitHeight: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? screen.height : Math.round(Style.barHeight * scaling)
- implicitWidth: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? Math.round(Style.barHeight * scaling) : screen.width
+ implicitHeight: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? screen.height : Style.barHeight
+ implicitWidth: (Settings.data.bar.position === "left" || Settings.data.bar.position === "right") ? Style.barHeight : screen.width
color: Color.transparent
anchors {
@@ -119,10 +119,10 @@ Variants {
// Floating bar margins - only apply when floating is enabled
// Also don't apply margin on the opposite side ot the bar orientation, ex: if bar is floating on top, margin is only applied on top, not bottom.
margins {
- top: Settings.data.bar.floating && Settings.data.bar.position !== "bottom" ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0
- bottom: Settings.data.bar.floating && Settings.data.bar.position !== "top" ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0
- left: Settings.data.bar.floating && Settings.data.bar.position !== "right" ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0
- right: Settings.data.bar.floating && Settings.data.bar.position !== "left" ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0
+ top: Settings.data.bar.floating && Settings.data.bar.position !== "bottom" ? Settings.data.bar.marginVertical * Style.marginXL : 0
+ bottom: Settings.data.bar.floating && Settings.data.bar.position !== "top" ? Settings.data.bar.marginVertical * Style.marginXL : 0
+ left: Settings.data.bar.floating && Settings.data.bar.position !== "right" ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
+ right: Settings.data.bar.floating && Settings.data.bar.position !== "left" ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
}
Component.onCompleted: {
@@ -244,8 +244,8 @@ Variants {
ColumnLayout {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
- anchors.topMargin: Style.marginM * root.scaling
- spacing: Style.marginS * root.scaling
+ anchors.topMargin: Style.marginM
+ spacing: Style.marginS
Repeater {
model: Settings.data.bar.widgets.left
@@ -253,7 +253,6 @@ Variants {
widgetId: (modelData.id !== undefined ? modelData.id : "")
widgetProps: {
"screen": root.modelData || null,
- "scaling": ScalingService.getScreenScale(screen),
"widgetId": modelData.id,
"section": "left",
"sectionWidgetIndex": index,
@@ -268,7 +267,7 @@ Variants {
ColumnLayout {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
- spacing: Style.marginS * root.scaling
+ spacing: Style.marginS
Repeater {
model: Settings.data.bar.widgets.center
@@ -276,7 +275,6 @@ Variants {
widgetId: (modelData.id !== undefined ? modelData.id : "")
widgetProps: {
"screen": root.modelData || null,
- "scaling": ScalingService.getScreenScale(screen),
"widgetId": modelData.id,
"section": "center",
"sectionWidgetIndex": index,
@@ -291,8 +289,8 @@ Variants {
ColumnLayout {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
- anchors.bottomMargin: Style.marginM * root.scaling
- spacing: Style.marginS * root.scaling
+ anchors.bottomMargin: Style.marginM
+ spacing: Style.marginS
Repeater {
model: Settings.data.bar.widgets.right
@@ -300,7 +298,6 @@ Variants {
widgetId: (modelData.id !== undefined ? modelData.id : "")
widgetProps: {
"screen": root.modelData || null,
- "scaling": ScalingService.getScreenScale(screen),
"widgetId": modelData.id,
"section": "right",
"sectionWidgetIndex": index,
@@ -324,9 +321,9 @@ Variants {
id: leftSection
objectName: "leftSection"
anchors.left: parent.left
- anchors.leftMargin: Style.marginS * root.scaling
+ anchors.leftMargin: Style.marginS
anchors.verticalCenter: parent.verticalCenter
- spacing: Style.marginS * root.scaling
+ spacing: Style.marginS
Repeater {
model: Settings.data.bar.widgets.left
@@ -334,7 +331,6 @@ Variants {
widgetId: (modelData.id !== undefined ? modelData.id : "")
widgetProps: {
"screen": root.modelData || null,
- "scaling": ScalingService.getScreenScale(screen),
"widgetId": modelData.id,
"section": "left",
"sectionWidgetIndex": index,
@@ -351,7 +347,7 @@ Variants {
objectName: "centerSection"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
- spacing: Style.marginS * root.scaling
+ spacing: Style.marginS
Repeater {
model: Settings.data.bar.widgets.center
@@ -359,7 +355,6 @@ Variants {
widgetId: (modelData.id !== undefined ? modelData.id : "")
widgetProps: {
"screen": root.modelData || null,
- "scaling": ScalingService.getScreenScale(screen),
"widgetId": modelData.id,
"section": "center",
"sectionWidgetIndex": index,
@@ -375,9 +370,9 @@ Variants {
id: rightSection
objectName: "rightSection"
anchors.right: parent.right
- anchors.rightMargin: Style.marginS * root.scaling
+ anchors.rightMargin: Style.marginS
anchors.verticalCenter: parent.verticalCenter
- spacing: Style.marginS * root.scaling
+ spacing: Style.marginS
Repeater {
model: Settings.data.bar.widgets.right
@@ -385,7 +380,6 @@ Variants {
widgetId: (modelData.id !== undefined ? modelData.id : "")
widgetProps: {
"screen": root.modelData || null,
- "scaling": ScalingService.getScreenScale(screen),
"widgetId": modelData.id,
"section": "right",
"sectionWidgetIndex": index,
diff --git a/Modules/Bar/Bluetooth/BluetoothDevicesList.qml b/Modules/Bar/Bluetooth/BluetoothDevicesList.qml
index f40b13e1..8e144c31 100644
--- a/Modules/Bar/Bluetooth/BluetoothDevicesList.qml
+++ b/Modules/Bar/Bluetooth/BluetoothDevicesList.qml
@@ -18,11 +18,11 @@ ColumnLayout {
}
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NText {
text: root.label
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: Color.mSecondary
font.weight: Style.fontWeightMedium
Layout.fillWidth: true
@@ -51,35 +51,35 @@ ColumnLayout {
}
Layout.fillWidth: true
- Layout.preferredHeight: deviceLayout.implicitHeight + (Style.marginM * scaling * 2)
- radius: Style.radiusM * scaling
+ Layout.preferredHeight: deviceLayout.implicitHeight + (Style.marginM * 2)
+ radius: Style.radiusM
color: Color.mSurface
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
border.color: getContentColor(Color.mOutline)
RowLayout {
id: deviceLayout
anchors.fill: parent
- anchors.margins: Style.marginM * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginM
+ spacing: Style.marginM
Layout.alignment: Qt.AlignVCenter
// One device BT icon
NIcon {
icon: BluetoothService.getDeviceIcon(modelData)
- pointSize: Style.fontSizeXXL * scaling
+ pointSize: Style.fontSizeXXL
color: getContentColor(Color.mOnSurface)
Layout.alignment: Qt.AlignVCenter
}
ColumnLayout {
Layout.fillWidth: true
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
// Device name
NText {
text: modelData.name || modelData.deviceName
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightMedium
elide: Text.ElideRight
color: getContentColor(Color.mOnSurface)
@@ -90,7 +90,7 @@ ColumnLayout {
NText {
text: BluetoothService.getStatusString(modelData)
visible: text !== ""
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: getContentColor(Color.mOnSurfaceVariant)
}
@@ -98,26 +98,26 @@ ColumnLayout {
RowLayout {
visible: modelData.signalStrength !== undefined
Layout.fillWidth: true
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
// Device signal strength - "Unknown" when not connected
NText {
text: BluetoothService.getSignalStrength(modelData)
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: getContentColor(Color.mOnSurfaceVariant)
}
NIcon {
visible: modelData.signalStrength > 0 && !modelData.pairing && !modelData.blocked
text: BluetoothService.getSignalIcon(modelData)
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: getContentColor(Color.mOnSurface)
}
NText {
visible: modelData.signalStrength > 0 && !modelData.pairing && !modelData.blocked
text: (modelData.signalStrength !== undefined && modelData.signalStrength > 0) ? modelData.signalStrength + "%" : ""
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: getContentColor(Color.mOnSurface)
}
}
@@ -126,7 +126,7 @@ ColumnLayout {
NText {
visible: modelData.batteryAvailable
text: BluetoothService.getBattery(modelData)
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: getContentColor(Color.mOnSurfaceVariant)
}
}
@@ -142,7 +142,7 @@ ColumnLayout {
visible: (modelData.state !== BluetoothDeviceState.Connecting)
enabled: (canConnect || canDisconnect) && !isBusy
outlined: !button.hovered
- fontSize: Style.fontSizeXS * scaling
+ fontSize: Style.fontSizeXS
fontWeight: Style.fontWeightMedium
backgroundColor: {
if (device.canDisconnect && !isBusy) {
diff --git a/Modules/Bar/Bluetooth/BluetoothPanel.qml b/Modules/Bar/Bluetooth/BluetoothPanel.qml
index c11d38eb..7e08efef 100644
--- a/Modules/Bar/Bluetooth/BluetoothPanel.qml
+++ b/Modules/Bar/Bluetooth/BluetoothPanel.qml
@@ -11,8 +11,8 @@ import qs.Widgets
NPanel {
id: root
- preferredWidth: 380
- preferredHeight: 500
+ preferredWidth: 380 * Style.uiScaleRatio
+ preferredHeight: 500 * Style.uiScaleRatio
panelKeyboardFocus: true
panelContent: Rectangle {
@@ -20,23 +20,23 @@ NPanel {
ColumnLayout {
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginM
// HEADER
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NIcon {
icon: "bluetooth"
- pointSize: Style.fontSizeXXL * scaling
+ pointSize: Style.fontSizeXXL
color: Color.mPrimary
}
NText {
text: I18n.tr("bluetooth.panel.title")
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: Color.mOnSurface
Layout.fillWidth: true
@@ -46,7 +46,7 @@ NPanel {
id: bluetoothSwitch
checked: BluetoothService.enabled
onToggled: checked => BluetoothService.setBluetoothEnabled(checked)
- baseSize: Style.baseWidgetSize * 0.65 * scaling
+ baseSize: Style.baseWidgetSize * 0.65
}
NIconButton {
@@ -84,25 +84,25 @@ NPanel {
// Center the content within this rectangle
ColumnLayout {
anchors.centerIn: parent
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NIcon {
icon: "bluetooth-off"
- pointSize: 64 * scaling
+ pointSize: 64
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
NText {
text: I18n.tr("bluetooth.panel.disabled")
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
NText {
text: I18n.tr("bluetooth.panel.enable-message")
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
@@ -120,7 +120,7 @@ NPanel {
ColumnLayout {
width: parent.width
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Connected devices
BluetoothDevicesList {
@@ -168,7 +168,7 @@ NPanel {
// Fallback - No devices, scanning
ColumnLayout {
Layout.alignment: Qt.AlignHCenter
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
visible: {
if (!BluetoothService.adapter || !BluetoothService.adapter.discovering || !Bluetooth.devices) {
return false
@@ -182,11 +182,11 @@ NPanel {
RowLayout {
Layout.alignment: Qt.AlignHCenter
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
NIcon {
icon: "refresh"
- pointSize: Style.fontSizeXXL * 1.5 * scaling
+ pointSize: Style.fontSizeXXL * 1.5
color: Color.mPrimary
RotationAnimation on rotation {
@@ -200,14 +200,14 @@ NPanel {
NText {
text: I18n.tr("bluetooth.panel.scanning")
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: Color.mOnSurface
}
}
NText {
text: I18n.tr("bluetooth.panel.pairing-mode")
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
diff --git a/Modules/Bar/Calendar/CalendarPanel.qml b/Modules/Bar/Calendar/CalendarPanel.qml
index fc520bf2..68b27ab3 100644
--- a/Modules/Bar/Calendar/CalendarPanel.qml
+++ b/Modules/Bar/Calendar/CalendarPanel.qml
@@ -10,14 +10,17 @@ import qs.Widgets
NPanel {
id: root
- preferredWidth: Settings.data.location.showWeekNumberInCalendar ? 400 : 380
- preferredHeight: 520
+ readonly property var now: Time.date
+
+ preferredWidth: (Settings.data.location.showWeekNumberInCalendar ? 400 : 380) * Style.uiScaleRatio
+ preferredHeight: 520 * Style.uiScaleRatio
+ panelKeyboardFocus: true
panelContent: ColumnLayout {
id: content
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginM
readonly property int firstDayOfWeek: Qt.locale().firstDayOfWeek
property bool isCurrentMonth: checkIsCurrentMonth()
@@ -27,6 +30,20 @@ NPanel {
return (Time.date.getMonth() === grid.month) && (Time.date.getFullYear() === grid.year)
}
+ Shortcut {
+ sequence: "Escape"
+ onActivated: {
+ if (timerActive) {
+ cancelTimer()
+ } else {
+ cancelTimer()
+ root.close()
+ }
+ }
+ context: Qt.WidgetShortcut
+ enabled: root.opened
+ }
+
Connections {
target: Time
function onDateChanged() {
@@ -37,8 +54,8 @@ NPanel {
// Combined blue banner with date/time and weather summary
Rectangle {
Layout.fillWidth: true
- Layout.preferredHeight: blueColumn.implicitHeight + Style.marginM * scaling * 2
- radius: Style.radiusL * scaling
+ Layout.preferredHeight: blueColumn.implicitHeight + Style.marginM * 2
+ radius: Style.radiusL
color: Color.mPrimary
ColumnLayout {
@@ -46,28 +63,28 @@ NPanel {
anchors.top: parent.top
anchors.left: parent.left
anchors.bottom: parent.bottom
- anchors.topMargin: Style.marginM * scaling
- anchors.leftMargin: Style.marginM * scaling
- anchors.bottomMargin: Style.marginM * scaling
- anchors.rightMargin: clockItem.width + (Style.marginM * scaling * 2)
+ anchors.topMargin: Style.marginM
+ anchors.leftMargin: Style.marginM
+ anchors.bottomMargin: Style.marginM
+ anchors.rightMargin: clockItem.width + (Style.marginM * 2)
spacing: 0
// Combined layout for weather icon, date, and weather text
RowLayout {
Layout.fillWidth: true
- height: 60 * scaling
+ height: 60 * Style.uiScaleRatio
clip: true
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
// Weather icon and temperature
ColumnLayout {
Layout.alignment: Qt.AlignVCenter
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
NIcon {
Layout.alignment: Qt.AlignHCenter
icon: weatherReady ? LocationService.weatherSymbolFromCode(LocationService.data.weather.current_weather.weathercode) : "cloud"
- pointSize: Style.fontSizeXXL * scaling
+ pointSize: Style.fontSizeXXL
color: Color.mOnPrimary
}
@@ -85,7 +102,7 @@ NPanel {
temp = Math.round(temp)
return `${temp}°${suffix}`
}
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightBold
color: Color.mOnPrimary
}
@@ -100,7 +117,7 @@ NPanel {
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
text: Time.date.getDate()
- pointSize: Style.fontSizeXXXL * 1.5 * scaling
+ pointSize: Style.fontSizeXXXL * 1.5
font.weight: Style.fontWeightBold
color: Color.mOnPrimary
@@ -119,17 +136,18 @@ NPanel {
// Month, year, location
ColumnLayout {
- // Give the whole column a fixed width to stabilize the layout
- Layout.preferredWidth: 170 * scaling
+ Layout.preferredWidth: 170 * Style.uiScaleRatio
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
- spacing: -Style.marginXS * scaling
+ Layout.bottomMargin: Style.marginXXS
+ Layout.topMargin: -Style.marginXXS
+ spacing: -Style.marginXS
RowLayout {
spacing: 0
NText {
text: Qt.locale().monthName(grid.month, Locale.LongFormat).toUpperCase()
- pointSize: Style.fontSizeXL * 1.2 * scaling
+ pointSize: Style.fontSizeXL * 1.1
font.weight: Style.fontWeightBold
color: Color.mOnPrimary
Layout.alignment: Qt.AlignBaseline
@@ -138,7 +156,7 @@ NPanel {
NText {
text: ` ${grid.year}`
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightBold
color: Qt.alpha(Color.mOnPrimary, 0.7)
Layout.alignment: Qt.AlignBaseline
@@ -155,16 +173,16 @@ NPanel {
const chunks = Settings.data.location.name.split(",")
return chunks[0]
}
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightMedium
color: Color.mOnPrimary
- Layout.maximumWidth: 150 * scaling
+ Layout.maximumWidth: 150
elide: Text.ElideRight
}
NText {
text: weatherReady ? ` (${LocationService.data.weather.timezone_abbreviation})` : ""
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
font.weight: Style.fontWeightMedium
color: Qt.alpha(Color.mOnPrimary, 0.7)
}
@@ -178,24 +196,26 @@ NPanel {
}
}
- // The Clock, anchored separately for stability
+ // Digital clock with circular progress
Item {
id: clockItem
+ Layout.alignment: Qt.AlignVCenter
anchors.right: parent.right
- anchors.rightMargin: Style.marginM * scaling
+ anchors.rightMargin: Style.marginM
anchors.verticalCenter: parent.verticalCenter
- width: Style.fontSizeXXXL * 1.9 * scaling
- height: Style.fontSizeXXXL * 1.9 * scaling
+ height: Math.round((Style.fontSizeXXXL * 1.9) / 2 * Style.uiScaleRatio) * 2
+ width: clockItem.height
+ // Seconds circular progress
Canvas {
id: secondsProgress
anchors.fill: parent
- property real progress: Time.date.getSeconds() / 60
+ property real progress: now.getSeconds() / 60
onProgressChanged: requestPaint()
Connections {
target: Time
function onDateChanged() {
- const total = Time.date.getSeconds() * 1000 + Time.date.getMilliseconds()
+ const total = now.getSeconds() * 1000 + now.getMilliseconds()
secondsProgress.progress = total / 60000
}
}
@@ -203,39 +223,47 @@ NPanel {
var ctx = getContext("2d")
var centerX = width / 2
var centerY = height / 2
- var radius = Math.min(width, height) / 2 - 3 * scaling
+ var radius = Math.min(width, height) / 2 - 3
ctx.reset()
+
+ // Background circle
ctx.beginPath()
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI)
- ctx.lineWidth = 2.5 * scaling
+ ctx.lineWidth = 2.5
ctx.strokeStyle = Qt.alpha(Color.mOnPrimary, 0.15)
ctx.stroke()
+
+ // Progress arc
ctx.beginPath()
ctx.arc(centerX, centerY, radius, -Math.PI / 2, -Math.PI / 2 + progress * 2 * Math.PI)
- ctx.lineWidth = 2.5 * scaling
+ ctx.lineWidth = 2.5
ctx.strokeStyle = Color.mOnPrimary
ctx.lineCap = "round"
ctx.stroke()
}
}
+ // Digital clock
ColumnLayout {
anchors.centerIn: parent
- spacing: -Style.marginXXS * scaling
+ spacing: -Style.marginXXS
+
NText {
text: {
- var t = Settings.data.location.use12hourFormat ? Qt.locale().toString(new Date(), "hh AP") : Qt.locale().toString(new Date(), "HH")
+ var t = Settings.data.location.use12hourFormat ? Qt.locale().toString(now, "hh AP") : Qt.locale().toString(now, "HH")
return t.split(" ")[0]
}
- pointSize: Style.fontSizeXS * scaling
+
+ pointSize: Style.fontSizeXS
font.weight: Style.fontWeightBold
color: Color.mOnPrimary
family: Settings.data.ui.fontFixed
Layout.alignment: Qt.AlignHCenter
}
+
NText {
- text: Qt.formatTime(Time.date, "mm")
- pointSize: Style.fontSizeXXS * scaling
+ text: Qt.formatTime(now, "mm")
+ pointSize: Style.fontSizeXXS
font.weight: Style.fontWeightBold
color: Color.mOnPrimary
family: Settings.data.ui.fontFixed
@@ -250,28 +278,28 @@ NPanel {
visible: weatherReady
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Repeater {
model: weatherReady ? Math.min(6, LocationService.data.weather.daily.time.length) : 0
delegate: ColumnLayout {
Layout.preferredWidth: 0
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
NText {
text: {
var weatherDate = new Date(LocationService.data.weather.daily.time[index].replace(/-/g, "/"))
return Qt.locale().toString(weatherDate, "ddd")
}
color: Color.mOnSurfaceVariant
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightMedium
Layout.alignment: Qt.AlignHCenter
}
NIcon {
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
icon: LocationService.weatherSymbolFromCode(LocationService.data.weather.daily.weathercode[index])
- pointSize: Style.fontSizeXXL * 1.5 * scaling
+ pointSize: Style.fontSizeXXL * 1.5
color: Color.mPrimary
}
NText {
@@ -287,7 +315,7 @@ NPanel {
min = Math.round(min)
return `${max}°/${min}°`
}
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mOnSurfaceVariant
font.weight: Style.fontWeightMedium
}
@@ -303,7 +331,7 @@ NPanel {
Item {}
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
NDivider {
Layout.fillWidth: true
}
@@ -339,7 +367,7 @@ NPanel {
spacing: 0
Item {
visible: Settings.data.location.showWeekNumberInCalendar
- Layout.preferredWidth: visible ? Style.baseWidgetSize * 0.7 * scaling : 0
+ Layout.preferredWidth: visible ? Style.baseWidgetSize * 0.7 : 0
}
GridLayout {
Layout.fillWidth: true
@@ -351,7 +379,7 @@ NPanel {
model: 7
Item {
Layout.fillWidth: true
- Layout.preferredHeight: Style.baseWidgetSize * 0.6 * scaling
+ Layout.preferredHeight: Style.baseWidgetSize * 0.6
NText {
anchors.centerIn: parent
text: {
@@ -360,7 +388,7 @@ NPanel {
return dayNames[dayIndex]
}
color: Color.mPrimary
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
font.weight: Style.fontWeightBold
horizontalAlignment: Text.AlignHCenter
}
@@ -374,7 +402,7 @@ NPanel {
spacing: 0
ColumnLayout {
visible: Settings.data.location.showWeekNumberInCalendar
- Layout.preferredWidth: visible ? Style.baseWidgetSize * 0.7 * scaling : 0
+ Layout.preferredWidth: visible ? Style.baseWidgetSize * 0.7 : 0
Layout.fillHeight: true
spacing: 0
Repeater {
@@ -385,7 +413,7 @@ NPanel {
NText {
anchors.centerIn: parent
color: Color.mOutline
- pointSize: Style.fontSizeXXS * scaling
+ pointSize: Style.fontSizeXXS
font.weight: Style.fontWeightMedium
text: {
let firstOfMonth = new Date(grid.year, grid.month, 1)
@@ -417,16 +445,16 @@ NPanel {
id: grid
Layout.fillWidth: true
Layout.fillHeight: true
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
month: Time.date.getMonth()
year: Time.date.getFullYear()
locale: Qt.locale()
delegate: Item {
Rectangle {
- width: Style.baseWidgetSize * 0.9 * scaling
- height: Style.baseWidgetSize * 0.9 * scaling
+ width: Style.baseWidgetSize * 0.9
+ height: Style.baseWidgetSize * 0.9
anchors.centerIn: parent
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
color: model.today ? Color.mSecondary : Color.transparent
NText {
anchors.centerIn: parent
@@ -439,7 +467,7 @@ NPanel {
return Color.mOnSurfaceVariant
}
opacity: model.month === grid.month ? 1.0 : 0.4
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: model.today ? Style.fontWeightBold : Style.fontWeightMedium
}
Behavior on color {
diff --git a/Modules/Bar/Extras/BarPill.qml b/Modules/Bar/Extras/BarPill.qml
index ff4ae3bb..ba1601d3 100644
--- a/Modules/Bar/Extras/BarPill.qml
+++ b/Modules/Bar/Extras/BarPill.qml
@@ -12,13 +12,13 @@ Item {
property string text: ""
property string suffix: ""
property string tooltipText: ""
+ property string density: ""
property bool autoHide: false
property bool forceOpen: false
property bool forceClose: false
property bool disableOpen: false
property bool rightOpen: false
property bool hovered: false
- property bool compact: false
readonly property string barPosition: Settings.data.bar.position
readonly property bool isVerticalBar: barPosition === "left" || barPosition === "right"
@@ -54,7 +54,7 @@ Item {
disableOpen: root.disableOpen
rightOpen: root.rightOpen
hovered: root.hovered
- compact: root.compact
+ density: root.density
onShown: root.shown()
onHidden: root.hidden()
onEntered: root.entered()
@@ -79,7 +79,7 @@ Item {
disableOpen: root.disableOpen
rightOpen: root.rightOpen
hovered: root.hovered
- compact: root.compact
+ density: root.density
onShown: root.shown()
onHidden: root.hidden()
onEntered: root.entered()
diff --git a/Modules/Bar/Extras/BarPillHorizontal.qml b/Modules/Bar/Extras/BarPillHorizontal.qml
index a7da0d1d..0c2b5e90 100644
--- a/Modules/Bar/Extras/BarPillHorizontal.qml
+++ b/Modules/Bar/Extras/BarPillHorizontal.qml
@@ -14,13 +14,13 @@ Item {
property string text: ""
property string suffix: ""
property string tooltipText: ""
+ property string density: ""
property bool autoHide: false
property bool forceOpen: false
property bool forceClose: false
property bool disableOpen: false
property bool rightOpen: false
property bool hovered: false
- property bool compact: false
// Effective shown state (true if hovered/animated open or forced)
readonly property bool revealed: !forceClose && (forceOpen || showPill)
@@ -38,13 +38,28 @@ Item {
property bool showPill: false
property bool shouldAnimateHide: false
- readonly property int pillHeight: Math.round(Style.capsuleHeight * scaling)
- readonly property int pillPaddingHorizontal: Math.round(Style.capsuleHeight * 0.2 * scaling)
- readonly property int pillOverlap: Math.round(Style.capsuleHeight * 0.5 * scaling)
- readonly property int pillMaxWidth: Math.max(1, textItem.implicitWidth + pillPaddingHorizontal * 2 + pillOverlap)
+ readonly property int pillHeight: Style.capsuleHeight
+ readonly property int pillPaddingHorizontal: Math.round(Style.capsuleHeight * 0.2)
+ readonly property int pillOverlap: Math.round(Style.capsuleHeight * 0.5)
+ readonly property int pillMaxWidth: Math.max(1, Math.round(textItem.implicitWidth + pillPaddingHorizontal * 2 + pillOverlap))
- readonly property real iconSize: Math.max(1, compact ? pillHeight * 0.65 : pillHeight * 0.48)
- readonly property real textSize: Math.max(1, compact ? pillHeight * 0.45 : pillHeight * 0.33)
+ readonly property real iconSize: {
+ switch (root.density) {
+ case "compact":
+ return Math.max(1, Math.round(pillHeight * 0.65))
+ default:
+ return Math.max(1, Math.round(pillHeight * 0.48))
+ }
+ }
+
+ readonly property real textSize: {
+ switch (root.density) {
+ case "compact":
+ return Math.max(1, Math.round(pillHeight * 0.45))
+ default:
+ return Math.max(1, Math.round(pillHeight * 0.33))
+ }
+ }
width: pillHeight + Math.max(0, pill.width - pillOverlap)
height: pillHeight
@@ -68,10 +83,12 @@ Item {
opacity: revealed ? Style.opacityFull : Style.opacityNone
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
- topLeftRadius: rightOpen ? 0 : pillHeight * 0.5
- bottomLeftRadius: rightOpen ? 0 : pillHeight * 0.5
- topRightRadius: rightOpen ? pillHeight * 0.5 : 0
- bottomRightRadius: rightOpen ? pillHeight * 0.5 : 0
+ readonly property int halfPillHeight: Math.round(pillHeight * 0.5)
+
+ topLeftRadius: rightOpen ? 0 : halfPillHeight
+ bottomLeftRadius: rightOpen ? 0 : halfPillHeight
+ topRightRadius: rightOpen ? halfPillHeight : 0
+ bottomRightRadius: rightOpen ? halfPillHeight : 0
anchors.verticalCenter: parent.verticalCenter
NText {
@@ -80,16 +97,17 @@ Item {
x: {
// Better text horizontal centering
var centerX = (parent.width - width) / 2
- var offset = rightOpen ? Style.marginXS * scaling : -Style.marginXS * scaling
+ var offset = rightOpen ? Style.marginXS : -Style.marginXS
if (forceOpen) {
// If its force open, the icon disc background is the same color as the bg pill move text slightly
- offset += rightOpen ? -Style.marginXXS * scaling : Style.marginXXS * scaling
+ offset += rightOpen ? -Style.marginXXS : Style.marginXXS
}
return centerX + offset
}
text: root.text + root.suffix
family: Settings.data.ui.fontFixed
pointSize: textSize
+ applyUiScale: false
font.weight: Style.fontWeightBold
color: forceOpen ? Color.mOnSurface : Color.mPrimary
visible: revealed
@@ -131,6 +149,7 @@ Item {
NIcon {
icon: root.icon
pointSize: iconSize
+ applyUiScale: false
color: hovered ? Color.mOnTertiary : Color.mOnSurface
// Center horizontally
x: (iconCircle.width - width) / 2
diff --git a/Modules/Bar/Extras/BarPillVertical.qml b/Modules/Bar/Extras/BarPillVertical.qml
index f11b06e6..c8b53997 100644
--- a/Modules/Bar/Extras/BarPillVertical.qml
+++ b/Modules/Bar/Extras/BarPillVertical.qml
@@ -12,13 +12,13 @@ Item {
property string text: ""
property string suffix: ""
property string tooltipText: ""
+ property string density: ""
property bool autoHide: false
property bool forceOpen: false
property bool forceClose: false
property bool disableOpen: false
property bool rightOpen: false
property bool hovered: false
- property bool compact: false
// Bar position detection for pill direction
readonly property string barPosition: Settings.data.bar.position
@@ -45,15 +45,30 @@ Item {
property bool shouldAnimateHide: false
// Sizing logic for vertical bars
- readonly property int buttonSize: Math.round(Style.capsuleHeight * scaling)
+ readonly property int buttonSize: Style.capsuleHeight
readonly property int pillHeight: buttonSize
- readonly property int pillPaddingVertical: 3 * 2 * scaling // Very precise adjustment don't replace by Style.margin
- readonly property int pillOverlap: buttonSize * 0.5
+ readonly property int pillPaddingVertical: 3 * 2 // Very precise adjustment don't replace by Style.margin
+ readonly property int pillOverlap: Math.round(buttonSize * 0.5)
readonly property int maxPillWidth: buttonSize
- readonly property int maxPillHeight: Math.max(1, textItem.implicitHeight + pillPaddingVertical * 4)
+ readonly property int maxPillHeight: Math.max(1, Math.round(textItem.implicitHeight + pillPaddingVertical * 4))
- readonly property real iconSize: Math.max(1, compact ? pillHeight * 0.65 : pillHeight * 0.48)
- readonly property real textSize: Math.max(1, compact ? pillHeight * 0.38 : pillHeight * 0.33)
+ readonly property real iconSize: {
+ switch (root.density) {
+ case "compact":
+ return Math.max(1, Math.round(pillHeight * 0.65))
+ default:
+ return Math.max(1, Math.round(pillHeight * 0.48))
+ }
+ }
+
+ readonly property real textSize: {
+ switch (root.density) {
+ case "compact":
+ return Math.max(1, Math.round(pillHeight * 0.38))
+ default:
+ return Math.max(1, Math.round(pillHeight * 0.33))
+ }
+ }
// For vertical bars: width is just icon size, height includes pill space
width: buttonSize
@@ -79,11 +94,13 @@ Item {
opacity: revealed ? Style.opacityFull : Style.opacityNone
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
+ readonly property int halfButtonSize: Math.round(buttonSize * 0.5)
+
// Radius logic for vertical expansion - rounded on the side that connects to icon
- topLeftRadius: openUpward ? buttonSize * 0.5 : 0
- bottomLeftRadius: openDownward ? buttonSize * 0.5 : 0
- topRightRadius: openUpward ? buttonSize * 0.5 : 0
- bottomRightRadius: openDownward ? buttonSize * 0.5 : 0
+ topLeftRadius: openUpward ? halfButtonSize : 0
+ bottomLeftRadius: openDownward ? halfButtonSize : 0
+ topRightRadius: openUpward ? halfButtonSize : 0
+ bottomRightRadius: openDownward ? halfButtonSize : 0
anchors.horizontalCenter: parent.horizontalCenter
@@ -92,16 +109,17 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: {
- var offset = openDownward ? pillPaddingVertical * 0.75 : -pillPaddingVertical * 0.75
+ var offset = openDownward ? Math.round(pillPaddingVertical * 0.75) : -Math.round(pillPaddingVertical * 0.75)
if (forceOpen) {
// If its force open, the icon disc background is the same color as the bg pill move text slightly
- offset += rightOpen ? -Style.marginXXS * scaling : Style.marginXXS * scaling
+ offset += rightOpen ? -Style.marginXXS : Style.marginXXS
}
return offset
}
text: root.text + root.suffix
family: Settings.data.ui.fontFixed
pointSize: textSize
+ applyUiScale: false
font.weight: Style.fontWeightMedium
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
@@ -154,6 +172,7 @@ Item {
NIcon {
icon: root.icon
pointSize: iconSize
+ applyUiScale: false
color: hovered ? Color.mOnTertiary : Color.mOnSurface
// Center horizontally
x: (iconCircle.width - width) / 2
diff --git a/Modules/Bar/Extras/BarWidgetLoader.qml b/Modules/Bar/Extras/BarWidgetLoader.qml
index d4194d1e..fff11ebf 100644
--- a/Modules/Bar/Extras/BarWidgetLoader.qml
+++ b/Modules/Bar/Extras/BarWidgetLoader.qml
@@ -16,16 +16,6 @@ Item {
implicitWidth: getImplicitSize(loader.item, "implicitWidth")
implicitHeight: getImplicitSize(loader.item, "implicitHeight")
- Connections {
- target: ScalingService
- enabled: loader.item && (loader.item.screen !== undefined)
- function onScaleChanged(aScreenName, scale) {
- if (loader.item && loader.item.screen && aScreenName === screenName) {
- loader.item['scaling'] = scale
- }
- }
- }
-
function getImplicitSize(item, prop) {
return (item && item.visible) ? Math.round(item[prop]) : 0
}
diff --git a/Modules/Bar/Extras/TrayMenu.qml b/Modules/Bar/Extras/TrayMenu.qml
index 9b6088b9..c0f15e0e 100644
--- a/Modules/Bar/Extras/TrayMenu.qml
+++ b/Modules/Bar/Extras/TrayMenu.qml
@@ -15,23 +15,13 @@ PopupWindow {
property bool isSubMenu: false
property bool isHovered: rootMouseArea.containsMouse
property ShellScreen screen
- property real scaling: ScalingService.getScreenScale(screen)
-
- Connections {
- target: ScalingService
- function onScaleChanged(screenName, scale) {
- if ((screen != null) && (screenName === screen.name)) {
- scaling = scale
- }
- }
- }
readonly property int menuWidth: 180
- implicitWidth: Math.round(menuWidth * scaling)
+ implicitWidth: menuWidth
// Use the content height of the Flickable for implicit height
- implicitHeight: Math.min(screen ? screen.height * 0.9 : Screen.height * 0.9, flickable.contentHeight + (Style.marginS * 2 * scaling))
+ implicitHeight: Math.min(screen ? screen.height * 0.9 : Screen.height * 0.9, flickable.contentHeight + (Style.marginS * 2))
visible: false
color: Color.transparent
anchor.item: anchorItem
@@ -98,14 +88,14 @@ PopupWindow {
anchors.fill: parent
color: Color.mSurface
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
- radius: Style.radiusM * scaling
+ border.width: Math.max(1, Style.borderS)
+ radius: Style.radiusM
}
Flickable {
id: flickable
anchors.fill: parent
- anchors.margins: Style.marginS * scaling
+ anchors.margins: Style.marginS
contentHeight: columnLayout.implicitHeight
interactive: true
@@ -125,11 +115,11 @@ PopupWindow {
Layout.preferredWidth: parent.width
Layout.preferredHeight: {
if (modelData?.isSeparator) {
- return 8 * scaling
+ return 8
} else {
// Calculate based on text content
- const textHeight = text.contentHeight || (Style.fontSizeS * scaling * 1.2)
- return Math.max(28 * scaling, textHeight + (Style.marginS * 2 * scaling))
+ const textHeight = text.contentHeight || (Style.fontSizeS * 1.2)
+ return Math.max(28, textHeight + (Style.marginS * 2))
}
}
@@ -138,35 +128,35 @@ PopupWindow {
NDivider {
anchors.centerIn: parent
- width: parent.width - (Style.marginM * scaling * 2)
+ width: parent.width - (Style.marginM * 2)
visible: modelData?.isSeparator ?? false
}
Rectangle {
anchors.fill: parent
color: mouseArea.containsMouse ? Color.mTertiary : Color.transparent
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
visible: !(modelData?.isSeparator ?? false)
RowLayout {
anchors.fill: parent
- anchors.leftMargin: Style.marginM * scaling
- anchors.rightMargin: Style.marginM * scaling
- spacing: Style.marginS * scaling
+ anchors.leftMargin: Style.marginM
+ anchors.rightMargin: Style.marginM
+ spacing: Style.marginS
NText {
id: text
Layout.fillWidth: true
color: (modelData?.enabled ?? true) ? (mouseArea.containsMouse ? Color.mOnTertiary : Color.mOnSurface) : Color.mOnSurfaceVariant
text: modelData?.text !== "" ? modelData?.text.replace(/[\n\r]+/g, ' ') : "..."
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
}
Image {
- Layout.preferredWidth: Style.marginL * scaling
- Layout.preferredHeight: Style.marginL * scaling
+ Layout.preferredWidth: Style.marginL
+ Layout.preferredHeight: Style.marginL
source: modelData?.icon ?? ""
visible: (modelData?.icon ?? "") !== ""
fillMode: Image.PreserveAspectFit
@@ -174,7 +164,8 @@ PopupWindow {
NIcon {
icon: modelData?.hasChildren ? "menu" : ""
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
+ applyUiScale: false
verticalAlignment: Text.AlignVCenter
visible: modelData?.hasChildren ?? false
color: (mouseArea.containsMouse ? Color.mOnTertiary : Color.mOnSurface)
@@ -216,8 +207,8 @@ PopupWindow {
}
// Need a slight overlap so that menu don't close when moving the mouse to a submenu
- const submenuWidth = menuWidth * scaling // Assuming a similar width as the parent
- const overlap = 4 * scaling // A small overlap to bridge the mouse path
+ const submenuWidth = menuWidth // Assuming a similar width as the parent
+ const overlap = 4 // A small overlap to bridge the mouse path
// Determine submenu opening direction based on bar position and available space
let openLeft = false
diff --git a/Modules/Bar/WiFi/WiFiPanel.qml b/Modules/Bar/WiFi/WiFiPanel.qml
index 4bd32b47..9bab6f25 100644
--- a/Modules/Bar/WiFi/WiFiPanel.qml
+++ b/Modules/Bar/WiFi/WiFiPanel.qml
@@ -10,8 +10,8 @@ import qs.Widgets
NPanel {
id: root
- preferredWidth: 400
- preferredHeight: 500
+ preferredWidth: 400 * Style.uiScaleRatio
+ preferredHeight: 500 * Style.uiScaleRatio
panelKeyboardFocus: true
property string passwordSsid: ""
@@ -25,23 +25,23 @@ NPanel {
ColumnLayout {
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginM
// Header
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NIcon {
icon: Settings.data.network.wifiEnabled ? "wifi" : "wifi-off"
- pointSize: Style.fontSizeXXL * scaling
+ pointSize: Style.fontSizeXXL
color: Settings.data.network.wifiEnabled ? Color.mPrimary : Color.mOnSurfaceVariant
}
NText {
text: I18n.tr("wifi.panel.title")
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: Color.mOnSurface
Layout.fillWidth: true
@@ -51,7 +51,7 @@ NPanel {
id: wifiSwitch
checked: Settings.data.network.wifiEnabled
onToggled: checked => NetworkService.setWifiEnabled(checked)
- baseSize: Style.baseWidgetSize * 0.65 * scaling
+ baseSize: Style.baseWidgetSize * 0.65
}
NIconButton {
@@ -78,28 +78,28 @@ NPanel {
Rectangle {
visible: NetworkService.lastError.length > 0
Layout.fillWidth: true
- Layout.preferredHeight: errorRow.implicitHeight + (Style.marginM * scaling * 2)
+ Layout.preferredHeight: errorRow.implicitHeight + (Style.marginM * 2)
color: Qt.rgba(Color.mError.r, Color.mError.g, Color.mError.b, 0.1)
- radius: Style.radiusS * scaling
- border.width: Math.max(1, Style.borderS * scaling)
+ radius: Style.radiusS
+ border.width: Math.max(1, Style.borderS)
border.color: Color.mError
RowLayout {
id: errorRow
anchors.fill: parent
- anchors.margins: Style.marginM * scaling
- spacing: Style.marginS * scaling
+ anchors.margins: Style.marginM
+ spacing: Style.marginS
NIcon {
icon: "warning"
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: Color.mError
}
NText {
text: NetworkService.lastError
color: Color.mError
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
wrapMode: Text.Wrap
Layout.fillWidth: true
}
@@ -122,7 +122,7 @@ NPanel {
ColumnLayout {
visible: !Settings.data.network.wifiEnabled
anchors.fill: parent
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
Item {
Layout.fillHeight: true
@@ -130,21 +130,21 @@ NPanel {
NIcon {
icon: "wifi-off"
- pointSize: 64 * scaling
+ pointSize: 64
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
NText {
text: I18n.tr("wifi.panel.disabled")
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
NText {
text: I18n.tr("wifi.panel.enable-message")
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
@@ -158,7 +158,7 @@ NPanel {
ColumnLayout {
visible: Settings.data.network.wifiEnabled && NetworkService.scanning && Object.keys(NetworkService.networks).length === 0
anchors.fill: parent
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Item {
Layout.fillHeight: true
@@ -167,13 +167,13 @@ NPanel {
NBusyIndicator {
running: true
color: Color.mPrimary
- size: Style.baseWidgetSize * scaling
+ size: Style.baseWidgetSize
Layout.alignment: Qt.AlignHCenter
}
NText {
text: I18n.tr("wifi.panel.searching")
- pointSize: Style.fontSizeNormal * scaling
+ pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
@@ -193,7 +193,7 @@ NPanel {
ColumnLayout {
width: parent.width
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Network list
Repeater {
@@ -211,14 +211,14 @@ NPanel {
Rectangle {
Layout.fillWidth: true
- implicitHeight: netColumn.implicitHeight + (Style.marginM * scaling * 2)
- radius: Style.radiusM * scaling
+ implicitHeight: netColumn.implicitHeight + (Style.marginM * 2)
+ radius: Style.radiusM
// Add opacity for operations in progress
opacity: (NetworkService.disconnectingFrom === modelData.ssid || NetworkService.forgettingNetwork === modelData.ssid) ? 0.6 : 1.0
color: modelData.connected ? Qt.rgba(Color.mPrimary.r, Color.mPrimary.g, Color.mPrimary.b, 0.05) : Color.mSurface
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
border.color: modelData.connected ? Color.mPrimary : Color.mOutline
// Smooth opacity animation
@@ -230,29 +230,29 @@ NPanel {
ColumnLayout {
id: netColumn
- width: parent.width - (Style.marginM * scaling * 2)
- x: Style.marginM * scaling
- y: Style.marginM * scaling
- spacing: Style.marginS * scaling
+ width: parent.width - (Style.marginM * 2)
+ x: Style.marginM
+ y: Style.marginM
+ spacing: Style.marginS
// Main row
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
NIcon {
icon: NetworkService.signalIcon(modelData.signal)
- pointSize: Style.fontSizeXXL * scaling
+ pointSize: Style.fontSizeXXL
color: modelData.connected ? Color.mPrimary : Color.mOnSurface
}
ColumnLayout {
Layout.fillWidth: true
- spacing: 2 * scaling
+ spacing: 2
NText {
text: modelData.ssid
- pointSize: Style.fontSizeNormal * scaling
+ pointSize: Style.fontSizeM
font.weight: modelData.connected ? Style.fontWeightBold : Style.fontWeightMedium
color: Color.mOnSurface
elide: Text.ElideRight
@@ -260,30 +260,30 @@ NPanel {
}
RowLayout {
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
NText {
text: I18n.tr("system.signal-strength", {
"signal": modelData.signal
})
- pointSize: Style.fontSizeXXS * scaling
+ pointSize: Style.fontSizeXXS
color: Color.mOnSurfaceVariant
}
NText {
text: "•"
- pointSize: Style.fontSizeXXS * scaling
+ pointSize: Style.fontSizeXXS
color: Color.mOnSurfaceVariant
}
NText {
text: NetworkService.isSecured(modelData.security) ? modelData.security : "Open"
- pointSize: Style.fontSizeXXS * scaling
+ pointSize: Style.fontSizeXXS
color: Color.mOnSurfaceVariant
}
Item {
- Layout.preferredWidth: Style.marginXXS * scaling
+ Layout.preferredWidth: Style.marginXXS
}
// Update the status badges area (around line 237)
@@ -291,14 +291,14 @@ NPanel {
visible: modelData.connected && NetworkService.disconnectingFrom !== modelData.ssid
color: Color.mPrimary
radius: height * 0.5
- width: connectedText.implicitWidth + (Style.marginS * scaling * 2)
- height: connectedText.implicitHeight + (Style.marginXXS * scaling * 2)
+ width: connectedText.implicitWidth + (Style.marginS * 2)
+ height: connectedText.implicitHeight + (Style.marginXXS * 2)
NText {
id: connectedText
anchors.centerIn: parent
text: I18n.tr("wifi.panel.connected")
- pointSize: Style.fontSizeXXS * scaling
+ pointSize: Style.fontSizeXXS
color: Color.mOnPrimary
}
}
@@ -307,14 +307,14 @@ NPanel {
visible: NetworkService.disconnectingFrom === modelData.ssid
color: Color.mError
radius: height * 0.5
- width: disconnectingText.implicitWidth + (Style.marginS * scaling * 2)
- height: disconnectingText.implicitHeight + (Style.marginXXS * scaling * 2)
+ width: disconnectingText.implicitWidth + (Style.marginS * 2)
+ height: disconnectingText.implicitHeight + (Style.marginXXS * 2)
NText {
id: disconnectingText
anchors.centerIn: parent
text: I18n.tr("wifi.panel.disconnecting")
- pointSize: Style.fontSizeXXS * scaling
+ pointSize: Style.fontSizeXXS
color: Color.mOnPrimary
}
}
@@ -323,14 +323,14 @@ NPanel {
visible: NetworkService.forgettingNetwork === modelData.ssid
color: Color.mError
radius: height * 0.5
- width: forgettingText.implicitWidth + (Style.marginS * scaling * 2)
- height: forgettingText.implicitHeight + (Style.marginXXS * scaling * 2)
+ width: forgettingText.implicitWidth + (Style.marginS * 2)
+ height: forgettingText.implicitHeight + (Style.marginXXS * 2)
NText {
id: forgettingText
anchors.centerIn: parent
text: I18n.tr("wifi.panel.forgetting")
- pointSize: Style.fontSizeXXS * scaling
+ pointSize: Style.fontSizeXXS
color: Color.mOnPrimary
}
}
@@ -339,16 +339,16 @@ NPanel {
visible: modelData.cached && !modelData.connected && NetworkService.forgettingNetwork !== modelData.ssid && NetworkService.disconnectingFrom !== modelData.ssid
color: Color.transparent
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
radius: height * 0.5
- width: savedText.implicitWidth + (Style.marginS * scaling * 2)
- height: savedText.implicitHeight + (Style.marginXXS * scaling * 2)
+ width: savedText.implicitWidth + (Style.marginS * 2)
+ height: savedText.implicitHeight + (Style.marginXXS * 2)
NText {
id: savedText
anchors.centerIn: parent
text: I18n.tr("wifi.panel.saved")
- pointSize: Style.fontSizeXXS * scaling
+ pointSize: Style.fontSizeXXS
color: Color.mOnSurfaceVariant
}
}
@@ -357,13 +357,13 @@ NPanel {
// Action area
RowLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
NBusyIndicator {
visible: NetworkService.connectingTo === modelData.ssid || NetworkService.disconnectingFrom === modelData.ssid || NetworkService.forgettingNetwork === modelData.ssid
running: visible
color: Color.mPrimary
- size: Style.baseWidgetSize * 0.5 * scaling
+ size: Style.baseWidgetSize * 0.5
}
NIconButton {
@@ -384,7 +384,7 @@ NPanel {
return I18n.tr("wifi.panel.password")
}
outlined: !hovered
- fontSize: Style.fontSizeXS * scaling
+ fontSize: Style.fontSizeXS
enabled: !NetworkService.connecting
onClicked: {
if (modelData.existing || modelData.cached || !NetworkService.isSecured(modelData.security)) {
@@ -401,7 +401,7 @@ NPanel {
visible: modelData.connected && NetworkService.disconnectingFrom !== modelData.ssid
text: I18n.tr("wifi.panel.disconnect")
outlined: !hovered
- fontSize: Style.fontSizeXS * scaling
+ fontSize: Style.fontSizeXS
backgroundColor: Color.mError
onClicked: NetworkService.disconnect(modelData.ssid)
}
@@ -412,35 +412,35 @@ NPanel {
Rectangle {
visible: passwordSsid === modelData.ssid && NetworkService.disconnectingFrom !== modelData.ssid && NetworkService.forgettingNetwork !== modelData.ssid
Layout.fillWidth: true
- height: passwordRow.implicitHeight + Style.marginS * scaling * 2
+ height: passwordRow.implicitHeight + Style.marginS * 2
color: Color.mSurfaceVariant
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
- radius: Style.radiusS * scaling
+ border.width: Math.max(1, Style.borderS)
+ radius: Style.radiusS
RowLayout {
id: passwordRow
anchors.fill: parent
- anchors.margins: Style.marginS * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginS
+ spacing: Style.marginM
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
- radius: Style.radiusXS * scaling
+ radius: Style.radiusXS
color: Color.mSurface
border.color: pwdInput.activeFocus ? Color.mSecondary : Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
TextInput {
id: pwdInput
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
- anchors.margins: Style.marginS * scaling
+ anchors.margins: Style.marginS
text: passwordInput
font.family: Settings.data.ui.fontFixed
- font.pointSize: Style.fontSizeS * scaling
+ font.pointSize: Style.fontSizeS
color: Color.mOnSurface
echoMode: TextInput.Password
selectByMouse: true
@@ -462,14 +462,14 @@ NPanel {
anchors.verticalCenter: parent.verticalCenter
text: I18n.tr("wifi.panel.enter-password")
color: Color.mOnSurfaceVariant
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
}
}
}
NButton {
text: I18n.tr("wifi.panel.connect")
- fontSize: Style.fontSizeXXS * scaling
+ fontSize: Style.fontSizeXXS
enabled: passwordInput.length > 0 && !NetworkService.connecting
outlined: true
onClicked: {
@@ -494,28 +494,28 @@ NPanel {
Rectangle {
visible: expandedSsid === modelData.ssid && NetworkService.disconnectingFrom !== modelData.ssid && NetworkService.forgettingNetwork !== modelData.ssid
Layout.fillWidth: true
- height: forgetRow.implicitHeight + Style.marginS * 2 * scaling
+ height: forgetRow.implicitHeight + Style.marginS * 2
color: Color.mSurfaceVariant
- radius: Style.radiusS * scaling
- border.width: Math.max(1, Style.borderS * scaling)
+ radius: Style.radiusS
+ border.width: Math.max(1, Style.borderS)
border.color: Color.mOutline
RowLayout {
id: forgetRow
anchors.fill: parent
- anchors.margins: Style.marginS * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginS
+ spacing: Style.marginM
RowLayout {
NIcon {
icon: "trash"
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: Color.mError
}
NText {
text: I18n.tr("wifi.panel.forget-network")
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: Color.mError
Layout.fillWidth: true
}
@@ -524,7 +524,7 @@ NPanel {
NButton {
id: forgetButton
text: I18n.tr("wifi.panel.forget")
- fontSize: Style.fontSizeXXS * scaling
+ fontSize: Style.fontSizeXXS
backgroundColor: Color.mError
outlined: forgetButton.hovered ? false : true
onClicked: {
@@ -550,7 +550,7 @@ NPanel {
ColumnLayout {
visible: Settings.data.network.wifiEnabled && !NetworkService.scanning && Object.keys(NetworkService.networks).length === 0
anchors.fill: parent
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Item {
Layout.fillHeight: true
@@ -558,14 +558,14 @@ NPanel {
NIcon {
icon: "search"
- pointSize: 64 * scaling
+ pointSize: 64
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
NText {
text: I18n.tr("wifi.panel.no-networks")
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
diff --git a/Modules/Bar/Widgets/ActiveWindow.qml b/Modules/Bar/Widgets/ActiveWindow.qml
index de10760d..6a10a095 100644
--- a/Modules/Bar/Widgets/ActiveWindow.qml
+++ b/Modules/Bar/Widgets/ActiveWindow.qml
@@ -12,7 +12,6 @@ Item {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -31,23 +30,24 @@ Item {
return {}
}
- readonly property bool hasActiveWindow: CompositorService.getFocusedWindowTitle() !== ""
+ readonly property bool hasFocusedWindow: CompositorService.getFocusedWindow() !== null
readonly property string windowTitle: CompositorService.getFocusedWindowTitle() || "No active window"
readonly property string fallbackIcon: "user-desktop"
readonly property string barPosition: Settings.data.bar.position
- readonly property bool compact: (Settings.data.bar.density === "compact")
// Widget settings - matching MediaMini pattern
readonly property bool showIcon: (widgetSettings.showIcon !== undefined) ? widgetSettings.showIcon : widgetMetadata.showIcon
- readonly property bool autoHide: (widgetSettings.autoHide !== undefined) ? widgetSettings.autoHide : widgetMetadata.autoHide
+ readonly property string hideMode: (widgetSettings.hideMode !== undefined) ? widgetSettings.hideMode : widgetMetadata.hideMode
readonly property string scrollingMode: (widgetSettings.scrollingMode !== undefined) ? widgetSettings.scrollingMode : (widgetMetadata.scrollingMode !== undefined ? widgetMetadata.scrollingMode : "hover")
readonly property int widgetWidth: (widgetSettings.width !== undefined) ? widgetSettings.width : Math.max(widgetMetadata.width, screen.width * 0.06)
- implicitHeight: visible ? ((barPosition === "left" || barPosition === "right") ? calculatedVerticalHeight() : Math.round(Style.barHeight * scaling)) : 0
- implicitWidth: visible ? ((barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : (widgetWidth * scaling)) : 0
+ implicitHeight: visible ? ((barPosition === "left" || barPosition === "right") ? calculatedVerticalHeight() : Style.barHeight) : 0
+ implicitWidth: visible ? ((barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8) : (widgetWidth)) : 0
- opacity: !autoHide || hasActiveWindow ? 1.0 : 0
+ // "visible": Always Visible, "hidden": Hide When Empty, "transparent": Transparent When Empty
+ visible: hideMode !== "hidden" || hasFocusedWindow
+ opacity: hideMode !== "transparent" || hasFocusedWindow ? 1.0 : 0
Behavior on opacity {
NumberAnimation {
duration: Style.animationNormal
@@ -56,7 +56,7 @@ Item {
}
function calculatedVerticalHeight() {
- return Math.round(Style.baseWidgetSize * 0.8 * scaling)
+ return Math.round(Style.baseWidgetSize * 0.8)
}
function getAppIcon() {
@@ -107,7 +107,8 @@ Item {
id: fullTitleMetrics
visible: false
text: windowTitle
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
+ applyUiScale: false
font.weight: Style.fontWeightMedium
}
@@ -116,29 +117,29 @@ Item {
visible: root.visible
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
- width: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : (widgetWidth * scaling)
- height: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : Math.round(Style.capsuleHeight * scaling)
- radius: (barPosition === "left" || barPosition === "right") ? width / 2 : Math.round(Style.radiusM * scaling)
+ width: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8) : (widgetWidth)
+ height: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8) : Style.capsuleHeight
+ radius: (barPosition === "left" || barPosition === "right") ? width / 2 : Style.radiusM
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
Item {
id: mainContainer
anchors.fill: parent
- anchors.leftMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling
- anchors.rightMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling
+ anchors.leftMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS
+ anchors.rightMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS
// Horizontal layout for top/bottom bars
RowLayout {
id: rowLayout
anchors.verticalCenter: parent.verticalCenter
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
visible: barPosition === "top" || barPosition === "bottom"
z: 1
// Window icon
Item {
- Layout.preferredWidth: Math.round(18 * scaling)
- Layout.preferredHeight: Math.round(18 * scaling)
+ Layout.preferredWidth: 18
+ Layout.preferredHeight: 18
Layout.alignment: Qt.AlignVCenter
visible: showIcon
@@ -149,6 +150,15 @@ Item {
asynchronous: true
smooth: true
visible: source !== ""
+
+ // Apply dock shader to active window icon (always themed)
+ layer.enabled: widgetSettings.colorizeIcons !== false
+ layer.effect: ShaderEffect {
+ property color targetColor: Color.mOnSurface
+ property real colorizeMode: 0.0 // Dock mode (grayscale)
+
+ fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
+ }
}
}
@@ -157,10 +167,10 @@ Item {
id: titleContainer
Layout.preferredWidth: {
// Calculate available width based on other elements
- var iconWidth = (showIcon && windowIcon.visible ? (18 * scaling + Style.marginS * scaling) : 0)
- var totalMargins = Style.marginXXS * scaling * 2
+ var iconWidth = (showIcon && windowIcon.visible ? (18 + Style.marginS) : 0)
+ var totalMargins = Style.marginXXS * 2
var availableWidth = mainContainer.width - iconWidth - totalMargins
- return Math.max(20 * scaling, availableWidth)
+ return Math.max(20, availableWidth)
}
Layout.maximumWidth: Layout.preferredWidth
Layout.alignment: Qt.AlignVCenter
@@ -239,12 +249,13 @@ Item {
x: scrollX
RowLayout {
- spacing: 50 * scaling // Gap between text copies
+ spacing: 50 // Gap between text copies
NText {
id: titleText
text: windowTitle
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
+ applyUiScale: false
font.weight: Style.fontWeightMedium
verticalAlignment: Text.AlignVCenter
color: Color.mOnSurface
@@ -254,6 +265,8 @@ Item {
NText {
text: windowTitle
font: titleText.font
+ pointSize: Style.fontSizeS
+ applyUiScale: false
verticalAlignment: Text.AlignVCenter
color: Color.mOnSurface
visible: titleContainer.needsScrolling && titleContainer.isScrolling
@@ -276,7 +289,7 @@ Item {
id: infiniteScroll
running: titleContainer.isScrolling && !titleContainer.isResetting
from: 0
- to: -(titleContainer.textWidth + 50 * scaling)
+ to: -(titleContainer.textWidth + 50)
duration: Math.max(4000, windowTitle.length * 100)
loops: Animation.Infinite
easing.type: Easing.Linear
@@ -296,15 +309,15 @@ Item {
Item {
id: verticalLayout
anchors.centerIn: parent
- width: parent.width - Style.marginM * scaling * 2
- height: parent.height - Style.marginM * scaling * 2
+ width: parent.width - Style.marginM * 2
+ height: parent.height - Style.marginM * 2
visible: barPosition === "left" || barPosition === "right"
z: 1
// Window icon
Item {
- width: Style.baseWidgetSize * 0.5 * scaling
- height: Style.baseWidgetSize * 0.5 * scaling
+ width: Style.baseWidgetSize * 0.5
+ height: Style.baseWidgetSize * 0.5
anchors.centerIn: parent
visible: windowTitle !== ""
@@ -315,6 +328,15 @@ Item {
asynchronous: true
smooth: true
visible: source !== ""
+
+ // Apply dock shader to active window icon (always themed)
+ layer.enabled: widgetSettings.colorizeIcons !== false
+ layer.effect: ShaderEffect {
+ property color targetColor: Color.mOnSurface
+ property real colorizeMode: 0.0 // Dock mode (grayscale)
+
+ fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
+ }
}
}
}
diff --git a/Modules/Bar/Widgets/Battery.qml b/Modules/Bar/Widgets/Battery.qml
index 336ee925..02032cd9 100644
--- a/Modules/Bar/Widgets/Battery.qml
+++ b/Modules/Bar/Widgets/Battery.qml
@@ -11,7 +11,6 @@ Item {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -87,7 +86,7 @@ Item {
BarPill {
id: pill
- compact: (Settings.data.bar.density === "compact")
+ density: Settings.data.bar.density
rightOpen: BarService.getPillDirection(root)
icon: testMode ? BatteryService.getIcon(testPercent, testCharging, true) : BatteryService.getIcon(percent, charging, isReady)
text: (isReady || testMode) ? Math.round(percent) : "-"
diff --git a/Modules/Bar/Widgets/Bluetooth.qml b/Modules/Bar/Widgets/Bluetooth.qml
index e76fa234..e6f50f0f 100644
--- a/Modules/Bar/Widgets/Bluetooth.qml
+++ b/Modules/Bar/Widgets/Bluetooth.qml
@@ -11,10 +11,10 @@ NIconButton {
id: root
property ShellScreen screen
- property real scaling: 1.0
baseSize: Style.capsuleHeight
- compact: (Settings.data.bar.density === "compact")
+ applyUiScale: false
+ density: Settings.data.bar.density
colorBg: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
colorFg: Color.mOnSurface
colorBorder: Color.transparent
diff --git a/Modules/Bar/Widgets/Brightness.qml b/Modules/Bar/Widgets/Brightness.qml
index 652660c0..5c02e490 100644
--- a/Modules/Bar/Widgets/Brightness.qml
+++ b/Modules/Bar/Widgets/Brightness.qml
@@ -10,7 +10,6 @@ Item {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -77,7 +76,7 @@ Item {
BarPill {
id: pill
- compact: (Settings.data.bar.density === "compact")
+ density: Settings.data.bar.density
rightOpen: BarService.getPillDirection(root)
icon: getIcon()
autoHide: false // Important to be false so we can hover as long as we want
diff --git a/Modules/Bar/Widgets/Clock.qml b/Modules/Bar/Widgets/Clock.qml
index 26ae5762..cbbecd2f 100644
--- a/Modules/Bar/Widgets/Clock.qml
+++ b/Modules/Bar/Widgets/Clock.qml
@@ -9,7 +9,6 @@ Rectangle {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -30,7 +29,7 @@ Rectangle {
readonly property string barPosition: Settings.data.bar.position
readonly property bool isBarVertical: barPosition === "left" || barPosition === "right"
- readonly property bool compact: (Settings.data.bar.density === "compact")
+ readonly property bool density: Settings.data.bar.density
readonly property var now: Time.date
@@ -41,11 +40,11 @@ Rectangle {
readonly property string formatHorizontal: widgetSettings.formatHorizontal !== undefined ? widgetSettings.formatHorizontal : widgetMetadata.formatHorizontal
readonly property string formatVertical: widgetSettings.formatVertical !== undefined ? widgetSettings.formatVertical : widgetMetadata.formatVertical
- implicitWidth: isBarVertical ? Math.round(Style.capsuleHeight * scaling) : Math.round((isBarVertical ? verticalLoader.implicitWidth : horizontalLoader.implicitWidth) + Style.marginM * 2 * scaling)
+ implicitWidth: isBarVertical ? Style.capsuleHeight : Math.round((isBarVertical ? verticalLoader.implicitWidth : horizontalLoader.implicitWidth) + Style.marginM * 2)
- implicitHeight: isBarVertical ? Math.round(verticalLoader.implicitHeight + Style.marginS * 2 * scaling) : Math.round(Style.capsuleHeight * scaling)
+ implicitHeight: isBarVertical ? Math.round(verticalLoader.implicitHeight + Style.marginS * 2) : Style.capsuleHeight
- radius: Math.round(Style.radiusS * scaling)
+ radius: Style.radiusS
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
Item {
@@ -59,7 +58,7 @@ Rectangle {
anchors.centerIn: parent
sourceComponent: ColumnLayout {
anchors.centerIn: parent
- spacing: Settings.data.bar.showCapsule ? -4 * scaling : -2 * scaling
+ spacing: Settings.data.bar.showCapsule ? -4 : -2
Repeater {
id: repeater
model: Qt.locale().toString(now, formatHorizontal.trim()).split("\\n")
@@ -69,11 +68,12 @@ Rectangle {
family: useCustomFont && customFont ? customFont : Settings.data.ui.fontDefault
pointSize: {
if (repeater.model.length == 1) {
- return Style.fontSizeS * scaling
+ return Style.fontSizeS
} else {
- return (index == 0) ? Style.fontSizeXS * scaling : Style.fontSizeXXS * scaling
+ return (index == 0) ? Style.fontSizeXS : Style.fontSizeXXS
}
}
+ applyUiScale: false
font.weight: Style.fontWeightBold
color: usePrimaryColor ? Color.mPrimary : Color.mOnSurface
wrapMode: Text.WordWrap
@@ -90,14 +90,15 @@ Rectangle {
anchors.centerIn: parent // Now this works without layout conflicts
sourceComponent: ColumnLayout {
anchors.centerIn: parent
- spacing: -2 * scaling
+ spacing: -2
Repeater {
model: Qt.locale().toString(now, formatVertical.trim()).split(" ")
delegate: NText {
visible: text !== ""
text: modelData
family: useCustomFont && customFont ? customFont : Settings.data.ui.fontDefault
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
+ applyUiScale: false
font.weight: Style.fontWeightBold
color: usePrimaryColor ? Color.mPrimary : Color.mOnSurface
wrapMode: Text.WordWrap
diff --git a/Modules/Bar/Widgets/ControlCenter.qml b/Modules/Bar/Widgets/ControlCenter.qml
index 65eb3b8c..b0ceea69 100644
--- a/Modules/Bar/Widgets/ControlCenter.qml
+++ b/Modules/Bar/Widgets/ControlCenter.qml
@@ -10,7 +10,6 @@ NIconButton {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -38,7 +37,8 @@ NIconButton {
tooltipText: I18n.tr("tooltips.open-control-center")
tooltipDirection: BarService.getTooltipDirection()
baseSize: Style.capsuleHeight
- compact: (Settings.data.bar.density === "compact")
+ applyUiScale: false
+ density: Settings.data.bar.density
colorBg: (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent)
colorFg: Color.mOnSurface
colorBgHover: useDistroLogo ? Color.mSurfaceVariant : Color.mTertiary
diff --git a/Modules/Bar/Widgets/CustomButton.qml b/Modules/Bar/Widgets/CustomButton.qml
index 50310b24..af0e58cd 100644
--- a/Modules/Bar/Widgets/CustomButton.qml
+++ b/Modules/Bar/Widgets/CustomButton.qml
@@ -12,7 +12,6 @@ Item {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -49,7 +48,7 @@ Item {
rightOpen: BarService.getPillDirection(root)
icon: customIcon
text: _dynamicText
- compact: (Settings.data.bar.density === "compact")
+ density: Settings.data.bar.density
autoHide: false
forceOpen: _dynamicText !== ""
forceClose: false
diff --git a/Modules/Bar/Widgets/DarkMode.qml b/Modules/Bar/Widgets/DarkMode.qml
index b35dd236..d9a2cb25 100644
--- a/Modules/Bar/Widgets/DarkMode.qml
+++ b/Modules/Bar/Widgets/DarkMode.qml
@@ -7,13 +7,13 @@ NIconButton {
id: root
property ShellScreen screen
- property real scaling: 1.0
icon: "dark-mode"
tooltipText: Settings.data.colorSchemes.darkMode ? I18n.tr("tooltips.switch-to-light-mode") : I18n.tr("tooltips.switch-to-dark-mode")
tooltipDirection: BarService.getTooltipDirection()
- compact: (Settings.data.bar.density === "compact")
+ density: Settings.data.bar.density
baseSize: Style.capsuleHeight
+ applyUiScale: false
colorBg: Settings.data.colorSchemes.darkMode ? (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent) : Color.mPrimary
colorFg: Settings.data.colorSchemes.darkMode ? Color.mOnSurface : Color.mOnPrimary
colorBorder: Color.transparent
diff --git a/Modules/Bar/Widgets/KeepAwake.qml b/Modules/Bar/Widgets/KeepAwake.qml
index ba09d92a..c0546884 100644
--- a/Modules/Bar/Widgets/KeepAwake.qml
+++ b/Modules/Bar/Widgets/KeepAwake.qml
@@ -9,10 +9,10 @@ NIconButton {
id: root
property ShellScreen screen
- property real scaling: 1.0
baseSize: Style.capsuleHeight
- compact: (Settings.data.bar.density === "compact")
+ applyUiScale: false
+ density: Settings.data.bar.density
icon: IdleInhibitorService.isInhibited ? "keep-awake-on" : "keep-awake-off"
tooltipText: IdleInhibitorService.isInhibited ? I18n.tr("tooltips.disable-keep-awake") : I18n.tr("tooltips.enable-keep-awake")
tooltipDirection: BarService.getTooltipDirection()
diff --git a/Modules/Bar/Widgets/KeyboardLayout.qml b/Modules/Bar/Widgets/KeyboardLayout.qml
index ec83b71e..6d597227 100644
--- a/Modules/Bar/Widgets/KeyboardLayout.qml
+++ b/Modules/Bar/Widgets/KeyboardLayout.qml
@@ -12,7 +12,6 @@ Item {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -43,7 +42,7 @@ Item {
id: pill
anchors.verticalCenter: parent.verticalCenter
- compact: (Settings.data.bar.density === "compact")
+ density: Settings.data.bar.density
rightOpen: BarService.getPillDirection(root)
icon: "keyboard"
autoHide: false // Important to be false so we can hover as long as we want
diff --git a/Modules/Bar/Widgets/MediaMini.qml b/Modules/Bar/Widgets/MediaMini.qml
index e33be8f2..f3502781 100644
--- a/Modules/Bar/Widgets/MediaMini.qml
+++ b/Modules/Bar/Widgets/MediaMini.qml
@@ -11,7 +11,6 @@ Item {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -31,9 +30,9 @@ Item {
}
readonly property string barPosition: Settings.data.bar.position
- readonly property bool compact: (Settings.data.bar.density === "compact")
+ readonly property bool density: Settings.data.bar.density
- readonly property bool autoHide: (widgetSettings.autoHide !== undefined) ? widgetSettings.autoHide : widgetMetadata.autoHide
+ readonly property string hideMode: (widgetSettings.hideMode !== undefined) ? widgetSettings.hideMode : "hidden" // "visible", "hidden", "transparent"
readonly property bool showAlbumArt: (widgetSettings.showAlbumArt !== undefined) ? widgetSettings.showAlbumArt : widgetMetadata.showAlbumArt
readonly property bool showVisualizer: (widgetSettings.showVisualizer !== undefined) ? widgetSettings.showVisualizer : widgetMetadata.showVisualizer
readonly property string visualizerType: (widgetSettings.visualizerType !== undefined && widgetSettings.visualizerType !== "") ? widgetSettings.visualizerType : widgetMetadata.visualizerType
@@ -42,7 +41,7 @@ Item {
// Fixed width - no expansion
readonly property real widgetWidth: Math.max(145, screen.width * 0.06)
- readonly property bool hasActivePlayer: MediaService.currentPlayer !== null && getTitle() !== ""
+ readonly property bool hasActivePlayer: MediaService.currentPlayer !== null
readonly property string placeholderText: I18n.tr("bar.widget-settings.media-mini.no-active-player")
readonly property string tooltipText: {
@@ -60,10 +59,12 @@ Item {
return title
}
- implicitHeight: visible ? ((barPosition === "left" || barPosition === "right") ? calculatedVerticalHeight() : Math.round(Style.barHeight * scaling)) : 0
- implicitWidth: visible ? ((barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : (widgetWidth * scaling)) : 0
+ implicitHeight: visible ? ((barPosition === "left" || barPosition === "right") ? calculatedVerticalHeight() : Style.barHeight) : 0
+ implicitWidth: visible ? ((barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8) : (widgetWidth)) : 0
- opacity: !autoHide || hasActivePlayer || (!hasActivePlayer && !autoHide) ? 1.0 : 0
+ // "visible": Always Visible, "hidden": Hide When Empty, "transparent": Transparent When Empty
+ visible: hideMode !== "hidden" || hasActivePlayer
+ opacity: hideMode !== "transparent" || hasActivePlayer ? 1.0 : 0
Behavior on opacity {
NumberAnimation {
duration: Style.animationNormal
@@ -76,7 +77,7 @@ Item {
}
function calculatedVerticalHeight() {
- return Math.round(Style.baseWidgetSize * 0.8 * scaling)
+ return Math.round(Style.baseWidgetSize * 0.8)
}
// A hidden text element to safely measure the full title width
@@ -85,6 +86,7 @@ Item {
visible: false
text: titleText.text
font: titleText.font
+ applyUiScale: false
}
Rectangle {
@@ -92,16 +94,16 @@ Item {
visible: root.visible
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
- width: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : (widgetWidth * scaling)
- height: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8 * scaling) : Math.round(Style.capsuleHeight * scaling)
- radius: (barPosition === "left" || barPosition === "right") ? width / 2 : Math.round(Style.radiusM * scaling)
+ width: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8) : (widgetWidth)
+ height: (barPosition === "left" || barPosition === "right") ? Math.round(Style.baseWidgetSize * 0.8) : Style.capsuleHeight
+ radius: (barPosition === "left" || barPosition === "right") ? width / 2 : Style.radiusM
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
Item {
id: mainContainer
anchors.fill: parent
- anchors.leftMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling
- anchors.rightMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS * scaling
+ anchors.leftMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS
+ anchors.rightMargin: (barPosition === "left" || barPosition === "right") ? 0 : Style.marginS
Loader {
anchors.verticalCenter: parent.verticalCenter
@@ -110,8 +112,8 @@ Item {
z: 0
sourceComponent: LinearSpectrum {
- width: mainContainer.width - Style.marginS * scaling
- height: 20 * scaling
+ width: mainContainer.width - Style.marginS
+ height: 20
values: CavaService.values
fillColor: Color.mPrimary
opacity: 0.4
@@ -125,8 +127,8 @@ Item {
z: 0
sourceComponent: MirroredSpectrum {
- width: mainContainer.width - Style.marginS * scaling
- height: mainContainer.height - Style.marginS * scaling
+ width: mainContainer.width - Style.marginS
+ height: mainContainer.height - Style.marginS
values: CavaService.values
fillColor: Color.mPrimary
opacity: 0.4
@@ -140,8 +142,8 @@ Item {
z: 0
sourceComponent: WaveSpectrum {
- width: mainContainer.width - Style.marginS * scaling
- height: mainContainer.height - Style.marginS * scaling
+ width: mainContainer.width - Style.marginS
+ height: mainContainer.height - Style.marginS
values: CavaService.values
fillColor: Color.mPrimary
opacity: 0.4
@@ -153,7 +155,7 @@ Item {
id: rowLayout
anchors.verticalCenter: parent.verticalCenter
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
visible: (barPosition === "top" || barPosition === "bottom")
z: 1 // Above the visualizer
@@ -161,7 +163,7 @@ Item {
id: windowIcon
icon: hasActivePlayer ? (MediaService.isPlaying ? "media-pause" : "media-play") : "disc"
color: hasActivePlayer ? Color.mOnSurface : Color.mOnSurfaceVariant
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
verticalAlignment: Text.AlignVCenter
Layout.alignment: Qt.AlignVCenter
visible: !hasActivePlayer || (!showAlbumArt && !trackArt.visible)
@@ -173,15 +175,15 @@ Item {
spacing: 0
Item {
- Layout.preferredWidth: Math.round(21 * scaling)
- Layout.preferredHeight: Math.round(21 * scaling)
+ Layout.preferredWidth: Math.round(21 * Style.uiScaleRatio)
+ Layout.preferredHeight: Math.round(21 * Style.uiScaleRatio)
NImageCircled {
id: trackArt
anchors.fill: parent
imagePath: MediaService.trackArtUrl
fallbackIcon: MediaService.isPlaying ? "media-pause" : "media-play"
- fallbackIconSize: 10 * scaling
+ fallbackIconSize: 10
borderWidth: 0
border.color: Color.transparent
}
@@ -192,11 +194,11 @@ Item {
id: titleContainer
Layout.preferredWidth: {
// Calculate available width based on other elements in the row
- var iconWidth = (windowIcon.visible ? (Style.fontSizeL * scaling + Style.marginS * scaling) : 0)
- var albumArtWidth = (hasActivePlayer && showAlbumArt ? (18 * scaling + Style.marginS * scaling) : 0)
- var totalMargins = Style.marginXXS * scaling * 2
+ var iconWidth = (windowIcon.visible ? (Style.fontSizeL + Style.marginS) : 0)
+ var albumArtWidth = (hasActivePlayer && showAlbumArt ? (18 + Style.marginS) : 0)
+ var totalMargins = Style.marginXXS * 2
var availableWidth = mainContainer.width - iconWidth - albumArtWidth - totalMargins
- return Math.max(20 * scaling, availableWidth)
+ return Math.max(20, availableWidth)
}
Layout.maximumWidth: Layout.preferredWidth
Layout.alignment: Qt.AlignVCenter
@@ -281,12 +283,13 @@ Item {
x: scrollX
RowLayout {
- spacing: 50 * scaling // Gap between text copies
+ spacing: 50 // Gap between text copies
NText {
id: titleText
text: hasActivePlayer ? getTitle() : placeholderText
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
+ applyUiScale: false
font.weight: Style.fontWeightMedium
verticalAlignment: Text.AlignVCenter
horizontalAlignment: hasActivePlayer ? Text.AlignLeft : Text.AlignHCenter
@@ -296,6 +299,7 @@ Item {
NText {
text: hasActivePlayer ? getTitle() : placeholderText
font: titleText.font
+ applyUiScale: false
verticalAlignment: Text.AlignVCenter
horizontalAlignment: hasActivePlayer ? Text.AlignLeft : Text.AlignHCenter
color: hasActivePlayer ? Color.mOnSurface : Color.mOnSurfaceVariant
@@ -319,7 +323,7 @@ Item {
id: infiniteScroll
running: titleContainer.isScrolling && !titleContainer.isResetting
from: 0
- to: -(titleContainer.textWidth + 50 * scaling) // Scroll one complete text width + gap
+ to: -(titleContainer.textWidth + 50) // Scroll one complete text width + gap
duration: Math.max(4000, getTitle().length * 120)
loops: Animation.Infinite
easing.type: Easing.Linear
@@ -339,15 +343,15 @@ Item {
Item {
id: verticalLayout
anchors.centerIn: parent
- width: parent.width - Style.marginM * scaling * 2
- height: parent.height - Style.marginM * scaling * 2
+ width: parent.width - Style.marginM * 2
+ height: parent.height - Style.marginM * 2
visible: barPosition === "left" || barPosition === "right"
z: 1 // Above the visualizer
// Media icon
Item {
- width: Style.baseWidgetSize * 0.5 * scaling
- height: Style.baseWidgetSize * 0.5 * scaling
+ width: Style.baseWidgetSize * 0.5
+ height: Style.baseWidgetSize * 0.5
anchors.centerIn: parent
NIcon {
@@ -355,7 +359,7 @@ Item {
anchors.fill: parent
icon: hasActivePlayer ? (MediaService.isPlaying ? "media-pause" : "media-play") : "disc"
color: hasActivePlayer ? Color.mOnSurface : Color.mOnSurfaceVariant
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
diff --git a/Modules/Bar/Widgets/Microphone.qml b/Modules/Bar/Widgets/Microphone.qml
index d0d35727..a3058e36 100644
--- a/Modules/Bar/Widgets/Microphone.qml
+++ b/Modules/Bar/Widgets/Microphone.qml
@@ -12,7 +12,6 @@ Item {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -92,7 +91,7 @@ Item {
rightOpen: BarService.getPillDirection(root)
icon: getIcon()
- compact: (Settings.data.bar.density === "compact")
+ density: Settings.data.bar.density
autoHide: false // Important to be false so we can hover as long as we want
text: Math.round(AudioService.inputVolume * 100)
suffix: "%"
diff --git a/Modules/Bar/Widgets/NightLight.qml b/Modules/Bar/Widgets/NightLight.qml
index b972d37d..80d2c01d 100644
--- a/Modules/Bar/Widgets/NightLight.qml
+++ b/Modules/Bar/Widgets/NightLight.qml
@@ -12,10 +12,10 @@ NIconButton {
id: root
property ShellScreen screen
- property real scaling: 1.0
- compact: (Settings.data.bar.density === "compact")
+ density: Settings.data.bar.density
baseSize: Style.capsuleHeight
+ applyUiScale: false
colorBg: Settings.data.nightLight.forced ? Color.mPrimary : (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent)
colorFg: Settings.data.nightLight.forced ? Color.mOnPrimary : Color.mOnSurface
colorBorder: Color.transparent
diff --git a/Modules/Bar/Widgets/NotificationHistory.qml b/Modules/Bar/Widgets/NotificationHistory.qml
index aee73598..6d6652fe 100644
--- a/Modules/Bar/Widgets/NotificationHistory.qml
+++ b/Modules/Bar/Widgets/NotificationHistory.qml
@@ -11,7 +11,6 @@ NIconButton {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -50,7 +49,8 @@ NIconButton {
}
baseSize: Style.capsuleHeight
- compact: (Settings.data.bar.density === "compact")
+ applyUiScale: false
+ density: Settings.data.bar.density
icon: Settings.data.notifications.doNotDisturb ? "bell-off" : "bell"
tooltipText: Settings.data.notifications.doNotDisturb ? I18n.tr("tooltips.open-notification-history-disable-dnd") : I18n.tr("tooltips.open-notification-history-enable-dnd")
tooltipDirection: BarService.getTooltipDirection()
@@ -69,14 +69,14 @@ NIconButton {
Loader {
anchors.right: parent.right
anchors.top: parent.top
- anchors.rightMargin: 2 * scaling
- anchors.topMargin: 1 * scaling
+ anchors.rightMargin: 2
+ anchors.topMargin: 1
z: 2
active: showUnreadBadge && (!hideWhenZero || computeUnreadCount() > 0)
sourceComponent: Rectangle {
id: badge
readonly property int count: computeUnreadCount()
- height: 8 * scaling
+ height: 8
width: height
radius: height / 2
color: Color.mError
diff --git a/Modules/Bar/Widgets/PowerProfile.qml b/Modules/Bar/Widgets/PowerProfile.qml
index fbd2a719..da96fcf1 100644
--- a/Modules/Bar/Widgets/PowerProfile.qml
+++ b/Modules/Bar/Widgets/PowerProfile.qml
@@ -10,17 +10,16 @@ NIconButton {
id: root
property ShellScreen screen
- property real scaling: 1.0
baseSize: Style.capsuleHeight
+ applyUiScale: false
+ density: Settings.data.bar.density
visible: PowerProfileService.available
-
icon: PowerProfileService.getIcon()
tooltipText: I18n.tr("tooltips.power-profile", {
"profile": PowerProfileService.getName()
})
tooltipDirection: BarService.getTooltipDirection()
- compact: (Settings.data.bar.density === "compact")
colorBg: (PowerProfileService.profile === PowerProfile.Balanced) ? (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent) : Color.mPrimary
colorFg: (PowerProfileService.profile === PowerProfile.Balanced) ? Color.mOnSurface : Color.mOnPrimary
colorBorder: Color.transparent
diff --git a/Modules/Bar/Widgets/ScreenRecorder.qml b/Modules/Bar/Widgets/ScreenRecorder.qml
index 16b57804..4e528c2f 100644
--- a/Modules/Bar/Widgets/ScreenRecorder.qml
+++ b/Modules/Bar/Widgets/ScreenRecorder.qml
@@ -8,13 +8,13 @@ NIconButton {
id: root
property ShellScreen screen
- property real scaling: 1.0
icon: "camera-video"
tooltipText: ScreenRecorderService.isRecording ? I18n.tr("tooltips.click-to-stop-recording") : I18n.tr("tooltips.click-to-start-recording")
tooltipDirection: BarService.getTooltipDirection()
- compact: (Settings.data.bar.density === "compact")
+ density: Settings.data.bar.density
baseSize: Style.capsuleHeight
+ applyUiScale: false
colorBg: ScreenRecorderService.isRecording ? Color.mPrimary : (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent)
colorFg: ScreenRecorderService.isRecording ? Color.mOnPrimary : Color.mOnSurface
colorBorder: Color.transparent
diff --git a/Modules/Bar/Widgets/SessionMenu.qml b/Modules/Bar/Widgets/SessionMenu.qml
index f8f09929..bb24f446 100644
--- a/Modules/Bar/Widgets/SessionMenu.qml
+++ b/Modules/Bar/Widgets/SessionMenu.qml
@@ -9,10 +9,10 @@ NIconButton {
id: root
property ShellScreen screen
- property real scaling: 1.0
- compact: (Settings.data.bar.density === "compact")
+ density: Settings.data.bar.density
baseSize: Style.capsuleHeight
+ applyUiScale: false
icon: "power"
tooltipText: I18n.tr("tooltips.session-menu")
tooltipDirection: BarService.getTooltipDirection()
diff --git a/Modules/Bar/Widgets/Spacer.qml b/Modules/Bar/Widgets/Spacer.qml
index d8e4abcb..3af0e792 100644
--- a/Modules/Bar/Widgets/Spacer.qml
+++ b/Modules/Bar/Widgets/Spacer.qml
@@ -9,7 +9,6 @@ Item {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -32,8 +31,8 @@ Item {
readonly property int spacerWidth: widgetSettings.width !== undefined ? widgetSettings.width : widgetMetadata.width
// Set the width based on user settings
- implicitWidth: spacerWidth * scaling
- implicitHeight: Style.barHeight * scaling
+ implicitWidth: spacerWidth
+ implicitHeight: Style.barHeight
width: implicitWidth
height: implicitHeight
}
diff --git a/Modules/Bar/Widgets/SystemMonitor.qml b/Modules/Bar/Widgets/SystemMonitor.qml
index cda66b11..7609f3bf 100644
--- a/Modules/Bar/Widgets/SystemMonitor.qml
+++ b/Modules/Bar/Widgets/SystemMonitor.qml
@@ -9,7 +9,6 @@ Rectangle {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -30,7 +29,7 @@ Rectangle {
readonly property string barPosition: Settings.data.bar.position
readonly property bool isVertical: barPosition === "left" || barPosition === "right"
- readonly property bool compact: (Settings.data.bar.density === "compact")
+ readonly property bool density: Settings.data.bar.density
readonly property bool showCpuUsage: (widgetSettings.showCpuUsage !== undefined) ? widgetSettings.showCpuUsage : widgetMetadata.showCpuUsage
readonly property bool showCpuTemp: (widgetSettings.showCpuTemp !== undefined) ? widgetSettings.showCpuTemp : widgetMetadata.showCpuTemp
@@ -42,12 +41,12 @@ Rectangle {
readonly property real iconSize: textSize * 1.4
readonly property real textSize: {
var base = isVertical ? width * 0.82 : height
- return Math.max(1, compact ? base * 0.43 : base * 0.33)
+ return Math.max(1, (density === "compact") ? base * 0.43 : base * 0.33)
}
- readonly property int percentTextWidth: Math.ceil(percentMetrics.boundingRect.width + 3 * scaling)
- readonly property int tempTextWidth: Math.ceil(tempMetrics.boundingRect.width + 3 * scaling)
- readonly property int memTextWidth: Math.ceil(memMetrics.boundingRect.width + 3 * scaling)
+ readonly property int percentTextWidth: Math.ceil(percentMetrics.boundingRect.width + 3)
+ readonly property int tempTextWidth: Math.ceil(tempMetrics.boundingRect.width + 3)
+ readonly property int memTextWidth: Math.ceil(memMetrics.boundingRect.width + 3)
TextMetrics {
id: percentMetrics
@@ -74,9 +73,9 @@ Rectangle {
}
anchors.centerIn: parent
- implicitWidth: isVertical ? Math.round(Style.capsuleHeight * scaling) : Math.round(mainGrid.implicitWidth + Style.marginM * 2 * scaling)
- implicitHeight: isVertical ? Math.round(mainGrid.implicitHeight + Style.marginM * 2 * scaling) : Math.round(Style.capsuleHeight * scaling)
- radius: Math.round(Style.radiusM * scaling)
+ implicitWidth: isVertical ? Style.capsuleHeight : Math.round(mainGrid.implicitWidth + Style.marginM * 2)
+ implicitHeight: isVertical ? Math.round(mainGrid.implicitHeight + Style.marginM * 2) : Style.capsuleHeight
+ radius: Style.radiusM
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
GridLayout {
@@ -85,13 +84,13 @@ Rectangle {
flow: isVertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
rows: isVertical ? -1 : 1
columns: isVertical ? 1 : -1
- rowSpacing: isVertical ? (Style.marginM * scaling) : 0
- columnSpacing: isVertical ? 0 : (Style.marginM * scaling)
+ rowSpacing: isVertical ? (Style.marginM) : 0
+ columnSpacing: isVertical ? 0 : (Style.marginM)
// CPU Usage Component
Item {
- Layout.preferredWidth: isVertical ? root.width : iconSize + percentTextWidth + (Style.marginXXS * scaling)
- Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling)
+ Layout.preferredWidth: isVertical ? root.width : iconSize + percentTextWidth + (Style.marginXXS)
+ Layout.preferredHeight: Style.capsuleHeight
Layout.alignment: isVertical ? Qt.AlignHCenter : Qt.AlignVCenter
visible: showCpuUsage
@@ -101,12 +100,13 @@ Rectangle {
flow: isVertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
rows: isVertical ? 2 : 1
columns: isVertical ? 1 : 2
- rowSpacing: Style.marginXXS * scaling
- columnSpacing: Style.marginXXS * scaling
+ rowSpacing: Style.marginXXS
+ columnSpacing: Style.marginXXS
NIcon {
icon: "cpu-usage"
pointSize: iconSize
+ applyUiScale: false
Layout.alignment: Qt.AlignCenter
Layout.row: isVertical ? 1 : 0
Layout.column: 0
@@ -116,6 +116,7 @@ Rectangle {
text: `${Math.round(SystemStatService.cpuUsage)}%`
family: Settings.data.ui.fontFixed
pointSize: textSize
+ applyUiScale: false
font.weight: Style.fontWeightMedium
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: isVertical ? -1 : percentTextWidth
@@ -131,8 +132,8 @@ Rectangle {
// CPU Temperature Component
Item {
- Layout.preferredWidth: isVertical ? root.width : (iconSize + tempTextWidth) + (Style.marginXXS * scaling)
- Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling)
+ Layout.preferredWidth: isVertical ? root.width : (iconSize + tempTextWidth) + (Style.marginXXS)
+ Layout.preferredHeight: Style.capsuleHeight
Layout.alignment: isVertical ? Qt.AlignHCenter : Qt.AlignVCenter
visible: showCpuTemp
@@ -142,12 +143,13 @@ Rectangle {
flow: isVertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
rows: isVertical ? 2 : 1
columns: isVertical ? 1 : 2
- rowSpacing: Style.marginXXS * scaling
- columnSpacing: Style.marginXXS * scaling
+ rowSpacing: Style.marginXXS
+ columnSpacing: Style.marginXXS
NIcon {
icon: "cpu-temperature"
pointSize: iconSize
+ applyUiScale: false
Layout.alignment: Qt.AlignCenter
Layout.row: isVertical ? 1 : 0
Layout.column: 0
@@ -157,6 +159,7 @@ Rectangle {
text: `${Math.round(SystemStatService.cpuTemp)}°`
family: Settings.data.ui.fontFixed
pointSize: textSize
+ applyUiScale: false
font.weight: Style.fontWeightMedium
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: isVertical ? -1 : tempTextWidth
@@ -172,8 +175,8 @@ Rectangle {
// Memory Usage Component
Item {
- Layout.preferredWidth: isVertical ? root.width : iconSize + (showMemoryAsPercent ? percentTextWidth : memTextWidth) + (Style.marginXXS * scaling)
- Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling)
+ Layout.preferredWidth: isVertical ? root.width : iconSize + (showMemoryAsPercent ? percentTextWidth : memTextWidth) + (Style.marginXXS)
+ Layout.preferredHeight: Style.capsuleHeight
Layout.alignment: isVertical ? Qt.AlignHCenter : Qt.AlignVCenter
visible: showMemoryUsage
@@ -183,12 +186,13 @@ Rectangle {
flow: isVertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
rows: isVertical ? 2 : 1
columns: isVertical ? 1 : 2
- rowSpacing: Style.marginXXS * scaling
- columnSpacing: Style.marginXXS * scaling
+ rowSpacing: Style.marginXXS
+ columnSpacing: Style.marginXXS
NIcon {
icon: "memory"
pointSize: iconSize
+ applyUiScale: false
Layout.alignment: Qt.AlignCenter
Layout.row: isVertical ? 1 : 0
Layout.column: 0
@@ -198,6 +202,7 @@ Rectangle {
text: showMemoryAsPercent ? `${Math.round(SystemStatService.memPercent)}%` : `${SystemStatService.memGb.toFixed(1)}G`
family: Settings.data.ui.fontFixed
pointSize: textSize
+ applyUiScale: false
font.weight: Style.fontWeightMedium
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: isVertical ? -1 : (showMemoryAsPercent ? percentTextWidth : memTextWidth)
@@ -213,8 +218,8 @@ Rectangle {
// Network Download Speed Component
Item {
- Layout.preferredWidth: isVertical ? root.width : iconSize + memTextWidth + (Style.marginXXS * scaling)
- Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling)
+ Layout.preferredWidth: isVertical ? root.width : iconSize + memTextWidth + (Style.marginXXS)
+ Layout.preferredHeight: Style.capsuleHeight
Layout.alignment: isVertical ? Qt.AlignHCenter : Qt.AlignVCenter
visible: showNetworkStats
@@ -224,12 +229,13 @@ Rectangle {
flow: isVertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
rows: isVertical ? 2 : 1
columns: isVertical ? 1 : 2
- rowSpacing: Style.marginXXS * scaling
- columnSpacing: Style.marginXXS * scaling
+ rowSpacing: Style.marginXXS
+ columnSpacing: Style.marginXXS
NIcon {
icon: "download-speed"
pointSize: iconSize
+ applyUiScale: false
Layout.alignment: Qt.AlignCenter
Layout.row: isVertical ? 1 : 0
Layout.column: 0
@@ -239,6 +245,7 @@ Rectangle {
text: isVertical ? SystemStatService.formatCompactSpeed(SystemStatService.rxSpeed) : SystemStatService.formatSpeed(SystemStatService.rxSpeed)
family: Settings.data.ui.fontFixed
pointSize: textSize
+ applyUiScale: false
font.weight: Style.fontWeightMedium
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: isVertical ? -1 : memTextWidth
@@ -254,8 +261,8 @@ Rectangle {
// Network Upload Speed Component
Item {
- Layout.preferredWidth: isVertical ? root.width : iconSize + memTextWidth + (Style.marginXXS * scaling)
- Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling)
+ Layout.preferredWidth: isVertical ? root.width : iconSize + memTextWidth + (Style.marginXXS)
+ Layout.preferredHeight: Style.capsuleHeight
Layout.alignment: isVertical ? Qt.AlignHCenter : Qt.AlignVCenter
visible: showNetworkStats
@@ -265,12 +272,13 @@ Rectangle {
flow: isVertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
rows: isVertical ? 2 : 1
columns: isVertical ? 1 : 2
- rowSpacing: Style.marginXXS * scaling
- columnSpacing: Style.marginXXS * scaling
+ rowSpacing: Style.marginXXS
+ columnSpacing: Style.marginXXS
NIcon {
icon: "upload-speed"
pointSize: iconSize
+ applyUiScale: false
Layout.alignment: Qt.AlignCenter
Layout.row: isVertical ? 1 : 0
Layout.column: 0
@@ -280,6 +288,7 @@ Rectangle {
text: isVertical ? SystemStatService.formatCompactSpeed(SystemStatService.txSpeed) : SystemStatService.formatSpeed(SystemStatService.txSpeed)
family: Settings.data.ui.fontFixed
pointSize: textSize
+ applyUiScale: false
font.weight: Style.fontWeightMedium
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: isVertical ? -1 : memTextWidth
@@ -295,8 +304,8 @@ Rectangle {
// Disk Usage Component (primary drive)
Item {
- Layout.preferredWidth: isVertical ? root.width : iconSize + percentTextWidth + (Style.marginXXS * scaling)
- Layout.preferredHeight: Math.round(Style.capsuleHeight * scaling)
+ Layout.preferredWidth: isVertical ? root.width : iconSize + percentTextWidth + (Style.marginXXS)
+ Layout.preferredHeight: Style.capsuleHeight
Layout.alignment: isVertical ? Qt.AlignHCenter : Qt.AlignVCenter
visible: showDiskUsage
@@ -306,12 +315,13 @@ Rectangle {
flow: isVertical ? GridLayout.TopToBottom : GridLayout.LeftToRight
rows: isVertical ? 2 : 1
columns: isVertical ? 1 : 2
- rowSpacing: Style.marginXXS * scaling
- columnSpacing: Style.marginXXS * scaling
+ rowSpacing: Style.marginXXS
+ columnSpacing: Style.marginXXS
NIcon {
icon: "storage"
pointSize: iconSize
+ applyUiScale: false
Layout.alignment: Qt.AlignCenter
Layout.row: isVertical ? 1 : 0
Layout.column: 0
@@ -321,6 +331,7 @@ Rectangle {
text: `${SystemStatService.diskPercent}%`
family: Settings.data.ui.fontFixed
pointSize: textSize
+ applyUiScale: false
font.weight: Style.fontWeightMedium
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: isVertical ? -1 : percentTextWidth
diff --git a/Modules/Bar/Widgets/Taskbar.qml b/Modules/Bar/Widgets/Taskbar.qml
index e9035002..8dcab751 100644
--- a/Modules/Bar/Widgets/Taskbar.qml
+++ b/Modules/Bar/Widgets/Taskbar.qml
@@ -12,7 +12,6 @@ Rectangle {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -21,8 +20,8 @@ Rectangle {
property int sectionWidgetsCount: 0
readonly property bool isVerticalBar: Settings.data.bar.position === "left" || Settings.data.bar.position === "right"
- readonly property bool compact: (Settings.data.bar.density === "compact")
- readonly property real itemSize: compact ? Style.capsuleHeight * 0.9 * scaling : Style.capsuleHeight * 0.8 * scaling
+ readonly property bool density: Settings.data.bar.density
+ readonly property real itemSize: (density === "compact") ? Style.capsuleHeight * 0.9 : Style.capsuleHeight * 0.8
property var widgetMetadata: BarWidgetRegistry.widgetMetadata[widgetId]
property var widgetSettings: {
@@ -36,27 +35,27 @@ Rectangle {
}
// Always visible when there are toplevels
- implicitWidth: isVerticalBar ? Math.round(Style.capsuleHeight * scaling) : Math.round(taskbarLayout.implicitWidth + Style.marginM * scaling * 2)
- implicitHeight: isVerticalBar ? Math.round(taskbarLayout.implicitHeight + Style.marginM * scaling * 2) : Math.round(Style.capsuleHeight * scaling)
- radius: Math.round(Style.radiusM * scaling)
+ implicitWidth: isVerticalBar ? Style.capsuleHeight : Math.round(taskbarLayout.implicitWidth + Style.marginM * 2)
+ implicitHeight: isVerticalBar ? Math.round(taskbarLayout.implicitHeight + Style.marginM * 2) : Style.capsuleHeight
+ radius: Style.radiusM
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
GridLayout {
id: taskbarLayout
anchors.fill: parent
anchors {
- leftMargin: isVerticalBar ? undefined : Style.marginM * scaling
- rightMargin: isVerticalBar ? undefined : Style.marginM * scaling
- topMargin: compact ? 0 : isVerticalBar ? Style.marginM * scaling : undefined
- bottomMargin: compact ? 0 : isVerticalBar ? Style.marginM * scaling : undefined
+ leftMargin: isVerticalBar ? undefined : Style.marginM
+ rightMargin: isVerticalBar ? undefined : Style.marginM
+ topMargin: (density === "compact") ? 0 : isVerticalBar ? Style.marginM : undefined
+ bottomMargin: (density === "compact") ? 0 : isVerticalBar ? Style.marginM : undefined
}
// Configure GridLayout to behave like RowLayout or ColumnLayout
rows: isVerticalBar ? -1 : 1 // -1 means unlimited
columns: isVerticalBar ? 1 : -1 // -1 means unlimited
- rowSpacing: isVerticalBar ? Style.marginXXS * root.scaling : 0
- columnSpacing: isVerticalBar ? 0 : Style.marginXXS * root.scaling
+ rowSpacing: isVerticalBar ? Style.marginXXS : 0
+ columnSpacing: isVerticalBar ? 0 : Style.marginXXS
Repeater {
model: CompositorService.windows
@@ -81,13 +80,22 @@ Rectangle {
asynchronous: true
opacity: modelData.isFocused ? Style.opacityFull : 0.6
+ // Apply dock shader to all taskbar icons
+ layer.enabled: widgetSettings.colorizeIcons !== false
+ layer.effect: ShaderEffect {
+ property color targetColor: Color.mOnSurface
+ property real colorizeMode: 0.0 // Dock mode (grayscale)
+
+ fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
+ }
+
Rectangle {
- anchors.bottomMargin: -2 * scaling
+ anchors.bottomMargin: -2
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
id: iconBackground
- width: 4 * scaling
- height: 4 * scaling
+ width: 4
+ height: 4
color: modelData.isFocused ? Color.mPrimary : Color.transparent
radius: width * 0.5
}
diff --git a/Modules/Bar/Widgets/Tray.qml b/Modules/Bar/Widgets/Tray.qml
index 0365cc2e..f76be377 100644
--- a/Modules/Bar/Widgets/Tray.qml
+++ b/Modules/Bar/Widgets/Tray.qml
@@ -14,7 +14,6 @@ Rectangle {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -35,8 +34,8 @@ Rectangle {
readonly property string barPosition: Settings.data.bar.position
readonly property bool isVertical: barPosition === "left" || barPosition === "right"
- readonly property bool compact: (Settings.data.bar.density === "compact")
- property real itemSize: Math.round(Style.capsuleHeight * 0.65 * scaling)
+ readonly property bool density: Settings.data.bar.density
+ property real itemSize: Math.round(Style.capsuleHeight * 0.65)
property list blacklist: widgetSettings.blacklist || widgetMetadata.blacklist || [] // Read from settings
property var filteredItems: []
@@ -145,9 +144,9 @@ Rectangle {
}
visible: filteredItems.length > 0
- implicitWidth: isVertical ? Math.round(Style.capsuleHeight * scaling) : Math.round(trayFlow.implicitWidth + Style.marginM * 2 * scaling)
- implicitHeight: isVertical ? Math.round(trayFlow.implicitHeight + Style.marginM * 2 * scaling) : Math.round(Style.capsuleHeight * scaling)
- radius: Math.round(Style.radiusM * scaling)
+ implicitWidth: isVertical ? Style.capsuleHeight : Math.round(trayFlow.implicitWidth + Style.marginM * 2)
+ implicitHeight: isVertical ? Math.round(trayFlow.implicitHeight + Style.marginM * 2) : Style.capsuleHeight
+ radius: Style.radiusM
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
Layout.alignment: Qt.AlignVCenter
@@ -155,7 +154,7 @@ Rectangle {
Flow {
id: trayFlow
anchors.centerIn: parent
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
flow: isVertical ? Flow.TopToBottom : Flow.LeftToRight
Repeater {
@@ -193,6 +192,14 @@ Rectangle {
}
opacity: status === Image.Ready ? 1 : 0
+ layer.enabled: widgetSettings.colorizeIcons !== false
+ layer.effect: ShaderEffect {
+ property color targetColor: Color.mOnSurface
+ property real colorizeMode: 1.0 // Tray mode (intensity-based)
+
+ fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
+ }
+
MouseArea {
anchors.fill: parent
hoverEnabled: true
@@ -231,16 +238,16 @@ Rectangle {
let menuX, menuY
if (barPosition === "left") {
// For left bar: position menu to the right of the bar
- menuX = width + Style.marginM * scaling
+ menuX = width + Style.marginM
menuY = 0
} else if (barPosition === "right") {
// For right bar: position menu to the left of the bar
- menuX = -trayMenu.item.width - Style.marginM * scaling
+ menuX = -trayMenu.item.width - Style.marginM
menuY = 0
} else {
// For horizontal bars: center horizontally and position below
menuX = (width / 2) - (trayMenu.item.width / 2)
- menuY = Math.round(Style.barHeight * scaling)
+ menuY = Style.barHeight
}
trayMenu.item.menu = modelData.menu
trayMenu.item.showAt(parent, menuX, menuY)
diff --git a/Modules/Bar/Widgets/Volume.qml b/Modules/Bar/Widgets/Volume.qml
index 775a31d6..4254b842 100644
--- a/Modules/Bar/Widgets/Volume.qml
+++ b/Modules/Bar/Widgets/Volume.qml
@@ -12,7 +12,6 @@ Item {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -75,7 +74,7 @@ Item {
BarPill {
id: pill
- compact: (Settings.data.bar.density === "compact")
+ density: Settings.data.bar.density
rightOpen: BarService.getPillDirection(root)
icon: getIcon()
autoHide: false // Important to be false so we can hover as long as we want
diff --git a/Modules/Bar/Widgets/WallpaperSelector.qml b/Modules/Bar/Widgets/WallpaperSelector.qml
index 4be3e9a1..e48f368a 100644
--- a/Modules/Bar/Widgets/WallpaperSelector.qml
+++ b/Modules/Bar/Widgets/WallpaperSelector.qml
@@ -9,10 +9,10 @@ NIconButton {
id: root
property ShellScreen screen
- property real scaling: 1.0
baseSize: Style.capsuleHeight
- compact: (Settings.data.bar.density === "compact")
+ applyUiScale: false
+ density: Settings.data.bar.density
icon: "wallpaper-selector"
tooltipText: I18n.tr("tooltips.open-wallpaper-selector")
tooltipDirection: BarService.getTooltipDirection()
diff --git a/Modules/Bar/Widgets/WiFi.qml b/Modules/Bar/Widgets/WiFi.qml
index 00fefab6..a9156e3e 100644
--- a/Modules/Bar/Widgets/WiFi.qml
+++ b/Modules/Bar/Widgets/WiFi.qml
@@ -11,10 +11,10 @@ NIconButton {
id: root
property ShellScreen screen
- property real scaling: 1.0
- compact: (Settings.data.bar.density === "compact")
+ density: Settings.data.bar.density
baseSize: Style.capsuleHeight
+ applyUiScale: false
colorBg: (Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent)
colorFg: Color.mOnSurface
colorBorder: Color.transparent
diff --git a/Modules/Bar/Widgets/Workspace.qml b/Modules/Bar/Widgets/Workspace.qml
index f093df3e..389cf148 100644
--- a/Modules/Bar/Widgets/Workspace.qml
+++ b/Modules/Bar/Widgets/Workspace.qml
@@ -13,7 +13,6 @@ Item {
id: root
property ShellScreen screen
- property real scaling: 1.0
// Widget properties passed from Bar.qml for per-instance settings
property string widgetId: ""
@@ -34,9 +33,9 @@ Item {
readonly property string barPosition: Settings.data.bar.position
readonly property bool isVertical: barPosition === "left" || barPosition === "right"
- readonly property bool compact: (Settings.data.bar.density === "compact")
+ readonly property bool density: Settings.data.bar.density
readonly property real baseDimensionRatio: {
- const b = compact ? 0.85 : 0.65
+ const b = (density === "compact") ? 0.85 : 0.65
if (widgetSettings.labelMode === "none") {
return b * 0.75
}
@@ -54,8 +53,8 @@ Item {
property bool effectsActive: false
property color effectColor: Color.mPrimary
- property int horizontalPadding: Math.round(Style.marginS * scaling)
- property int spacingBetweenPills: Math.round(Style.marginXS * scaling)
+ property int horizontalPadding: Math.round(Style.marginS)
+ property int spacingBetweenPills: Math.round(Style.marginXS)
// Wheel scroll handling
property int wheelAccumulatedDelta: 0
@@ -63,19 +62,19 @@ Item {
signal workspaceChanged(int workspaceId, color accentColor)
- implicitWidth: isVertical ? Math.round(Style.barHeight * scaling) : computeWidth()
- implicitHeight: isVertical ? computeHeight() : Math.round(Style.barHeight * scaling)
+ implicitWidth: isVertical ? Style.barHeight : computeWidth()
+ implicitHeight: isVertical ? computeHeight() : Style.barHeight
function getWorkspaceWidth(ws) {
const d = Style.capsuleHeight * root.baseDimensionRatio
const factor = ws.isFocused ? 2.2 : 1
- return d * factor * scaling
+ return d * factor
}
function getWorkspaceHeight(ws) {
const d = Style.capsuleHeight * root.baseDimensionRatio
const factor = ws.isFocused ? 2.2 : 1
- return d * factor * scaling
+ return d * factor
}
function computeWidth() {
@@ -203,9 +202,9 @@ Item {
Rectangle {
id: workspaceBackground
- width: isVertical ? Math.round(Style.capsuleHeight * scaling) : parent.width
- height: isVertical ? parent.height : Math.round(Style.capsuleHeight * scaling)
- radius: Math.round(Style.radiusM * scaling)
+ width: isVertical ? Style.capsuleHeight : parent.width
+ height: isVertical ? parent.height : Style.capsuleHeight
+ radius: Style.radiusM
color: Settings.data.bar.showCapsule ? Color.mSurfaceVariant : Color.transparent
anchors.horizontalCenter: parent.horizontalCenter
@@ -266,7 +265,7 @@ Item {
Item {
id: workspacePillContainer
width: root.getWorkspaceWidth(model)
- height: Style.capsuleHeight * root.baseDimensionRatio * scaling
+ height: Style.capsuleHeight * root.baseDimensionRatio
Rectangle {
id: pill
@@ -287,6 +286,7 @@ Item {
}
family: Settings.data.ui.fontFixed
pointSize: model.isFocused ? workspacePillContainer.height * 0.45 : workspacePillContainer.height * 0.42
+ applyUiScale: false
font.capitalization: Font.AllUppercase
font.weight: Style.fontWeightBold
wrapMode: Text.Wrap
@@ -387,7 +387,7 @@ Item {
radius: width / 2
color: Color.transparent
border.color: root.effectColor
- border.width: Math.max(1, Math.round((2 + 6 * (1.0 - root.masterProgress)) * scaling))
+ border.width: Math.max(1, Math.round((2 + 6 * (1.0 - root.masterProgress))))
opacity: root.effectsActive && model.isFocused ? (1.0 - root.masterProgress) * 0.7 : 0
visible: root.effectsActive && model.isFocused
z: 1
@@ -409,7 +409,7 @@ Item {
model: localWorkspaces
Item {
id: workspacePillContainerVertical
- width: Style.capsuleHeight * root.baseDimensionRatio * scaling
+ width: Style.capsuleHeight * root.baseDimensionRatio
height: root.getWorkspaceHeight(model)
Rectangle {
@@ -431,6 +431,7 @@ Item {
}
family: Settings.data.ui.fontFixed
pointSize: model.isFocused ? workspacePillContainerVertical.width * 0.45 : workspacePillContainerVertical.width * 0.42
+ applyUiScale: false
font.capitalization: Font.AllUppercase
font.weight: Style.fontWeightBold
wrapMode: Text.Wrap
@@ -531,7 +532,7 @@ Item {
radius: width / 2
color: Color.transparent
border.color: root.effectColor
- border.width: Math.max(1, Math.round((2 + 6 * (1.0 - root.masterProgress)) * scaling))
+ border.width: Math.max(1, Math.round((2 + 6 * (1.0 - root.masterProgress))))
opacity: root.effectsActive && model.isFocused ? (1.0 - root.masterProgress) * 0.7 : 0
visible: root.effectsActive && model.isFocused
z: 1
diff --git a/Modules/ControlCenter/Cards/AudioCard.qml b/Modules/ControlCenter/Cards/AudioCard.qml
index 8436aa13..c09b05bf 100644
--- a/Modules/ControlCenter/Cards/AudioCard.qml
+++ b/Modules/ControlCenter/Cards/AudioCard.qml
@@ -41,12 +41,12 @@ NBox {
ColumnLayout {
anchors.fill: parent
- anchors.margins: Style.marginM * scaling
+ anchors.margins: Style.marginM
spacing: 0
// Output Volume Section
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
opacity: AudioService.sink ? 1.0 : 0.5
enabled: AudioService.sink
@@ -54,7 +54,7 @@ NBox {
// Output Volume Header
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
NIconButton {
icon: AudioService.muted ? "volume-off" : "volume-high"
@@ -71,19 +71,19 @@ NBox {
}
RowLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
NText {
text: I18n.tr("settings.audio.volumes.output-volume.label")
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mOnSurface
font.weight: Style.fontWeightMedium
}
NText {
text: AudioService.sink ? AudioService.sink.description : "No output device"
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mOnSurfaceVariant
font.weight: Style.fontWeightMedium
elide: Text.ElideRight
@@ -100,7 +100,7 @@ NBox {
value: localOutputVolume || 0
stepSize: 0.01
text: Math.round((AudioService.volume || 0) * 100) + "%"
- textSize: Style.fontSizeXS * scaling
+ textSize: Style.fontSizeXS
customHeightRatio: 0.6
onMoved: value => localOutputVolume = value
}
@@ -108,7 +108,7 @@ NBox {
// Input Volume Section
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
opacity: AudioService.source ? 1.0 : 0.5
enabled: AudioService.source
@@ -116,7 +116,7 @@ NBox {
// Input Volume Header
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
NIconButton {
icon: AudioService.inputMuted ? "microphone-off" : "microphone"
@@ -129,19 +129,19 @@ NBox {
}
RowLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
NText {
text: I18n.tr("settings.audio.volumes.input-volume.label")
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mOnSurface
font.weight: Style.fontWeightMedium
}
NText {
text: AudioService.source ? AudioService.source.description : "No input device"
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mOnSurfaceVariant
font.weight: Style.fontWeightMedium
elide: Text.ElideRight
@@ -158,7 +158,7 @@ NBox {
value: AudioService.inputVolume || 0
stepSize: 0.01
text: Math.round((AudioService.inputVolume || 0) * 100) + "%"
- textSize: Style.fontSizeXS * scaling
+ textSize: Style.fontSizeXS
customHeightRatio: 0.6
onMoved: value => AudioService.setInputVolume(value)
}
diff --git a/Modules/ControlCenter/Cards/MediaCard.qml b/Modules/ControlCenter/Cards/MediaCard.qml
index b4d7b7a6..06891868 100644
--- a/Modules/ControlCenter/Cards/MediaCard.qml
+++ b/Modules/ControlCenter/Cards/MediaCard.qml
@@ -20,7 +20,7 @@ NBox {
id: bgArtImage
anchors.fill: parent
imagePath: MediaService.trackArtUrl
- imageRadius: Style.radiusM * scaling
+ imageRadius: Style.radiusM
visible: MediaService.trackArtUrl !== ""
}
@@ -29,7 +29,7 @@ NBox {
anchors.fill: parent
color: Color.mSurfaceVariant
opacity: 0.85
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
}
// Border
@@ -38,7 +38,7 @@ NBox {
color: Color.transparent
border.color: Color.mOutline
border.width: 1
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
}
}
@@ -55,7 +55,7 @@ NBox {
sourceItem: Rectangle {
width: root.width
height: root.height
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
color: "white"
}
}
@@ -116,29 +116,29 @@ NBox {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
- anchors.topMargin: Style.marginXS * scaling
- anchors.leftMargin: Style.marginM * scaling
- anchors.rightMargin: Style.marginM * scaling
- height: Style.barHeight * scaling
+ anchors.topMargin: Style.marginXS
+ anchors.leftMargin: Style.marginM
+ anchors.rightMargin: Style.marginM
+ height: Style.barHeight
visible: MediaService.getAvailablePlayers().length > 1
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
color: Color.transparent
property var currentPlayer: MediaService.getAvailablePlayers()[MediaService.selectedPlayerIndex]
RowLayout {
anchors.fill: parent
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
NIcon {
icon: "caret-down"
- pointSize: Style.fontSizeXXL * scaling
+ pointSize: Style.fontSizeXXL
color: Color.mOnSurfaceVariant
}
NText {
text: playerSelectorButton.currentPlayer ? playerSelectorButton.currentPlayer.identity : ""
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mOnSurfaceVariant
Layout.fillWidth: true
}
@@ -170,7 +170,7 @@ NBox {
NContextMenu {
id: playerContextMenu
parent: root
- width: 200 * scaling
+ width: 200
onTriggered: function (action) {
var index = parseInt(action)
@@ -184,14 +184,14 @@ NBox {
ColumnLayout {
anchors.fill: parent
- anchors.margins: Style.marginM * scaling
+ anchors.margins: Style.marginM
// No media player detected
ColumnLayout {
id: fallback
visible: !main.visible
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
Item {
Layout.fillWidth: true
@@ -204,12 +204,12 @@ NBox {
ColumnLayout {
anchors.centerIn: parent
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Item {
Layout.alignment: Qt.AlignHCenter
- Layout.preferredWidth: Style.fontSizeXXXL * 4 * scaling
- Layout.preferredHeight: Style.fontSizeXXXL * 4 * scaling
+ Layout.preferredWidth: Style.fontSizeXXXL * 4
+ Layout.preferredHeight: Style.fontSizeXXXL * 4
// Pulsating audio circles (background)
Repeater {
@@ -258,7 +258,7 @@ NBox {
NIcon {
anchors.centerIn: parent
icon: "disc"
- pointSize: Style.fontSizeXXXL * 3 * scaling
+ pointSize: Style.fontSizeXXXL * 3
color: Color.mOnSurfaceVariant
RotationAnimator on rotation {
@@ -274,7 +274,7 @@ NBox {
// Descriptive text
ColumnLayout {
Layout.alignment: Qt.AlignHCenter
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
}
}
}
@@ -290,23 +290,23 @@ NBox {
id: main
visible: MediaService.currentPlayer && MediaService.canPlay
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
// Spacer to push content down
Item {
- Layout.preferredHeight: Style.marginM * scaling
+ Layout.preferredHeight: Style.marginM
}
// Metadata at the bottom left
ColumnLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignLeft
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
NText {
visible: MediaService.trackTitle !== ""
text: MediaService.trackTitle
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
elide: Text.ElideRight
wrapMode: Text.Wrap
@@ -318,7 +318,7 @@ NBox {
visible: MediaService.trackArtist !== ""
text: MediaService.trackArtist
color: Color.mPrimary
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
elide: Text.ElideRight
Layout.fillWidth: true
}
@@ -327,7 +327,7 @@ NBox {
visible: MediaService.trackAlbum !== ""
text: MediaService.trackAlbum
color: Color.mOnSurfaceVariant
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
elide: Text.ElideRight
Layout.fillWidth: true
}
@@ -338,7 +338,7 @@ NBox {
id: progressWrapper
visible: (MediaService.currentPlayer && MediaService.trackLength > 0)
Layout.fillWidth: true
- height: Style.baseWidgetSize * 0.5 * scaling
+ height: Style.baseWidgetSize * 0.5
property real localSeekRatio: -1
property real lastSentSeekRatio: -1
@@ -408,12 +408,12 @@ NBox {
// Spacer to push media controls down
Item {
- Layout.preferredHeight: Style.marginL * scaling
+ Layout.preferredHeight: Style.marginL
}
// Media controls
RowLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
diff --git a/Modules/ControlCenter/Cards/PowerProfilesCard.qml b/Modules/ControlCenter/Cards/PowerProfilesCard.qml
deleted file mode 100644
index d93b26ba..00000000
--- a/Modules/ControlCenter/Cards/PowerProfilesCard.qml
+++ /dev/null
@@ -1,66 +0,0 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-import Quickshell
-import Quickshell.Services.UPower
-import qs.Commons
-import qs.Services
-import qs.Widgets
-
-// Power Profiles: performance, balanced, eco
-NBox {
-
- property real spacing: 0
-
- // Centralized service
- readonly property bool hasPP: PowerProfileService.available
-
- RowLayout {
- id: powerRow
- anchors.fill: parent
- anchors.margins: Style.marginS * scaling
- spacing: spacing
- Item {
- Layout.fillWidth: true
- }
- // Performance
- NIconButton {
- icon: PowerProfileService.getIcon(PowerProfile.Performance)
- tooltipText: I18n.tr("tooltips.set-power-profile", {
- "profile": PowerProfileService.getName(PowerProfile.Performance)
- })
- enabled: hasPP
- opacity: enabled ? Style.opacityFull : Style.opacityMedium
- colorBg: (enabled && PowerProfileService.profile === PowerProfile.Performance) ? Color.mPrimary : Color.mSurfaceVariant
- colorFg: (enabled && PowerProfileService.profile === PowerProfile.Performance) ? Color.mOnPrimary : Color.mPrimary
- onClicked: PowerProfileService.setProfile(PowerProfile.Performance)
- }
- // Balanced
- NIconButton {
- icon: PowerProfileService.getIcon(PowerProfile.Balanced)
- tooltipText: I18n.tr("tooltips.set-power-profile", {
- "profile": PowerProfileService.getName(PowerProfile.Balanced)
- })
- enabled: hasPP
- opacity: enabled ? Style.opacityFull : Style.opacityMedium
- colorBg: (enabled && PowerProfileService.profile === PowerProfile.Balanced) ? Color.mPrimary : Color.mSurfaceVariant
- colorFg: (enabled && PowerProfileService.profile === PowerProfile.Balanced) ? Color.mOnPrimary : Color.mPrimary
- onClicked: PowerProfileService.setProfile(PowerProfile.Balanced)
- }
- // Eco
- NIconButton {
- icon: PowerProfileService.getIcon(PowerProfile.PowerSaver)
- tooltipText: I18n.tr("tooltips.set-power-profile", {
- "profile": PowerProfileService.getName(PowerProfile.PowerSaver)
- })
- enabled: hasPP
- opacity: enabled ? Style.opacityFull : Style.opacityMedium
- colorBg: (enabled && PowerProfileService.profile === PowerProfile.PowerSaver) ? Color.mPrimary : Color.mSurfaceVariant
- colorFg: (enabled && PowerProfileService.profile === PowerProfile.PowerSaver) ? Color.mOnPrimary : Color.mPrimary
- onClicked: PowerProfileService.setProfile(PowerProfile.PowerSaver)
- }
- Item {
- Layout.fillWidth: true
- }
- }
-}
diff --git a/Modules/ControlCenter/Cards/ProfileCard.qml b/Modules/ControlCenter/Cards/ProfileCard.qml
index ec9b4527..7c891182 100644
--- a/Modules/ControlCenter/Cards/ProfileCard.qml
+++ b/Modules/ControlCenter/Cards/ProfileCard.qml
@@ -17,25 +17,25 @@ NBox {
property string uptimeText: "--"
RowLayout {
- id: content
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
- anchors.margins: Style.marginM * scaling
- spacing: Style.marginM * scaling
+ anchors.bottom: parent.bottom
+ anchors.margins: Style.marginM
+ spacing: Style.marginM
NImageCircled {
- width: Style.baseWidgetSize * 1.25 * scaling
- height: Style.baseWidgetSize * 1.25 * scaling
- imagePath: Settings.data.general.avatarImage
+ Layout.preferredWidth: Math.round(Style.baseWidgetSize * 1.25 * Style.uiScaleRatio)
+ Layout.preferredHeight: Math.round(Style.baseWidgetSize * 1.25 * Style.uiScaleRatio)
+ imagePath: Settings.preprocessPath(Settings.data.general.avatarImage)
fallbackIcon: "person"
borderColor: Color.mPrimary
- borderWidth: Math.max(1, Style.borderM * scaling)
+ borderWidth: Math.max(1, Style.borderM)
}
ColumnLayout {
Layout.fillWidth: true
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
NText {
text: Quickshell.env("USER") || "user"
font.weight: Style.fontWeightBold
@@ -45,13 +45,13 @@ NBox {
text: I18n.tr("system.uptime", {
"uptime": uptimeText
})
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: Color.mOnSurfaceVariant
}
}
RowLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
Item {
Layout.fillWidth: true
diff --git a/Modules/ControlCenter/Cards/ShortcutsCard.qml b/Modules/ControlCenter/Cards/ShortcutsCard.qml
new file mode 100644
index 00000000..bf45b879
--- /dev/null
+++ b/Modules/ControlCenter/Cards/ShortcutsCard.qml
@@ -0,0 +1,84 @@
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import Quickshell
+import qs.Modules.ControlCenter.Cards
+import qs.Commons
+import qs.Services
+import qs.Widgets
+import qs.Modules.ControlCenter.Extras
+
+RowLayout {
+ Layout.fillWidth: true
+ spacing: Style.marginL
+
+ NBox {
+ Layout.fillWidth: true
+ Layout.preferredHeight: root.shortcutsHeight
+
+ RowLayout {
+ id: leftContent
+ anchors.fill: parent
+ spacing: Style.marginS
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ Repeater {
+ model: Settings.data.controlCenter.shortcuts.left
+ delegate: ControlCenterWidgetLoader {
+ Layout.fillWidth: false
+ widgetId: (modelData.id !== undefined ? modelData.id : "")
+ widgetProps: {
+ "screen": root.modelData || null,
+ "widgetId": modelData.id,
+ "section": "quickSettings",
+ "sectionWidgetIndex": index,
+ "sectionWidgetsCount": Settings.data.controlCenter.shortcuts.left.length
+ }
+ Layout.alignment: Qt.AlignVCenter
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+ }
+
+ NBox {
+ Layout.fillWidth: true
+ Layout.preferredHeight: root.shortcutsHeight
+
+ RowLayout {
+ id: rightContent
+ anchors.fill: parent
+ spacing: Style.marginS
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ Repeater {
+ model: Settings.data.controlCenter.shortcuts.right
+ delegate: ControlCenterWidgetLoader {
+ Layout.fillWidth: false
+ widgetId: (modelData.id !== undefined ? modelData.id : "")
+ widgetProps: {
+ "screen": root.modelData || null,
+ "widgetId": modelData.id,
+ "section": "quickSettings",
+ "sectionWidgetIndex": index,
+ "sectionWidgetsCount": Settings.data.controlCenter.shortcuts.right.length
+ }
+ Layout.alignment: Qt.AlignVCenter
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+ }
+ }
+}
diff --git a/Modules/ControlCenter/Cards/SystemMonitorCard.qml b/Modules/ControlCenter/Cards/SystemMonitorCard.qml
index 4e7254a3..3e23aa89 100644
--- a/Modules/ControlCenter/Cards/SystemMonitorCard.qml
+++ b/Modules/ControlCenter/Cards/SystemMonitorCard.qml
@@ -12,7 +12,9 @@ NBox {
Item {
id: content
anchors.fill: parent
- anchors.margins: Style.marginS * scaling
+ anchors.margins: Style.marginS
+
+ property int widgetHeight: Math.round(65 * Style.uiScaleRatio)
ColumnLayout {
anchors.centerIn: parent
@@ -23,8 +25,7 @@ NBox {
icon: "cpu-usage"
flat: true
contentScale: 0.8
- width: 70 * scaling
- height: 65 * scaling
+ height: content.widgetHeight
Layout.alignment: Qt.AlignHCenter
}
NCircleStat {
@@ -33,8 +34,7 @@ NBox {
icon: "cpu-temperature"
flat: true
contentScale: 0.8
- width: 70 * scaling
- height: 65 * scaling
+ height: content.widgetHeight
Layout.alignment: Qt.AlignHCenter
}
NCircleStat {
@@ -42,8 +42,7 @@ NBox {
icon: "memory"
flat: true
contentScale: 0.8
- width: 70 * scaling
- height: 65 * scaling
+ height: content.widgetHeight
Layout.alignment: Qt.AlignHCenter
}
NCircleStat {
@@ -51,8 +50,7 @@ NBox {
icon: "storage"
flat: true
contentScale: 0.8
- width: 70 * scaling
- height: 65 * scaling
+ height: content.widgetHeight
Layout.alignment: Qt.AlignHCenter
}
}
diff --git a/Modules/ControlCenter/Cards/TopCard.qml b/Modules/ControlCenter/Cards/TopCard.qml
deleted file mode 100644
index 21b68eca..00000000
--- a/Modules/ControlCenter/Cards/TopCard.qml
+++ /dev/null
@@ -1,157 +0,0 @@
-import QtQuick
-import QtQuick.Effects
-import QtQuick.Layouts
-import Quickshell
-import Quickshell.Io
-import Quickshell.Widgets
-import qs.Modules.Settings
-import qs.Modules.ControlCenter
-import qs.Modules.ControlCenter.Extras
-import qs.Commons
-import qs.Services
-import qs.Widgets
-
-// Header card with avatar, user and quick actions
-NBox {
- id: root
-
- property string uptimeText: "--"
- property real spacing: Style.marginS * scaling
-
- ColumnLayout {
- anchors.fill: parent
- anchors.margins: Style.marginM * scaling
-
- // Profile, Uptime, Settings, SessionMenu, Close
- RowLayout {
- id: content
-
- spacing: root.spacing
- Layout.alignment: Qt.AlignVCenter
-
- NImageCircled {
- width: Style.baseWidgetSize * 1.25 * scaling
- height: width
- imagePath: Settings.data.general.avatarImage
- fallbackIcon: "person"
- borderColor: Color.mPrimary
- borderWidth: Math.max(1, Style.borderM * scaling)
- Layout.alignment: Qt.AlignVCenter
- Layout.topMargin: Style.marginXS * scaling
- }
-
- ColumnLayout {
- Layout.fillWidth: true
- spacing: Style.marginXXS * scaling
- NText {
- text: Quickshell.env("USER") || "user"
- font.weight: Style.fontWeightBold
- font.capitalization: Font.Capitalize
- }
- NText {
- text: I18n.tr("system.uptime", {
- "uptime": uptimeText
- })
- pointSize: Style.fontSizeXS * scaling
- color: Color.mOnSurfaceVariant
- }
- }
-
- Item {
- Layout.fillWidth: true
- }
-
- RowLayout {
- spacing: root.spacing
- Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
-
- NIconButton {
- baseSize: Style.baseWidgetSize * 0.9
- icon: "settings"
- tooltipText: I18n.tr("tooltips.open-settings")
- onClicked: {
- settingsPanel.requestedTab = SettingsPanel.Tab.General
- settingsPanel.open()
- }
- }
-
- NIconButton {
- baseSize: Style.baseWidgetSize * 0.9
- icon: "power"
- tooltipText: I18n.tr("tooltips.session-menu")
- onClicked: {
- sessionMenuPanel.open()
- controlCenterPanel.close()
- }
- }
-
- NIconButton {
- baseSize: Style.baseWidgetSize * 0.9
- icon: "close"
- tooltipText: I18n.tr("tooltips.close")
- onClicked: {
- controlCenterPanel.close()
- }
- }
- }
- }
-
- NDivider {
- Layout.fillWidth: true
- Layout.topMargin: Style.marginS * scaling
- Layout.bottomMargin: Style.marginS * scaling
- }
-
- GridLayout {
- id: grid
- Layout.fillWidth: true
- columns: (Settings.data.controlCenter.quickSettingsStyle === "compact") ? 4 : 3
- columnSpacing: Style.marginS * scaling
- rowSpacing: Style.marginS * scaling
-
- Repeater {
- model: Settings.data.controlCenter.widgets.quickSettings
- delegate: ControlCenterWidgetLoader {
- Layout.fillWidth: true
- widgetId: (modelData.id !== undefined ? modelData.id : "")
- widgetProps: {
- "screen": root.modelData || null,
- "scaling": ScalingService.getScreenScale(screen),
- "widgetId": modelData.id,
- "section": "quickSettings",
- "sectionWidgetIndex": index,
- "sectionWidgetsCount": Settings.data.controlCenter.widgets.quickSettings.length
- }
- Layout.alignment: Qt.AlignVCenter
- }
- }
- }
- }
-
- // ----------------------------------
- // Uptime
- Timer {
- interval: 60000
- repeat: true
- running: true
- onTriggered: uptimeProcess.running = true
- }
-
- Process {
- id: uptimeProcess
- command: ["cat", "/proc/uptime"]
- running: true
-
- stdout: StdioCollector {
- onStreamFinished: {
- var uptimeSeconds = parseFloat(this.text.trim().split(' ')[0])
- uptimeText = Time.formatVagueHumanReadableDuration(uptimeSeconds)
- uptimeProcess.running = false
- }
- }
- }
-
- function updateSystemInfo() {
- uptimeProcess.running = true
- }
-}
diff --git a/Modules/ControlCenter/Cards/UtilitiesCard.qml b/Modules/ControlCenter/Cards/UtilitiesCard.qml
deleted file mode 100644
index decd9659..00000000
--- a/Modules/ControlCenter/Cards/UtilitiesCard.qml
+++ /dev/null
@@ -1,66 +0,0 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-import Quickshell
-import qs.Commons
-import qs.Modules.Settings
-import qs.Services
-import qs.Widgets
-
-// Utilities: record & wallpaper
-NBox {
-
- property real spacing: 0
-
- RowLayout {
- id: utilRow
- anchors.fill: parent
- anchors.margins: Style.marginS * scaling
- spacing: spacing
- Item {
- Layout.fillWidth: true
- }
- // Screen Recorder
- NIconButton {
- icon: "camera-video"
- enabled: ScreenRecorderService.isAvailable
- tooltipText: ScreenRecorderService.isAvailable ? (ScreenRecorderService.isRecording ? I18n.tr("tooltips.stop-screen-recording") : I18n.tr("tooltips.start-screen-recording")) : I18n.tr("tooltips.screen-recorder-not-installed")
- colorBg: ScreenRecorderService.isRecording ? Color.mPrimary : Color.mSurfaceVariant
- colorFg: ScreenRecorderService.isRecording ? Color.mOnPrimary : Color.mPrimary
- onClicked: {
- if (!ScreenRecorderService.isAvailable)
- return
- ScreenRecorderService.toggleRecording()
- // If we were not recording and we just initiated a start, close the panel
- if (!ScreenRecorderService.isRecording) {
- var panel = PanelService.getPanel("controlCenterPanel")
- panel?.close()
- }
- }
- }
-
- // Idle Inhibitor
- NIconButton {
- icon: IdleInhibitorService.isInhibited ? "keep-awake-on" : "keep-awake-off"
- tooltipText: IdleInhibitorService.isInhibited ? I18n.tr("tooltips.disable-keep-awake") : I18n.tr("tooltips.enable-keep-awake")
- colorBg: IdleInhibitorService.isInhibited ? Color.mPrimary : Color.mSurfaceVariant
- colorFg: IdleInhibitorService.isInhibited ? Color.mOnPrimary : Color.mPrimary
- onClicked: {
- IdleInhibitorService.manualToggle()
- }
- }
-
- // Wallpaper
- NIconButton {
- visible: Settings.data.wallpaper.enabled
- icon: "wallpaper-selector"
- tooltipText: I18n.tr("tooltips.wallpaper-selector")
- onClicked: PanelService.getPanel("wallpaperPanel")?.toggle(this)
- onRightClicked: WallpaperService.setRandomWallpaper()
- }
-
- Item {
- Layout.fillWidth: true
- }
- }
-}
diff --git a/Modules/ControlCenter/Cards/WeatherCard.qml b/Modules/ControlCenter/Cards/WeatherCard.qml
index 9b7d6aec..e6b366ff 100644
--- a/Modules/ControlCenter/Cards/WeatherCard.qml
+++ b/Modules/ControlCenter/Cards/WeatherCard.qml
@@ -16,28 +16,28 @@ NBox {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
- anchors.margins: Style.marginM * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginM
+ spacing: Style.marginM
clip: true
RowLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
NIcon {
Layout.alignment: Qt.AlignVCenter
icon: weatherReady ? LocationService.weatherSymbolFromCode(LocationService.data.weather.current_weather.weathercode) : ""
- pointSize: Style.fontSizeXXXL * 1.75 * scaling
+ pointSize: Style.fontSizeXXXL * 1.75
color: Color.mPrimary
}
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
NText {
text: {
// Ensure the name is not too long if one had to specify the country
const chunks = Settings.data.location.name.split(",")
return chunks[0]
}
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
}
@@ -57,13 +57,13 @@ NBox {
temp = Math.round(temp)
return `${temp}°${suffix}`
}
- pointSize: Style.fontSizeXL * scaling
+ pointSize: Style.fontSizeXL
font.weight: Style.fontWeightBold
}
NText {
text: weatherReady ? `(${LocationService.data.weather.timezone_abbreviation})` : ""
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mOnSurfaceVariant
visible: LocationService.data.weather
}
@@ -80,12 +80,12 @@ NBox {
visible: weatherReady
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Repeater {
model: weatherReady ? LocationService.data.weather.daily.time : []
delegate: ColumnLayout {
Layout.alignment: Qt.AlignHCenter
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
NText {
text: {
var weatherDate = new Date(LocationService.data.weather.daily.time[index].replace(/-/g, "/"))
@@ -97,7 +97,7 @@ NBox {
NIcon {
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
icon: LocationService.weatherSymbolFromCode(LocationService.data.weather.daily.weathercode[index])
- pointSize: Style.fontSizeXXL * 1.6 * scaling
+ pointSize: Style.fontSizeXXL * 1.6
color: Color.mPrimary
}
NText {
@@ -113,7 +113,7 @@ NBox {
min = Math.round(min)
return `${max}°/${min}°`
}
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mOnSurfaceVariant
}
}
diff --git a/Modules/ControlCenter/ControlCenterPanel.qml b/Modules/ControlCenter/ControlCenterPanel.qml
index 19e6e30a..4f997b17 100644
--- a/Modules/ControlCenter/ControlCenterPanel.qml
+++ b/Modules/ControlCenter/ControlCenterPanel.qml
@@ -10,9 +10,39 @@ import qs.Widgets
NPanel {
id: root
- preferredWidth: 460
- preferredHeight: 790
panelKeyboardFocus: true
+ preferredWidth: Math.round(460 * Style.uiScaleRatio)
+ preferredHeight: {
+ var height = 0
+ var count = 0
+ for (var i = 0; i < Settings.data.controlCenter.cards.length; i++) {
+ const card = Settings.data.controlCenter.cards[i]
+ if (!card.enabled) {
+ continue
+ }
+ count++
+ switch (card.id) {
+ case "profile-card":
+ height += profileHeight
+ break
+ case "shortcuts-card":
+ height += shortcutsHeight
+ break
+ case "audio-card":
+ height += audioHeight
+ break
+ case "weather-card":
+ height += weatherHeight
+ break
+ case "media-sysmon-card":
+ height += mediaSysMonHeight
+ break
+ default:
+ break
+ }
+ }
+ return height + (count + 1) * Style.marginL
+ }
// Positioning
readonly property string controlCenterPosition: Settings.data.controlCenter.position
@@ -23,35 +53,86 @@ NPanel {
panelAnchorBottom: controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.startsWith("bottom_")
panelAnchorTop: controlCenterPosition !== "close_to_bar_button" && controlCenterPosition.startsWith("top_")
+ readonly property int profileHeight: Math.round(64 * Style.uiScaleRatio)
+ readonly property int shortcutsHeight: Math.round(52 * Style.uiScaleRatio)
+ readonly property int audioHeight: Math.round(120 * Style.uiScaleRatio)
+ readonly property int weatherHeight: Math.round(190 * Style.uiScaleRatio)
+ readonly property int mediaSysMonHeight: Math.round(260 * Style.uiScaleRatio)
+
panelContent: Item {
id: content
- property real cardSpacing: Style.marginL * scaling
-
- // Layout content
ColumnLayout {
id: layout
- x: content.cardSpacing
- y: content.cardSpacing
- width: parent.width - (2 * content.cardSpacing)
- spacing: content.cardSpacing
+ x: Style.marginL
+ y: Style.marginL
+ width: parent.width - (Style.marginL * 2)
+ spacing: Style.marginL
- // Cards (consistent inter-card spacing via ColumnLayout spacing)
- ProfileCard {
- Layout.fillWidth: true
- Layout.preferredHeight: Math.max(64 * scaling)
+ Repeater {
+ model: Settings.data.controlCenter.cards
+ Loader {
+ active: modelData.enabled
+ visible: active
+ Layout.fillWidth: true
+ Layout.preferredHeight: {
+ switch (modelData.id) {
+ case "profile-card":
+ return profileHeight
+ case "shortcuts-card":
+ return shortcutsHeight
+ case "audio-card":
+ return audioHeight
+ case "weather-card":
+ return weatherHeight
+ case "media-sysmon-card":
+ return mediaSysMonHeight
+ default:
+ return 0
+ }
+ }
+ sourceComponent: {
+ switch (modelData.id) {
+ case "profile-card":
+ return profileCard
+ case "shortcuts-card":
+ return shortcutsCard
+ case "audio-card":
+ return audioCard
+ case "weather-card":
+ return weatherCard
+ case "media-sysmon-card":
+ return mediaSysMonCard
+ }
+ }
+ }
}
+ }
- WeatherCard {
- Layout.fillWidth: true
- Layout.preferredHeight: Math.max(190 * scaling)
- }
+ Component {
+ id: profileCard
+ ProfileCard {}
+ }
- // Middle section: media + stats column
+ Component {
+ id: shortcutsCard
+ ShortcutsCard {}
+ }
+
+ Component {
+ id: audioCard
+ AudioCard {}
+ }
+
+ Component {
+ id: weatherCard
+ WeatherCard {}
+ }
+
+ Component {
+ id: mediaSysMonCard
RowLayout {
- Layout.fillWidth: true
- Layout.preferredHeight: Math.max(260 * scaling)
- spacing: content.cardSpacing
+ spacing: Style.marginL
// Media card
MediaCard {
@@ -61,37 +142,10 @@ NPanel {
// System monitors combined in one card
SystemMonitorCard {
- Layout.preferredWidth: Style.baseWidgetSize * 2.625 * scaling
+ Layout.preferredWidth: Math.round(Style.baseWidgetSize * 2.625)
Layout.fillHeight: true
}
}
-
- // Audio card below media and system monitor
- AudioCard {
- Layout.fillWidth: true
- Layout.preferredHeight: Math.max(120 * scaling)
- }
-
- // Bottom actions (two grouped rows of round buttons)
- RowLayout {
- Layout.fillWidth: true
- Layout.preferredHeight: Math.max(60 * scaling)
- spacing: content.cardSpacing
-
- // Power Profiles switcher
- PowerProfilesCard {
- Layout.fillWidth: true
- Layout.fillHeight: true
- spacing: content.cardSpacing
- }
-
- // Utilities buttons
- UtilitiesCard {
- Layout.fillWidth: true
- Layout.fillHeight: true
- spacing: content.cardSpacing
- }
- }
}
}
}
diff --git a/Modules/ControlCenter/Extras/ControlCenterWidgetLoader.qml b/Modules/ControlCenter/Extras/ControlCenterWidgetLoader.qml
index 4e7577ee..5dbe1338 100644
--- a/Modules/ControlCenter/Extras/ControlCenterWidgetLoader.qml
+++ b/Modules/ControlCenter/Extras/ControlCenterWidgetLoader.qml
@@ -16,16 +16,6 @@ Item {
implicitWidth: getImplicitSize(loader.item, "implicitWidth")
implicitHeight: getImplicitSize(loader.item, "implicitHeight")
- Connections {
- target: ScalingService
- enabled: loader.item && (loader.item.screen !== undefined)
- function onScaleChanged(aScreenName, scale) {
- if (loader.item && loader.item.screen && aScreenName === screenName) {
- loader.item['scaling'] = scale
- }
- }
- }
-
function getImplicitSize(item, prop) {
return (item && item.visible) ? item[prop] : 0
}
diff --git a/Modules/ControlCenter/Widgets/Bluetooth.qml b/Modules/ControlCenter/Widgets/Bluetooth.qml
index e9886a4f..e4549a31 100644
--- a/Modules/ControlCenter/Widgets/Bluetooth.qml
+++ b/Modules/ControlCenter/Widgets/Bluetooth.qml
@@ -4,13 +4,10 @@ import qs.Commons
import qs.Services
import qs.Widgets
-NQuickSetting {
+NIconButtonHot {
property ShellScreen screen
- property real scaling: 1.0
- text: I18n.tr("quickSettings.bluetooth.label.enabled")
icon: BluetoothService.enabled ? "bluetooth" : "bluetooth-off"
tooltipText: I18n.tr("quickSettings.bluetooth.tooltip.action")
- style: Settings.data.controlCenter.quickSettingsStyle || "modern"
onClicked: PanelService.getPanel("bluetoothPanel")?.toggle(this)
}
diff --git a/Modules/ControlCenter/Widgets/KeepAwake.qml b/Modules/ControlCenter/Widgets/KeepAwake.qml
index 044734e4..96d60733 100644
--- a/Modules/ControlCenter/Widgets/KeepAwake.qml
+++ b/Modules/ControlCenter/Widgets/KeepAwake.qml
@@ -4,15 +4,11 @@ import qs.Commons
import qs.Services
import qs.Widgets
-NQuickSetting {
+NIconButtonHot {
property ShellScreen screen
- property real scaling: 1.0
- text: I18n.tr("quickSettings.keepAwake.label.enabled")
icon: IdleInhibitorService.isInhibited ? "keep-awake-on" : "keep-awake-off"
hot: IdleInhibitorService.isInhibited
tooltipText: I18n.tr("quickSettings.keepAwake.tooltip.action")
- style: Settings.data.controlCenter.quickSettingsStyle || "modern"
-
onClicked: IdleInhibitorService.manualToggle()
}
diff --git a/Modules/ControlCenter/Widgets/NightLight.qml b/Modules/ControlCenter/Widgets/NightLight.qml
index 19cdd669..eb338882 100644
--- a/Modules/ControlCenter/Widgets/NightLight.qml
+++ b/Modules/ControlCenter/Widgets/NightLight.qml
@@ -4,15 +4,12 @@ import qs.Commons
import qs.Services
import qs.Widgets
-NQuickSetting {
+NIconButtonHot {
property ShellScreen screen
- property real scaling: 1.0
enabled: ProgramCheckerService.wlsunsetAvailable
- text: I18n.tr("quickSettings.nightLight.label.enabled")
icon: Settings.data.nightLight.enabled ? (Settings.data.nightLight.forced ? "nightlight-forced" : "nightlight-on") : "nightlight-off"
hot: !Settings.data.nightLight.enabled || Settings.data.nightLight.forced
- style: Settings.data.controlCenter.quickSettingsStyle || "modern"
tooltipText: I18n.tr("quickSettings.nightLight.tooltip.action")
onClicked: {
diff --git a/Modules/ControlCenter/Widgets/Notifications.qml b/Modules/ControlCenter/Widgets/Notifications.qml
index 19c22a82..ae291517 100644
--- a/Modules/ControlCenter/Widgets/Notifications.qml
+++ b/Modules/ControlCenter/Widgets/Notifications.qml
@@ -4,16 +4,12 @@ import qs.Commons
import qs.Services
import qs.Widgets
-NQuickSetting {
+NIconButtonHot {
property ShellScreen screen
- property real scaling: 1.0
- text: Settings.data.notifications.doNotDisturb ? I18n.tr("quickSettings.notifications.label.disabled") : I18n.tr("quickSettings.notifications.label.enabled")
icon: Settings.data.notifications.doNotDisturb ? "bell-off" : "bell"
hot: Settings.data.notifications.doNotDisturb
tooltipText: I18n.tr("quickSettings.notifications.tooltip.action")
- style: Settings.data.controlCenter.quickSettingsStyle || "modern"
-
onClicked: PanelService.getPanel("notificationHistoryPanel")?.toggle(this)
onRightClicked: Settings.data.notifications.doNotDisturb = !Settings.data.notifications.doNotDisturb
}
diff --git a/Modules/ControlCenter/Widgets/PowerProfile.qml b/Modules/ControlCenter/Widgets/PowerProfile.qml
index 1a504963..ca5f497f 100644
--- a/Modules/ControlCenter/Widgets/PowerProfile.qml
+++ b/Modules/ControlCenter/Widgets/PowerProfile.qml
@@ -6,18 +6,15 @@ import qs.Services
import qs.Widgets
// Performance
-NQuickSetting {
+NIconButtonHot {
property ShellScreen screen
- property real scaling: 1.0
+
readonly property bool hasPP: PowerProfileService.available
enabled: hasPP
- text: hasPP ? PowerProfileService.getName() : I18n.tr("quickSettings.powerProfile.label.unavailable")
icon: PowerProfileService.getIcon()
hot: !PowerProfileService.isDefault()
tooltipText: I18n.tr("quickSettings.powerProfile.tooltip.action")
- style: Settings.data.controlCenter.quickSettingsStyle || "modern"
-
onClicked: {
PowerProfileService.cycleProfile()
}
diff --git a/Modules/ControlCenter/Widgets/ScreenRecorder.qml b/Modules/ControlCenter/Widgets/ScreenRecorder.qml
index f9ad8786..7a58c8f3 100644
--- a/Modules/ControlCenter/Widgets/ScreenRecorder.qml
+++ b/Modules/ControlCenter/Widgets/ScreenRecorder.qml
@@ -4,21 +4,13 @@ import qs.Commons
import qs.Services
import qs.Widgets
-NQuickSetting {
+NIconButtonHot {
property ShellScreen screen
- property real scaling: 1.0
enabled: ProgramCheckerService.gpuScreenRecorderAvailable
icon: "camera-video"
- text: ScreenRecorderService.isRecording ? I18n.tr("quickSettings.screenRecorder.label.recording") : I18n.tr("quickSettings.screenRecorder.label.stopped")
hot: ScreenRecorderService.isRecording
tooltipText: I18n.tr("quickSettings.screenRecorder.tooltip.action")
- style: Settings.data.controlCenter.quickSettingsStyle || "modern"
-
- // Force hover state when recording to get hover colors
- property bool originalHovered: hovered
- hovered: ScreenRecorderService.isRecording || originalHovered
-
onClicked: {
ScreenRecorderService.toggleRecording()
if (!ScreenRecorderService.isRecording) {
diff --git a/Modules/ControlCenter/Widgets/WallpaperSelector.qml b/Modules/ControlCenter/Widgets/WallpaperSelector.qml
index 95a50af3..ff513bc1 100644
--- a/Modules/ControlCenter/Widgets/WallpaperSelector.qml
+++ b/Modules/ControlCenter/Widgets/WallpaperSelector.qml
@@ -4,16 +4,12 @@ import qs.Commons
import qs.Services
import qs.Widgets
-NQuickSetting {
+NIconButtonHot {
property ShellScreen screen
- property real scaling: 1.0
enabled: Settings.data.wallpaper.enabled
icon: "wallpaper-selector"
- text: I18n.tr("quickSettings.wallpaperSelector.label")
tooltipText: I18n.tr("quickSettings.wallpaperSelector.tooltip.action")
- style: Settings.data.controlCenter.quickSettingsStyle || "modern"
-
onClicked: PanelService.getPanel("wallpaperPanel")?.toggle(this)
onRightClicked: WallpaperService.setRandomWallpaper()
}
diff --git a/Modules/ControlCenter/Widgets/WiFi.qml b/Modules/ControlCenter/Widgets/WiFi.qml
index 7f739866..faaedc73 100644
--- a/Modules/ControlCenter/Widgets/WiFi.qml
+++ b/Modules/ControlCenter/Widgets/WiFi.qml
@@ -4,9 +4,8 @@ import qs.Commons
import qs.Services
import qs.Widgets
-NQuickSetting {
+NIconButtonHot {
property ShellScreen screen
- property real scaling: 1.0
icon: {
try {
@@ -29,21 +28,6 @@ NQuickSetting {
}
}
- text: {
- if (NetworkService.ethernetConnected) {
- return I18n.tr("quickSettings.wifi.label.ethernet")
- }
- let connected = false
- for (const net in NetworkService.networks) {
- if (NetworkService.networks[net].connected) {
- connected = true
- break
- }
- }
- return connected ? I18n.tr("quickSettings.wifi.label.wifi") : I18n.tr("quickSettings.wifi.label.disconnected")
- }
-
- style: Settings.data.controlCenter.quickSettingsStyle || "modern"
tooltipText: I18n.tr("quickSettings.wifi.tooltip.action")
onClicked: PanelService.getPanel("wifiPanel")?.toggle(this)
}
diff --git a/Modules/Dock/Dock.qml b/Modules/Dock/Dock.qml
index b23c90bc..56a932e5 100644
--- a/Modules/Dock/Dock.qml
+++ b/Modules/Dock/Dock.qml
@@ -16,7 +16,7 @@ Variants {
id: root
required property ShellScreen modelData
- property real scaling: ScalingService.getScreenScale(modelData)
+
property bool barIsReady: modelData ? BarService.isBarReady(modelData.name) : false
Connections {
@@ -28,15 +28,6 @@ Variants {
}
}
- Connections {
- target: ScalingService
- function onScaleChanged(screenName, scale) {
- if (screenName === modelData.name) {
- scaling = scale
- }
- }
- }
-
// Update dock apps when toplevels change
Connections {
target: ToplevelManager ? ToplevelManager.toplevels : null
@@ -71,14 +62,14 @@ Variants {
readonly property int showDelay: 100
readonly property int hideAnimationDuration: Style.animationFast
readonly property int showAnimationDuration: Style.animationFast
- readonly property int peekHeight: 1 // no scaling for peek
- readonly property int iconSize: 36 * scaling
- readonly property int floatingMargin: Settings.data.dock.floatingRatio * Style.marginL * scaling
+ readonly property int peekHeight: 1
+ readonly property int iconSize: 36
+ readonly property int floatingMargin: Settings.data.dock.floatingRatio * Style.marginL
// Bar detection and positioning properties
readonly property bool hasBar: modelData && modelData.name ? (Settings.data.bar.monitors.includes(modelData.name) || (Settings.data.bar.monitors.length === 0)) : false
readonly property bool barAtBottom: hasBar && Settings.data.bar.position === "bottom"
- readonly property int barHeight: Style.barHeight * scaling
+ readonly property int barHeight: Style.barHeight
// Shared state between windows
property bool dockHovered: false
@@ -264,7 +255,7 @@ Variants {
margins.bottom: {
switch (Settings.data.bar.position) {
case "bottom":
- return (Style.barHeight + Style.marginM) * scaling + (Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL * scaling + floatingMargin : floatingMargin)
+ return (Style.barHeight + Style.marginM) + (Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL + floatingMargin : floatingMargin)
default:
return floatingMargin
}
@@ -305,12 +296,12 @@ Variants {
Rectangle {
id: dockContainer
- width: dockLayout.implicitWidth + Style.marginM * scaling * 2
+ width: dockLayout.implicitWidth + Style.marginM * 2
height: Math.round(iconSize * 1.5)
color: Qt.alpha(Color.mSurface, Settings.data.dock.backgroundOpacity)
anchors.centerIn: parent
- radius: Style.radiusL * scaling
- border.width: Math.max(1, Style.borderS * scaling)
+ radius: Style.radiusL
+ border.width: Math.max(1, Style.borderS)
border.color: Qt.alpha(Color.mOutline, Settings.data.dock.backgroundOpacity)
MouseArea {
@@ -343,7 +334,7 @@ Variants {
Item {
id: dock
width: dockLayout.implicitWidth
- height: parent.height - (Style.marginM * 2 * scaling)
+ height: parent.height - (Style.marginM * 2)
anchors.centerIn: parent
function getAppIcon(appData): string {
@@ -354,7 +345,7 @@ Variants {
RowLayout {
id: dockLayout
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
Layout.preferredHeight: parent.height
anchors.centerIn: parent
@@ -401,6 +392,15 @@ Variants {
scale: appButton.hovered ? 1.15 : 1.0
+ // Apply dock-specific colorization shader only to non-focused apps
+ layer.enabled: !appButton.isActive && Settings.data.dock.colorizeIcons
+ layer.effect: ShaderEffect {
+ property color targetColor: Color.mOnSurface
+ property real colorizeMode: 0.0 // Dock mode (grayscale)
+
+ fragmentShader: Qt.resolvedUrl(Quickshell.shellDir + "/Shaders/qsb/appicon_colorize.frag.qsb")
+ }
+
Behavior on scale {
NumberAnimation {
duration: Style.animationNormal
@@ -446,7 +446,6 @@ Variants {
// Context menu popup
DockMenu {
id: contextMenu
- scaling: root.scaling
onHoveredChanged: menuHovered = hovered
onRequestClose: {
contextMenu.hide()
@@ -542,7 +541,7 @@ Variants {
width: iconSize * 0.2
height: iconSize * 0.1
color: Color.mPrimary
- radius: Style.radiusXS * scaling
+ radius: Style.radiusXS
anchors.top: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
diff --git a/Modules/Dock/DockMenu.qml b/Modules/Dock/DockMenu.qml
index 255e3b9d..d09ea6e7 100644
--- a/Modules/Dock/DockMenu.qml
+++ b/Modules/Dock/DockMenu.qml
@@ -13,7 +13,7 @@ PopupWindow {
property var toplevel: null
property Item anchorItem: null
- property real scaling: 1.0
+
property bool hovered: menuMouseArea.containsMouse
property var onAppClosed: null // Callback function for when an app is closed
property bool canAutoClose: false
@@ -25,8 +25,8 @@ PopupWindow {
signal requestClose
- implicitWidth: Math.max(160 * scaling, contextMenuColumn.implicitWidth)
- implicitHeight: contextMenuColumn.implicitHeight + (Style.marginM * scaling * 2)
+ implicitWidth: Math.max(160, contextMenuColumn.implicitWidth)
+ implicitHeight: contextMenuColumn.implicitHeight + (Style.marginM * 2)
color: Color.transparent
visible: false
@@ -117,7 +117,7 @@ PopupWindow {
anchor.item: anchorItem
anchor.rect.x: anchorItem ? (anchorItem.width - implicitWidth) / 2 : 0
- anchor.rect.y: anchorItem ? -implicitHeight - (Style.marginM * scaling) : 0
+ anchor.rect.y: anchorItem ? -implicitHeight - (Style.marginM) : 0
function show(item, toplevelData) {
if (!item) {
@@ -140,8 +140,8 @@ PopupWindow {
// Helper function to determine which menu item is under the mouse
function getHoveredItem(mouseY) {
- const itemHeight = 32 * scaling
- const startY = Style.marginM * scaling
+ const itemHeight = 32
+ const startY = Style.marginM
const relativeY = mouseY - startY
if (relativeY < 0)
@@ -208,9 +208,9 @@ PopupWindow {
Rectangle {
anchors.fill: parent
color: Color.mSurfaceVariant
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
// Single MouseArea to handle both auto-close and menu interactions
MouseArea {
@@ -246,7 +246,7 @@ PopupWindow {
ColumnLayout {
id: contextMenuColumn
anchors.fill: parent
- anchors.margins: Style.marginM * scaling
+ anchors.margins: Style.marginM
spacing: 0
Repeater {
@@ -254,26 +254,26 @@ PopupWindow {
Rectangle {
Layout.fillWidth: true
- height: 32 * scaling
+ height: 32
color: root.hoveredItem === index ? Color.mTertiary : Color.transparent
- radius: Style.radiusXS * scaling
+ radius: Style.radiusXS
RowLayout {
anchors.left: parent.left
- anchors.leftMargin: Style.marginS * scaling
+ anchors.leftMargin: Style.marginS
anchors.verticalCenter: parent.verticalCenter
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
NIcon {
icon: modelData.icon
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: root.hoveredItem === index ? Color.mOnTertiary : Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignVCenter
}
NText {
text: modelData.text
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: root.hoveredItem === index ? Color.mOnTertiary : Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignVCenter
elide: Text.ElideRight
diff --git a/Modules/Launcher/Launcher.qml b/Modules/Launcher/Launcher.qml
index f6ec7ae9..271d4c4b 100644
--- a/Modules/Launcher/Launcher.qml
+++ b/Modules/Launcher/Launcher.qml
@@ -37,8 +37,8 @@ NPanel {
property bool resultsReady: false
property bool ignoreMouseHover: false
- readonly property int badgeSize: Math.round(Style.baseWidgetSize * 1.6 * scaling)
- readonly property int entryHeight: Math.round(badgeSize + Style.marginM * 2 * scaling)
+ readonly property int badgeSize: Math.round(Style.baseWidgetSize * 1.6)
+ readonly property int entryHeight: Math.round(badgeSize + Style.marginM * 2)
// Public API for plugins
function setSearchText(text) {
@@ -192,10 +192,8 @@ NPanel {
// Reset when launcher opens
Connections {
target: root
- function onOpenedChanged() {
- if (root.opened) {
- mouseMovementDetector.initialized = false
- }
+ function onOpened() {
+ mouseMovementDetector.initialized = false
}
}
}
@@ -295,14 +293,14 @@ NPanel {
ColumnLayout {
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginM
NTextInput {
id: searchInput
Layout.fillWidth: true
- fontSize: Style.fontSizeL * scaling
+ fontSize: Style.fontSizeL
fontWeight: Style.fontWeightSemiBold
text: searchText
@@ -350,7 +348,7 @@ NPanel {
Layout.fillWidth: true
Layout.fillHeight: true
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
model: results
currentIndex: selectedIndex
cacheBuffer: resultsList.height * 2
@@ -401,9 +399,9 @@ NPanel {
}
}
- width: resultsList.width - Style.marginS * scaling
+ width: resultsList.width - Style.marginS
implicitHeight: entryHeight
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
color: entry.isSelected ? Color.mTertiary : Color.mSurface
Behavior on color {
@@ -416,19 +414,19 @@ NPanel {
ColumnLayout {
id: contentLayout
anchors.fill: parent
- anchors.margins: Style.marginM * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginM
+ spacing: Style.marginM
// Top row - Main entry content with pin button
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Icon badge or Image preview
Rectangle {
Layout.preferredWidth: badgeSize
Layout.preferredHeight: badgeSize
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
color: Color.mSurfaceVariant
// Image preview for clipboard images
@@ -436,7 +434,7 @@ NPanel {
id: imagePreview
anchors.fill: parent
visible: modelData.isImage
- imageRadius: Style.radiusM * scaling
+ imageRadius: Style.radiusM
// This property creates a dependency on the service's revision counter
readonly property int _rev: ClipboardService.revision
@@ -457,7 +455,7 @@ NPanel {
BusyIndicator {
anchors.centerIn: parent
running: true
- width: Style.baseWidgetSize * 0.5 * scaling
+ width: Style.baseWidgetSize * 0.5
height: width
}
}
@@ -475,7 +473,7 @@ NPanel {
Loader {
id: iconLoader
anchors.fill: parent
- anchors.margins: Style.marginXS * scaling
+ anchors.margins: Style.marginXS
visible: !modelData.isImage || imagePreview.status === Image.Error
active: visible
@@ -495,7 +493,7 @@ NPanel {
anchors.centerIn: parent
visible: !imagePreview.visible && !iconLoader.visible
text: modelData.name ? modelData.name.charAt(0).toUpperCase() : "?"
- pointSize: Style.fontSizeXXL * scaling
+ pointSize: Style.fontSizeXXL
font.weight: Style.fontWeightBold
color: Color.mOnPrimary
}
@@ -505,10 +503,10 @@ NPanel {
visible: modelData.isImage && imagePreview.visible
anchors.bottom: parent.bottom
anchors.right: parent.right
- anchors.margins: 2 * scaling
- width: formatLabel.width + 6 * scaling
- height: formatLabel.height + 2 * scaling
- radius: Style.radiusM * scaling
+ anchors.margins: 2
+ width: formatLabel.width + 6
+ height: formatLabel.height + 2
+ radius: Style.radiusM
color: Color.mSurfaceVariant
NText {
@@ -521,7 +519,7 @@ NPanel {
const parts = desc.split(" • ")
return parts[0] || "IMG"
}
- pointSize: Style.fontSizeXXS * scaling
+ pointSize: Style.fontSizeXXS
color: Color.mPrimary
}
}
@@ -530,11 +528,11 @@ NPanel {
// Text content
ColumnLayout {
Layout.fillWidth: true
- spacing: 0 * scaling
+ spacing: 0
NText {
text: modelData.name || "Unknown"
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: entry.isSelected ? Color.mOnTertiary : Color.mOnSurface
elide: Text.ElideRight
@@ -543,7 +541,7 @@ NPanel {
NText {
text: modelData.description || ""
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: entry.isSelected ? Color.mOnTertiary : Color.mOnSurfaceVariant
elide: Text.ElideRight
Layout.fillWidth: true
@@ -598,7 +596,7 @@ NPanel {
const prefix = activePlugin?.name ? `${activePlugin.name}: ` : ""
return prefix + `${results.length} result${results.length !== 1 ? 's' : ''}`
}
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mOnSurfaceVariant
horizontalAlignment: Text.AlignCenter
}
diff --git a/Modules/LockScreen/LockScreen.qml b/Modules/LockScreen/LockScreen.qml
index 82654abf..8b646e57 100644
--- a/Modules/LockScreen/LockScreen.qml
+++ b/Modules/LockScreen/LockScreen.qml
@@ -49,7 +49,7 @@ Loader {
locked: lockScreen.active
WlSessionLockSurface {
- readonly property real scaling: ScalingService.dynamicScale(screen)
+ readonly property var now: Time.date
Item {
id: batteryIndicator
@@ -103,8 +103,8 @@ Loader {
visible: Settings.data.general.showScreenCorners
property color cornerColor: Settings.data.general.forceBlackScreenCorners ? Qt.rgba(0, 0, 0, 1) : Qt.alpha(Color.mSurface, Settings.data.bar.backgroundOpacity)
- property real cornerRadius: Style.screenRadius * scaling
- property real cornerSize: Style.screenRadius * scaling
+ property real cornerRadius: Style.screenRadius
+ property real cornerSize: Style.screenRadius
// Top-left concave corner
Canvas {
@@ -248,12 +248,12 @@ Loader {
// Time, Date, and User Profile Container
Rectangle {
- width: Math.max(500 * scaling, contentRow.implicitWidth + 24 * scaling)
- height: 120 * scaling
+ width: Math.max(500, contentRow.implicitWidth + 32)
+ height: Math.max(120, contentRow.implicitHeight + 32)
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
- anchors.topMargin: 100 * scaling
- radius: 32 * scaling
+ anchors.topMargin: 100
+ radius: Style.radiusL
color: Color.mSurface
border.color: Qt.alpha(Color.mOutline, 0.2)
border.width: 1
@@ -261,13 +261,13 @@ Loader {
RowLayout {
id: contentRow
anchors.fill: parent
- anchors.margins: 12 * scaling
- spacing: 8 * scaling
+ anchors.margins: 16
+ spacing: 32
// Left side: Avatar
Rectangle {
- Layout.preferredWidth: 70 * scaling
- Layout.preferredHeight: 70 * scaling
+ Layout.preferredWidth: 70
+ Layout.preferredHeight: 70
Layout.alignment: Qt.AlignVCenter
radius: width * 0.5
color: Color.transparent
@@ -296,9 +296,9 @@ Loader {
NImageCircled {
anchors.centerIn: parent
- width: 66 * scaling
- height: 66 * scaling
- imagePath: Settings.data.general.avatarImage
+ width: 66
+ height: 66
+ imagePath: Settings.preprocessPath(Settings.data.general.avatarImage)
fallbackIcon: "person"
SequentialAnimation on scale {
@@ -317,20 +317,15 @@ Loader {
}
}
- // Spacer to center the text section
- Item {
- Layout.fillWidth: true
- }
-
// Center: User Info Column (left-aligned text)
ColumnLayout {
Layout.alignment: Qt.AlignVCenter
- spacing: 2 * scaling
+ spacing: 2
// Welcome back + Username on one line
NText {
- text: I18n.tr("lock-screen.welcome-back") + " " + Quickshell.env("USER") + "!"
- pointSize: Style.fontSizeXXXL * scaling
+ text: I18n.tr("lock-screen.welcome-back") + " " + (Quickshell.env("USER").charAt(0).toUpperCase() + Quickshell.env("USER").slice(1)) + "!"
+ pointSize: Style.fontSizeXXL
font.weight: Font.Medium
color: Color.mOnSurface
horizontalAlignment: Text.AlignLeft
@@ -339,22 +334,21 @@ Loader {
// Date below
NText {
text: Qt.locale().toString(Time.date, "dddd, MMMM d")
- pointSize: Style.fontSizeXXL * scaling
+ pointSize: Style.fontSizeXL
font.weight: Font.Medium
color: Color.mOnSurfaceVariant
horizontalAlignment: Text.AlignLeft
}
}
- // Spacer to push cool time to the right
+ // Spacer to push time to the right
Item {
Layout.fillWidth: true
}
- // Right side: Cool Time (from Calendar)
Item {
- Layout.preferredWidth: 70 * scaling
- Layout.preferredHeight: 70 * scaling
+ Layout.preferredWidth: 70
+ Layout.preferredHeight: 70
Layout.alignment: Qt.AlignVCenter
// Seconds circular progress
@@ -377,21 +371,21 @@ Loader {
var ctx = getContext("2d")
var centerX = width / 2
var centerY = height / 2
- var radius = Math.min(width, height) / 2 - 3 * scaling
+ var radius = Math.min(width, height) / 2 - 3
ctx.reset()
// Background circle
ctx.beginPath()
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI)
- ctx.lineWidth = 2.5 * scaling
+ ctx.lineWidth = 2.5
ctx.strokeStyle = Qt.alpha(Color.mOnSurface, 0.15)
ctx.stroke()
// Progress arc
ctx.beginPath()
ctx.arc(centerX, centerY, radius, -Math.PI / 2, -Math.PI / 2 + progress * 2 * Math.PI)
- ctx.lineWidth = 2.5 * scaling
+ ctx.lineWidth = 2.5
ctx.strokeStyle = Color.mPrimary
ctx.lineCap = "round"
ctx.stroke()
@@ -405,11 +399,12 @@ Loader {
NText {
text: {
- var t = Settings.data.location.use12hourFormat ? Qt.locale().toString(new Date(), "hh AP") : Qt.locale().toString(new Date(), "HH")
+ var t = Settings.data.location.use12hourFormat ? Qt.locale().toString(Time.date, "hh AP") : Qt.locale().toString(Time.date, "HH")
return t
}
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightBold
+ family: Settings.data.ui.fontFixed
color: Color.mOnSurface
horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignHCenter
@@ -417,8 +412,9 @@ Loader {
NText {
text: Qt.formatTime(Time.date, "mm")
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightBold
+ family: Settings.data.ui.fontFixed
color: Color.mOnSurfaceVariant
horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignHCenter
@@ -430,12 +426,12 @@ Loader {
// Error notification
Rectangle {
- width: 450 * scaling
- height: 60 * scaling
+ width: 450
+ height: 60
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
- anchors.bottomMargin: 300 * scaling
- radius: 30 * scaling
+ anchors.bottomMargin: (Settings.data.general.compactLockScreen ? 240 : 320) * Style.uiScaleRatio
+ radius: 30
color: Color.mError
border.color: Color.mError
border.width: 1
@@ -444,18 +440,18 @@ Loader {
RowLayout {
anchors.centerIn: parent
- spacing: 10 * scaling
+ spacing: 10
NIcon {
icon: "alert-circle"
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: Color.mOnError
}
NText {
text: lockContext.errorMessage || "Authentication failed"
color: Color.mOnError
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Font.Medium
horizontalAlignment: Text.AlignHCenter
}
@@ -469,42 +465,108 @@ Loader {
}
}
- // Bottom container with weather, password input and controls
+ // Compact status indicators container (compact mode only)
Rectangle {
- width: 750 * scaling
- height: 220 * scaling
+ width: {
+ var hasBattery = UPower.displayDevice && UPower.displayDevice.ready && UPower.displayDevice.isPresent
+ var hasKeyboard = keyboardLayout.currentLayout !== "Unknown"
+
+ if (hasBattery && hasKeyboard) {
+ return 200
+ } else if (hasBattery || hasKeyboard) {
+ return 120
+ } else {
+ return 0
+ }
+ }
+ height: 40
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
- anchors.bottomMargin: 100 * scaling
- radius: 32 * scaling
+ anchors.bottomMargin: 96 + (Settings.data.general.compactLockScreen ? 116 : 220)
+ topLeftRadius: Style.radiusL
+ topRightRadius: Style.radiusL
+ color: Color.mSurface
+ visible: Settings.data.general.compactLockScreen && ((UPower.displayDevice && UPower.displayDevice.ready && UPower.displayDevice.isPresent) || keyboardLayout.currentLayout !== "Unknown")
+
+ RowLayout {
+ anchors.centerIn: parent
+ spacing: 16
+
+ // Battery indicator
+ RowLayout {
+ spacing: 6
+ visible: UPower.displayDevice && UPower.displayDevice.ready && UPower.displayDevice.isPresent
+
+ NIcon {
+ icon: BatteryService.getIcon(Math.round(UPower.displayDevice.percentage * 100), UPower.displayDevice.state === UPowerDeviceState.Charging, true)
+ pointSize: Style.fontSizeM
+ color: UPower.displayDevice.state === UPowerDeviceState.Charging ? Color.mPrimary : Color.mOnSurfaceVariant
+ }
+
+ NText {
+ text: Math.round(UPower.displayDevice.percentage * 100) + "%"
+ color: Color.mOnSurfaceVariant
+ pointSize: Style.fontSizeM
+ font.weight: Font.Medium
+ }
+ }
+
+ // Keyboard layout indicator
+ RowLayout {
+ spacing: 6
+ visible: keyboardLayout.currentLayout !== "Unknown"
+
+ NIcon {
+ icon: "keyboard"
+ pointSize: Style.fontSizeM
+ color: Color.mOnSurfaceVariant
+ }
+
+ NText {
+ text: keyboardLayout.currentLayout
+ color: Color.mOnSurfaceVariant
+ pointSize: Style.fontSizeM
+ font.weight: Font.Medium
+ elide: Text.ElideRight
+ }
+ }
+ }
+ }
+
+ // Bottom container with weather, password input and controls
+ Rectangle {
+ width: 750
+ height: Settings.data.general.compactLockScreen ? 120 : 220
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 100
+ radius: Style.radiusL
color: Color.mSurface
- border.color: Qt.alpha(Color.mOutline, 0.2)
- border.width: 1
ColumnLayout {
anchors.fill: parent
- anchors.margins: 14 * scaling
- spacing: 14 * scaling
+ anchors.margins: 14
+ spacing: 14
// Weather section
RowLayout {
Layout.fillWidth: true
- Layout.preferredHeight: 65 * scaling
- spacing: 18 * scaling
- visible: LocationService.coordinatesReady && LocationService.data.weather !== null
+ Layout.preferredHeight: 65
+ spacing: 18
+ visible: !Settings.data.general.compactLockScreen && LocationService.coordinatesReady && LocationService.data.weather !== null
// Media widget with visualizer
Rectangle {
- Layout.preferredWidth: 220 * scaling
- Layout.preferredHeight: 50 * scaling
- radius: 25 * scaling
+ Layout.preferredWidth: 220
+ Layout.preferredHeight: 50
+ radius: 25
color: Color.transparent
clip: true
visible: MediaService.currentPlayer && MediaService.canPlay
Loader {
anchors.fill: parent
- anchors.margins: 4 * scaling
+ anchors.margins: 4
active: Settings.data.audio.visualizerType === "linear"
z: 0
sourceComponent: LinearSpectrum {
@@ -517,7 +579,7 @@ Loader {
Loader {
anchors.fill: parent
- anchors.margins: 4 * scaling
+ anchors.margins: 4
active: Settings.data.audio.visualizerType === "mirrored"
z: 0
sourceComponent: MirroredSpectrum {
@@ -530,7 +592,7 @@ Loader {
Loader {
anchors.fill: parent
- anchors.margins: 4 * scaling
+ anchors.margins: 4
active: Settings.data.audio.visualizerType === "wave"
z: 0
sourceComponent: WaveSpectrum {
@@ -543,35 +605,35 @@ Loader {
RowLayout {
anchors.fill: parent
- anchors.margins: 8 * scaling
- spacing: 8 * scaling
+ anchors.margins: 8
+ spacing: 8
z: 1
Rectangle {
- Layout.preferredWidth: 34 * scaling
- Layout.preferredHeight: 34 * scaling
+ Layout.preferredWidth: 34
+ Layout.preferredHeight: 34
radius: width * 0.5
color: Color.transparent
clip: true
NImageCircled {
anchors.fill: parent
- anchors.margins: 2 * scaling
+ anchors.margins: 2
imagePath: MediaService.trackArtUrl
fallbackIcon: "disc"
- fallbackIconSize: Style.fontSizeM * scaling
+ fallbackIconSize: Style.fontSizeM
borderColor: Color.mOutline
- borderWidth: Math.max(1, Style.borderS * scaling)
+ borderWidth: Math.max(1, Style.borderS)
}
}
ColumnLayout {
Layout.fillWidth: true
- spacing: 2 * scaling
+ spacing: 2
NText {
text: MediaService.trackTitle || "No media"
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightMedium
color: Color.mOnSurface
Layout.fillWidth: true
@@ -580,7 +642,7 @@ Loader {
NText {
text: MediaService.trackArtist || ""
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
Layout.fillWidth: true
elide: Text.ElideRight
@@ -592,46 +654,64 @@ Loader {
Rectangle {
Layout.preferredWidth: 1
Layout.fillHeight: true
- Layout.rightMargin: 4 * scaling
+ Layout.rightMargin: 4
color: Qt.alpha(Color.mOutline, 0.3)
visible: MediaService.currentPlayer && MediaService.canPlay
}
Item {
- Layout.preferredWidth: Style.marginM * scaling
+ Layout.preferredWidth: Style.marginM
visible: !(MediaService.currentPlayer && MediaService.canPlay)
}
// Current weather
RowLayout {
- Layout.preferredWidth: 180 * scaling
- spacing: 8 * scaling
+ Layout.preferredWidth: 180
+ spacing: 8
NIcon {
Layout.alignment: Qt.AlignVCenter
icon: LocationService.weatherSymbolFromCode(LocationService.data.weather.current_weather.weathercode)
- pointSize: Style.fontSizeXXXL * scaling
+ pointSize: Style.fontSizeXXXL
color: Color.mPrimary
}
ColumnLayout {
Layout.fillWidth: true
- spacing: 2 * scaling
+ spacing: 2
RowLayout {
Layout.fillWidth: true
- spacing: 12 * scaling
+ spacing: 12
NText {
- text: Math.round(LocationService.data.weather.current_weather.temperature) + "°"
- pointSize: Style.fontSizeXL * scaling
+ text: {
+ var temp = LocationService.data.weather.current_weather.temperature
+ var suffix = "C"
+ if (Settings.data.location.useFahrenheit) {
+ temp = LocationService.celsiusToFahrenheit(temp)
+ suffix = "F"
+ }
+ temp = Math.round(temp)
+ return temp + "°" + suffix
+ }
+ pointSize: Style.fontSizeXL
font.weight: Style.fontWeightBold
color: Color.mOnSurface
}
NText {
- text: LocationService.data.weather.current_weather.windspeed + " km/h"
- pointSize: Style.fontSizeM * scaling
+ text: {
+ var wind = LocationService.data.weather.current_weather.windspeed
+ var unit = "km/h"
+ if (Settings.data.location.useFahrenheit) {
+ wind = wind * 0.621371 // Convert km/h to mph
+ unit = "mph"
+ }
+ wind = Math.round(wind)
+ return wind + " " + unit
+ }
+ pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
font.weight: Font.Normal
}
@@ -639,17 +719,17 @@ Loader {
RowLayout {
Layout.fillWidth: true
- spacing: 8 * scaling
+ spacing: 8
NText {
text: Settings.data.location.name.split(",")[0]
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
}
NText {
text: (LocationService.data.weather.current && LocationService.data.weather.current.relativehumidity_2m) ? LocationService.data.weather.current.relativehumidity_2m + "% humidity" : ""
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
}
}
@@ -658,19 +738,19 @@ Loader {
// 3-day forecast
RowLayout {
- Layout.preferredWidth: 260 * scaling
- Layout.rightMargin: 8 * scaling
- spacing: 4 * scaling
+ Layout.preferredWidth: 260
+ Layout.rightMargin: 8
+ spacing: 4
Repeater {
model: 3
delegate: ColumnLayout {
Layout.fillWidth: true
- spacing: 3 * scaling
+ spacing: 3
NText {
- text: Qt.locale().toString(new Date(LocationService.data.weather.daily.time[index].replace(/-/g, "/")), "ddd")
- pointSize: Style.fontSizeM * scaling
+ text: Qt.locale().toString(now, "ddd")
+ pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
horizontalAlignment: Text.AlignHCenter
Layout.fillWidth: true
@@ -679,13 +759,23 @@ Loader {
NIcon {
Layout.alignment: Qt.AlignHCenter
icon: LocationService.weatherSymbolFromCode(LocationService.data.weather.daily.weathercode[index])
- pointSize: Style.fontSizeXL * scaling
+ pointSize: Style.fontSizeXL
color: Color.mOnSurfaceVariant
}
NText {
- text: Math.round(LocationService.data.weather.daily.temperature_2m_max[index]) + "°/" + Math.round(LocationService.data.weather.daily.temperature_2m_min[index]) + "°"
- pointSize: Style.fontSizeM * scaling
+ text: {
+ var max = LocationService.data.weather.daily.temperature_2m_max[index]
+ var min = LocationService.data.weather.daily.temperature_2m_min[index]
+ if (Settings.data.location.useFahrenheit) {
+ max = LocationService.celsiusToFahrenheit(max)
+ min = LocationService.celsiusToFahrenheit(min)
+ }
+ max = Math.round(max)
+ min = Math.round(min)
+ return max + "°/" + min + "°"
+ }
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightMedium
color: Color.mOnSurfaceVariant
horizontalAlignment: Text.AlignHCenter
@@ -695,47 +785,50 @@ Loader {
}
}
- // Battery and Keyboard Layout
+ // Battery and Keyboard Layout (full mode only)
ColumnLayout {
- Layout.preferredWidth: 60 * scaling
- spacing: 4 * scaling
+ Layout.preferredWidth: 60
+ spacing: 8
+ // Battery
RowLayout {
- Layout.preferredWidth: 60 * scaling
- Layout.preferredHeight: 22 * scaling
- spacing: 4 * scaling
+ spacing: 4
visible: UPower.displayDevice && UPower.displayDevice.ready && UPower.displayDevice.isPresent
NIcon {
icon: BatteryService.getIcon(Math.round(UPower.displayDevice.percentage * 100), UPower.displayDevice.state === UPowerDeviceState.Charging, true)
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: UPower.displayDevice.state === UPowerDeviceState.Charging ? Color.mPrimary : Color.mOnSurfaceVariant
}
NText {
text: Math.round(UPower.displayDevice.percentage * 100) + "%"
color: Color.mOnSurfaceVariant
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: Font.Medium
+ elide: Text.ElideRight
+ Layout.fillWidth: true
}
}
+ // Keyboard Layout
RowLayout {
- Layout.preferredWidth: 60 * scaling
- Layout.preferredHeight: 22 * scaling
- spacing: 4 * scaling
+ spacing: 4
+ visible: keyboardLayout.currentLayout !== "Unknown"
NIcon {
icon: "keyboard"
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
}
NText {
text: keyboardLayout.currentLayout
color: Color.mOnSurfaceVariant
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: Font.Medium
+ elide: Text.ElideRight
+ Layout.fillWidth: true
}
}
}
@@ -747,26 +840,26 @@ Loader {
spacing: 0
Item {
- Layout.preferredWidth: Style.marginM * scaling
+ Layout.preferredWidth: Style.marginM
}
Rectangle {
Layout.fillWidth: true
- Layout.preferredHeight: 48 * scaling
- radius: 24 * scaling
+ Layout.preferredHeight: 48
+ radius: 24
color: Color.mSurface
border.color: passwordInput.activeFocus ? Color.mPrimary : Qt.alpha(Color.mOutline, 0.3)
border.width: passwordInput.activeFocus ? 2 : 1
Row {
anchors.left: parent.left
- anchors.leftMargin: 18 * scaling
+ anchors.leftMargin: 18
anchors.verticalCenter: parent.verticalCenter
- spacing: 14 * scaling
+ spacing: 14
NIcon {
icon: "lock"
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: passwordInput.activeFocus ? Color.mPrimary : Color.mOnSurfaceVariant
anchors.verticalCenter: parent.verticalCenter
}
@@ -778,7 +871,7 @@ Loader {
height: 0
visible: false
enabled: !lockContext.unlockInProgress
- font.pointSize: Style.fontSizeM * scaling
+ font.pointSize: Style.fontSizeM
color: Color.mPrimary
echoMode: TextInput.Password
passwordCharacter: "•"
@@ -799,8 +892,8 @@ Loader {
spacing: 0
Rectangle {
- width: 2 * scaling
- height: 20 * scaling
+ width: 2
+ height: 20
color: Color.mPrimary
visible: passwordInput.activeFocus && passwordInput.text.length === 0
anchors.verticalCenter: parent.verticalCenter
@@ -820,7 +913,7 @@ Loader {
}
Row {
- spacing: 6 * scaling
+ spacing: 6
visible: passwordInput.text.length > 0
anchors.verticalCenter: parent.verticalCenter
@@ -829,7 +922,7 @@ Loader {
NIcon {
icon: "circle-filled"
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: Color.mPrimary
opacity: 1.0
}
@@ -837,8 +930,8 @@ Loader {
}
Rectangle {
- width: 2 * scaling
- height: 20 * scaling
+ width: 2
+ height: 20
color: Color.mPrimary
visible: passwordInput.activeFocus && passwordInput.text.length > 0
anchors.verticalCenter: parent.verticalCenter
@@ -861,10 +954,10 @@ Loader {
Rectangle {
anchors.right: parent.right
- anchors.rightMargin: 8 * scaling
+ anchors.rightMargin: 8
anchors.verticalCenter: parent.verticalCenter
- width: 36 * scaling
- height: 36 * scaling
+ width: 36
+ height: 36
radius: width * 0.5
color: submitButtonArea.containsMouse ? Color.mPrimary : Qt.alpha(Color.mPrimary, 0.8)
border.color: Color.mPrimary
@@ -874,7 +967,7 @@ Loader {
NIcon {
anchors.centerIn: parent
icon: "arrow-forward"
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: Color.mOnPrimary
}
@@ -895,40 +988,42 @@ Loader {
}
Item {
- Layout.preferredWidth: Style.marginM * scaling
+ Layout.preferredWidth: Style.marginM
}
}
// System control buttons
RowLayout {
Layout.fillWidth: true
- Layout.preferredHeight: 48 * scaling
- spacing: 10 * scaling
+ Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 : 48
+ spacing: 10
Item {
- Layout.preferredWidth: Style.marginM * scaling
+ Layout.preferredWidth: Style.marginM
}
Rectangle {
Layout.fillWidth: true
- Layout.preferredHeight: 48 * scaling
- radius: 24 * scaling
+ Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 : 48
+ radius: Settings.data.general.compactLockScreen ? 18 : 24
color: logoutButtonArea.containsMouse ? Color.mTertiary : "transparent"
+ border.color: Color.mOutline
+ border.width: 1
RowLayout {
anchors.centerIn: parent
- spacing: 6 * scaling
+ spacing: 6
NIcon {
icon: "logout"
- pointSize: Style.fontSizeL * scaling
+ pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeM : Style.fontSizeL
color: logoutButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
}
NText {
text: I18n.tr("session-menu.logout")
color: logoutButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
- pointSize: Style.fontSizeM * scaling
+ pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeS : Style.fontSizeM
font.weight: Font.Medium
}
}
@@ -946,28 +1041,85 @@ Loader {
easing.type: Easing.OutCubic
}
}
+
+ Behavior on border.color {
+ ColorAnimation {
+ duration: 200
+ easing.type: Easing.OutCubic
+ }
+ }
}
Rectangle {
Layout.fillWidth: true
- Layout.preferredHeight: 48 * scaling
- radius: 24 * scaling
- color: rebootButtonArea.containsMouse ? Color.mTertiary : "transparent"
+ Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 : 48
+ radius: Settings.data.general.compactLockScreen ? 18 : 24
+ color: suspendButtonArea.containsMouse ? Color.mTertiary : "transparent"
+ border.color: Color.mOutline
+ border.width: 1
RowLayout {
anchors.centerIn: parent
- spacing: 6 * scaling
+ spacing: 6
+
+ NIcon {
+ icon: "suspend"
+ pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeM : Style.fontSizeL
+ color: suspendButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
+ }
+
+ NText {
+ text: I18n.tr("session-menu.suspend")
+ color: suspendButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
+ pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeS : Style.fontSizeM
+ font.weight: Font.Medium
+ }
+ }
+
+ MouseArea {
+ id: suspendButtonArea
+ anchors.fill: parent
+ hoverEnabled: true
+ onClicked: CompositorService.suspend()
+ }
+
+ Behavior on color {
+ ColorAnimation {
+ duration: 200
+ easing.type: Easing.OutCubic
+ }
+ }
+
+ Behavior on border.color {
+ ColorAnimation {
+ duration: 200
+ easing.type: Easing.OutCubic
+ }
+ }
+ }
+
+ Rectangle {
+ Layout.fillWidth: true
+ Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 : 48
+ radius: Settings.data.general.compactLockScreen ? 18 : 24
+ color: rebootButtonArea.containsMouse ? Color.mTertiary : "transparent"
+ border.color: Color.mOutline
+ border.width: 1
+
+ RowLayout {
+ anchors.centerIn: parent
+ spacing: 6
NIcon {
icon: "reboot"
- pointSize: Style.fontSizeL * scaling
+ pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeM : Style.fontSizeL
color: rebootButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
}
NText {
text: I18n.tr("session-menu.reboot")
color: rebootButtonArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
- pointSize: Style.fontSizeM * scaling
+ pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeS : Style.fontSizeM
font.weight: Font.Medium
}
}
@@ -985,30 +1137,37 @@ Loader {
easing.type: Easing.OutCubic
}
}
+
+ Behavior on border.color {
+ ColorAnimation {
+ duration: 200
+ easing.type: Easing.OutCubic
+ }
+ }
}
Rectangle {
Layout.fillWidth: true
- Layout.preferredHeight: 48 * scaling
- radius: 24 * scaling
+ Layout.preferredHeight: Settings.data.general.compactLockScreen ? 36 : 48
+ radius: Settings.data.general.compactLockScreen ? 18 : 24
color: shutdownButtonArea.containsMouse ? Color.mError : "transparent"
- border.color: shutdownButtonArea.containsMouse ? Color.mError : Color.transparent
+ border.color: shutdownButtonArea.containsMouse ? Color.mError : Color.mOutline
border.width: 1
RowLayout {
anchors.centerIn: parent
- spacing: 6 * scaling
+ spacing: 6
NIcon {
icon: "shutdown"
- pointSize: Style.fontSizeL * scaling
+ pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeM : Style.fontSizeL
color: shutdownButtonArea.containsMouse ? Color.mOnError : Color.mOnSurfaceVariant
}
NText {
text: I18n.tr("session-menu.shutdown")
color: shutdownButtonArea.containsMouse ? Color.mOnError : Color.mOnSurfaceVariant
- pointSize: Style.fontSizeM * scaling
+ pointSize: Settings.data.general.compactLockScreen ? Style.fontSizeS : Style.fontSizeM
font.weight: Font.Medium
}
}
@@ -1036,7 +1195,7 @@ Loader {
}
Item {
- Layout.preferredWidth: Style.marginM * scaling
+ Layout.preferredWidth: Style.marginM
}
}
}
diff --git a/Modules/Notification/Notification.qml b/Modules/Notification/Notification.qml
index b6dd8672..3c97971a 100644
--- a/Modules/Notification/Notification.qml
+++ b/Modules/Notification/Notification.qml
@@ -17,7 +17,6 @@ Variants {
id: root
required property ShellScreen modelData
- property real scaling: ScalingService.getScreenScale(modelData)
// Access the notification model from the service
property ListModel notificationModel: NotificationService.activeList
@@ -42,15 +41,6 @@ Variants {
}
}
- Connections {
- target: ScalingService
- function onScaleChanged(screenName, scale) {
- if (root.modelData && screenName === root.modelData.name) {
- root.scaling = scale
- }
- }
- }
-
sourceComponent: PanelWindow {
screen: modelData
@@ -79,10 +69,10 @@ Variants {
margins.top: {
if (!(anchors.top))
return 0
- var base = Style.marginM * scaling
+ var base = Style.marginM
if (Settings.data.bar.position === "top") {
- var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0
- return (Style.barHeight * scaling) + base + floatExtraV
+ var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL : 0
+ return (Style.barHeight) + base + floatExtraV
}
return base
}
@@ -90,10 +80,10 @@ Variants {
margins.bottom: {
if (!(anchors.bottom))
return 0
- var base = Style.marginM * scaling
+ var base = Style.marginM
if (Settings.data.bar.position === "bottom") {
- var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0
- return (Style.barHeight * scaling) + base + floatExtraV
+ var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL : 0
+ return (Style.barHeight) + base + floatExtraV
}
return base
}
@@ -101,10 +91,10 @@ Variants {
margins.left: {
if (!(anchors.left))
return 0
- var base = Style.marginM * scaling
+ var base = Style.marginM
if (Settings.data.bar.position === "left") {
- var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0
- return (Style.barHeight * scaling) + base + floatExtraH
+ var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
+ return (Style.barHeight) + base + floatExtraH
}
return base
}
@@ -112,15 +102,15 @@ Variants {
margins.right: {
if (!(anchors.right))
return 0
- var base = Style.marginM * scaling
+ var base = Style.marginM
if (Settings.data.bar.position === "right") {
- var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0
- return (Style.barHeight * scaling) + base + floatExtraH
+ var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
+ return (Style.barHeight) + base + floatExtraH
}
return base
}
- implicitWidth: 360 * scaling
+ implicitWidth: 360
implicitHeight: notificationStack.implicitHeight
WlrLayershell.exclusionMode: ExclusionMode.Ignore
@@ -165,10 +155,20 @@ Variants {
anchors.left: parent.isLeft ? parent.left : undefined
anchors.right: parent.isRight ? parent.right : undefined
anchors.horizontalCenter: parent.isCentered ? parent.horizontalCenter : undefined
- spacing: Style.marginS * scaling
- width: 360 * scaling
+ spacing: Style.marginS
+ width: 360
visible: true
+ // Animate when notifications are added/removed
+ Behavior on implicitHeight {
+ SpringAnimation {
+ spring: 2.0
+ damping: 0.4
+ epsilon: 0.01
+ mass: 0.8
+ }
+ }
+
// Multiple notifications display
Repeater {
model: notificationModel
@@ -178,15 +178,14 @@ Variants {
// Store the notification ID and data for reference
property string notificationId: model.id
property var notificationData: model
- property real cardScaling: root.scaling
- Layout.preferredWidth: 360 * cardScaling
- Layout.preferredHeight: notificationLayout.implicitHeight + (Style.marginL * 2 * cardScaling)
+ Layout.preferredWidth: 360
+ Layout.preferredHeight: notificationLayout.implicitHeight + (Style.marginL * 2)
Layout.maximumHeight: Layout.preferredHeight
- radius: Style.radiusL * cardScaling
+ radius: Style.radiusL
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * cardScaling)
+ border.width: Math.max(1, Style.borderS)
color: Color.mSurface
// Optimized progress bar container
@@ -195,7 +194,7 @@ Variants {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
- height: 2 * cardScaling
+ height: 2
color: Color.transparent
// Pre-calculate available width for the progress bar
@@ -243,8 +242,12 @@ Variants {
// Animation properties
property real scaleValue: 0.8
property real opacityValue: 0.0
+ property real slideOffset: 0
property bool isRemoving: false
+ // Staggered animation delay based on index
+ readonly property int animationDelay: index * 100
+
// Right-click to dismiss
MouseArea {
anchors.fill: parent
@@ -256,14 +259,55 @@ Variants {
}
}
- // Scale and fade-in animation
+ // Scale, fade, and slide animation
scale: scaleValue
opacity: opacityValue
+ // Slide animation based on notification position (vertical only for stacking)
+ y: slideOffset
+
+ // Calculate slide direction based on notification location
+ readonly property real slideDistance: 300
+ readonly property real slideInOffset: {
+ // For vertical stacking, always slide from top
+ if (parent.isTop)
+ return -slideDistance
+ if (parent.isBottom)
+ return slideDistance
+ return 0
+ }
+ readonly property real slideOutOffset: {
+ // Slide out in the same direction as slide in
+ if (parent.isTop)
+ return -slideDistance
+ if (parent.isBottom)
+ return slideDistance
+ return 0
+ }
+
// Animate in when the item is created
Component.onCompleted: {
- scaleValue = 1.0
- opacityValue = 1.0
+ // Start from slide position
+ slideOffset = slideInOffset
+ scaleValue = 0.8
+ opacityValue = 0.0
+
+ // Delay animation based on index for staggered effect
+ delayTimer.interval = animationDelay
+ delayTimer.start()
+ }
+
+ // Timer for staggered animation start
+ Timer {
+ id: delayTimer
+ interval: 0
+ repeat: false
+ onTriggered: {
+ // Animate to final position
+ slideOffset = 0
+ scaleValue = 1.0
+ opacityValue = 1.0
+ }
}
// Animate out when being removed
@@ -272,6 +316,7 @@ Variants {
return
// Prevent multiple animations
isRemoving = true
+ slideOffset = slideOutOffset
scaleValue = 0.8
opacityValue = 0.0
}
@@ -293,46 +338,57 @@ Variants {
}
}
- // Animation behaviors
+ // Animation behaviors with spring physics
Behavior on scale {
- NumberAnimation {
- duration: Style.animationNormal
- easing.type: Easing.OutExpo
+ SpringAnimation {
+ spring: 3
+ damping: 0.4
+ epsilon: 0.01
+ mass: 0.8
}
}
Behavior on opacity {
NumberAnimation {
duration: Style.animationNormal
- easing.type: Easing.OutQuad
+ easing.type: Easing.OutCubic
+ }
+ }
+
+ Behavior on y {
+ SpringAnimation {
+ spring: 2.5
+ damping: 0.3
+ epsilon: 0.01
+ mass: 0.6
}
}
ColumnLayout {
id: notificationLayout
anchors.fill: parent
- anchors.margins: Style.marginM * cardScaling
- anchors.rightMargin: (Style.marginM + 32) * cardScaling // Leave space for close button
- spacing: Style.marginM * cardScaling
+ anchors.margins: Style.marginM
+ anchors.rightMargin: (Style.marginM + 32) // Leave space for close button
+ spacing: Style.marginM
// Main content section
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * cardScaling
+ spacing: Style.marginM
ColumnLayout {
// For real-time notification always show the original image
// as the cached version is most likely still processing.
NImageCircled {
- Layout.preferredWidth: 40 * cardScaling
- Layout.preferredHeight: 40 * cardScaling
+ Layout.preferredWidth: Math.round(40 * Style.uiScaleRatio)
+ Layout.preferredHeight: Math.round(40 * Style.uiScaleRatio)
Layout.alignment: Qt.AlignTop
- Layout.topMargin: 30 * cardScaling
+ Layout.topMargin: 30
imagePath: model.originalImage || ""
borderColor: Color.transparent
borderWidth: 0
fallbackIcon: "bell"
- fallbackIconSize: 24 * cardScaling
+ fallbackIconSize: 24
}
Item {
Layout.fillHeight: true
@@ -342,17 +398,17 @@ Variants {
// Text content
ColumnLayout {
Layout.fillWidth: true
- spacing: Style.marginS * cardScaling
+ spacing: Style.marginS
// Header section with app name and timestamp
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginS * cardScaling
+ spacing: Style.marginS
Rectangle {
- Layout.preferredWidth: 6 * cardScaling
- Layout.preferredHeight: 6 * cardScaling
- radius: Style.radiusXS * cardScaling
+ Layout.preferredWidth: 6
+ Layout.preferredHeight: 6
+ radius: Style.radiusXS
color: {
if (model.urgency === NotificationUrgency.Critical || model.urgency === 2)
return Color.mError
@@ -367,7 +423,7 @@ Variants {
NText {
text: `${model.appName || I18n.tr("system.unknown-app")} · ${Time.formatRelativeTime(model.timestamp)}`
color: Color.mSecondary
- pointSize: Style.fontSizeXS * cardScaling
+ pointSize: Style.fontSizeXS
}
Item {
@@ -377,7 +433,7 @@ Variants {
NText {
text: model.summary || I18n.tr("general.no-summary")
- pointSize: Style.fontSizeL * cardScaling
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightMedium
color: Color.mOnSurface
textFormat: Text.PlainText
@@ -390,7 +446,7 @@ Variants {
NText {
text: model.body || ""
- pointSize: Style.fontSizeM * cardScaling
+ pointSize: Style.fontSizeM
color: Color.mOnSurface
textFormat: Text.PlainText
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
@@ -403,8 +459,8 @@ Variants {
// Notification actions
Flow {
Layout.fillWidth: true
- spacing: Style.marginS * cardScaling
- Layout.topMargin: Style.marginM * cardScaling
+ spacing: Style.marginS
+ Layout.topMargin: Style.marginM
flow: Flow.LeftToRight
layoutDirection: Qt.LeftToRight
@@ -436,12 +492,12 @@ Variants {
}
return actionText
}
- fontSize: Style.fontSizeS * cardScaling
+ fontSize: Style.fontSizeS
backgroundColor: Color.mPrimary
textColor: hovered ? Color.mOnTertiary : Color.mOnPrimary
hoverColor: Color.mTertiary
outlined: false
- implicitHeight: 24 * cardScaling
+ implicitHeight: 24
onClicked: {
NotificationService.invokeAction(parent.parentNotificationId, actionData.identifier)
}
@@ -458,9 +514,9 @@ Variants {
tooltipText: I18n.tr("tooltips.close")
baseSize: Style.baseWidgetSize * 0.6
anchors.top: parent.top
- anchors.topMargin: Style.marginM * cardScaling
+ anchors.topMargin: Style.marginM
anchors.right: parent.right
- anchors.rightMargin: Style.marginM * cardScaling
+ anchors.rightMargin: Style.marginM
onClicked: {
animateOut()
diff --git a/Modules/Notification/NotificationHistoryPanel.qml b/Modules/Notification/NotificationHistoryPanel.qml
index bd830f21..8bf5583f 100644
--- a/Modules/Notification/NotificationHistoryPanel.qml
+++ b/Modules/Notification/NotificationHistoryPanel.qml
@@ -26,23 +26,23 @@ NPanel {
ColumnLayout {
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginM
// Header section
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NIcon {
icon: "bell"
- pointSize: Style.fontSizeXXL * scaling
+ pointSize: Style.fontSizeXXL
color: Color.mPrimary
}
NText {
text: I18n.tr("notifications.panel.title")
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: Color.mOnSurface
Layout.fillWidth: true
@@ -84,7 +84,7 @@ NPanel {
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
visible: NotificationService.historyList.count === 0
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Item {
Layout.fillHeight: true
@@ -92,21 +92,21 @@ NPanel {
NIcon {
icon: "bell-off"
- pointSize: 64 * scaling
+ pointSize: 64
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
NText {
text: I18n.tr("notifications.panel.no-notifications")
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
}
NText {
text: I18n.tr("notifications.panel.description")
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
@@ -128,7 +128,7 @@ NPanel {
verticalPolicy: ScrollBar.AsNeeded
model: NotificationService.historyList
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
clip: true
boundsBehavior: Flickable.StopAtBounds
visible: NotificationService.historyList.count > 0
@@ -141,11 +141,11 @@ NPanel {
property bool isExpanded: notificationList.expandedId === notificationId
width: notificationList.width
- height: notificationLayout.implicitHeight + (Style.marginM * scaling * 2)
- radius: Style.radiusM * scaling
+ height: notificationLayout.implicitHeight + (Style.marginM * 2)
+ radius: Style.radiusM
color: Color.mSurfaceVariant
border.color: Qt.alpha(Color.mOutline, Style.opacityMedium)
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
Behavior on height {
NumberAnimation {
@@ -165,7 +165,7 @@ NPanel {
MouseArea {
anchors.fill: parent
// Don't capture clicks on the delete button
- anchors.rightMargin: 48 * scaling
+ anchors.rightMargin: 48
enabled: (summaryText.truncated || bodyText.truncated)
onClicked: {
if (notificationList.expandedId === notificationId) {
@@ -180,20 +180,20 @@ NPanel {
RowLayout {
id: notificationLayout
anchors.fill: parent
- anchors.margins: Style.marginM * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginM
+ spacing: Style.marginM
ColumnLayout {
NImageCircled {
- Layout.preferredWidth: 40 * scaling
- Layout.preferredHeight: 40 * scaling
+ Layout.preferredWidth: Math.round(40 * Style.uiScaleRatio)
+ Layout.preferredHeight: Math.round(40 * Style.uiScaleRatio)
Layout.alignment: Qt.AlignTop
- Layout.topMargin: 20 * scaling
+ Layout.topMargin: 20
imagePath: model.cachedImage || model.originalImage || ""
borderColor: Color.transparent
borderWidth: 0
fallbackIcon: "bell"
- fallbackIconSize: 24 * scaling
+ fallbackIconSize: 24
}
Item {
Layout.fillHeight: true
@@ -204,20 +204,20 @@ NPanel {
ColumnLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignTop
- spacing: Style.marginXS * scaling
- Layout.rightMargin: -(Style.marginM + Style.baseWidgetSize * 0.6) * scaling
+ spacing: Style.marginXS
+ Layout.rightMargin: -(Style.marginM + Style.baseWidgetSize * 0.6)
// Header row with app name and timestamp
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
// Urgency indicator
Rectangle {
- Layout.preferredWidth: 6 * scaling
- Layout.preferredHeight: 6 * scaling
+ Layout.preferredWidth: 6
+ Layout.preferredHeight: 6
Layout.alignment: Qt.AlignVCenter
- radius: 3 * scaling
+ radius: 3
visible: model.urgency !== 1
color: {
if (model.urgency === 2)
@@ -231,13 +231,13 @@ NPanel {
NText {
text: model.appName || "Unknown App"
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mSecondary
}
NText {
text: Time.formatRelativeTime(model.timestamp)
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mSecondary
}
@@ -250,7 +250,7 @@ NPanel {
NText {
id: summaryText
text: model.summary || I18n.tr("general.no-summary")
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: Font.Medium
color: Color.mOnSurface
textFormat: Text.PlainText
@@ -264,7 +264,7 @@ NPanel {
NText {
id: bodyText
text: model.body || ""
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: Color.mOnSurfaceVariant
textFormat: Text.PlainText
wrapMode: Text.Wrap
@@ -277,14 +277,14 @@ NPanel {
// Spacer for expand indicator
Item {
Layout.fillWidth: true
- Layout.preferredHeight: (!isExpanded && (summaryText.truncated || bodyText.truncated)) ? (Style.marginS * scaling) : 0
+ Layout.preferredHeight: (!isExpanded && (summaryText.truncated || bodyText.truncated)) ? (Style.marginS) : 0
}
// Expand indicator
RowLayout {
Layout.fillWidth: true
visible: !isExpanded && (summaryText.truncated || bodyText.truncated)
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
Item {
Layout.fillWidth: true
@@ -292,14 +292,14 @@ NPanel {
NText {
text: I18n.tr("notifications.panel.click-to-expand") || "Click to expand"
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mPrimary
font.weight: Font.Medium
}
NIcon {
icon: "chevron-down"
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: Color.mPrimary
}
}
diff --git a/Modules/OSD/OSD.qml b/Modules/OSD/OSD.qml
index a4ec5701..23c63a0b 100644
--- a/Modules/OSD/OSD.qml
+++ b/Modules/OSD/OSD.qml
@@ -16,7 +16,6 @@ Variants {
id: root
required property ShellScreen modelData
- property real scaling: ScalingService.getScreenScale(modelData)
// Access the notification model from the service
property ListModel notificationModel: NotificationService.activeList
@@ -40,13 +39,9 @@ Variants {
property bool inputMuteInitialized: false
// Brightness properties
+ property real lastUpdatedBrightness: 0
+ readonly property real currentBrightness: lastUpdatedBrightness
property bool brightnessInitialized: false
- readonly property real currentBrightness: {
- if (BrightnessService.monitors.length > 0) {
- return BrightnessService.monitors[0].brightness || 0
- }
- return 0
- }
// Get appropriate icon based on current OSD type
function getIcon() {
@@ -130,20 +125,13 @@ Variants {
readonly property bool isRight: (location.indexOf("_right") >= 0) || (location === "right")
readonly property bool isCentered: (location === "top" || location === "bottom")
readonly property bool verticalMode: (location === "left" || location === "right")
- readonly property int hWidth: Math.round(320 * root.scaling)
- readonly property int hHeight: Math.round(64 * root.scaling)
+ readonly property int hWidth: Math.round(320 * Style.uiScaleRatio)
+ readonly property int hHeight: Math.round(64 * Style.uiScaleRatio)
+ readonly property int vHeight: hWidth // Vertical OSD height (matches horizontal width)
// Ensure an even width to keep the vertical bar perfectly centered
- readonly property int barThickness: (function () {
- const base = Math.max(6, Math.round(6 * root.scaling))
+ readonly property int barThickness: {
+ const base = Math.max(8, Math.round(8 * Style.uiScaleRatio))
return (base % 2 === 0) ? base : base + 1
- })()
-
- Component.onCompleted: {
- connectBrightnessMonitors()
- }
-
- Component.onDestruction: {
- disconnectBrightnessMonitors()
}
// Anchor selection based on location (window edges)
@@ -156,10 +144,10 @@ Variants {
margins.top: {
if (!(anchors.top))
return 0
- var base = Style.marginM * scaling
+ var base = Style.marginM
if (Settings.data.bar.position === "top") {
- var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0
- return (Style.barHeight * scaling) + base + floatExtraV
+ var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL : 0
+ return Style.barHeight + base + floatExtraV
}
return base
}
@@ -167,10 +155,10 @@ Variants {
margins.bottom: {
if (!(anchors.bottom))
return 0
- var base = Style.marginM * scaling
+ var base = Style.marginM
if (Settings.data.bar.position === "bottom") {
- var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0
- return (Style.barHeight * scaling) + base + floatExtraV
+ var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL : 0
+ return Style.barHeight + base + floatExtraV
}
return base
}
@@ -178,10 +166,10 @@ Variants {
margins.left: {
if (!(anchors.left))
return 0
- var base = Style.marginM * scaling
+ var base = Style.marginM
if (Settings.data.bar.position === "left") {
- var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0
- return (Style.barHeight * scaling) + base + floatExtraH
+ var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
+ return Style.barHeight + base + floatExtraH
}
return base
}
@@ -189,10 +177,10 @@ Variants {
margins.right: {
if (!(anchors.right))
return 0
- var base = Style.marginM * scaling
+ var base = Style.marginM
if (Settings.data.bar.position === "right") {
- var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0
- return (Style.barHeight * scaling) + base + floatExtraH
+ var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
+ return Style.barHeight + base + floatExtraH
}
return base
}
@@ -203,26 +191,29 @@ Variants {
color: Color.transparent
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
+ WlrLayershell.layer: (Settings.data.osd && Settings.data.osd.alwaysOnTop) ? WlrLayer.Overlay : WlrLayer.Top
exclusionMode: PanelWindow.ExclusionMode.Ignore
Rectangle {
id: osdItem
width: parent.width
- height: panel.verticalMode ? panel.hWidth : Math.round(64 * root.scaling)
- radius: Style.radiusL * root.scaling
+ height: panel.verticalMode ? panel.vHeight : Math.round(64 * Style.uiScaleRatio)
+ radius: Style.radiusL
color: Color.mSurface
border.color: Color.mOutline
- border.width: (function () {
- const bw = Math.max(2, Math.round(Style.borderM * root.scaling))
+ border.width: {
+ const bw = Math.max(2, Style.borderM)
return (bw % 2 === 0) ? bw : bw + 1
- })()
+ }
visible: false
opacity: 0
- scale: 0.85
+ scale: 0.85 // initial scale for a little zoom effect
- anchors.horizontalCenter: verticalMode ? undefined : parent.horizontalCenter
- anchors.verticalCenter: verticalMode ? parent.verticalCenter : undefined
+ // Only horizontally center when the window itself is centered (top/bottom positions)
+ // For left/right vertical mode, fill the parent width
+ anchors.horizontalCenter: (!panel.verticalMode && panel.isCentered) ? parent.horizontalCenter : undefined
+ anchors.verticalCenter: panel.verticalMode ? parent.verticalCenter : undefined
Behavior on opacity {
NumberAnimation {
@@ -274,13 +265,13 @@ Variants {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
- anchors.margins: Style.marginM * root.scaling
- spacing: Style.marginM * root.scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginM
NIcon {
icon: root.getIcon()
color: root.getIconColor()
- pointSize: Style.fontSizeXL * root.scaling
+ pointSize: Style.fontSizeXL
Layout.alignment: Qt.AlignVCenter
Behavior on color {
@@ -293,7 +284,7 @@ Variants {
// Progress bar with calculated width
Rectangle {
- Layout.preferredWidth: Math.round(220 * root.scaling)
+ Layout.fillWidth: true
height: panel.barThickness
radius: Math.round(panel.barThickness / 2)
color: Color.mSurfaceVariant
@@ -326,12 +317,12 @@ Variants {
NText {
text: root.getDisplayPercentage()
color: Color.mOnSurface
- pointSize: Style.fontSizeS * root.scaling
+ pointSize: Style.fontSizeS
family: Settings.data.ui.fontFixed
- Layout.alignment: Qt.AlignVCenter
- horizontalAlignment: Text.AlignLeft
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
+ horizontalAlignment: Text.AlignRight
verticalAlignment: Text.AlignVCenter
- Layout.preferredWidth: Math.round(50 * root.scaling)
+ Layout.preferredWidth: Math.round(50 * Style.uiScaleRatio)
}
}
}
@@ -339,90 +330,88 @@ Variants {
Component {
id: verticalContent
- ColumnLayout {
- // Ensure inner padding respects the rounded corners; avoid clipping the icon/text
- property int vMargin: (function () {
- const styleMargin = Math.round(Style.marginL * root.scaling)
- const cornerGuard = Math.round(osdItem.radius)
- return Math.max(styleMargin, cornerGuard)
- })()
- property int vMarginTop: Math.max(Math.round(osdItem.radius), Math.round(Style.marginS * root.scaling))
- property int balanceDelta: Math.round(Style.marginS * root.scaling)
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- anchors.topMargin: vMarginTop
- anchors.bottomMargin: vMargin
- width: (function () {
- const w = parent.width - (vMargin * 2)
- return (w % 2 === 0) ? w : w - 1
- })()
- spacing: Math.round(Style.marginS * root.scaling)
+ Item {
+ anchors.fill: parent
- // Percentage text at top
- Item {
- Layout.fillWidth: true
- Layout.preferredHeight: percentText.implicitHeight
- NText {
- id: percentText
- text: root.getDisplayPercentage()
- color: Color.mOnSurface
- pointSize: Style.fontSizeS * root.scaling
- family: Settings.data.ui.fontFixed
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.verticalCenter: parent.verticalCenter
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
+ ColumnLayout {
+ // Ensure inner padding respects the rounded corners; avoid clipping the icon/text
+ property int vMargin: {
+ const styleMargin = Style.marginL
+ const cornerGuard = Math.round(osdItem.radius)
+ return Math.max(styleMargin, cornerGuard)
}
- }
+ property int vMarginTop: Math.round(Math.max(osdItem.radius, Style.marginS))
+ property int balanceDelta: Style.marginS
+ anchors.fill: parent
+ anchors.topMargin: vMargin
+ anchors.bottomMargin: vMargin
+ spacing: Style.marginS
- // Progress bar
- Item {
- Layout.fillWidth: true
- Layout.fillHeight: true
- Rectangle {
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: panel.barThickness
- radius: Math.round(panel.barThickness / 2)
- color: Color.mSurfaceVariant
+ // Percentage text at top
+ Item {
+ Layout.fillWidth: true
+ Layout.preferredHeight: Math.round(20 * Style.uiScaleRatio)
+ NText {
+ id: percentText
+ text: root.getDisplayPercentage()
+ color: Color.mOnSurface
+ pointSize: Style.fontSizeS
+ family: Settings.data.ui.fontFixed
+ width: Math.round(50 * Style.uiScaleRatio)
+ height: parent.height
+ anchors.centerIn: parent
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
+ // Progress bar
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true // Fill remaining space between text and icon
Rectangle {
- anchors.left: parent.left
- anchors.right: parent.right
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
anchors.bottom: parent.bottom
- height: parent.height * Math.min(1.0, root.getCurrentValue())
- radius: parent.radius
- color: root.getProgressColor()
+ width: panel.barThickness
+ radius: Math.round(panel.barThickness / 2)
+ color: Color.mSurfaceVariant
- Behavior on height {
- NumberAnimation {
- duration: Style.animationNormal
- easing.type: Easing.InOutQuad
+ Rectangle {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ height: parent.height * Math.min(1.0, root.getCurrentValue())
+ radius: parent.radius
+ color: root.getProgressColor()
+
+ Behavior on height {
+ NumberAnimation {
+ duration: Style.animationNormal
+ easing.type: Easing.InOutQuad
+ }
}
- }
- Behavior on color {
- ColorAnimation {
- duration: Style.animationNormal
- easing.type: Easing.InOutQuad
+ Behavior on color {
+ ColorAnimation {
+ duration: Style.animationNormal
+ easing.type: Easing.InOutQuad
+ }
}
}
}
}
- }
- // Icon at bottom
- NIcon {
- icon: root.getIcon()
- color: root.getIconColor()
- pointSize: Style.fontSizeXL * root.scaling
- Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
- Layout.bottomMargin: vMargin + Math.round(Style.marginM * root.scaling) + balanceDelta
- Behavior on color {
- ColorAnimation {
- duration: Style.animationNormal
- easing.type: Easing.InOutQuad
+ // Icon at bottom
+ NIcon {
+ icon: root.getIcon()
+ color: root.getIconColor()
+ pointSize: Style.fontSizeL
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
+ Behavior on color {
+ ColorAnimation {
+ duration: Style.animationNormal
+ easing.type: Easing.InOutQuad
+ }
}
}
}
@@ -513,6 +502,8 @@ Variants {
muteInitialized = true
inputVolumeInitialized = true
inputMuteInitialized = true
+ // Don't initialize brightness here - let it initialize on first change like volume
+ connectBrightnessMonitors()
}
}
@@ -542,11 +533,14 @@ Variants {
}
function onBrightnessChanged(newBrightness) {
+ root.lastUpdatedBrightness = newBrightness
+
if (!brightnessInitialized) {
brightnessInitialized = true
- } else {
- showOSD("brightness")
+ return
}
+
+ showOSD("brightness")
}
function showOSD(type) {
diff --git a/Modules/SessionMenu/SessionMenu.qml b/Modules/SessionMenu/SessionMenu.qml
index 039c2c98..034a362c 100644
--- a/Modules/SessionMenu/SessionMenu.qml
+++ b/Modules/SessionMenu/SessionMenu.qml
@@ -13,8 +13,8 @@ import qs.Widgets
NPanel {
id: root
- preferredWidth: 440
- preferredHeight: 480
+ preferredWidth: 380 * Style.uiScaleRatio
+ preferredHeight: 440 * Style.uiScaleRatio
panelAnchorHorizontalCenter: true
panelAnchorVerticalCenter: true
panelKeyboardFocus: true
@@ -259,16 +259,16 @@ NPanel {
ColumnLayout {
anchors.fill: parent
- anchors.topMargin: Style.marginL * scaling
- anchors.leftMargin: Style.marginL * scaling
- anchors.rightMargin: Style.marginL * scaling
- anchors.bottomMargin: Style.marginM * scaling
- spacing: Style.marginS * scaling
+ anchors.topMargin: Style.marginL
+ anchors.leftMargin: Style.marginL
+ anchors.rightMargin: Style.marginL
+ anchors.bottomMargin: Style.marginM
+ spacing: Style.marginS
// Header with title and close button
RowLayout {
Layout.fillWidth: true
- Layout.preferredHeight: Style.baseWidgetSize * 0.8 * scaling
+ Layout.preferredHeight: Style.baseWidgetSize * 0.8
NText {
text: timerActive ? I18n.tr("session-menu.action-in-seconds", {
@@ -276,7 +276,7 @@ NPanel {
"seconds": Math.ceil(timeRemaining / 1000)
}) : I18n.tr("session-menu.title")
font.weight: Style.fontWeightBold
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: timerActive ? Color.mPrimary : Color.mOnSurface
Layout.alignment: Qt.AlignVCenter
verticalAlignment: Text.AlignVCenter
@@ -310,7 +310,7 @@ NPanel {
// Power options
ColumnLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
Repeater {
model: powerOptions
@@ -345,8 +345,8 @@ NPanel {
signal clicked
- height: Style.baseWidgetSize * 1.6 * scaling
- radius: Style.radiusS * scaling
+ height: Style.baseWidgetSize * 1.6 * Style.uiScaleRatio
+ radius: Style.radiusS
color: {
if (pending) {
return Qt.alpha(Color.mPrimary, 0.08)
@@ -357,7 +357,7 @@ NPanel {
return Color.transparent
}
- border.width: pending ? Math.max(Style.borderM * scaling) : 0
+ border.width: pending ? Math.max(Style.borderM) : 0
border.color: pending ? Color.mPrimary : Color.mOutline
Behavior on color {
@@ -368,7 +368,7 @@ NPanel {
Item {
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
+ anchors.margins: Style.marginL
// Icon on the left
NIcon {
@@ -385,8 +385,8 @@ NPanel {
return Color.mOnTertiary
return Color.mOnSurface
}
- pointSize: Style.fontSizeXXXL * scaling
- width: Style.baseWidgetSize * 0.6 * scaling
+ pointSize: Style.fontSizeXXXL
+ width: Style.baseWidgetSize * 0.6
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
@@ -402,14 +402,14 @@ NPanel {
anchors.left: iconElement.right
anchors.right: pendingIndicator.visible ? pendingIndicator.left : parent.right
anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: Style.marginXL * scaling
- anchors.rightMargin: pendingIndicator.visible ? Style.marginM * scaling : 0
+ anchors.leftMargin: Style.marginXL
+ anchors.rightMargin: pendingIndicator.visible ? Style.marginM : 0
spacing: 0
NText {
text: buttonRoot.title
font.weight: Style.fontWeightMedium
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: {
if (buttonRoot.pending)
return Color.mPrimary
@@ -434,7 +434,7 @@ NPanel {
}
return buttonRoot.subtitle
}
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: {
if (buttonRoot.pending)
return Color.mPrimary
@@ -455,8 +455,8 @@ NPanel {
id: pendingIndicator
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
- width: 24 * scaling
- height: 24 * scaling
+ width: 24
+ height: 24
radius: width * 0.5
color: Color.mPrimary
visible: buttonRoot.pending
@@ -464,7 +464,7 @@ NPanel {
NText {
anchors.centerIn: parent
text: Math.ceil(timeRemaining / 1000)
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
font.weight: Style.fontWeightBold
color: Color.mOnPrimary
}
diff --git a/Modules/Settings/Bar/BarWidgetSettingsDialog.qml b/Modules/Settings/Bar/BarWidgetSettingsDialog.qml
index 363a7e63..4b35b7fd 100644
--- a/Modules/Settings/Bar/BarWidgetSettingsDialog.qml
+++ b/Modules/Settings/Bar/BarWidgetSettingsDialog.qml
@@ -19,9 +19,9 @@ Popup {
x: (parent.width - width) * 0.5
y: (parent.height - height) * 0.5
- width: Math.max(content.implicitWidth + padding * 2, 500 * scaling)
+ width: Math.max(content.implicitWidth + padding * 2, 500)
height: content.implicitHeight + padding * 2
- padding: Style.marginXL * scaling
+ padding: Style.marginXL
modal: true
onOpened: {
@@ -42,16 +42,16 @@ Popup {
id: bgRect
color: Color.mSurface
- radius: Style.radiusL * scaling
+ radius: Style.radiusL
border.color: Color.mPrimary
- border.width: Math.max(1, Style.borderM * scaling)
+ border.width: Math.max(1, Style.borderM)
}
contentItem: ColumnLayout {
id: content
width: parent.width
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Title
RowLayout {
@@ -61,7 +61,7 @@ Popup {
text: I18n.tr("system.widget-settings-title", {
"widget": widgetSettings.widgetId
})
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: Color.mPrimary
Layout.fillWidth: true
@@ -91,8 +91,8 @@ Popup {
// Action buttons
RowLayout {
Layout.fillWidth: true
- Layout.topMargin: Style.marginM * scaling
- spacing: Style.marginM * scaling
+ Layout.topMargin: Style.marginM
+ spacing: Style.marginM
Item {
Layout.fillWidth: true
diff --git a/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml b/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml
index 3d1be163..643684dd 100644
--- a/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/ActiveWindowSettings.qml
@@ -7,7 +7,7 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Properties to receive data from parent
property var widgetData: null
@@ -15,25 +15,43 @@ ColumnLayout {
// Local state
property bool valueShowIcon: widgetData.showIcon !== undefined ? widgetData.showIcon : widgetMetadata.showIcon
- property bool valueAutoHide: widgetData.autoHide !== undefined ? widgetData.autoHide : widgetMetadata.autoHide
+ property string valueHideMode: "hidden" // Default to 'Hide When Empty'
property string valueScrollingMode: widgetData.scrollingMode || widgetMetadata.scrollingMode
property int valueWidth: widgetData.width !== undefined ? widgetData.width : widgetMetadata.width
+ property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons
+
+ Component.onCompleted: {
+ if (widgetData && widgetData.hideMode !== undefined) {
+ valueHideMode = widgetData.hideMode
+ }
+ }
function saveSettings() {
var settings = Object.assign({}, widgetData || {})
- settings.autoHide = valueAutoHide
+ settings.hideMode = valueHideMode
settings.showIcon = valueShowIcon
settings.scrollingMode = valueScrollingMode
settings.width = parseInt(widthInput.text) || widgetMetadata.width
+ settings.colorizeIcons = valueColorizeIcons
return settings
}
- NToggle {
+ NComboBox {
Layout.fillWidth: true
- label: I18n.tr("bar.widget-settings.active-window.auto-hide.label")
- description: I18n.tr("bar.widget-settings.active-window.auto-hide.description")
- checked: root.valueAutoHide
- onToggled: checked => root.valueAutoHide = checked
+ label: I18n.tr("bar.widget-settings.active-window.hide-mode.label")
+ description: I18n.tr("bar.widget-settings.active-window.hide-mode.description")
+ model: [{
+ "key": "visible",
+ "name": I18n.tr("options.hide-modes.visible")
+ }, {
+ "key": "hidden",
+ "name": I18n.tr("options.hide-modes.hidden")
+ }, {
+ "key": "transparent",
+ "name": I18n.tr("options.hide-modes.transparent")
+ }]
+ currentKey: root.valueHideMode
+ onSelected: key => root.valueHideMode = key
}
NToggle {
@@ -44,6 +62,14 @@ ColumnLayout {
onToggled: checked => root.valueShowIcon = checked
}
+ NToggle {
+ Layout.fillWidth: true
+ label: I18n.tr("bar.widget-settings.active-window.colorize-icons.label")
+ description: I18n.tr("bar.widget-settings.active-window.colorize-icons.description")
+ checked: root.valueColorizeIcons
+ onToggled: checked => root.valueColorizeIcons = checked
+ }
+
NTextInput {
id: widthInput
Layout.fillWidth: true
@@ -68,6 +94,6 @@ ColumnLayout {
}]
currentKey: valueScrollingMode
onSelected: key => valueScrollingMode = key
- minimumWidth: 200 * scaling
+ minimumWidth: 200
}
}
diff --git a/Modules/Settings/Bar/WidgetSettings/BatterySettings.qml b/Modules/Settings/Bar/WidgetSettings/BatterySettings.qml
index addf7ff8..8377958d 100644
--- a/Modules/Settings/Bar/WidgetSettings/BatterySettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/BatterySettings.qml
@@ -7,7 +7,7 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Properties to receive data from parent
property var widgetData: null
@@ -27,7 +27,7 @@ ColumnLayout {
NComboBox {
label: I18n.tr("bar.widget-settings.battery.display-mode.label")
description: I18n.tr("bar.widget-settings.battery.display-mode.description")
- minimumWidth: 134 * scaling
+ minimumWidth: 134
model: [{
"key": "onhover",
"name": I18n.tr("options.display-mode.on-hover")
diff --git a/Modules/Settings/Bar/WidgetSettings/BrightnessSettings.qml b/Modules/Settings/Bar/WidgetSettings/BrightnessSettings.qml
index c21d7aae..bc572776 100644
--- a/Modules/Settings/Bar/WidgetSettings/BrightnessSettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/BrightnessSettings.qml
@@ -7,7 +7,7 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Properties to receive data from parent
property var widgetData: null
@@ -25,7 +25,7 @@ ColumnLayout {
NComboBox {
label: I18n.tr("bar.widget-settings.brightness.display-mode.label")
description: I18n.tr("bar.widget-settings.brightness.display-mode.description")
- minimumWidth: 134 * scaling
+ minimumWidth: 134
model: [{
"key": "onhover",
"name": I18n.tr("options.display-mode.on-hover")
diff --git a/Modules/Settings/Bar/WidgetSettings/ClockSettings.qml b/Modules/Settings/Bar/WidgetSettings/ClockSettings.qml
index d76c8d48..9729ccce 100644
--- a/Modules/Settings/Bar/WidgetSettings/ClockSettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/ClockSettings.qml
@@ -7,8 +7,8 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
- width: 700 * scaling
+ spacing: Style.marginM
+ width: 700
// Properties to receive data from parent
property var widgetData: null
@@ -89,8 +89,8 @@ ColumnLayout {
currentKey: valueCustomFont
placeholder: I18n.tr("bar.widget-settings.clock.custom-font.placeholder")
searchPlaceholder: I18n.tr("bar.widget-settings.clock.custom-font.search-placeholder")
- popupHeight: 420 * scaling
- minimumWidth: 300 * scaling
+ popupHeight: 420
+ minimumWidth: 300
onSelected: function (key) {
valueCustomFont = key
}
@@ -108,12 +108,12 @@ ColumnLayout {
RowLayout {
id: main
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
ColumnLayout {
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
Layout.fillWidth: true
Layout.preferredWidth: 1 // Equal sizing hint
@@ -175,13 +175,13 @@ ColumnLayout {
}
Rectangle {
- Layout.preferredWidth: 320 * scaling
- Layout.preferredHeight: 160 * scaling // Fixed height instead of fillHeight
+ Layout.preferredWidth: 320
+ Layout.preferredHeight: 160 // Fixed height instead of fillHeight
color: Color.mSurfaceVariant
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
border.color: Color.mSecondary
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
Behavior on border.color {
ColorAnimation {
@@ -190,22 +190,22 @@ ColumnLayout {
}
ColumnLayout {
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
anchors.centerIn: parent
ColumnLayout {
- spacing: -2 * scaling
+ spacing: -2
Layout.alignment: Qt.AlignHCenter
// Horizontal
Repeater {
- Layout.topMargin: Style.marginM * scaling
+ Layout.topMargin: Style.marginM
model: Qt.locale().toString(now, valueFormatHorizontal.trim()).split("\\n")
delegate: NText {
visible: text !== ""
text: modelData
family: valueUseCustomFont && valueCustomFont ? valueCustomFont : Settings.data.ui.fontDefault
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightBold
color: valueUsePrimaryColor ? Color.mPrimary : Color.mOnSurface
wrapMode: Text.WordWrap
@@ -226,17 +226,17 @@ ColumnLayout {
// Vertical
ColumnLayout {
- spacing: -2 * scaling
+ spacing: -2
Layout.alignment: Qt.AlignHCenter
Repeater {
- Layout.topMargin: Style.marginM * scaling
+ Layout.topMargin: Style.marginM
model: Qt.locale().toString(now, valueFormatVertical.trim()).split(" ")
delegate: NText {
visible: text !== ""
text: modelData
family: valueUseCustomFont && valueCustomFont ? valueCustomFont : Settings.data.ui.fontDefault
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightBold
color: valueUsePrimaryColor ? Color.mPrimary : Color.mOnSurface
wrapMode: Text.WordWrap
@@ -256,13 +256,13 @@ ColumnLayout {
}
NDivider {
- Layout.topMargin: Style.marginM * scaling
- Layout.bottomMargin: Style.marginM * scaling
+ Layout.topMargin: Style.marginM
+ Layout.bottomMargin: Style.marginM
}
NDateTimeTokens {
Layout.fillWidth: true
- height: 200 * scaling
+ height: 200
// Connect to token clicked signal if NDateTimeTokens provides it
onTokenClicked: token => root.insertToken(token)
diff --git a/Modules/Settings/Bar/WidgetSettings/ControlCenterSettings.qml b/Modules/Settings/Bar/WidgetSettings/ControlCenterSettings.qml
index ac4ae04c..2c0383e2 100644
--- a/Modules/Settings/Bar/WidgetSettings/ControlCenterSettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/ControlCenterSettings.qml
@@ -8,7 +8,7 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Properties to receive data from parent
property var widgetData: null
@@ -41,7 +41,7 @@ ColumnLayout {
}
RowLayout {
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NLabel {
label: I18n.tr("bar.widget-settings.control-center.icon.label")
@@ -49,23 +49,23 @@ ColumnLayout {
}
NImageCircled {
+ Layout.preferredWidth: Style.fontSizeXL * 2
+ Layout.preferredHeight: Style.fontSizeXL * 2
Layout.alignment: Qt.AlignVCenter
imagePath: valueCustomIconPath
visible: valueCustomIconPath !== ""
- width: Style.fontSizeXL * 2 * scaling
- height: Style.fontSizeXL * 2 * scaling
}
NIcon {
Layout.alignment: Qt.AlignVCenter
icon: valueIcon
- pointSize: Style.fontSizeXXL * 1.5 * scaling
+ pointSize: Style.fontSizeXXL * 1.5
visible: valueIcon !== "" && valueCustomIconPath === ""
}
}
RowLayout {
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NButton {
enabled: !valueUseDistroLogo
text: I18n.tr("bar.widget-settings.control-center.browse-library")
diff --git a/Modules/Settings/Bar/WidgetSettings/CustomButtonSettings.qml b/Modules/Settings/Bar/WidgetSettings/CustomButtonSettings.qml
index 0520740f..c3a6aefe 100644
--- a/Modules/Settings/Bar/WidgetSettings/CustomButtonSettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/CustomButtonSettings.qml
@@ -8,7 +8,7 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
property var widgetData: null
property var widgetMetadata: null
@@ -27,7 +27,7 @@ ColumnLayout {
}
RowLayout {
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NLabel {
label: I18n.tr("bar.widget-settings.custom-button.icon.label")
@@ -37,7 +37,7 @@ ColumnLayout {
NIcon {
Layout.alignment: Qt.AlignVCenter
icon: valueIcon
- pointSize: Style.fontSizeXL * scaling
+ pointSize: Style.fontSizeXL
visible: valueIcon !== ""
}
diff --git a/Modules/Settings/Bar/WidgetSettings/KeyboardLayoutSettings.qml b/Modules/Settings/Bar/WidgetSettings/KeyboardLayoutSettings.qml
index d3551044..86ada35a 100644
--- a/Modules/Settings/Bar/WidgetSettings/KeyboardLayoutSettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/KeyboardLayoutSettings.qml
@@ -7,7 +7,7 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Properties to receive data from parent
property var widgetData: null
@@ -25,7 +25,7 @@ ColumnLayout {
NComboBox {
label: I18n.tr("bar.widget-settings.keyboard-layout.display-mode.label")
description: I18n.tr("bar.widget-settings.keyboard-layout.display-mode.description")
- minimumWidth: 134 * scaling
+ minimumWidth: 134
model: [{
"key": "onhover",
"name": I18n.tr("options.display-mode.on-hover")
diff --git a/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml b/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml
index 184a37e5..1d03c87f 100644
--- a/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/MediaMiniSettings.qml
@@ -7,22 +7,28 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Properties to receive data from parent
property var widgetData: null
property var widgetMetadata: null
// Local state
- property bool valueAutoHide: widgetData.autoHide !== undefined ? widgetData.autoHide : widgetMetadata.autoHide
+ property string valueHideMode: "hidden" // Default to 'Hide When Empty'
property bool valueShowAlbumArt: widgetData.showAlbumArt !== undefined ? widgetData.showAlbumArt : widgetMetadata.showAlbumArt
property bool valueShowVisualizer: widgetData.showVisualizer !== undefined ? widgetData.showVisualizer : widgetMetadata.showVisualizer
property string valueVisualizerType: widgetData.visualizerType || widgetMetadata.visualizerType
property string valueScrollingMode: widgetData.scrollingMode || widgetMetadata.scrollingMode
+ Component.onCompleted: {
+ if (widgetData && widgetData.hideMode !== undefined) {
+ valueHideMode = widgetData.hideMode
+ }
+ }
+
function saveSettings() {
var settings = Object.assign({}, widgetData || {})
- settings.autoHide = valueAutoHide
+ settings.hideMode = valueHideMode
settings.showAlbumArt = valueShowAlbumArt
settings.showVisualizer = valueShowVisualizer
settings.visualizerType = valueVisualizerType
@@ -30,12 +36,22 @@ ColumnLayout {
return settings
}
- NToggle {
+ NComboBox {
Layout.fillWidth: true
- label: I18n.tr("bar.widget-settings.media-mini.auto-hide.label")
- description: I18n.tr("bar.widget-settings.media-mini.auto-hide.description")
- checked: root.valueAutoHide
- onToggled: checked => root.valueAutoHide = checked
+ label: I18n.tr("bar.widget-settings.media-mini.hide-mode.label")
+ description: I18n.tr("bar.widget-settings.media-mini.hide-mode.description")
+ model: [{
+ "key": "visible",
+ "name": I18n.tr("options.hide-modes.visible")
+ }, {
+ "key": "hidden",
+ "name": I18n.tr("options.hide-modes.hidden")
+ }, {
+ "key": "transparent",
+ "name": I18n.tr("options.hide-modes.transparent")
+ }]
+ currentKey: root.valueHideMode
+ onSelected: key => root.valueHideMode = key
}
NToggle {
@@ -68,7 +84,7 @@ ColumnLayout {
}]
currentKey: valueVisualizerType
onSelected: key => valueVisualizerType = key
- minimumWidth: 200 * scaling
+ minimumWidth: 200
}
NComboBox {
@@ -86,6 +102,6 @@ ColumnLayout {
}]
currentKey: valueScrollingMode
onSelected: key => valueScrollingMode = key
- minimumWidth: 200 * scaling
+ minimumWidth: 200
}
}
diff --git a/Modules/Settings/Bar/WidgetSettings/MicrophoneSettings.qml b/Modules/Settings/Bar/WidgetSettings/MicrophoneSettings.qml
index 5091474d..e62ac1da 100644
--- a/Modules/Settings/Bar/WidgetSettings/MicrophoneSettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/MicrophoneSettings.qml
@@ -7,7 +7,7 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Properties to receive data from parent
property var widgetData: null
@@ -25,7 +25,7 @@ ColumnLayout {
NComboBox {
label: I18n.tr("bar.widget-settings.microphone.display-mode.label")
description: I18n.tr("bar.widget-settings.microphone.display-mode.description")
- minimumWidth: 134 * scaling
+ minimumWidth: 134
model: [{
"key": "onhover",
"name": I18n.tr("options.display-mode.on-hover")
diff --git a/Modules/Settings/Bar/WidgetSettings/NotificationHistorySettings.qml b/Modules/Settings/Bar/WidgetSettings/NotificationHistorySettings.qml
index 4510a605..61c4e10d 100644
--- a/Modules/Settings/Bar/WidgetSettings/NotificationHistorySettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/NotificationHistorySettings.qml
@@ -7,7 +7,7 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Properties to receive data from parent
property var widgetData: null
diff --git a/Modules/Settings/Bar/WidgetSettings/SpacerSettings.qml b/Modules/Settings/Bar/WidgetSettings/SpacerSettings.qml
index 7c6b8b17..9679c619 100644
--- a/Modules/Settings/Bar/WidgetSettings/SpacerSettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/SpacerSettings.qml
@@ -7,7 +7,7 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Properties to receive data from parent
property var widgetData: null
diff --git a/Modules/Settings/Bar/WidgetSettings/SystemMonitorSettings.qml b/Modules/Settings/Bar/WidgetSettings/SystemMonitorSettings.qml
index 852ea8d8..8133ab18 100644
--- a/Modules/Settings/Bar/WidgetSettings/SystemMonitorSettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/SystemMonitorSettings.qml
@@ -7,7 +7,7 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Properties to receive data from parent
property var widgetData: null
diff --git a/Modules/Settings/Bar/WidgetSettings/TaskbarSettings.qml b/Modules/Settings/Bar/WidgetSettings/TaskbarSettings.qml
index c80dd09f..e98c0eaa 100644
--- a/Modules/Settings/Bar/WidgetSettings/TaskbarSettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/TaskbarSettings.qml
@@ -7,7 +7,7 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Properties to receive data from parent
property var widgetData: null
@@ -16,11 +16,13 @@ ColumnLayout {
// Local state
property bool valueOnlyActiveWorkspaces: widgetData.onlyActiveWorkspaces !== undefined ? widgetData.onlyActiveWorkspaces : widgetMetadata.onlyActiveWorkspaces
property bool valueOnlySameOutput: widgetData.onlySameOutput !== undefined ? widgetData.onlySameOutput : widgetMetadata.onlySameOutput
+ property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons
function saveSettings() {
var settings = Object.assign({}, widgetData || {})
settings.onlySameOutput = valueOnlySameOutput
settings.onlyActiveWorkspaces = valueOnlyActiveWorkspaces
+ settings.colorizeIcons = valueColorizeIcons
return settings
}
@@ -39,4 +41,12 @@ ColumnLayout {
checked: root.valueOnlyActiveWorkspaces
onToggled: checked => root.valueOnlyActiveWorkspaces = checked
}
+
+ NToggle {
+ Layout.fillWidth: true
+ label: I18n.tr("bar.widget-settings.taskbar.colorize-icons.label")
+ description: I18n.tr("bar.widget-settings.taskbar.colorize-icons.description")
+ checked: root.valueColorizeIcons
+ onToggled: checked => root.valueColorizeIcons = checked
+ }
}
diff --git a/Modules/Settings/Bar/WidgetSettings/TraySettings.qml b/Modules/Settings/Bar/WidgetSettings/TraySettings.qml
index 25d08bce..a9a41243 100644
--- a/Modules/Settings/Bar/WidgetSettings/TraySettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/TraySettings.qml
@@ -5,12 +5,14 @@ import qs.Commons
import qs.Widgets
ColumnLayout {
+ id: root
// Properties to receive data from parent
property var widgetData: ({}) // Expected by BarWidgetSettingsDialog
property var widgetMetadata: ({}) // Expected by BarWidgetSettingsDialog
- // Local state for the blacklist
+ // Local state
property var localBlacklist: widgetData.blacklist || []
+ property bool valueColorizeIcons: widgetData.colorizeIcons !== undefined ? widgetData.colorizeIcons : widgetMetadata.colorizeIcons
ListModel {
id: blacklistModel
@@ -25,11 +27,19 @@ ColumnLayout {
}
}
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
+
+ NToggle {
+ Layout.fillWidth: true
+ label: I18n.tr("bar.widget-settings.tray.colorize-icons.label")
+ description: I18n.tr("bar.widget-settings.tray.colorize-icons.description")
+ checked: root.valueColorizeIcons
+ onToggled: checked => root.valueColorizeIcons = checked
+ }
ColumnLayout {
Layout.fillWidth: true
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
NLabel {
label: I18n.tr("settings.bar.tray.blacklist.label")
@@ -38,7 +48,7 @@ ColumnLayout {
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
NTextInput {
id: newRuleInput
@@ -49,7 +59,7 @@ ColumnLayout {
NIconButton {
Layout.alignment: Qt.AlignVCenter
icon: "add"
- baseSize: Style.baseWidgetSize * 0.8 * scaling
+ baseSize: Style.baseWidgetSize * 0.8
onClicked: {
if (newRuleInput.text.length > 0) {
var newRule = newRuleInput.text.trim()
@@ -76,30 +86,30 @@ ColumnLayout {
// List of current blacklist items
ListView {
Layout.fillWidth: true
- Layout.preferredHeight: 150 * scaling
- Layout.topMargin: Style.marginL * scaling // Increased top margin
+ Layout.preferredHeight: 150
+ Layout.topMargin: Style.marginL // Increased top margin
clip: true
model: blacklistModel
delegate: Item {
width: ListView.width
- height: 40 * scaling
+ height: 40
Rectangle {
id: itemBackground
anchors.fill: parent
- anchors.margins: Style.marginXS * scaling
+ anchors.margins: Style.marginXS
color: Color.transparent // Make background transparent
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
- radius: Style.radiusS * scaling
+ border.width: Math.max(1, Style.borderS)
+ radius: Style.radiusS
visible: model.rule !== undefined && model.rule !== "" // Only visible if rule exists
}
Row {
anchors.fill: parent
- anchors.leftMargin: Style.marginS * scaling
- anchors.rightMargin: Style.marginS * scaling
- spacing: Style.marginS * scaling
+ anchors.leftMargin: Style.marginS
+ anchors.rightMargin: Style.marginS
+ spacing: Style.marginS
NText {
text: model.rule
@@ -109,10 +119,10 @@ ColumnLayout {
}
NIconButton {
- width: 16 * scaling
- height: 16 * scaling
+ width: 16
+ height: 16
icon: "close"
- baseSize: 8 * scaling
+ baseSize: 8
colorBg: Color.mSurfaceVariant
colorFg: Color.mOnSurface
colorBgHover: Color.mError
@@ -135,6 +145,7 @@ ColumnLayout {
// Return the updated settings for this widget instance
var settings = Object.assign({}, widgetData || {})
settings.blacklist = newBlacklist
+ settings.colorizeIcons = root.valueColorizeIcons
return settings
}
}
diff --git a/Modules/Settings/Bar/WidgetSettings/VolumeSettings.qml b/Modules/Settings/Bar/WidgetSettings/VolumeSettings.qml
index 2781f4a6..3b131d38 100644
--- a/Modules/Settings/Bar/WidgetSettings/VolumeSettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/VolumeSettings.qml
@@ -7,7 +7,7 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Properties to receive data from parent
property var widgetData: null
@@ -25,7 +25,7 @@ ColumnLayout {
NComboBox {
label: I18n.tr("bar.widget-settings.volume.display-mode.label")
description: I18n.tr("bar.widget-settings.volume.display-mode.description")
- minimumWidth: 134 * scaling
+ minimumWidth: 134
model: [{
"key": "onhover",
"name": I18n.tr("options.display-mode.on-hover")
diff --git a/Modules/Settings/Bar/WidgetSettings/WorkspaceSettings.qml b/Modules/Settings/Bar/WidgetSettings/WorkspaceSettings.qml
index b44f16b9..fb63a593 100644
--- a/Modules/Settings/Bar/WidgetSettings/WorkspaceSettings.qml
+++ b/Modules/Settings/Bar/WidgetSettings/WorkspaceSettings.qml
@@ -7,7 +7,7 @@ import qs.Services
ColumnLayout {
id: root
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Properties to receive data from parent
property var widgetData: null
@@ -37,7 +37,7 @@ ColumnLayout {
}]
currentKey: widgetData.labelMode || widgetMetadata.labelMode
onSelected: key => labelModeCombo.currentKey = key
- minimumWidth: 200 * scaling
+ minimumWidth: 200
}
NToggle {
diff --git a/Modules/Settings/Extras/SectionEditor.qml b/Modules/Settings/Extras/SectionEditor.qml
index af5a8380..f6d2ef4a 100644
--- a/Modules/Settings/Extras/SectionEditor.qml
+++ b/Modules/Settings/Extras/SectionEditor.qml
@@ -13,12 +13,14 @@ NBox {
property string sectionId: ""
property var widgetModel: []
property var availableWidgets: []
- property bool enableMoveBetweenSections: true
+ property var availableSections: ["left", "center", "right"]
+ property int maxWidgets: -1 // -1 means unlimited
property var widgetRegistry: null
property string settingsDialogComponent: "BarWidgetSettingsDialog.qml"
readonly property real miniButtonSize: Style.baseWidgetSize * 0.65
+ readonly property bool isAtMaxCapacity: maxWidgets > 0 && widgetModel.length >= maxWidgets
signal addWidget(string widgetId, string section)
signal removeWidget(string section, int index)
@@ -31,16 +33,26 @@ NBox {
color: Color.mSurface
Layout.fillWidth: true
Layout.minimumHeight: {
- var widgetCount = widgetModel.length
- if (widgetCount === 0)
- return 140 * scaling
+ // header + minimal content area
+ var absoluteMin = (Style.marginL * 2) + (Style.fontSizeL * 2) + Style.marginM + (65 * Style.uiScaleRatio)
- var availableWidth = parent.width
- var avgWidgetWidth = 150 * scaling
+ var widgetCount = widgetModel.length
+ if (widgetCount === 0) {
+ return absoluteMin
+ }
+
+ // Calculate rows based on estimated widget layout
+ var availableWidth = parent.width - (Style.marginL * 2)
+ var avgWidgetWidth = 120 * Style.uiScaleRatio // More accurate estimate
var widgetsPerRow = Math.max(1, Math.floor(availableWidth / avgWidgetWidth))
var rows = Math.ceil(widgetCount / widgetsPerRow)
- return (50 + 20 + (rows * 48) + ((rows - 1) * Style.marginS) + 20) * scaling
+ // Header height + spacing + (rows * widget height) + (spacing between rows) + margins
+ var headerHeight = Style.fontSizeL * 2
+ var widgetHeight = Style.baseWidgetSize * 1.15 * Style.uiScaleRatio
+ var widgetAreaHeight = ((rows + 1) * widgetHeight) + ((rows - 1) * Style.marginS)
+
+ return Math.max(absoluteMin, (Style.marginL * 2) + headerHeight + Style.marginM + widgetAreaHeight)
}
// Generate widget color from name checksum
@@ -66,23 +78,34 @@ NBox {
ColumnLayout {
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginM
RowLayout {
Layout.fillWidth: true
NText {
- text: sectionName + " Section"
- pointSize: Style.fontSizeL * scaling
+ text: sectionName
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: Color.mOnSurface
Layout.alignment: Qt.AlignVCenter
}
+ // Widget count indicator (when max is set)
+ NText {
+ visible: root.maxWidgets > 0
+ text: "(" + widgetModel.length + "/" + root.maxWidgets + ")"
+ pointSize: Style.fontSizeS
+ color: root.isAtMaxCapacity ? Color.mError : Color.mOnSurfaceVariant
+ Layout.alignment: Qt.AlignVCenter
+ Layout.leftMargin: Style.marginXS
+ }
+
Item {
Layout.fillWidth: true
}
+
NSearchableComboBox {
id: comboBox
model: availableWidgets
@@ -91,8 +114,9 @@ NBox {
placeholder: I18n.tr("bar.widget-settings.section-editor.placeholder")
searchPlaceholder: I18n.tr("bar.widget-settings.section-editor.search-placeholder")
onSelected: key => comboBox.currentKey = key
- popupHeight: 340 * scaling
- minimumWidth: 200 * scaling
+ popupHeight: 300 * Style.uiScaleRatio
+ minimumWidth: 200 * Style.uiScaleRatio
+ enabled: !root.isAtMaxCapacity
Layout.alignment: Qt.AlignVCenter
@@ -114,12 +138,12 @@ NBox {
colorFg: Color.mOnPrimary
colorBgHover: Color.mSecondary
colorFgHover: Color.mOnSecondary
- enabled: comboBox.currentKey !== ""
- tooltipText: I18n.tr("tooltips.add-widget")
+ enabled: comboBox.currentKey !== "" && !root.isAtMaxCapacity
+ tooltipText: root.isAtMaxCapacity ? I18n.tr("tooltips.max-widgets-reached") : I18n.tr("tooltips.add-widget")
Layout.alignment: Qt.AlignVCenter
- Layout.leftMargin: Style.marginS * scaling
+ Layout.leftMargin: Style.marginS
onClicked: {
- if (comboBox.currentKey !== "") {
+ if (comboBox.currentKey !== "" && !root.isAtMaxCapacity) {
addWidget(comboBox.currentKey, sectionId)
comboBox.currentKey = ""
}
@@ -131,13 +155,13 @@ NBox {
Item {
Layout.fillWidth: true
Layout.fillHeight: true
- Layout.minimumHeight: 65 * scaling
+ Layout.minimumHeight: 65 * Style.uiScaleRatio
clip: false // Don't clip children so ghost can move freely
Flow {
id: widgetFlow
anchors.fill: parent
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
flow: Flow.LeftToRight
Repeater {
@@ -148,16 +172,16 @@ NBox {
required property int index
required property var modelData
- width: widgetContent.implicitWidth + Style.marginL * scaling
- height: Style.baseWidgetSize * 1.15 * scaling
- radius: Style.radiusL * scaling
+ width: widgetContent.implicitWidth + Style.marginL
+ height: Style.baseWidgetSize * 1.15 * Style.uiScaleRatio
+ radius: Style.radiusL
color: root.getWidgetColor(modelData)[0]
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
// Store the widget index for drag operations
property int widgetIndex: index
- readonly property int buttonsWidth: Math.round(20 * scaling)
+ readonly property int buttonsWidth: Math.round(20)
readonly property int buttonsCount: 1 + (root.widgetRegistry ? root.widgetRegistry.widgetHasUserSettings(modelData.id) : 0)
// Visual feedback during drag
@@ -180,22 +204,22 @@ NBox {
NContextMenu {
id: contextMenu
parent: Overlay.overlay
- width: 240 * scaling
+ width: 240 * Style.uiScaleRatio
model: [{
"label": I18n.tr("tooltips.move-to-left-section"),
"action": "left",
"icon": "arrow-bar-to-left",
- "visible": root.sectionId !== "left"
+ "visible": root.availableSections.includes("left") && root.sectionId !== "left"
}, {
"label": I18n.tr("tooltips.move-to-center-section"),
"action": "center",
"icon": "layout-columns",
- "visible": root.sectionId !== "center"
+ "visible": root.availableSections.includes("center") && root.sectionId !== "center"
}, {
"label": I18n.tr("tooltips.move-to-right-section"),
"action": "right",
"icon": "arrow-bar-to-right",
- "visible": root.sectionId !== "right"
+ "visible": root.availableSections.includes("right") && root.sectionId !== "right"
}]
onTriggered: action => root.moveWidget(root.sectionId, index, action)
@@ -204,7 +228,7 @@ NBox {
// MouseArea for the context menu
MouseArea {
id: contextMouseArea
- enabled: enableMoveBetweenSections
+ enabled: root.availableSections.length > 1 // Enable if there are other sections to move to
anchors.fill: parent
acceptedButtons: Qt.RightButton
z: -1 // Below the buttons but above background
@@ -223,20 +247,20 @@ NBox {
RowLayout {
id: widgetContent
anchors.centerIn: parent
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
NText {
text: modelData.id
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeXS
color: root.getWidgetColor(modelData)[1]
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
- Layout.preferredWidth: 80 * scaling
+ Layout.preferredWidth: 60 * Style.uiScaleRatio
}
RowLayout {
spacing: 0
- Layout.preferredWidth: buttonsCount * buttonsWidth
+ Layout.preferredWidth: buttonsCount * buttonsWidth * Style.uiScaleRatio
Loader {
active: root.widgetRegistry && root.widgetRegistry.widgetHasUserSettings(modelData.id)
@@ -261,19 +285,19 @@ NBox {
if (dialog) {
dialog.open()
} else {
- Logger.error("WidgetSectionEditor", "Failed to create settings dialog instance")
+ Logger.error("SectionEditor", "Failed to create settings dialog instance")
}
}
if (component.status === Component.Ready) {
instantiateAndOpen()
} else if (component.status === Component.Error) {
- Logger.error("WidgetSectionEditor", component.errorString())
+ Logger.error("SectionEditor", component.errorString())
} else {
component.statusChanged.connect(function () {
if (component.status === Component.Ready) {
instantiateAndOpen()
} else if (component.status === Component.Error) {
- Logger.error("WidgetSectionEditor", component.errorString())
+ Logger.error("SectionEditor", component.errorString())
}
})
}
@@ -304,11 +328,11 @@ NBox {
Rectangle {
id: dragGhost
width: 0
- height: Style.baseWidgetSize * 1.15 * scaling
- radius: Style.radiusL * scaling
+ height: Style.baseWidgetSize * 1.15
+ radius: Style.radiusL
color: Color.transparent
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
opacity: 0.7
visible: flowDragArea.dragStarted
z: 2000
@@ -317,7 +341,7 @@ NBox {
NText {
id: ghostText
anchors.centerIn: parent
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: Color.mOnPrimary
}
}
@@ -325,8 +349,8 @@ NBox {
// Drop indicator - visual feedback for where the widget will be inserted
Rectangle {
id: dropIndicator
- width: 3 * scaling
- height: Style.baseWidgetSize * 1.15 * scaling
+ width: 3
+ height: Style.baseWidgetSize * 1.15
radius: width / 2
color: Color.mPrimary
opacity: 0
@@ -378,7 +402,7 @@ NBox {
property bool dragStarted: false
property bool potentialDrag: false // Track if we're in a potential drag interaction
property int draggedIndex: -1
- property real dragThreshold: 15 * scaling
+ property real dragThreshold: 15
property Item draggedWidget: null
property int dropTargetIndex: -1
property var draggedModelData: null
@@ -413,13 +437,13 @@ NBox {
if (leftDist < minDistance) {
minDistance = leftDist
bestIndex = i
- bestPosition = Qt.point(widget.x - dropIndicator.width / 2 - Style.marginXS * scaling, widget.y)
+ bestPosition = Qt.point(widget.x - dropIndicator.width / 2 - Style.marginXS, widget.y)
}
if (rightDist < minDistance) {
minDistance = rightDist
bestIndex = i + 1
- bestPosition = Qt.point(widget.x + widget.width + Style.marginXS * scaling - dropIndicator.width / 2, widget.y)
+ bestPosition = Qt.point(widget.x + widget.width + Style.marginXS - dropIndicator.width / 2, widget.y)
}
}
@@ -431,13 +455,13 @@ NBox {
if (dist < minDistance && mouseX < firstWidget.x + firstWidget.width / 2) {
minDistance = dist
bestIndex = 0
- bestPosition = Qt.point(Math.max(0, firstWidget.x - dropIndicator.width - Style.marginS * scaling), firstWidget.y)
+ bestPosition = Qt.point(Math.max(0, firstWidget.x - dropIndicator.width - Style.marginS), firstWidget.y)
}
}
}
// Only show indicator if we're close enough and it's a different position
- if (minDistance < 80 * scaling && bestIndex !== -1) {
+ if (minDistance < 80 && bestIndex !== -1) {
// Adjust index if we're moving forward
let adjustedIndex = bestIndex
if (bestIndex > draggedIndex) {
diff --git a/Modules/Settings/SettingsPanel.qml b/Modules/Settings/SettingsPanel.qml
index ff499cfe..e5b64566 100644
--- a/Modules/Settings/SettingsPanel.qml
+++ b/Modules/Settings/SettingsPanel.qml
@@ -11,14 +11,11 @@ import qs.Widgets
NPanel {
id: root
- preferredWidth: 1000
- preferredHeight: 1000
- preferredWidthRatio: 0.4
- preferredHeightRatio: 0.75
+ preferredWidth: 820 * Style.uiScaleRatio
+ preferredHeight: 940 * Style.uiScaleRatio
panelAnchorHorizontalCenter: true
panelAnchorVerticalCenter: true
-
panelKeyboardFocus: true
draggable: !PanelService.hasOpenedPopup
@@ -40,6 +37,7 @@ NPanel {
Network,
Notifications,
ScreenRecorder,
+ UserInterface,
Wallpaper
}
@@ -116,7 +114,10 @@ NPanel {
id: controlCenterTab
ControlCenterTab {}
}
-
+ Component {
+ id: userInterfaceTab
+ UserInterfaceTab {}
+ }
// Order *DOES* matter
function updateTabsModel() {
let newTabs = [{
@@ -124,18 +125,22 @@ NPanel {
"label": "settings.general.title",
"icon": "settings-general",
"source": generalTab
+ }, {
+ "id": SettingsPanel.Tab.UserInterface,
+ "label": "settings.user-interface.title",
+ "icon": "settings-user-interface",
+ "source": userInterfaceTab
}, {
"id": SettingsPanel.Tab.Bar,
"label": "settings.bar.title",
"icon": "settings-bar",
"source": barTab
- }, //{
- // "id": SettingsPanel.Tab.ControlCenter,
- // "label": "settings.control-center.title",
- // "icon": "settings-bar",
- // "source": controlCenterTab
- //},
- {
+ }, {
+ "id": SettingsPanel.Tab.ControlCenter,
+ "label": "settings.control-center.title",
+ "icon": "settings-control-center",
+ "source": controlCenterTab
+ }, {
"id": SettingsPanel.Tab.Dock,
"label": "settings.dock.title",
"icon": "settings-dock",
@@ -273,7 +278,7 @@ NPanel {
// Main layout container that fills the panel
ColumnLayout {
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
+ anchors.margins: Style.marginL
spacing: 0
// Keyboard shortcuts container
@@ -336,18 +341,18 @@ NPanel {
RowLayout {
Layout.fillWidth: true
Layout.fillHeight: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginL
// Sidebar
Rectangle {
id: sidebar
- Layout.preferredWidth: 220 * scaling
+ Layout.preferredWidth: 220 * Style.uiScaleRatio
Layout.fillHeight: true
Layout.alignment: Qt.AlignTop
color: Color.mSurfaceVariant
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
- radius: Style.radiusM * scaling
+ border.width: Math.max(1, Style.borderS)
+ radius: Style.radiusM
MouseArea {
anchors.fill: parent
@@ -368,8 +373,8 @@ NPanel {
ColumnLayout {
anchors.fill: parent
- anchors.margins: Style.marginS * scaling
- spacing: Style.marginXS * scaling
+ anchors.margins: Style.marginS
+ spacing: Style.marginXS
Repeater {
id: sections
@@ -377,8 +382,8 @@ NPanel {
delegate: Rectangle {
id: tabItem
Layout.fillWidth: true
- Layout.preferredHeight: tabEntryRow.implicitHeight + Style.marginS * scaling * 2
- radius: Style.radiusS * scaling
+ Layout.preferredHeight: tabEntryRow.implicitHeight + Style.marginM * 2
+ radius: Style.radiusS
color: selected ? Color.mPrimary : (tabItem.hovering ? Color.mTertiary : Color.transparent)
readonly property bool selected: index === currentTabIndex
property bool hovering: false
@@ -399,22 +404,22 @@ NPanel {
RowLayout {
id: tabEntryRow
anchors.fill: parent
- anchors.leftMargin: Style.marginS * scaling
- anchors.rightMargin: Style.marginS * scaling
- spacing: Style.marginM * scaling
+ anchors.leftMargin: Style.marginS
+ anchors.rightMargin: Style.marginS
+ spacing: Style.marginM
// Tab icon
NIcon {
icon: modelData.icon
color: tabTextColor
- pointSize: Style.fontSizeXL * scaling
+ pointSize: Style.fontSizeXL
}
// Tab label
NText {
text: I18n.tr(modelData.label)
color: tabTextColor
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightBold
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
@@ -445,34 +450,34 @@ NPanel {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignTop
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
color: Color.mSurfaceVariant
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
ColumnLayout {
id: contentLayout
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
- spacing: Style.marginS * scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginS
// Header row
RowLayout {
id: headerRow
Layout.fillWidth: true
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
// Main icon
NIcon {
icon: root.tabsModel[currentTabIndex]?.icon
color: Color.mPrimary
- pointSize: Style.fontSizeXXL * scaling
+ pointSize: Style.fontSizeXXL
}
// Main title
NText {
text: I18n.tr(root.tabsModel[currentTabIndex]?.label) || ""
- pointSize: Style.fontSizeXL * scaling
+ pointSize: Style.fontSizeXL
font.weight: Style.fontWeightBold
color: Color.mPrimary
Layout.fillWidth: true
@@ -527,7 +532,7 @@ NPanel {
anchors.fill: parent
horizontalPolicy: ScrollBar.AlwaysOff
verticalPolicy: ScrollBar.AsNeeded
- padding: Style.marginL * scaling
+ padding: Style.marginL
Component.onCompleted: {
root.activeScrollView = scrollView
}
diff --git a/Modules/Settings/Tabs/AboutTab.qml b/Modules/Settings/Tabs/AboutTab.qml
index 6e226e1b..1faf3a53 100644
--- a/Modules/Settings/Tabs/AboutTab.qml
+++ b/Modules/Settings/Tabs/AboutTab.qml
@@ -15,7 +15,7 @@ ColumnLayout {
property string currentVersion: UpdateService.currentVersion
property var contributors: GitHubService.contributors
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
NHeader {
label: I18n.tr("settings.about.noctalia.section.label")
@@ -23,13 +23,13 @@ ColumnLayout {
}
RowLayout {
- spacing: Style.marginXL * scaling
+ spacing: Style.marginXL
// Versions
GridLayout {
columns: 2
- rowSpacing: Style.marginXS * scaling
- columnSpacing: Style.marginS * scaling
+ rowSpacing: Style.marginXS
+ columnSpacing: Style.marginS
NText {
text: I18n.tr("settings.about.noctalia.latest-version")
@@ -76,17 +76,66 @@ ColumnLayout {
icon: "download"
text: I18n.tr("settings.about.noctalia.download-latest")
outlined: !hovered
- fontSize: Style.fontSizeXS * scaling
+ fontSize: Style.fontSizeXS
onClicked: {
Quickshell.execDetached(["xdg-open", "https://github.com/Ly-sec/Noctalia/releases/latest"])
}
}
}
+ // Ko-fi support button
+ Rectangle {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.topMargin: Style.marginM
+ Layout.bottomMargin: Style.marginM
+ width: supportRow.implicitWidth + Style.marginXL
+ height: supportRow.implicitHeight + Style.marginM
+ radius: Style.radiusS
+ color: supportArea.containsMouse ? Qt.alpha(Color.mOnSurface, 0.05) : Color.transparent
+ border.width: 0
+
+ Behavior on color {
+ ColorAnimation {
+ duration: Style.animationFast
+ }
+ }
+
+ RowLayout {
+ id: supportRow
+ anchors.centerIn: parent
+ spacing: Style.marginS
+
+ NText {
+ text: I18n.tr("settings.about.support")
+ pointSize: Style.fontSizeXS
+ color: Color.mOnSurface
+ opacity: supportArea.containsMouse ? Style.opacityFull : Style.opacityMedium
+ }
+
+ NIcon {
+ icon: supportArea.containsMouse ? "heart-filled" : "heart"
+ pointSize: 14
+ color: Color.mOnSurface
+ opacity: supportArea.containsMouse ? Style.opacityFull : Style.opacityMedium
+ }
+ }
+
+ MouseArea {
+ id: supportArea
+ anchors.fill: parent
+ hoverEnabled: true
+ cursorShape: Qt.PointingHandCursor
+ onClicked: {
+ Quickshell.execDetached(["xdg-open", "https://ko-fi.com/lysec"])
+ ToastService.showNotice(I18n.tr("settings.about.support"), I18n.tr("toast.kofi.opened"), 3000)
+ }
+ }
+ }
+
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXXXL
+ Layout.bottomMargin: Style.marginXL
}
// Contributors
@@ -101,23 +150,26 @@ ColumnLayout {
GridView {
id: contributorsGrid
+
+ readonly property int columnsCount: 2
+
Layout.alignment: Qt.AlignHCenter
- Layout.preferredWidth: cellWidth * 3 // Fixed 3 columns
+ Layout.preferredWidth: cellWidth * columnsCount
Layout.preferredHeight: {
if (root.contributors.length === 0)
return 0
- const columns = 3
- const rows = Math.ceil(root.contributors.length / columns)
+
+ const rows = Math.ceil(root.contributors.length / columnsCount)
return rows * cellHeight
}
- cellWidth: Style.baseWidgetSize * 7 * scaling
- cellHeight: Style.baseWidgetSize * 3 * scaling
+ cellWidth: Math.round(Style.baseWidgetSize * 7)
+ cellHeight: Math.round(Style.baseWidgetSize * 2.5)
model: root.contributors
delegate: Rectangle {
- width: contributorsGrid.cellWidth - Style.marginM * scaling
- height: contributorsGrid.cellHeight - Style.marginM * scaling
- radius: Style.radiusL * scaling
+ width: contributorsGrid.cellWidth - Style.marginM
+ height: contributorsGrid.cellHeight - Style.marginM
+ radius: Style.radiusL
color: contributorArea.containsMouse ? Color.mTertiary : Color.transparent
Behavior on color {
@@ -128,21 +180,21 @@ ColumnLayout {
RowLayout {
anchors.fill: parent
- anchors.margins: Style.marginS * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginS
+ spacing: Style.marginM
Item {
Layout.alignment: Qt.AlignVCenter
- Layout.preferredWidth: Style.baseWidgetSize * 2 * scaling
- Layout.preferredHeight: Style.baseWidgetSize * 2 * scaling
+ Layout.preferredWidth: Style.baseWidgetSize * 2 * Style.uiScaleRatio
+ Layout.preferredHeight: Style.baseWidgetSize * 2 * Style.uiScaleRatio
NImageCircled {
imagePath: modelData.avatar_url || ""
anchors.fill: parent
- anchors.margins: Style.marginXS * scaling
+ anchors.margins: Style.marginXS
fallbackIcon: "person"
borderColor: contributorArea.containsMouse ? Color.mOnTertiary : Color.mPrimary
- borderWidth: Math.max(1, Style.borderM * scaling)
+ borderWidth: Math.max(1, Style.borderM)
Behavior on borderColor {
ColorAnimation {
@@ -153,7 +205,7 @@ ColumnLayout {
}
ColumnLayout {
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
Layout.alignment: Qt.AlignVCenter
Layout.fillWidth: true
@@ -167,8 +219,8 @@ ColumnLayout {
NText {
text: (modelData.contributions || 0) + " " + ((modelData.contributions || 0) === 1 ? "commit" : "commits")
- pointSize: Style.fontSizeXS * scaling
- color: contributorArea.containsMouse ? Color.mOnTertiary : Color.mOnSurface
+ pointSize: Style.fontSizeXS
+ color: contributorArea.containsMouse ? Color.mOnTertiary : Color.mOnSurfaceVariant
}
}
}
@@ -186,8 +238,4 @@ ColumnLayout {
}
}
}
-
- Item {
- Layout.fillHeight: true
- }
}
diff --git a/Modules/Settings/Tabs/AudioTab.qml b/Modules/Settings/Tabs/AudioTab.qml
index e4f70407..ef73bbdd 100644
--- a/Modules/Settings/Tabs/AudioTab.qml
+++ b/Modules/Settings/Tabs/AudioTab.qml
@@ -8,7 +8,7 @@ import qs.Widgets
ColumnLayout {
id: root
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
NHeader {
label: I18n.tr("settings.audio.volumes.section.label")
@@ -26,7 +26,7 @@ ColumnLayout {
// Master Volume
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
NLabel {
@@ -61,7 +61,7 @@ ColumnLayout {
// Mute Toggle
ColumnLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
Layout.fillWidth: true
NToggle {
@@ -78,7 +78,7 @@ ColumnLayout {
// Input Volume
ColumnLayout {
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
Layout.fillWidth: true
NLabel {
@@ -99,7 +99,7 @@ ColumnLayout {
// Input Mute Toggle
ColumnLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
Layout.fillWidth: true
NToggle {
@@ -112,7 +112,7 @@ ColumnLayout {
// Volume Step Size
ColumnLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
Layout.fillWidth: true
NSpinBox {
@@ -130,7 +130,7 @@ ColumnLayout {
// Raise maximum volume above 100%
ColumnLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
Layout.fillWidth: true
NToggle {
@@ -143,13 +143,13 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// AudioService Devices
ColumnLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
Layout.fillWidth: true
NHeader {
@@ -164,9 +164,9 @@ ColumnLayout {
}
ColumnLayout {
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
Layout.fillWidth: true
- Layout.bottomMargin: Style.marginL * scaling
+ Layout.bottomMargin: Style.marginL
NLabel {
label: I18n.tr("settings.audio.devices.output-device.label")
@@ -196,7 +196,7 @@ ColumnLayout {
}
ColumnLayout {
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
Layout.fillWidth: true
NLabel {
@@ -222,13 +222,13 @@ ColumnLayout {
// Divider
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Media Player Preferences
ColumnLayout {
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
NHeader {
label: I18n.tr("settings.audio.media.section.label")
@@ -249,11 +249,11 @@ ColumnLayout {
// Blacklist editor
ColumnLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
Layout.fillWidth: true
RowLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
Layout.fillWidth: true
NTextInput {
@@ -267,7 +267,7 @@ ColumnLayout {
NIconButton {
icon: "add"
Layout.alignment: Qt.AlignBottom
- Layout.bottomMargin: blacklistInput.description ? Style.marginS * scaling : 0
+ Layout.bottomMargin: blacklistInput.description ? Style.marginS : 0
onClicked: {
const val = (blacklistInput.text || "").trim()
if (val !== "") {
@@ -285,40 +285,40 @@ ColumnLayout {
// Current blacklist entries
Flow {
Layout.fillWidth: true
- Layout.leftMargin: Style.marginS * scaling
- spacing: Style.marginS * scaling
+ Layout.leftMargin: Style.marginS
+ spacing: Style.marginS
Repeater {
model: Settings.data.audio.mprisBlacklist
delegate: Rectangle {
required property string modelData
// Padding around the inner row
- property real pad: Style.marginS * scaling
+ property real pad: Style.marginS
// Visuals
color: Qt.alpha(Color.mOnSurface, 0.125)
border.color: Qt.alpha(Color.mOnSurface, Style.opacityLight)
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
// Content
RowLayout {
id: chipRow
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
anchors.fill: parent
anchors.margins: pad
NText {
text: modelData
color: Color.mOnSurface
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
Layout.alignment: Qt.AlignVCenter
- Layout.leftMargin: Style.marginS * scaling
+ Layout.leftMargin: Style.marginS
}
NIconButton {
icon: "close"
baseSize: Style.baseWidgetSize * 0.8
Layout.alignment: Qt.AlignVCenter
- Layout.rightMargin: Style.marginXS * scaling
+ Layout.rightMargin: Style.marginXS
onClicked: {
const arr = (Settings.data.audio.mprisBlacklist || [])
const idx = arr.findIndex(x => String(x) === modelData)
@@ -333,8 +333,8 @@ ColumnLayout {
// Intrinsic size derived from inner row + padding
implicitWidth: chipRow.implicitWidth + pad * 2
- implicitHeight: Math.max(chipRow.implicitHeight + pad * 2, Style.baseWidgetSize * 0.8 * scaling)
- radius: Style.radiusM * scaling
+ implicitHeight: Math.max(chipRow.implicitHeight + pad * 2, Style.baseWidgetSize * 0.8)
+ radius: Style.radiusM
}
}
}
@@ -407,7 +407,7 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
}
diff --git a/Modules/Settings/Tabs/BarTab.qml b/Modules/Settings/Tabs/BarTab.qml
index 272740f3..e8fb026e 100644
--- a/Modules/Settings/Tabs/BarTab.qml
+++ b/Modules/Settings/Tabs/BarTab.qml
@@ -9,7 +9,7 @@ import qs.Modules.Settings.Extras
ColumnLayout {
id: root
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
// Helper functions to update arrays immutably
function addMonitor(list, name) {
@@ -71,6 +71,9 @@ ColumnLayout {
label: I18n.tr("settings.bar.appearance.density.label")
description: I18n.tr("settings.bar.appearance.density.description")
model: [{
+ "key": "mini",
+ "name": I18n.tr("options.bar.density.mini")
+ }, {
"key": "compact",
"name": I18n.tr("options.bar.density.compact")
}, {
@@ -84,26 +87,6 @@ ColumnLayout {
onSelected: key => Settings.data.bar.density = key
}
- ColumnLayout {
- spacing: Style.marginXXS * scaling
- Layout.fillWidth: true
-
- NLabel {
- label: I18n.tr("settings.bar.appearance.background-opacity.label")
- description: I18n.tr("settings.bar.appearance.background-opacity.description")
- }
-
- NValueSlider {
- Layout.fillWidth: true
- from: 0
- to: 1
- stepSize: 0.01
- value: Settings.data.bar.backgroundOpacity
- onMoved: value => Settings.data.bar.backgroundOpacity = value
- text: Math.floor(Settings.data.bar.backgroundOpacity * 100) + "%"
- }
- }
-
NToggle {
Layout.fillWidth: true
label: I18n.tr("settings.bar.appearance.show-capsule.label")
@@ -131,7 +114,7 @@ ColumnLayout {
// Floating bar options - only show when floating is enabled
ColumnLayout {
visible: Settings.data.bar.floating
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
Layout.fillWidth: true
NLabel {
@@ -141,14 +124,14 @@ ColumnLayout {
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
NText {
text: I18n.tr("settings.bar.appearance.margins.vertical")
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mOnSurfaceVariant
}
@@ -164,11 +147,11 @@ ColumnLayout {
}
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
NText {
text: I18n.tr("settings.bar.appearance.margins.horizontal")
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mOnSurfaceVariant
}
@@ -185,15 +168,35 @@ ColumnLayout {
}
}
+ ColumnLayout {
+ spacing: Style.marginXXS
+ Layout.fillWidth: true
+
+ NLabel {
+ label: I18n.tr("settings.bar.appearance.background-opacity.label")
+ description: I18n.tr("settings.bar.appearance.background-opacity.description")
+ }
+
+ NValueSlider {
+ Layout.fillWidth: true
+ from: 0
+ to: 1
+ stepSize: 0.01
+ value: Settings.data.bar.backgroundOpacity
+ onMoved: value => Settings.data.bar.backgroundOpacity = value
+ text: Math.floor(Settings.data.bar.backgroundOpacity * 100) + "%"
+ }
+ }
+
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Widgets Management Section
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
NHeader {
@@ -205,8 +208,8 @@ ColumnLayout {
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
- Layout.topMargin: Style.marginM * scaling
- spacing: Style.marginM * scaling
+ Layout.topMargin: Style.marginM
+ spacing: Style.marginM
// Left Section
SectionEditor {
@@ -263,13 +266,13 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Monitor Configuration
ColumnLayout {
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
Layout.fillWidth: true
NHeader {
@@ -282,11 +285,15 @@ ColumnLayout {
delegate: NCheckbox {
Layout.fillWidth: true
label: modelData.name || "Unknown"
- description: I18n.tr("system.monitor-description", {
- "model": modelData.model,
- "width": modelData.width,
- "height": modelData.height
- })
+ description: {
+ const compositorScale = CompositorService.getDisplayScale(modelData.name)
+ I18n.tr("system.monitor-description", {
+ "model": modelData.model,
+ "width": modelData.width * compositorScale,
+ "height": modelData.height * compositorScale,
+ "scale": compositorScale
+ })
+ }
checked: (Settings.data.bar.monitors || []).indexOf(modelData.name) !== -1
onToggled: checked => {
if (checked) {
@@ -301,8 +308,8 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// ---------------------------------
diff --git a/Modules/Settings/Tabs/ColorSchemeTab.qml b/Modules/Settings/Tabs/ColorSchemeTab.qml
index a5c66ead..b38d521e 100644
--- a/Modules/Settings/Tabs/ColorSchemeTab.qml
+++ b/Modules/Settings/Tabs/ColorSchemeTab.qml
@@ -13,7 +13,7 @@ ColumnLayout {
property var schemeColorsCache: ({})
property int cacheVersion: 0 // Increment to trigger UI updates
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
// Helper function to extract scheme name from path
function extractSchemeName(schemePath) {
@@ -211,14 +211,14 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
visible: !Settings.data.colorSchemes.useWallpaperColors
}
// Predefined Color Schemes
ColumnLayout {
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
Layout.fillWidth: true
visible: !Settings.data.colorSchemes.useWallpaperColors
@@ -230,8 +230,8 @@ ColumnLayout {
// Color Schemes Grid
GridLayout {
columns: 3
- rowSpacing: Style.marginM * scaling
- columnSpacing: Style.marginM * scaling
+ rowSpacing: Style.marginM
+ columnSpacing: Style.marginM
Layout.fillWidth: true
Repeater {
@@ -245,10 +245,10 @@ ColumnLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
- height: 50 * scaling
- radius: Style.radiusS * scaling
+ height: 50
+ radius: Style.radiusS
color: root.getSchemeColor(schemeName, "mSurface")
- border.width: Math.max(1, Style.borderL * scaling)
+ border.width: Math.max(1, Style.borderL)
border.color: {
if (Settings.data.colorSchemes.predefinedScheme === schemeName) {
return Color.mSecondary
@@ -261,12 +261,12 @@ ColumnLayout {
RowLayout {
anchors.fill: parent
- anchors.margins: Style.marginM * scaling
- spacing: Style.marginXS * scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginXS
NText {
text: schemeItem.schemeName
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
font.weight: Style.fontWeightMedium
color: Color.mOnSurface
Layout.fillWidth: true
@@ -277,29 +277,29 @@ ColumnLayout {
}
Rectangle {
- width: 14 * scaling
- height: 14 * scaling
+ width: 14
+ height: 14
radius: width * 0.5
color: root.getSchemeColor(schemeItem.schemeName, "mPrimary")
}
Rectangle {
- width: 14 * scaling
- height: 14 * scaling
+ width: 14
+ height: 14
radius: width * 0.5
color: root.getSchemeColor(schemeItem.schemeName, "mSecondary")
}
Rectangle {
- width: 14 * scaling
- height: 14 * scaling
+ width: 14
+ height: 14
radius: width * 0.5
color: root.getSchemeColor(schemeItem.schemeName, "mTertiary")
}
Rectangle {
- width: 14 * scaling
- height: 14 * scaling
+ width: 14
+ height: 14
radius: width * 0.5
color: root.getSchemeColor(schemeItem.schemeName, "mError")
}
@@ -324,18 +324,18 @@ ColumnLayout {
visible: (Settings.data.colorSchemes.predefinedScheme === schemeItem.schemeName)
anchors.right: parent.right
anchors.top: parent.top
- anchors.rightMargin: -3 * scaling
- anchors.topMargin: -3 * scaling
- width: 20 * scaling
- height: 20 * scaling
+ anchors.rightMargin: -3
+ anchors.topMargin: -3
+ width: 20
+ height: 20
radius: width * 0.5
color: Color.mSecondary
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
border.color: Color.mOnSecondary
NIcon {
icon: "check"
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
font.weight: Style.fontWeightBold
color: Color.mOnSecondary
anchors.centerIn: parent
@@ -363,20 +363,20 @@ ColumnLayout {
ColorSchemeService.applyScheme(Settings.data.colorSchemes.predefinedScheme)
}
}
- Layout.topMargin: Style.marginL * scaling
+ Layout.topMargin: Style.marginL
}
}
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Template toggles organized by category
ColumnLayout {
Layout.fillWidth: true
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
NHeader {
label: I18n.tr("settings.color-scheme.templates.section.label")
@@ -536,7 +536,7 @@ ColumnLayout {
visible: ProgramCheckerService.availableDiscordClients.length === 0
text: I18n.tr("settings.color-scheme.templates.programs.discord.description-missing")
color: Color.mOnSurfaceVariant
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
}
NCheckbox {
diff --git a/Modules/Settings/Tabs/ControlCenterTab.qml b/Modules/Settings/Tabs/ControlCenterTab.qml
index a880334c..f2212806 100644
--- a/Modules/Settings/Tabs/ControlCenterTab.qml
+++ b/Modules/Settings/Tabs/ControlCenterTab.qml
@@ -9,7 +9,35 @@ import qs.Modules.Settings.Extras
ColumnLayout {
id: root
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
+
+ property list cardsModel: []
+ property list cardsDefault: [{
+ "id": "profile-card",
+ "text": "Profile",
+ "enabled": true,
+ "required": true
+ }, {
+ "id": "shortcuts-card",
+ "text": "Shortcuts",
+ "enabled": true,
+ "required": false
+ }, {
+ "id": "audio-card",
+ "text": "Audio Sliders",
+ "enabled": true,
+ "required": false
+ }, {
+ "id": "weather-card",
+ "text": "Weather",
+ "enabled": true,
+ "required": false
+ }, {
+ "id": "media-sysmon-card",
+ "text": "Media and System Monitor",
+ "enabled": true,
+ "required": false
+ }]
// Handler for drag start - disables panel background clicks
function handleDragStart() {
@@ -27,74 +55,205 @@ ColumnLayout {
}
}
- // Quick Settings Style Section
+ function saveCards() {
+ var toSave = []
+ for (var i = 0; i < cardsModel.length; i++) {
+ toSave.push({
+ "id": cardsModel[i].id,
+ "enabled": cardsModel[i].enabled
+ })
+ }
+ Settings.data.controlCenter.cards = toSave
+ }
+
+ Component.onCompleted: {
+ // Fill out availableWidgets ListModel
+ availableWidgets.clear()
+ ControlCenterWidgetRegistry.getAvailableWidgets().forEach(entry => {
+ availableWidgets.append({
+ "key": entry,
+ "name": entry
+ })
+ })
+ // Starts empty
+ cardsModel = []
+
+ // Add the cards available in settings
+ for (var i = 0; i < Settings.data.controlCenter.cards.length; i++) {
+ const settingCard = Settings.data.controlCenter.cards[i]
+
+ for (var j = 0; j < cardsDefault.length; j++) {
+ if (settingCard.id === cardsDefault[j].id) {
+ var card = cardsDefault[j]
+ card.enabled = settingCard.enabled
+ cardsModel.push(card)
+ }
+ }
+ }
+
+ // Add any missing cards from default
+ for (var i = 0; i < cardsDefault.length; i++) {
+ var found = false
+ for (var j = 0; j < cardsModel.length; j++) {
+ if (cardsModel[j].id === cardsDefault[i].id) {
+ found = true
+ break
+ }
+ }
+
+ if (!found) {
+ cardsModel.push(cardsDefault[i])
+ }
+ }
+
+ saveCards()
+ }
+
ColumnLayout {
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NHeader {
- label: I18n.tr("settings.control-center.quickSettingsStyle.section.label")
- description: I18n.tr("settings.control-center.quickSettingsStyle.section.description")
+ label: I18n.tr("settings.control-center.section.label")
+ description: I18n.tr("settings.control-center.section.description")
}
NComboBox {
- id: quickSettingsStyle
- label: I18n.tr("settings.control-center.quickSettingsStyle.style.label")
- description: I18n.tr("settings.control-center.quickSettingsStyle.style.description")
+ id: controlCenterPosition
+ label: I18n.tr("settings.control-center.position.label")
+ description: I18n.tr("settings.control-center.position.description")
Layout.fillWidth: true
model: [{
- "key": "compact",
- "name": I18n.tr("options.control-center.quickSettingsStyle.compact")
+ "key": "close_to_bar_button",
+ "name": I18n.tr("options.control-center.position.close_to_bar_button")
}, {
- "key": "classic",
- "name": I18n.tr("options.control-center.quickSettingsStyle.classic")
+ "key": "top_left",
+ "name": I18n.tr("options.control-center.position.top_left")
}, {
- "key": "modern",
- "name": I18n.tr("options.control-center.quickSettingsStyle.modern")
+ "key": "top_right",
+ "name": I18n.tr("options.control-center.position.top_right")
+ }, {
+ "key": "bottom_left",
+ "name": I18n.tr("options.control-center.position.bottom_left")
+ }, {
+ "key": "bottom_right",
+ "name": I18n.tr("options.control-center.position.bottom_right")
+ }, {
+ "key": "bottom_center",
+ "name": I18n.tr("options.control-center.position.bottom_center")
+ }, {
+ "key": "top_center",
+ "name": I18n.tr("options.control-center.position.top_center")
}]
- currentKey: Settings.data.controlCenter.quickSettingsStyle || "compact"
+ currentKey: Settings.data.controlCenter.position
onSelected: function (key) {
- Settings.data.controlCenter.quickSettingsStyle = key
+ Settings.data.controlCenter.position = key
}
}
}
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Widgets Management Section
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
NHeader {
- label: I18n.tr("settings.control-center.widgets.section.label")
- description: I18n.tr("settings.control-center.widgets.section.description")
+ label: I18n.tr("settings.control-center.cards.section.label")
+ description: I18n.tr("settings.control-center.cards.section.description")
}
- // Bar Sections
+ NReorderCheckboxes {
+ Layout.fillWidth: true
+ model: cardsModel
+ onDragPotentialStarted: {
+ root.handleDragStart()
+ }
+ onDragPotentialEnded: {
+ root.handleDragEnd()
+ }
+ onItemToggled: function (index, enabled) {
+ //Logger.log("ControlCenterTab", "Item", index, "toggled to", enabled)
+ var newModel = cardsModel.slice()
+ newModel[index] = Object.assign({}, newModel[index], {
+ "enabled": enabled
+ })
+ cardsModel = newModel
+ saveCards()
+ }
+ onItemsReordered: function (fromIndex, toIndex) {
+ //Logger.log("ControlCenterTab", "Item moved from", fromIndex, "to", toIndex)
+ var newModel = cardsModel.slice()
+ var item = newModel.splice(fromIndex, 1)[0]
+ newModel.splice(toIndex, 0, item)
+ cardsModel = newModel
+ saveCards()
+ }
+ }
+ }
+
+ NDivider {
+ Layout.fillWidth: true
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
+ }
+
+ // Widgets Management Section
+ ColumnLayout {
+ spacing: Style.marginXXS
+ Layout.fillWidth: true
+
+ NHeader {
+ label: I18n.tr("settings.control-center.shortcuts.section.label")
+ description: I18n.tr("settings.control-center.shortcuts.section.description")
+ }
+
+ // Sections
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
- Layout.topMargin: Style.marginM * scaling
- spacing: Style.marginM * scaling
+ Layout.topMargin: Style.marginM
+ spacing: Style.marginM
- // Quick Settings
+ // Left
SectionEditor {
- sectionName: I18n.tr("settings.control-center.quickSettings.sectionName")
- sectionId: "quickSettings"
+ sectionName: I18n.tr("settings.control-center.shortcuts.sectionLeft")
+ sectionId: "left"
settingsDialogComponent: ""
+ maxWidgets: 5
widgetRegistry: ControlCenterWidgetRegistry
- widgetModel: Settings.data.controlCenter.widgets["quickSettings"]
+ widgetModel: Settings.data.controlCenter.shortcuts["left"]
availableWidgets: availableWidgets
- enableMoveBetweenSections: false
+ availableSections: ["left", "right"]
onAddWidget: (widgetId, section) => _addWidgetToSection(widgetId, section)
onRemoveWidget: (section, index) => _removeWidgetFromSection(section, index)
onReorderWidget: (section, fromIndex, toIndex) => _reorderWidgetInSection(section, fromIndex, toIndex)
onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsInSection(section, index, settings)
+ onMoveWidget: (fromSection, index, toSection) => _moveWidgetBetweenSections(fromSection, index, toSection)
+ onDragPotentialStarted: root.handleDragStart()
+ onDragPotentialEnded: root.handleDragEnd()
+ }
+
+ // Right
+ SectionEditor {
+ sectionName: I18n.tr("settings.control-center.shortcuts.sectionRight")
+ sectionId: "right"
+ settingsDialogComponent: ""
+ maxWidgets: 5
+ widgetRegistry: ControlCenterWidgetRegistry
+ widgetModel: Settings.data.controlCenter.shortcuts["right"]
+ availableWidgets: availableWidgets
+ availableSections: ["left", "right"]
+ onAddWidget: (widgetId, section) => _addWidgetToSection(widgetId, section)
+ onRemoveWidget: (section, index) => _removeWidgetFromSection(section, index)
+ onReorderWidget: (section, fromIndex, toIndex) => _reorderWidgetInSection(section, fromIndex, toIndex)
+ onUpdateWidgetSettings: (section, index, settings) => _updateWidgetSettingsInSection(section, index, settings)
+ onMoveWidget: (fromSection, index, toSection) => _moveWidgetBetweenSections(fromSection, index, toSection)
onDragPotentialStarted: root.handleDragStart()
onDragPotentialEnded: root.handleDragEnd()
}
@@ -103,8 +262,8 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// ---------------------------------
@@ -124,55 +283,56 @@ ColumnLayout {
})
}
}
- Settings.data.controlCenter.widgets[section].push(newWidget)
+ Settings.data.controlCenter.shortcuts[section].push(newWidget)
}
function _removeWidgetFromSection(section, index) {
- if (index >= 0 && index < Settings.data.controlCenter.widgets[section].length) {
- var newArray = Settings.data.controlCenter.widgets[section].slice()
+ if (index >= 0 && index < Settings.data.controlCenter.shortcuts[section].length) {
+ var newArray = Settings.data.controlCenter.shortcuts[section].slice()
var removedWidgets = newArray.splice(index, 1)
- Settings.data.controlCenter.widgets[section] = newArray
-
- // Check that we still have a control center
- if (removedWidgets[0].id === "ControlCenter" && BarService.lookupWidget("ControlCenter") === undefined) {
- ToastService.showWarning(I18n.tr("toast.missing-control-center.label"), I18n.tr("toast.missing-control-center.description"), 12000)
- }
+ Settings.data.controlCenter.shortcuts[section] = newArray
}
}
function _reorderWidgetInSection(section, fromIndex, toIndex) {
- if (fromIndex >= 0 && fromIndex < Settings.data.controlCenter.widgets[section].length && toIndex >= 0 && toIndex < Settings.data.controlCenter.widgets[section].length) {
+ if (fromIndex >= 0 && fromIndex < Settings.data.controlCenter.shortcuts[section].length && toIndex >= 0 && toIndex < Settings.data.controlCenter.shortcuts[section].length) {
// Create a new array to avoid modifying the original
- var newArray = Settings.data.controlCenter.widgets[section].slice()
+ var newArray = Settings.data.controlCenter.shortcuts[section].slice()
var item = newArray[fromIndex]
newArray.splice(fromIndex, 1)
newArray.splice(toIndex, 0, item)
- Settings.data.controlCenter.widgets[section] = newArray
- //Logger.log("BarTab", "Widget reordered. New array:", JSON.stringify(newArray))
+ Settings.data.controlCenter.shortcuts[section] = newArray
+ }
+ }
+
+ function _moveWidgetBetweenSections(fromSection, index, toSection) {
+ // Get the widget from the source section
+ if (index >= 0 && index < Settings.data.controlCenter.shortcuts[fromSection].length) {
+ var widget = Settings.data.controlCenter.shortcuts[fromSection][index]
+
+ // Remove from source section
+ var sourceArray = Settings.data.controlCenter.shortcuts[fromSection].slice()
+ sourceArray.splice(index, 1)
+ Settings.data.controlCenter.shortcuts[fromSection] = sourceArray
+
+ // Add to target section
+ var targetArray = Settings.data.controlCenter.shortcuts[toSection].slice()
+ targetArray.push(widget)
+ Settings.data.controlCenter.shortcuts[toSection] = targetArray
+
+ //Logger.log("BarTab", `Moved widget ${widget.id} from ${fromSection} to ${toSection}`)
}
}
function _updateWidgetSettingsInSection(section, index, settings) {
// Update the widget settings in the Settings data
- Settings.data.controlCenter.widgets[section][index] = settings
- //Logger.log("BarTab", `Updated widget settings for ${settings.id} in ${section} section`)
+ Settings.data.controlCenter.shortcuts[section][index] = settings
}
// Base list model for all combo boxes
ListModel {
id: availableWidgets
}
-
- Component.onCompleted: {
- // Fill out availableWidgets ListModel
- availableWidgets.clear()
- ControlCenterWidgetRegistry.getAvailableWidgets().forEach(entry => {
- availableWidgets.append({
- "key": entry,
- "name": entry
- })
- })
- }
}
diff --git a/Modules/Settings/Tabs/DisplayTab.qml b/Modules/Settings/Tabs/DisplayTab.qml
index 6eed0a7b..d1823fa1 100644
--- a/Modules/Settings/Tabs/DisplayTab.qml
+++ b/Modules/Settings/Tabs/DisplayTab.qml
@@ -49,7 +49,7 @@ ColumnLayout {
stderr: StdioCollector {}
}
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
NHeader {
label: I18n.tr("settings.display.monitors.section.label")
@@ -57,36 +57,26 @@ ColumnLayout {
}
ColumnLayout {
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Repeater {
model: Quickshell.screens || []
delegate: Rectangle {
Layout.fillWidth: true
- implicitHeight: contentCol.implicitHeight + Style.marginL * 2 * scaling
- radius: Style.radiusM * scaling
+ implicitHeight: contentCol.implicitHeight + Style.marginL * 2
+ radius: Style.radiusM
color: Color.mSurfaceVariant
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
- property real localScaling: ScalingService.getScreenScale(modelData)
property var brightnessMonitor: BrightnessService.getMonitorForScreen(modelData)
- Connections {
- target: ScalingService
- function onScaleChanged(screenName, scale) {
- if (screenName === modelData.name) {
- localScaling = scale
- }
- }
- }
-
ColumnLayout {
id: contentCol
- width: parent.width - 2 * Style.marginL * scaling
- x: Style.marginL * scaling
- y: Style.marginL * scaling
- spacing: Style.marginXXS * scaling
+ width: parent.width - 2 * Style.marginL
+ x: Style.marginL
+ y: Style.marginL
+ spacing: Style.marginXXS
NLabel {
label: modelData.name || "Unknown"
@@ -101,67 +91,19 @@ ColumnLayout {
}
}
- // Scale
- ColumnLayout {
- spacing: Style.marginS * scaling
- Layout.fillWidth: true
-
- RowLayout {
- spacing: Style.marginL * scaling
- Layout.fillWidth: true
-
- NText {
- text: I18n.tr("settings.display.monitors.scale")
- Layout.preferredWidth: 90 * scaling
- Layout.alignment: Qt.AlignVCenter
- }
-
- NValueSlider {
- id: scaleSlider
- from: 0.7
- to: 1.8
- stepSize: 0.01
- value: localScaling
- onPressedChanged: (pressed, value) => ScalingService.setScreenScale(modelData, value)
- Layout.fillWidth: true
- }
-
- NText {
- text: I18n.tr("system.scaling-percentage", {
- "percentage": Math.round(scaleSlider.value * 100)
- })
- Layout.preferredWidth: 55 * scaling
- horizontalAlignment: Text.AlignRight
- Layout.alignment: Qt.AlignVCenter
- }
-
- Item {
- Layout.preferredWidth: 30 * scaling
- Layout.fillHeight: true
- NIconButton {
- icon: "refresh"
- baseSize: Style.baseWidgetSize * 0.8
- tooltipText: I18n.tr("settings.display.monitors.reset-scaling")
- onClicked: ScalingService.setScreenScale(modelData, 1.0)
- anchors.centerIn: parent
- }
- }
- }
- }
-
// Brightness
ColumnLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
Layout.fillWidth: true
visible: brightnessMonitor !== undefined && brightnessMonitor !== null
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
NText {
text: I18n.tr("settings.display.monitors.brightness")
- Layout.preferredWidth: 90 * scaling
+ Layout.preferredWidth: 90
Layout.alignment: Qt.AlignVCenter
}
@@ -182,13 +124,13 @@ ColumnLayout {
NText {
text: brightnessMonitor ? Math.round(brightnessSlider.value * 100) + "%" : "N/A"
- Layout.preferredWidth: 55 * scaling
+ Layout.preferredWidth: 55
horizontalAlignment: Text.AlignRight
Layout.alignment: Qt.AlignVCenter
}
Item {
- Layout.preferredWidth: 30 * scaling
+ Layout.preferredWidth: 30
Layout.fillHeight: true
NIcon {
icon: brightnessMonitor.method == "internal" ? "device-laptop" : "device-desktop"
@@ -217,13 +159,13 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Night Light Section
ColumnLayout {
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
Layout.fillWidth: true
NHeader {
@@ -251,7 +193,7 @@ ColumnLayout {
// Temperature
ColumnLayout {
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
Layout.alignment: Qt.AlignVCenter
NLabel {
@@ -261,14 +203,14 @@ ColumnLayout {
RowLayout {
visible: Settings.data.nightLight.enabled
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
Layout.fillWidth: false
Layout.fillHeight: true
Layout.alignment: Qt.AlignVCenter
NText {
text: I18n.tr("settings.display.night-light.temperature.night")
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignVCenter
}
@@ -290,7 +232,7 @@ ColumnLayout {
NText {
text: I18n.tr("settings.display.night-light.temperature.day")
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignVCenter
}
@@ -323,7 +265,7 @@ ColumnLayout {
// Manual scheduling
ColumnLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
visible: Settings.data.nightLight.enabled && !Settings.data.nightLight.autoSchedule && !Settings.data.nightLight.forced
NLabel {
@@ -333,11 +275,11 @@ ColumnLayout {
RowLayout {
Layout.fillWidth: false
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
NText {
text: I18n.tr("settings.display.night-light.manual-schedule.sunrise")
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
}
@@ -346,16 +288,16 @@ 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 * scaling
+ minimumWidth: 120
}
Item {
- Layout.preferredWidth: 20 * scaling
+ Layout.preferredWidth: 20
}
NText {
text: I18n.tr("settings.display.night-light.manual-schedule.sunset")
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
}
@@ -364,7 +306,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 * scaling
+ minimumWidth: 120
}
}
}
@@ -388,7 +330,7 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
}
diff --git a/Modules/Settings/Tabs/DockTab.qml b/Modules/Settings/Tabs/DockTab.qml
index 5d31c074..3203446e 100644
--- a/Modules/Settings/Tabs/DockTab.qml
+++ b/Modules/Settings/Tabs/DockTab.qml
@@ -9,7 +9,7 @@ import qs.Widgets
ColumnLayout {
id: root
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
// Helper functions to update arrays immutably
function addMonitor(list, name) {
@@ -50,7 +50,7 @@ ColumnLayout {
}
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
NLabel {
label: I18n.tr("settings.dock.appearance.background-opacity.label")
@@ -68,7 +68,7 @@ ColumnLayout {
}
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
NLabel {
@@ -87,15 +87,30 @@ ColumnLayout {
}
}
+ NToggle {
+ label: I18n.tr("settings.dock.monitors.only-same-output.label")
+ description: I18n.tr("settings.dock.monitors.only-same-output.description")
+ checked: Settings.data.dock.onlySameOutput
+ onToggled: checked => Settings.data.dock.onlySameOutput = checked
+ }
+
+ NToggle {
+ Layout.fillWidth: true
+ label: I18n.tr("settings.dock.appearance.colorize-icons.label")
+ description: I18n.tr("settings.dock.appearance.colorize-icons.description")
+ checked: Settings.data.dock.colorizeIcons
+ onToggled: checked => Settings.data.dock.colorizeIcons = checked
+ }
+
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Monitor Configuration
ColumnLayout {
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
Layout.fillWidth: true
NHeader {
@@ -108,11 +123,15 @@ ColumnLayout {
delegate: NCheckbox {
Layout.fillWidth: true
label: modelData.name || "Unknown"
- description: I18n.tr("system.monitor-description", {
- "model": modelData.model,
- "width": modelData.width,
- "height": modelData.height
- })
+ description: {
+ const compositorScale = CompositorService.getDisplayScale(modelData.name)
+ I18n.tr("system.monitor-description", {
+ "model": modelData.model,
+ "width": modelData.width * compositorScale,
+ "height": modelData.height * compositorScale,
+ "scale": compositorScale
+ })
+ }
checked: (Settings.data.dock.monitors || []).indexOf(modelData.name) !== -1
onToggled: checked => {
if (checked) {
@@ -125,16 +144,9 @@ ColumnLayout {
}
}
- NToggle {
- label: I18n.tr("settings.dock.monitors.only-same-output.label")
- description: I18n.tr("settings.dock.monitors.only-same-output.description")
- checked: Settings.data.dock.onlySameOutput
- onToggled: checked => Settings.data.dock.onlySameOutput = checked
- }
-
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
}
diff --git a/Modules/Settings/Tabs/GeneralTab.qml b/Modules/Settings/Tabs/GeneralTab.qml
index 4f9183a1..c4554145 100644
--- a/Modules/Settings/Tabs/GeneralTab.qml
+++ b/Modules/Settings/Tabs/GeneralTab.qml
@@ -17,16 +17,16 @@ ColumnLayout {
// Profile section
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
// Avatar preview
NImageCircled {
- width: 108 * scaling
- height: 108 * scaling
- imagePath: Settings.data.general.avatarImage
+ Layout.preferredWidth: 88 * Style.uiScaleRatio
+ Layout.preferredHeight: width
+ imagePath: Settings.preprocessPath(Settings.data.general.avatarImage)
fallbackIcon: "person"
borderColor: Color.mPrimary
- borderWidth: Math.max(1, Style.borderM * scaling)
+ borderWidth: Math.max(1, Style.borderM)
Layout.alignment: Qt.AlignTop
}
@@ -50,7 +50,7 @@ ColumnLayout {
id: avatarPicker
title: I18n.tr("settings.general.profile.select-avatar")
selectionMode: "files"
- initialPath: Settings.data.general.avatarImage.substr(0, Settings.data.general.avatarImage.lastIndexOf("/")) || Quickshell.env("HOME")
+ initialPath: Settings.preprocessPath(Settings.data.general.avatarImage).substr(0, Settings.preprocessPath(Settings.data.general.avatarImage).lastIndexOf("/")) || Quickshell.env("HOME")
nameFilters: ["*.jpg", "*.jpeg", "*.png", "*.gif", "*.pnm", "*.bmp"]
onAccepted: paths => {
if (paths.length > 0) {
@@ -61,199 +61,13 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
- }
-
- // User Interface
- ColumnLayout {
- spacing: Style.marginL * scaling
- Layout.fillWidth: true
-
- NHeader {
- label: I18n.tr("settings.general.ui.section.label")
- description: I18n.tr("settings.general.ui.section.description")
- }
-
- NToggle {
- label: I18n.tr("settings.general.ui.dim-desktop.label")
- description: I18n.tr("settings.general.ui.dim-desktop.description")
- checked: Settings.data.general.dimDesktop
- onToggled: checked => Settings.data.general.dimDesktop = checked
- }
-
- NToggle {
- label: I18n.tr("settings.general.ui.tooltips.label")
- description: I18n.tr("settings.general.ui.tooltips.description")
- checked: Settings.data.ui.tooltipsEnabled
- onToggled: checked => Settings.data.ui.tooltipsEnabled = checked
- }
-
- ColumnLayout {
- spacing: Style.marginXXS * scaling
- Layout.fillWidth: true
-
- NLabel {
- label: I18n.tr("settings.general.ui.border-radius.label")
- description: I18n.tr("settings.general.ui.border-radius.description")
- }
-
- NValueSlider {
- Layout.fillWidth: true
- from: 0
- to: 1
- stepSize: 0.01
- value: Settings.data.general.radiusRatio
- onMoved: value => Settings.data.general.radiusRatio = value
- text: Math.floor(Settings.data.general.radiusRatio * 100) + "%"
- }
- }
-
- // Animation Speed
- ColumnLayout {
- spacing: Style.marginL * scaling
- Layout.fillWidth: true
-
- NToggle {
- label: I18n.tr("settings.general.ui.animation-disable.label")
- description: I18n.tr("settings.general.ui.animation-disable.description")
- checked: Settings.data.general.animationDisabled
- onToggled: checked => Settings.data.general.animationDisabled = checked
- }
-
- ColumnLayout {
- spacing: Style.marginXXS * scaling
- Layout.fillWidth: true
- visible: !Settings.data.general.animationDisabled
-
- NLabel {
- label: I18n.tr("settings.general.ui.animation-speed.label")
- description: I18n.tr("settings.general.ui.animation-speed.description")
- }
-
- NValueSlider {
- Layout.fillWidth: true
- from: 0.1
- to: 2.0
- stepSize: 0.01
- value: Settings.data.general.animationSpeed
- onMoved: value => Settings.data.general.animationSpeed = value
- text: Math.round(Settings.data.general.animationSpeed * 100) + "%"
- }
- }
- }
- }
-
- NDivider {
- Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
- }
-
- // Dock
- ColumnLayout {
- spacing: Style.marginL * scaling
- Layout.fillWidth: true
-
- NHeader {
- label: I18n.tr("settings.general.screen-corners.section.label")
- description: I18n.tr("settings.general.screen-corners.section.description")
- }
-
- NToggle {
- label: I18n.tr("settings.general.screen-corners.show-corners.label")
- description: I18n.tr("settings.general.screen-corners.show-corners.description")
- checked: Settings.data.general.showScreenCorners
- onToggled: checked => Settings.data.general.showScreenCorners = checked
- }
-
- NToggle {
- label: I18n.tr("settings.general.screen-corners.solid-black.label")
- description: I18n.tr("settings.general.screen-corners.solid-black.description")
- checked: Settings.data.general.forceBlackScreenCorners
- onToggled: checked => Settings.data.general.forceBlackScreenCorners = checked
- }
-
- ColumnLayout {
- spacing: Style.marginXXS * scaling
- Layout.fillWidth: true
-
- NLabel {
- label: I18n.tr("settings.general.screen-corners.radius.label")
- description: I18n.tr("settings.general.screen-corners.radius.description")
- }
-
- NValueSlider {
- Layout.fillWidth: true
- from: 0
- to: 2
- stepSize: 0.01
- value: Settings.data.general.screenRadiusRatio
- onMoved: value => Settings.data.general.screenRadiusRatio = value
- text: Math.floor(Settings.data.general.screenRadiusRatio * 100) + "%"
- }
- }
- }
-
- NDivider {
- Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
- }
-
- // Control Center
- ColumnLayout {
- spacing: Style.marginL * scaling
- Layout.fillWidth: true
-
- NHeader {
- label: I18n.tr("settings.general.control-center.section.label")
- description: I18n.tr("settings.general.control-center.section.description")
- }
-
- NComboBox {
- id: controlCenterPosition
- label: I18n.tr("settings.general.control-center.position.label")
- description: I18n.tr("settings.general.control-center.position.description")
- Layout.fillWidth: true
- model: [{
- "key": "close_to_bar_button",
- "name": I18n.tr("options.control-center.position.close_to_bar_button")
- }, {
- "key": "top_left",
- "name": I18n.tr("options.control-center.position.top_left")
- }, {
- "key": "top_right",
- "name": I18n.tr("options.control-center.position.top_right")
- }, {
- "key": "bottom_left",
- "name": I18n.tr("options.control-center.position.bottom_left")
- }, {
- "key": "bottom_right",
- "name": I18n.tr("options.control-center.position.bottom_right")
- }, {
- "key": "bottom_center",
- "name": I18n.tr("options.control-center.position.bottom_center")
- }, {
- "key": "top_center",
- "name": I18n.tr("options.control-center.position.top_center")
- }]
- currentKey: Settings.data.controlCenter.position
- onSelected: function (key) {
- Settings.data.controlCenter.position = key
- }
- }
- }
-
- NDivider {
- Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Fonts
ColumnLayout {
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NHeader {
@@ -263,7 +77,7 @@ ColumnLayout {
// Font configuration section
ColumnLayout {
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NSearchableComboBox {
@@ -273,8 +87,8 @@ ColumnLayout {
currentKey: Settings.data.ui.fontDefault
placeholder: I18n.tr("settings.general.fonts.default.placeholder")
searchPlaceholder: I18n.tr("settings.general.fonts.default.search-placeholder")
- popupHeight: 420 * scaling
- minimumWidth: 300 * scaling
+ popupHeight: 420
+ minimumWidth: 300
onSelected: function (key) {
Settings.data.ui.fontDefault = key
}
@@ -287,8 +101,8 @@ ColumnLayout {
currentKey: Settings.data.ui.fontFixed
placeholder: I18n.tr("settings.general.fonts.monospace.placeholder")
searchPlaceholder: I18n.tr("settings.general.fonts.monospace.search-placeholder")
- popupHeight: 320 * scaling
- minimumWidth: 300 * scaling
+ popupHeight: 320
+ minimumWidth: 300
onSelected: function (key) {
Settings.data.ui.fontFixed = key
}
@@ -301,7 +115,7 @@ ColumnLayout {
}
RowLayout {
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NValueSlider {
@@ -316,8 +130,8 @@ ColumnLayout {
// Reset button container
Item {
- Layout.preferredWidth: 30 * scaling
- Layout.preferredHeight: 30 * scaling
+ Layout.preferredWidth: 30 * Style.uiScaleRatio
+ Layout.preferredHeight: 30 * Style.uiScaleRatio
NIconButton {
icon: "refresh"
@@ -338,7 +152,7 @@ ColumnLayout {
}
RowLayout {
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NValueSlider {
@@ -353,8 +167,8 @@ ColumnLayout {
// Reset button container
Item {
- Layout.preferredWidth: 30 * scaling
- Layout.preferredHeight: 30 * scaling
+ Layout.preferredWidth: 30 * Style.uiScaleRatio
+ Layout.preferredHeight: 30 * Style.uiScaleRatio
NIconButton {
icon: "refresh"
@@ -369,4 +183,10 @@ ColumnLayout {
}
}
}
+
+ NDivider {
+ Layout.fillWidth: true
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
+ }
}
diff --git a/Modules/Settings/Tabs/HooksTab.qml b/Modules/Settings/Tabs/HooksTab.qml
index ae339d1e..0b664cd3 100644
--- a/Modules/Settings/Tabs/HooksTab.qml
+++ b/Modules/Settings/Tabs/HooksTab.qml
@@ -7,7 +7,7 @@ import qs.Widgets
ColumnLayout {
id: contentColumn
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
width: root.width
NHeader {
@@ -25,7 +25,7 @@ ColumnLayout {
ColumnLayout {
visible: Settings.data.hooks.enabled
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NDivider {
@@ -78,7 +78,7 @@ ColumnLayout {
// Info section
ColumnLayout {
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
Layout.fillWidth: true
NLabel {
diff --git a/Modules/Settings/Tabs/LauncherTab.qml b/Modules/Settings/Tabs/LauncherTab.qml
index a01c13fb..b64f26b6 100644
--- a/Modules/Settings/Tabs/LauncherTab.qml
+++ b/Modules/Settings/Tabs/LauncherTab.qml
@@ -7,7 +7,7 @@ import qs.Widgets
ColumnLayout {
id: root
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
NHeader {
label: I18n.tr("settings.launcher.settings.section.label")
@@ -48,19 +48,19 @@ ColumnLayout {
}
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
NText {
text: I18n.tr("settings.launcher.settings.background-opacity.label")
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: Color.mOnSurface
}
NText {
text: I18n.tr("settings.launcher.settings.background-opacity.description")
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
color: Color.mOnSurfaceVariant
wrapMode: Text.WordWrap
Layout.fillWidth: true
@@ -111,7 +111,7 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
}
diff --git a/Modules/Settings/Tabs/LocationTab.qml b/Modules/Settings/Tabs/LocationTab.qml
index 769735d2..b4ccfe4f 100644
--- a/Modules/Settings/Tabs/LocationTab.qml
+++ b/Modules/Settings/Tabs/LocationTab.qml
@@ -7,7 +7,7 @@ import qs.Widgets
ColumnLayout {
id: root
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
NHeader {
label: I18n.tr("settings.location.location.section.label")
@@ -17,7 +17,7 @@ ColumnLayout {
// Location section
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
NTextInput {
label: I18n.tr("settings.location.location.search.label")
@@ -37,7 +37,7 @@ ColumnLayout {
LocationService.resetWeather()
}
}
- Layout.maximumWidth: 420 * scaling
+ Layout.maximumWidth: 420
}
NText {
@@ -46,24 +46,24 @@ ColumnLayout {
"name": LocationService.stableName,
"coordinates": LocationService.displayCoordinates
})
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: Color.mOnSurfaceVariant
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignRight
Layout.alignment: Qt.AlignBottom
- Layout.bottomMargin: Style.marginM * scaling
+ Layout.bottomMargin: Style.marginM
}
}
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Weather section
ColumnLayout {
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
Layout.fillWidth: true
NHeader {
@@ -81,13 +81,13 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Date & time section
ColumnLayout {
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
Layout.fillWidth: true
NHeader {
@@ -112,7 +112,7 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
}
diff --git a/Modules/Settings/Tabs/NetworkTab.qml b/Modules/Settings/Tabs/NetworkTab.qml
index b19a0819..90e3216f 100644
--- a/Modules/Settings/Tabs/NetworkTab.qml
+++ b/Modules/Settings/Tabs/NetworkTab.qml
@@ -9,7 +9,7 @@ import qs.Widgets
ColumnLayout {
id: root
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
NHeader {
description: I18n.tr("settings.network.section.description")
@@ -29,7 +29,7 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
}
diff --git a/Modules/Settings/Tabs/NotificationsTab.qml b/Modules/Settings/Tabs/NotificationsTab.qml
index 6673305d..beae8cdc 100644
--- a/Modules/Settings/Tabs/NotificationsTab.qml
+++ b/Modules/Settings/Tabs/NotificationsTab.qml
@@ -24,7 +24,7 @@ ColumnLayout {
// General Notification Settings
ColumnLayout {
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NHeader {
@@ -77,13 +77,13 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Duration
ColumnLayout {
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NHeader {
@@ -101,7 +101,7 @@ ColumnLayout {
// Low Urgency Duration
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
NLabel {
@@ -122,7 +122,7 @@ ColumnLayout {
// Normal Urgency Duration
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
NLabel {
@@ -143,7 +143,7 @@ ColumnLayout {
// Critical Urgency Duration
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
NLabel {
@@ -164,8 +164,8 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Monitor Configuration
@@ -179,11 +179,15 @@ ColumnLayout {
delegate: NCheckbox {
Layout.fillWidth: true
label: modelData.name || I18n.tr("system.unknown")
- description: I18n.tr("system.monitor-description", {
- "model": modelData.model,
- "width": modelData.width,
- "height": modelData.height
- })
+ description: {
+ const compositorScale = CompositorService.getDisplayScale(modelData.name)
+ I18n.tr("system.monitor-description", {
+ "model": modelData.model,
+ "width": modelData.width * compositorScale,
+ "height": modelData.height * compositorScale,
+ "scale": compositorScale
+ })
+ }
checked: (Settings.data.notifications.monitors || []).indexOf(modelData.name) !== -1
onToggled: checked => {
if (checked) {
@@ -198,7 +202,7 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
}
diff --git a/Modules/Settings/Tabs/OsdTab.qml b/Modules/Settings/Tabs/OsdTab.qml
index 93e4a733..edb16fd3 100644
--- a/Modules/Settings/Tabs/OsdTab.qml
+++ b/Modules/Settings/Tabs/OsdTab.qml
@@ -24,7 +24,7 @@ ColumnLayout {
// Display
ColumnLayout {
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NComboBox {
@@ -62,13 +62,13 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// General
ColumnLayout {
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NHeader {
@@ -83,6 +83,13 @@ ColumnLayout {
onToggled: checked => Settings.data.osd.enabled = checked
}
+ NToggle {
+ label: I18n.tr("settings.osd.always-on-top.label")
+ description: I18n.tr("settings.osd.always-on-top.description")
+ checked: Settings.data.osd.alwaysOnTop
+ onToggled: checked => Settings.data.osd.alwaysOnTop = checked
+ }
+
NLabel {
label: I18n.tr("settings.osd.duration.auto-hide.label")
description: I18n.tr("settings.osd.duration.auto-hide.description")
@@ -101,13 +108,13 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Monitor Configuration
ColumnLayout {
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NHeader {
@@ -120,11 +127,15 @@ ColumnLayout {
delegate: NCheckbox {
Layout.fillWidth: true
label: modelData.name || I18n.tr("system.unknown")
- description: I18n.tr("system.monitor-description", {
- "model": modelData.model,
- "width": modelData.width,
- "height": modelData.height
- })
+ description: {
+ const compositorScale = CompositorService.getDisplayScale(modelData.name)
+ I18n.tr("system.monitor-description", {
+ "model": modelData.model,
+ "width": modelData.width * compositorScale,
+ "height": modelData.height * compositorScale,
+ "scale": compositorScale
+ })
+ }
checked: (Settings.data.osd.monitors || []).indexOf(modelData.name) !== -1
onToggled: checked => {
if (checked) {
diff --git a/Modules/Settings/Tabs/ScreenRecorderTab.qml b/Modules/Settings/Tabs/ScreenRecorderTab.qml
index 957579bf..f1bed075 100644
--- a/Modules/Settings/Tabs/ScreenRecorderTab.qml
+++ b/Modules/Settings/Tabs/ScreenRecorderTab.qml
@@ -9,7 +9,7 @@ import qs.Widgets
ColumnLayout {
id: root
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
NHeader {
label: I18n.tr("settings.screen-recorder.general.section.label")
@@ -18,7 +18,7 @@ ColumnLayout {
// Output Folder
ColumnLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
Layout.fillWidth: true
NTextInputButton {
@@ -43,13 +43,13 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Video Settings
ColumnLayout {
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NHeader {
@@ -179,13 +179,13 @@ ColumnLayout {
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
// Audio Settings
ColumnLayout {
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NHeader {
diff --git a/Modules/Settings/Tabs/UserInterfaceTab.qml b/Modules/Settings/Tabs/UserInterfaceTab.qml
new file mode 100644
index 00000000..13557c29
--- /dev/null
+++ b/Modules/Settings/Tabs/UserInterfaceTab.qml
@@ -0,0 +1,260 @@
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import Quickshell
+import qs.Commons
+import qs.Services
+import qs.Widgets
+
+ColumnLayout {
+ id: root
+
+ // User Interface
+ ColumnLayout {
+ spacing: Style.marginL
+ Layout.fillWidth: true
+
+ NHeader {
+ label: I18n.tr("settings.user-interface.section.label")
+ description: I18n.tr("settings.user-interface.section.description")
+ }
+
+ NToggle {
+ label: I18n.tr("settings.user-interface.dim-desktop.label")
+ description: I18n.tr("settings.user-interface.dim-desktop.description")
+ checked: Settings.data.general.dimDesktop
+ onToggled: checked => Settings.data.general.dimDesktop = checked
+ }
+
+ NToggle {
+ label: I18n.tr("settings.user-interface.tooltips.label")
+ description: I18n.tr("settings.user-interface.tooltips.description")
+ checked: Settings.data.ui.tooltipsEnabled
+ onToggled: checked => Settings.data.ui.tooltipsEnabled = checked
+ }
+
+ NToggle {
+ label: I18n.tr("settings.user-interface.compact-lockscreen.label")
+ description: I18n.tr("settings.user-interface.compact-lockscreen.description")
+ checked: Settings.data.general.compactLockScreen
+ onToggled: checked => Settings.data.general.compactLockScreen = checked
+ }
+
+ NDivider {
+ Layout.fillWidth: true
+ Layout.topMargin: Style.marginL
+ Layout.bottomMargin: Style.marginL
+ }
+
+ ColumnLayout {
+ spacing: Style.marginXXS
+ Layout.fillWidth: true
+
+ NLabel {
+ label: I18n.tr("settings.user-interface.scaling.label")
+ description: I18n.tr("settings.user-interface.scaling.description")
+ }
+
+ RowLayout {
+ spacing: Style.marginL
+ Layout.fillWidth: true
+
+ NValueSlider {
+ Layout.fillWidth: true
+ from: 0.8
+ to: 1.2
+ stepSize: 0.05
+ value: Settings.data.general.scaleRatio
+ onMoved: value => Settings.data.general.scaleRatio = value
+ text: Math.floor(Settings.data.general.scaleRatio * 100) + "%"
+ }
+
+ // Reset button container
+ Item {
+ Layout.preferredWidth: 30 * Style.uiScaleRatio
+ Layout.preferredHeight: 30 * Style.uiScaleRatio
+
+ NIconButton {
+ icon: "refresh"
+ baseSize: Style.baseWidgetSize * 0.8
+ tooltipText: I18n.tr("settings.user-interface.scaling.reset-scaling")
+ onClicked: Settings.data.general.scaleRatio = 1.0
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+ }
+ }
+
+ ColumnLayout {
+ spacing: Style.marginXXS
+ Layout.fillWidth: true
+
+ NLabel {
+ label: I18n.tr("settings.user-interface.border-radius.label")
+ description: I18n.tr("settings.user-interface.border-radius.description")
+ }
+
+ RowLayout {
+ spacing: Style.marginL
+ Layout.fillWidth: true
+
+ NValueSlider {
+ Layout.fillWidth: true
+ from: 0
+ to: 1
+ stepSize: 0.01
+ value: Settings.data.general.radiusRatio
+ onMoved: value => Settings.data.general.radiusRatio = value
+ text: Math.floor(Settings.data.general.radiusRatio * 100) + "%"
+ }
+
+ // Reset button container
+ Item {
+ Layout.preferredWidth: 30 * Style.uiScaleRatio
+ Layout.preferredHeight: 30 * Style.uiScaleRatio
+
+ NIconButton {
+ icon: "refresh"
+ baseSize: Style.baseWidgetSize * 0.8
+ tooltipText: I18n.tr("settings.user-interface.border-radius.reset")
+ onClicked: Settings.data.general.radiusRatio = 1.0
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+ }
+ }
+
+ // Animation Speed
+ ColumnLayout {
+ spacing: Style.marginL
+ Layout.fillWidth: true
+
+ ColumnLayout {
+ spacing: Style.marginXXS
+ Layout.fillWidth: true
+ visible: !Settings.data.general.animationDisabled
+
+ NLabel {
+ label: I18n.tr("settings.user-interface.animation-speed.label")
+ description: I18n.tr("settings.user-interface.animation-speed.description")
+ }
+
+ RowLayout {
+ spacing: Style.marginL
+ Layout.fillWidth: true
+
+ NValueSlider {
+ Layout.fillWidth: true
+ from: 0.1
+ to: 2.0
+ stepSize: 0.01
+ value: Settings.data.general.animationSpeed
+ onMoved: value => Settings.data.general.animationSpeed = value
+ text: Math.round(Settings.data.general.animationSpeed * 100) + "%"
+ }
+
+ // Reset button container
+ Item {
+ Layout.preferredWidth: 30 * Style.uiScaleRatio
+ Layout.preferredHeight: 30 * Style.uiScaleRatio
+
+ NIconButton {
+ icon: "refresh"
+ baseSize: Style.baseWidgetSize * 0.8
+ tooltipText: I18n.tr("settings.user-interface.animation-speed.reset")
+ onClicked: Settings.data.general.animationSpeed = 1.0
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+ }
+ }
+
+ NToggle {
+ label: I18n.tr("settings.user-interface.animation-disable.label")
+ description: I18n.tr("settings.user-interface.animation-disable.description")
+ checked: Settings.data.general.animationDisabled
+ onToggled: checked => Settings.data.general.animationDisabled = checked
+ }
+ }
+ }
+
+ NDivider {
+ Layout.fillWidth: true
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
+ }
+
+ // Dock
+ ColumnLayout {
+ spacing: Style.marginL
+ Layout.fillWidth: true
+
+ NHeader {
+ label: I18n.tr("settings.general.screen-corners.section.label")
+ description: I18n.tr("settings.general.screen-corners.section.description")
+ }
+
+ NToggle {
+ label: I18n.tr("settings.general.screen-corners.show-corners.label")
+ description: I18n.tr("settings.general.screen-corners.show-corners.description")
+ checked: Settings.data.general.showScreenCorners
+ onToggled: checked => Settings.data.general.showScreenCorners = checked
+ }
+
+ NToggle {
+ label: I18n.tr("settings.general.screen-corners.solid-black.label")
+ description: I18n.tr("settings.general.screen-corners.solid-black.description")
+ checked: Settings.data.general.forceBlackScreenCorners
+ onToggled: checked => Settings.data.general.forceBlackScreenCorners = checked
+ }
+
+ ColumnLayout {
+ spacing: Style.marginXXS
+ Layout.fillWidth: true
+
+ NLabel {
+ label: I18n.tr("settings.general.screen-corners.radius.label")
+ description: I18n.tr("settings.general.screen-corners.radius.description")
+ }
+
+ RowLayout {
+ spacing: Style.marginL
+ Layout.fillWidth: true
+
+ NValueSlider {
+ Layout.fillWidth: true
+ from: 0
+ to: 2
+ stepSize: 0.01
+ value: Settings.data.general.screenRadiusRatio
+ onMoved: value => Settings.data.general.screenRadiusRatio = value
+ text: Math.floor(Settings.data.general.screenRadiusRatio * 100) + "%"
+ }
+
+ // Reset button container
+ Item {
+ Layout.preferredWidth: 30 * Style.uiScaleRatio
+ Layout.preferredHeight: 30 * Style.uiScaleRatio
+
+ NIconButton {
+ icon: "refresh"
+ baseSize: Style.baseWidgetSize * 0.8
+ tooltipText: I18n.tr("settings.general.screen-corners.radius.reset")
+ onClicked: Settings.data.general.screenRadiusRatio = 1.0
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+ }
+ }
+ }
+
+ NDivider {
+ Layout.fillWidth: true
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
+ }
+}
diff --git a/Modules/Settings/Tabs/WallpaperTab.qml b/Modules/Settings/Tabs/WallpaperTab.qml
index d8a2bc56..c93c60da 100644
--- a/Modules/Settings/Tabs/WallpaperTab.qml
+++ b/Modules/Settings/Tabs/WallpaperTab.qml
@@ -12,7 +12,7 @@ ColumnLayout {
property string specificFolderMonitorName: ""
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
NHeader {
label: I18n.tr("settings.wallpaper.settings.section.label")
@@ -24,12 +24,12 @@ ColumnLayout {
description: I18n.tr("settings.wallpaper.settings.enable-management.description")
checked: Settings.data.wallpaper.enabled
onToggled: checked => Settings.data.wallpaper.enabled = checked
- Layout.bottomMargin: Style.marginL * scaling
+ Layout.bottomMargin: Style.marginL
}
ColumnLayout {
visible: Settings.data.wallpaper.enabled
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NTextInputButton {
@@ -56,29 +56,28 @@ ColumnLayout {
visible: Settings.data.wallpaper.enableMultiMonitorDirectories
Layout.fillWidth: true
- Layout.minimumWidth: 550 * scaling
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
color: Color.mSurfaceVariant
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
- implicitHeight: contentCol.implicitHeight + Style.marginXL * 2 * scaling
+ border.width: Math.max(1, Style.borderS)
+ implicitHeight: contentCol.implicitHeight + Style.marginL * 2
ColumnLayout {
id: contentCol
anchors.fill: parent
- anchors.margins: Style.marginXL * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginM
Repeater {
model: Quickshell.screens || []
delegate: ColumnLayout {
Layout.fillWidth: true
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
NText {
text: (modelData.name || "Unknown")
color: Color.mPrimary
font.weight: Style.fontWeightBold
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
}
NTextInputButton {
@@ -101,13 +100,13 @@ ColumnLayout {
NDivider {
visible: Settings.data.wallpaper.enabled
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
ColumnLayout {
visible: Settings.data.wallpaper.enabled
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NHeader {
@@ -184,13 +183,13 @@ ColumnLayout {
NDivider {
visible: Settings.data.wallpaper.enabled
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
ColumnLayout {
visible: Settings.data.wallpaper.enabled
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
NHeader {
@@ -225,7 +224,7 @@ ColumnLayout {
// Preset chips using Repeater
RowLayout {
id: presetRow
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
// Factorized presets data
property var intervalPresets: [5 * 60, 10 * 60, 15 * 60, 30 * 60, 45 * 60, 60 * 60, 90 * 60, 120 * 60]
@@ -272,8 +271,8 @@ ColumnLayout {
RowLayout {
id: customRow
visible: presetRow.customForcedVisible || !presetRow.isCurrentPreset
- spacing: Style.marginS * scaling
- Layout.topMargin: Style.marginS * scaling
+ spacing: Style.marginS
+ Layout.topMargin: Style.marginS
NTextInput {
label: I18n.tr("settings.wallpaper.automation.custom-interval.label")
@@ -313,8 +312,8 @@ ColumnLayout {
radius: height * 0.5
color: selected ? Color.mPrimary : Color.mSurfaceVariant
- implicitHeight: Math.max(Style.baseWidgetSize * 0.55 * scaling, 24 * scaling)
- implicitWidth: chipLabel.implicitWidth + Style.marginM * 1.5 * scaling
+ implicitHeight: Math.max(Style.baseWidgetSize * 0.55, 24)
+ implicitWidth: chipLabel.implicitWidth + Style.marginM * 1.5
border.width: 1
border.color: selected ? Color.transparent : Color.mOutline
@@ -328,15 +327,15 @@ ColumnLayout {
id: chipLabel
anchors.centerIn: parent
text: parent.label
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: parent.selected ? Color.mOnPrimary : Color.mOnSurface
}
}
NDivider {
Layout.fillWidth: true
- Layout.topMargin: Style.marginXL * scaling
- Layout.bottomMargin: Style.marginXL * scaling
+ Layout.topMargin: Style.marginXL
+ Layout.bottomMargin: Style.marginXL
}
NFilePicker {
diff --git a/Modules/Toast/SimpleToast.qml b/Modules/Toast/SimpleToast.qml
index 339e09c6..1575c4a4 100644
--- a/Modules/Toast/SimpleToast.qml
+++ b/Modules/Toast/SimpleToast.qml
@@ -16,8 +16,8 @@ Rectangle {
signal hidden
width: parent.width
- height: Math.round(contentLayout.implicitHeight + Style.marginL * 2 * scaling)
- radius: Style.radiusL * scaling
+ height: Math.round(contentLayout.implicitHeight + Style.marginL * 2)
+ radius: Style.radiusL
visible: false
opacity: 0
scale: initialScale
@@ -34,7 +34,7 @@ Rectangle {
return Color.mOutline
}
}
- border.width: Math.max(2, Style.borderM * scaling)
+ border.width: Math.max(2, Style.borderM)
Behavior on opacity {
NumberAnimation {
@@ -74,8 +74,8 @@ Rectangle {
RowLayout {
id: contentLayout
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
- spacing: Style.marginL * scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginL
// Icon
NIcon {
@@ -100,13 +100,13 @@ Rectangle {
return Color.mOnSurface
}
}
- pointSize: Style.fontSizeXXL * 1.5 * scaling
+ pointSize: Style.fontSizeXXL * 1.5
Layout.alignment: Qt.AlignVCenter
}
// Label and description
ColumnLayout {
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
@@ -114,7 +114,7 @@ Rectangle {
Layout.fillWidth: true
text: root.message
color: Color.mOnSurface
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
wrapMode: Text.WordWrap
visible: text.length > 0
@@ -124,7 +124,7 @@ Rectangle {
Layout.fillWidth: true
text: root.description
color: Color.mOnSurface
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
wrapMode: Text.WordWrap
visible: text.length > 0
}
diff --git a/Modules/Toast/ToastOverlay.qml b/Modules/Toast/ToastOverlay.qml
index 1c8cabab..3051108d 100644
--- a/Modules/Toast/ToastOverlay.qml
+++ b/Modules/Toast/ToastOverlay.qml
@@ -11,8 +11,6 @@ Variants {
delegate: ToastScreen {
required property ShellScreen modelData
-
screen: modelData
- scaling: ScalingService.getScreenScale(modelData)
}
}
diff --git a/Modules/Toast/ToastScreen.qml b/Modules/Toast/ToastScreen.qml
index 0c732184..ee19a625 100644
--- a/Modules/Toast/ToastScreen.qml
+++ b/Modules/Toast/ToastScreen.qml
@@ -10,7 +10,6 @@ Item {
id: root
required property ShellScreen screen
- required property real scaling
// Local queue for this screen only (bounded to prevent memory issues)
property var messageQueue: []
@@ -20,15 +19,6 @@ Item {
// If true, immediately show new toasts
property bool replaceOnNew: true
- Connections {
- target: ScalingService
- function onScaleChanged(screenName, scale) {
- if (screenName === root.screen.name) {
- root.scaling = scale
- }
- }
- }
-
Connections {
target: ToastService
@@ -161,10 +151,10 @@ Item {
margins.top: {
if (!(anchors.top))
return 0
- var base = Style.marginM * scaling
+ var base = Style.marginM
if (Settings.data.bar.position === "top") {
- var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0
- return (Style.barHeight * scaling) + base + floatExtraV
+ var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL : 0
+ return (Style.barHeight) + base + floatExtraV
}
return base
}
@@ -172,10 +162,10 @@ Item {
margins.bottom: {
if (!(anchors.bottom))
return 0
- var base = Style.marginM * scaling
+ var base = Style.marginM
if (Settings.data.bar.position === "bottom") {
- var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0
- return (Style.barHeight * scaling) + base + floatExtraV
+ var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL : 0
+ return (Style.barHeight) + base + floatExtraV
}
return base
}
@@ -183,10 +173,10 @@ Item {
margins.left: {
if (!(anchors.left))
return 0
- var base = Style.marginM * scaling
+ var base = Style.marginM
if (Settings.data.bar.position === "left") {
- var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0
- return (Style.barHeight * scaling) + base + floatExtraH
+ var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
+ return (Style.barHeight) + base + floatExtraH
}
return base
}
@@ -194,15 +184,15 @@ Item {
margins.right: {
if (!(anchors.right))
return 0
- var base = Style.marginM * scaling
+ var base = Style.marginM
if (Settings.data.bar.position === "right") {
- var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0
- return (Style.barHeight * scaling) + base + floatExtraH
+ var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0
+ return (Style.barHeight) + base + floatExtraH
}
return base
}
- implicitWidth: 420 * root.scaling
+ implicitWidth: 420
implicitHeight: toastItem.height
color: Color.transparent
diff --git a/Modules/Tooltip/Tooltip.qml b/Modules/Tooltip/Tooltip.qml
index 8e8e532a..43a6850c 100644
--- a/Modules/Tooltip/Tooltip.qml
+++ b/Modules/Tooltip/Tooltip.qml
@@ -8,7 +8,6 @@ import qs.Widgets
PopupWindow {
id: root
- property real scaling: 1.0
property int screenWidth: 0
property int screenHeight: 0
@@ -114,7 +113,6 @@ PopupWindow {
if (!screen || !target || !tipText || tipText === "")
return
- root.scaling = ScalingService.getScreenScaleByName(screen.name)
root.screenWidth = screen.width
root.screenHeight = screen.height
@@ -153,10 +151,10 @@ PopupWindow {
}
// Calculate tooltip dimensions
- const tipWidth = Math.min(tooltipText.implicitWidth + (padding * 2 * scaling), maxWidth * scaling)
+ const tipWidth = Math.min(tooltipText.implicitWidth + (padding * 2), maxWidth)
root.implicitWidth = tipWidth
- const tipHeight = tooltipText.implicitHeight + (padding * 2 * scaling)
+ const tipHeight = tooltipText.implicitHeight + (padding * 2)
root.implicitHeight = tipHeight
// Get target's global position
@@ -179,26 +177,26 @@ PopupWindow {
"dir": "bottom",
"space": spaceBottom,
"x": (targetWidth - tipWidth) / 2,
- "y": targetHeight + margin * scaling,
- "fits": spaceBottom >= tipHeight + margin * scaling
+ "y": targetHeight + margin,
+ "fits": spaceBottom >= tipHeight + margin
}, {
"dir": "top",
"space": spaceTop,
"x": (targetWidth - tipWidth) / 2,
- "y": -tipHeight - margin * scaling,
- "fits": spaceTop >= tipHeight + margin * scaling
+ "y": -tipHeight - margin,
+ "fits": spaceTop >= tipHeight + margin
}, {
"dir": "right",
"space": spaceRight,
- "x": targetWidth + margin * scaling,
+ "x": targetWidth + margin,
"y": (targetHeight - tipHeight) / 2,
- "fits": spaceRight >= tipWidth + margin * scaling
+ "fits": spaceRight >= tipWidth + margin
}, {
"dir": "left",
"space": spaceLeft,
- "x": -tipWidth - margin * scaling,
+ "x": -tipWidth - margin,
"y": (targetHeight - tipHeight) / 2,
- "fits": spaceLeft >= tipWidth + margin * scaling
+ "fits": spaceLeft >= tipWidth + margin
}]
// Find first position that fits
@@ -226,29 +224,29 @@ PopupWindow {
if (direction === "auto") {
const globalX = targetGlobal.x + newAnchorX
if (globalX < 0) {
- newAnchorX = -targetGlobal.x + margin * scaling
+ newAnchorX = -targetGlobal.x + margin
} else if (globalX + tipWidth > screenWidth) {
- newAnchorX = screenWidth - targetGlobal.x - tipWidth - margin * scaling
+ newAnchorX = screenWidth - targetGlobal.x - tipWidth - margin
}
}
} else {
// Manual direction positioning
switch (direction) {
case "left":
- newAnchorX = -tipWidth - margin * scaling
+ newAnchorX = -tipWidth - margin
newAnchorY = (targetHeight - tipHeight) / 2
break
case "right":
- newAnchorX = targetWidth + margin * scaling
+ newAnchorX = targetWidth + margin
newAnchorY = (targetHeight - tipHeight) / 2
break
case "top":
newAnchorX = (targetWidth - tipWidth) / 2
- newAnchorY = -tipHeight - margin * scaling
+ newAnchorY = -tipHeight - margin
break
case "bottom":
newAnchorX = (targetWidth - tipWidth) / 2
- newAnchorY = targetHeight + margin * scaling
+ newAnchorY = targetHeight + margin
break
}
}
@@ -370,8 +368,8 @@ PopupWindow {
anchors.fill: parent
color: Color.mSurface
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * root.scaling)
- radius: Style.radiusS * root.scaling
+ border.width: Math.max(1, Style.borderS)
+ radius: Style.radiusS
// Only show content when we have text
visible: root.text !== ""
@@ -379,14 +377,14 @@ PopupWindow {
NText {
id: tooltipText
anchors.centerIn: parent
- anchors.margins: root.padding * root.scaling
+ anchors.margins: root.padding
text: root.text
- pointSize: Style.fontSizeS * root.scaling
+ pointSize: Style.fontSizeS
color: Color.mOnSurfaceVariant
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
- width: root.maxWidth * root.scaling - (root.padding * 2 * root.scaling)
+ width: root.maxWidth - (root.padding * 2)
}
}
}
diff --git a/Modules/Wallpaper/WallpaperPanel.qml b/Modules/Wallpaper/WallpaperPanel.qml
index 6ff2ed49..be3a526b 100644
--- a/Modules/Wallpaper/WallpaperPanel.qml
+++ b/Modules/Wallpaper/WallpaperPanel.qml
@@ -58,23 +58,23 @@ NPanel {
ColumnLayout {
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginM
// Header
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NIcon {
icon: "settings-wallpaper-selector"
- pointSize: Style.fontSizeXXL * scaling
+ pointSize: Style.fontSizeXXL
color: Color.mPrimary
}
NText {
text: I18n.tr("wallpaper.panel.title")
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: Color.mOnSurface
Layout.fillWidth: true
@@ -125,7 +125,7 @@ NPanel {
Layout.fillWidth: true
currentIndex: currentScreenIndex
onCurrentIndexChanged: currentScreenIndex = currentIndex
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
background: Rectangle {
color: Color.transparent
@@ -135,12 +135,12 @@ NPanel {
model: Quickshell.screens
delegate: TabButton {
text: modelData.name || `Screen ${index + 1}`
- width: implicitWidth + Style.marginS * 2 * scaling
+ width: implicitWidth + Style.marginS * 2
background: Rectangle {
color: screenTabBar.currentIndex === index ? Color.mSecondary : Color.transparent
- radius: Style.radiusS * scaling
- border.width: screenTabBar.currentIndex === index ? 0 : Math.max(1, Style.borderS * scaling)
+ radius: Style.radiusS
+ border.width: screenTabBar.currentIndex === index ? 0 : Math.max(1, Style.borderS)
border.color: Color.mOutline
Behavior on color {
@@ -152,7 +152,7 @@ NPanel {
contentItem: NText {
text: parent.text
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: screenTabBar.currentIndex === index ? Style.fontWeightBold : Style.fontWeightRegular
family: Settings.data.ui.fontDefault
color: screenTabBar.currentIndex === index ? Color.mOnSecondary : Color.mOnSurfaceVariant
@@ -169,7 +169,7 @@ NPanel {
anchors.fill: parent
color: Color.mOnSurface
opacity: tabHover.hovered && screenTabBar.currentIndex !== index ? 0.08 : 0
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
Behavior on opacity {
NumberAnimation {
@@ -200,12 +200,12 @@ NPanel {
// Filter input
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NText {
text: I18n.tr("wallpaper.panel.search")
color: Color.mOnSurface
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
Layout.preferredWidth: implicitWidth
}
@@ -306,7 +306,7 @@ NPanel {
ColumnLayout {
anchors.fill: parent
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
GridView {
id: wallpaperGridView
@@ -327,12 +327,12 @@ NPanel {
property int itemSize: cellWidth
cellWidth: Math.floor((width - leftMargin - rightMargin) / columns)
- cellHeight: Math.floor(itemSize * 0.7) + Style.marginXS * scaling + Style.fontSizeXS * scaling + Style.marginM * scaling
+ cellHeight: Math.floor(itemSize * 0.7) + Style.marginXS + Style.fontSizeXS + Style.marginM
- leftMargin: Style.marginS * scaling
- rightMargin: Style.marginS * scaling
- topMargin: Style.marginS * scaling
- bottomMargin: Style.marginS * scaling
+ leftMargin: Style.marginS
+ rightMargin: Style.marginS
+ topMargin: Style.marginS
+ bottomMargin: Style.marginS
onCurrentIndexChanged: {
// Synchronize scroll with current item position
@@ -377,7 +377,7 @@ NPanel {
property string filename: wallpaperPath.split('/').pop()
width: wallpaperGridView.itemSize
- spacing: Style.marginXS * scaling
+ spacing: Style.marginXS
Rectangle {
id: imageContainer
@@ -405,24 +405,24 @@ NPanel {
}
return Color.mSurface
}
- border.width: Math.max(1, Style.borderL * 1.5 * scaling)
+ border.width: Math.max(1, Style.borderL * 1.5)
}
Rectangle {
anchors.top: parent.top
anchors.right: parent.right
- anchors.margins: Style.marginS * scaling
- width: 28 * scaling
- height: 28 * scaling
+ anchors.margins: Style.marginS
+ width: 28
+ height: 28
radius: width / 2
color: Color.mSecondary
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
visible: isSelected
NIcon {
icon: "check"
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightBold
color: Color.mOnSecondary
anchors.centerIn: parent
@@ -461,10 +461,10 @@ NPanel {
NText {
text: filename
color: (hoverHandler.hovered || isSelected || wallpaperGridView.currentIndex === index) ? Color.mOnSurface : Color.mOnSurfaceVariant
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
Layout.fillWidth: true
- Layout.leftMargin: Style.marginS * scaling
- Layout.rightMargin: Style.marginS * scaling
+ Layout.leftMargin: Style.marginS
+ Layout.rightMargin: Style.marginS
Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
@@ -475,12 +475,12 @@ NPanel {
// Empty / scanning state
Rectangle {
color: Color.mSurface
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
visible: (filteredWallpapers.length === 0 && !WallpaperService.scanning) || WallpaperService.scanning
Layout.fillWidth: true
- Layout.preferredHeight: 130 * scaling
+ Layout.preferredHeight: 130
ColumnLayout {
anchors.fill: parent
@@ -498,7 +498,7 @@ NPanel {
}
NIcon {
icon: "folder-open"
- pointSize: Style.fontSizeXXL * scaling
+ pointSize: Style.fontSizeXXL
color: Color.mOnSurface
Layout.alignment: Qt.AlignHCenter
}
diff --git a/Services/AppThemeService.qml b/Services/AppThemeService.qml
index 3fbf1153..6117fcdb 100644
--- a/Services/AppThemeService.qml
+++ b/Services/AppThemeService.qml
@@ -91,11 +91,13 @@ Singleton {
Logger.log("AppThemeService", "Service started")
}
+ // --------------------------------------------------------------------------------
function generate() {
if (Settings.data.colorSchemes.useWallpaperColors) {
generateFromWallpaper()
} else {
- generateFromPredefinedScheme()
+ // Re-apply the scheme, this is the best way to regenerate all templates too.
+ ColorSchemeService.applyScheme(Settings.data.colorSchemes.predefinedScheme)
}
}
diff --git a/Services/AudioService.qml b/Services/AudioService.qml
index f600f9d9..c187c87f 100644
--- a/Services/AudioService.qml
+++ b/Services/AudioService.qml
@@ -111,6 +111,14 @@ Singleton {
}
}
+ function increaseInputVolume() {
+ setInputVolume(inputVolume + stepVolume)
+ }
+
+ function decreaseInputVolume() {
+ setInputVolume(inputVolume - stepVolume)
+ }
+
function setInputVolume(newVolume: real) {
if (source?.ready && source?.audio) {
// Clamp it accordingly
diff --git a/Services/BarWidgetRegistry.qml b/Services/BarWidgetRegistry.qml
index efb85537..1bb0199c 100644
--- a/Services/BarWidgetRegistry.qml
+++ b/Services/BarWidgetRegistry.qml
@@ -41,9 +41,11 @@ Singleton {
"ActiveWindow": {
"allowUserSettings": true,
"showIcon": true,
- "autoHide": false,
- "scrollingMode": "hover",
- "width": 145
+ "hideMode": "hidden",
+ "scrollingMode"// "visible", "hidden", "transparent"
+ : "hover",
+ "width": 145,
+ "colorizeIcons": false
},
"Battery": {
"allowUserSettings": true,
@@ -83,8 +85,9 @@ Singleton {
},
"MediaMini": {
"allowUserSettings": true,
- "autoHide": false,
- "scrollingMode": "hover",
+ "hideMode": "hidden",
+ "scrollingMode"// "visible", "hidden", "transparent"
+ : "hover",
"showAlbumArt": false,
"showVisualizer": false,
"visualizerType": "linear"
@@ -114,11 +117,13 @@ Singleton {
"Taskbar": {
"allowUserSettings": true,
"onlySameOutput": true,
- "onlyActiveWorkspaces": true
+ "onlyActiveWorkspaces": true,
+ "colorizeIcons": false
},
"Tray": {
"allowUserSettings": true,
- "blacklist": []
+ "blacklist": [],
+ "colorizeIcons": false
},
"Workspace": {
"allowUserSettings": true,
diff --git a/Services/ColorSchemeService.qml b/Services/ColorSchemeService.qml
index 19d5fc05..7e07f27a 100644
--- a/Services/ColorSchemeService.qml
+++ b/Services/ColorSchemeService.qml
@@ -150,7 +150,7 @@ Singleton {
Logger.log("ColorScheme", "Applying color scheme:", getBasename(path))
// Generate Matugen templates if any are enabled and setting allows it
- if (Settings.data.colorSchemes.generateTemplatesForPredefined && hasEnabledMatugenTemplates()) {
+ if (Settings.data.colorSchemes.generateTemplatesForPredefined && hasEnabledTemplates()) {
AppThemeService.generateFromPredefinedScheme(data)
}
} catch (e) {
@@ -159,8 +159,8 @@ Singleton {
}
}
- // Check if any Matugen templates are enabled
- function hasEnabledMatugenTemplates() {
+ // Check if any templates are enabled
+ function hasEnabledTemplates() {
return Settings.data.templates.gtk || Settings.data.templates.qt || Settings.data.templates.kitty || Settings.data.templates.ghostty || Settings.data.templates.foot || Settings.data.templates.fuzzel || Settings.data.templates.discord || Settings.data.templates.discord_vesktop || Settings.data.templates.discord_webcord
|| Settings.data.templates.discord_armcord || Settings.data.templates.discord_equibop || Settings.data.templates.discord_lightcord || Settings.data.templates.discord_dorion || Settings.data.templates.pywalfox
}
diff --git a/Services/IPCService.qml b/Services/IPCService.qml
index 70999aa1..a62e2474 100644
--- a/Services/IPCService.qml
+++ b/Services/IPCService.qml
@@ -43,6 +43,14 @@ Item {
function clear() {
NotificationService.clearHistory()
}
+
+ function dismissOldest() {
+ NotificationService.dismissOldestActive()
+ }
+
+ function dismissAll() {
+ NotificationService.dismissAllActive()
+ }
}
IpcHandler {
@@ -128,6 +136,10 @@ Item {
function toggle() {
sessionMenuPanel.toggle()
}
+
+ function lockAndSuspend() {
+ CompositorService.lockAndSuspend()
+ }
}
IpcHandler {
diff --git a/Services/NotificationService.qml b/Services/NotificationService.qml
index 2a4d23ce..249a5845 100644
--- a/Services/NotificationService.qml
+++ b/Services/NotificationService.qml
@@ -414,6 +414,13 @@ Singleton {
removeActive(id)
}
+ function dismissOldestActive() {
+ if (activeList.count > 0) {
+ const lastNotif = activeList.get(activeList.count - 1)
+ dismissActiveNotification(lastNotif.id)
+ }
+ }
+
function dismissAllActive() {
Object.values(activeMap).forEach(n => n.dismiss())
activeList.clear()
diff --git a/Services/ScalingService.qml b/Services/ScalingService.qml
deleted file mode 100644
index d85b9a3e..00000000
--- a/Services/ScalingService.qml
+++ /dev/null
@@ -1,131 +0,0 @@
-pragma Singleton
-
-import QtQuick
-import Quickshell
-import qs.Commons
-
-Singleton {
- id: root
-
- // Cache for current scales - updated via signals
- property var currentScales: ({})
-
- // Signal emitted when scale changes
- signal scaleChanged(string screenName, real scale)
-
- Component.onCompleted: {
- Logger.log("Scaling", "Service started")
- // Initialize cache from Settings once they are loaded on startup
- var monitors = Settings.data.ui.monitorsScaling || []
- for (var i = 0; i < monitors.length; i++) {
- if (monitors[i].name && monitors[i].scale !== undefined) {
- currentScales[monitors[i].name] = monitors[i].scale
- root.scaleChanged(monitors[i].name, monitors[i].scale)
- Logger.log("Scaling", "Caching scaling for", monitors[i].name, ":", monitors[i].scale)
- }
- }
- }
-
- // -------------------------------------------
- // Manual scaling via Settings
- function getScreenScale(aScreen) {
- try {
- if (aScreen !== undefined && aScreen.name !== undefined) {
- return getScreenScaleByName(aScreen.name)
- }
- } catch (e) {
-
- //Logger.warn(e)
- }
- return 1.0
- }
-
- // -------------------------------------------
- // Get scale from cache for better performance
- function getScreenScaleByName(aScreenName) {
- try {
- var scale = currentScales[aScreenName]
- if ((scale !== undefined) && (scale != null)) {
- return scale
- }
- } catch (e) {
-
- //Logger.warn(e)
- }
- return 1.0
- }
-
- // -------------------------------------------
- function setScreenScale(aScreen, scale) {
- try {
- if (aScreen !== undefined && aScreen.name !== undefined) {
- return setScreenScaleByName(aScreen.name, scale)
- }
- } catch (e) {
-
- //Logger.warn(e)
- }
- }
-
- // -------------------------------------------
- function setScreenScaleByName(aScreenName, scale) {
- try {
- // Check if scale actually changed
- var oldScale = currentScales[aScreenName] || 1.0
- if (oldScale === scale) {
- return
- // No change needed
- }
-
- // Update cache directly
- currentScales[aScreenName] = scale
-
- // Update Settings with immutable update for proper persistence
- var monitors = Settings.data.ui.monitorsScaling || []
- var found = false
-
- var newMonitors = monitors.map(function (monitor) {
- if (monitor.name === aScreenName) {
- found = true
- return {
- "name": aScreenName,
- "scale": scale
- }
- }
- return monitor
- })
-
- if (!found) {
- newMonitors.push({
- "name": aScreenName,
- "scale": scale
- })
- }
-
- // Use slice() to ensure Settings detects the change
- Settings.data.ui.monitorsScaling = newMonitors.slice()
-
- // Emit signal for components to react
- root.scaleChanged(aScreenName, scale)
-
- Logger.log("Scaling", "Scale changed for", aScreenName, "to", scale)
- } catch (e) {
- Logger.warn("Scaling", "Error setting scale:", e)
- }
- }
-
- // -------------------------------------------
- // Dynamic scaling based on resolution
- // Design reference resolution (for scale = 1.0)
- readonly property int designScreenWidth: 2560
- readonly property int designScreenHeight: 1440
- function dynamicScale(aScreen) {
- return 1.0
- // if (aScreen != null) {
- // var ratioW = aScreen.width / designScreenWidth
- // var ratioH = aScreen.height / designScreenHeight
- // return Math.min(ratioW, ratioH)
- // }
- // return 1.0
- }
-}
diff --git a/Services/ScreenRecorderService.qml b/Services/ScreenRecorderService.qml
index 7e57ce75..57fc578a 100644
--- a/Services/ScreenRecorderService.qml
+++ b/Services/ScreenRecorderService.qml
@@ -49,7 +49,7 @@ Singleton {
function launchRecorder() {
var filename = Time.getFormattedTimestamp() + ".mp4"
- var videoDir = settings.directory
+ var videoDir = Settings.preprocessPath(settings.directory)
if (videoDir && !videoDir.endsWith("/")) {
videoDir += "/"
}
diff --git a/Services/UpdateService.qml b/Services/UpdateService.qml
index b826fc69..c738d6e3 100644
--- a/Services/UpdateService.qml
+++ b/Services/UpdateService.qml
@@ -8,7 +8,7 @@ Singleton {
id: root
// Public properties
- property string baseVersion: "2.17.2"
+ property string baseVersion: "2.17.3"
property bool isDevelopment: true
property string currentVersion: `v${!isDevelopment ? baseVersion : baseVersion + "-dev"}`
diff --git a/Services/WallpaperService.qml b/Services/WallpaperService.qml
index c60f2eba..2046f6cc 100644
--- a/Services/WallpaperService.qml
+++ b/Services/WallpaperService.qml
@@ -10,6 +10,7 @@ Singleton {
id: root
readonly property ListModel fillModeModel: ListModel {}
+ readonly property string defaultDirectory: Settings.preprocessPath(Settings.data.wallpaper.directory)
// All available wallpaper transitions
readonly property ListModel transitionsModel: ListModel {}
@@ -44,7 +45,7 @@ Singleton {
if (!Settings.data.wallpaper.enableMultiMonitorDirectories) {
// All monitors use the main directory
for (var i = 0; i < Quickshell.screens.length; i++) {
- root.wallpaperDirectoryChanged(Quickshell.screens[i].name, Settings.data.wallpaper.directory)
+ root.wallpaperDirectoryChanged(Quickshell.screens[i].name, root.defaultDirectory)
}
} else {
// Only monitors without custom directories are affected
@@ -52,7 +53,7 @@ Singleton {
var screenName = Quickshell.screens[i].name
var monitor = root.getMonitorConfig(screenName)
if (!monitor || !monitor.directory) {
- root.wallpaperDirectoryChanged(screenName, Settings.data.wallpaper.directory)
+ root.wallpaperDirectoryChanged(screenName, root.defaultDirectory)
}
}
}
@@ -177,16 +178,16 @@ Singleton {
// Get specific monitor directory
function getMonitorDirectory(screenName) {
if (!Settings.data.wallpaper.enableMultiMonitorDirectories) {
- return Settings.data.wallpaper.directory
+ return root.defaultDirectory
}
var monitor = getMonitorConfig(screenName)
if (monitor !== undefined && monitor.directory !== undefined) {
- return monitor.directory
+ return Settings.preprocessPath(monitor.directory)
}
// Fall back to the main/single directory
- return Settings.data.wallpaper.directory
+ return root.defaultDirectory
}
// -------------------------------------------------------------------
@@ -218,7 +219,7 @@ Singleton {
// Update Settings with new array to ensure proper persistence
Settings.data.wallpaper.monitors = newMonitors.slice()
- root.wallpaperDirectoryChanged(screenName, directory)
+ root.wallpaperDirectoryChanged(screenName, Settings.preprocessPath(directory))
}
// -------------------------------------------------------------------
@@ -274,7 +275,7 @@ Singleton {
found = true
return {
"name": screenName,
- "directory": monitor.directory || getMonitorDirectory(screenName),
+ "directory": Settings.preprocessPath(monitor.directory) || getMonitorDirectory(screenName),
"wallpaper": path
}
}
diff --git a/Shaders/frag/appicon_colorize.frag b/Shaders/frag/appicon_colorize.frag
new file mode 100644
index 00000000..ae108701
--- /dev/null
+++ b/Shaders/frag/appicon_colorize.frag
@@ -0,0 +1,29 @@
+#version 450
+layout(location = 0) in vec2 qt_TexCoord0;
+layout(location = 0) out vec4 fragColor;
+layout(binding = 1) uniform sampler2D source;
+layout(std140, binding = 0) uniform buf {
+ mat4 qt_Matrix;
+ float qt_Opacity;
+ vec4 targetColor;
+ float colorizeMode; // 0.0 = dock mode (grayscale), 1.0 = tray mode (intensity)
+} ubuf;
+
+void main() {
+ vec4 tex = texture(source, qt_TexCoord0);
+
+ float intensity;
+
+ if (ubuf.colorizeMode < 0.5) {
+ // Dock mode: Convert to grayscale using proper luminance weights
+ intensity = dot(tex.rgb, vec3(0.299, 0.587, 0.114));
+ } else {
+ // Tray mode: Use the maximum RGB channel value as intensity
+ intensity = max(max(tex.r, tex.g), tex.b);
+
+ // Normalize intensity to make all icons more uniform
+ intensity = smoothstep(0.1, 0.9, intensity);
+ }
+
+ fragColor = vec4(ubuf.targetColor.rgb * intensity, tex.a) * ubuf.qt_Opacity;
+}
diff --git a/Shaders/qsb/appicon_colorize.frag.qsb b/Shaders/qsb/appicon_colorize.frag.qsb
new file mode 100644
index 00000000..15618b86
Binary files /dev/null and b/Shaders/qsb/appicon_colorize.frag.qsb differ
diff --git a/Shaders/qsb/progress_border.frag.qsb b/Shaders/qsb/progress_border.frag.qsb
new file mode 100644
index 00000000..e6e8f315
Binary files /dev/null and b/Shaders/qsb/progress_border.frag.qsb differ
diff --git a/Widgets/NBox.qml b/Widgets/NBox.qml
index 4dad5c68..72ab90f0 100644
--- a/Widgets/NBox.qml
+++ b/Widgets/NBox.qml
@@ -12,7 +12,7 @@ Rectangle {
implicitHeight: childrenRect.height
color: Color.mSurfaceVariant
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
}
diff --git a/Widgets/NBusyIndicator.qml b/Widgets/NBusyIndicator.qml
index 67f104ae..bf93abe8 100644
--- a/Widgets/NBusyIndicator.qml
+++ b/Widgets/NBusyIndicator.qml
@@ -7,8 +7,8 @@ Item {
property bool running: true
property color color: Color.mPrimary
- property int size: Style.baseWidgetSize * scaling
- property int strokeWidth: Style.borderL * scaling
+ property int size: Style.baseWidgetSize
+ property int strokeWidth: Style.borderL
property int duration: Style.animationSlow * 2
implicitWidth: size
diff --git a/Widgets/NButton.qml b/Widgets/NButton.qml
index 3d1b05a3..654de952 100644
--- a/Widgets/NButton.qml
+++ b/Widgets/NButton.qml
@@ -15,9 +15,9 @@ Rectangle {
property color textColor: Color.mOnPrimary
property color hoverColor: Color.mTertiary
property bool enabled: true
- property real fontSize: Style.fontSizeM * scaling
+ property real fontSize: Style.fontSizeM
property int fontWeight: Style.fontWeightBold
- property real iconSize: Style.fontSizeL * scaling
+ property real iconSize: Style.fontSizeL
property bool outlined: false
property int horizontalAlignment: Qt.AlignHCenter
@@ -30,11 +30,11 @@ Rectangle {
property bool hovered: false
// Dimensions
- implicitWidth: contentRow.implicitWidth + (Style.marginL * 2 * scaling)
- implicitHeight: Math.max(Style.baseWidgetSize * scaling, contentRow.implicitHeight + (Style.marginM * scaling))
+ implicitWidth: contentRow.implicitWidth + (Style.marginL * 2)
+ implicitHeight: Math.max(Style.baseWidgetSize, contentRow.implicitHeight + (Style.marginM))
// Appearance
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
color: {
if (!enabled)
return outlined ? Color.transparent : Qt.lighter(Color.mSurfaceVariant, 1.2)
@@ -43,7 +43,7 @@ Rectangle {
return outlined ? Color.transparent : backgroundColor
}
- border.width: outlined ? Math.max(1, Style.borderS * scaling) : 0
+ border.width: outlined ? Math.max(1, Style.borderS) : 0
border.color: {
if (!enabled)
return Color.mOutline
@@ -74,8 +74,8 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
anchors.left: root.horizontalAlignment === Qt.AlignLeft ? parent.left : undefined
anchors.horizontalCenter: root.horizontalAlignment === Qt.AlignHCenter ? parent.horizontalCenter : undefined
- anchors.leftMargin: root.horizontalAlignment === Qt.AlignLeft ? Style.marginL * scaling : 0
- spacing: Style.marginXS * scaling
+ anchors.leftMargin: root.horizontalAlignment === Qt.AlignLeft ? Style.marginL : 0
+ spacing: Style.marginXS
// Icon (optional)
NIcon {
diff --git a/Widgets/NCheckbox.qml b/Widgets/NCheckbox.qml
index 4ea76318..f27694e6 100644
--- a/Widgets/NCheckbox.qml
+++ b/Widgets/NCheckbox.qml
@@ -6,7 +6,7 @@ import qs.Commons
RowLayout {
id: root
- // Public API (mirrors NToggle but compact)
+ // Public API
property string label: ""
property string description: ""
property bool checked: false
@@ -35,12 +35,12 @@ RowLayout {
Rectangle {
id: box
- implicitWidth: Math.round(root.baseSize * scaling)
- implicitHeight: Math.round(root.baseSize * scaling)
- radius: Style.radiusXS * scaling
+ implicitWidth: Math.round(root.baseSize)
+ implicitHeight: Math.round(root.baseSize)
+ radius: Style.radiusXS
color: root.checked ? root.activeColor : Color.mSurface
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
Behavior on color {
ColorAnimation {
@@ -57,10 +57,10 @@ RowLayout {
NIcon {
visible: root.checked
anchors.centerIn: parent
- anchors.horizontalCenterOffset: -1 * scaling
+ anchors.horizontalCenterOffset: -1
icon: "check"
color: root.activeOnColor
- pointSize: Math.max(Style.fontSizeXS, root.baseSize * 0.5) * scaling
+ pointSize: Math.max(Style.fontSizeXS, root.baseSize * 0.5)
font.weight: Style.fontWeightBold
}
diff --git a/Widgets/NCircleStat.qml b/Widgets/NCircleStat.qml
index f6d4332d..3279084e 100644
--- a/Widgets/NCircleStat.qml
+++ b/Widgets/NCircleStat.qml
@@ -17,12 +17,12 @@ Rectangle {
// outer width/height footprint of the component
property real contentScale: 1.0
- width: 68 * scaling
- height: 92 * scaling
+ width: 68
+ height: 92
color: flat ? Color.transparent : Color.mSurface
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
border.color: flat ? Color.transparent : Color.mSurfaceVariant
- border.width: flat ? 0 : Math.max(1, Style.borderS * scaling)
+ border.width: flat ? 0 : Math.max(1, Style.borderS)
// Repaint gauge when the bound value changes
onValueChanged: gauge.requestPaint()
@@ -30,7 +30,7 @@ Rectangle {
ColumnLayout {
id: mainLayout
anchors.fill: parent
- anchors.margins: Style.marginS * scaling * contentScale
+ anchors.margins: Style.marginS * contentScale
spacing: 0
// Main gauge container
@@ -39,19 +39,19 @@ Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignCenter
- Layout.preferredWidth: 68 * scaling * contentScale
- Layout.preferredHeight: 68 * scaling * contentScale
+ Layout.preferredWidth: 68 * contentScale
+ Layout.preferredHeight: 68 * contentScale
Canvas {
id: gauge
anchors.fill: parent
- renderStrategy: Canvas.Cooperative
+ renderStrategy: Canvas.Immediate
onPaint: {
const ctx = getContext("2d")
const w = width, h = height
const cx = w / 2, cy = h / 2
- const r = Math.min(w, h) / 2 - 5 * scaling * contentScale
+ const r = Math.min(w, h) / 2 - 5 * contentScale
// Rotated 90° to the right: gap at the bottom
// Start at 150° and end at 390° (30°) → bottom opening
@@ -59,7 +59,7 @@ Rectangle {
const endBg = Math.PI * 13 / 6 // 390° (equivalent to 30°)
ctx.reset()
- ctx.lineWidth = 6 * scaling * contentScale
+ ctx.lineWidth = 6 * contentScale
// Track uses surface for stronger contrast
ctx.strokeStyle = Color.mSurface
@@ -96,9 +96,9 @@ Rectangle {
NText {
id: valueLabel
anchors.centerIn: parent
- anchors.verticalCenterOffset: -4 * scaling * contentScale
+ anchors.verticalCenterOffset: -4 * contentScale
text: `${root.value}${root.suffix}`
- pointSize: Style.fontSizeM * scaling * contentScale * 0.9
+ pointSize: Style.fontSizeM * contentScale * 0.9
font.weight: Style.fontWeightBold
color: Color.mOnSurface
horizontalAlignment: Text.AlignHCenter
@@ -108,10 +108,10 @@ Rectangle {
id: iconText
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: valueLabel.bottom
- anchors.topMargin: 8 * scaling * contentScale
+ anchors.topMargin: 8 * contentScale
icon: root.icon
color: Color.mPrimary
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
diff --git a/Widgets/NCollapsible.qml b/Widgets/NCollapsible.qml
index 6b78f4fd..3834220e 100644
--- a/Widgets/NCollapsible.qml
+++ b/Widgets/NCollapsible.qml
@@ -8,7 +8,7 @@ ColumnLayout {
property string description: ""
property bool expanded: false
property bool defaultExpanded: false
- property real contentSpacing: Style.marginM * scaling
+ property real contentSpacing: Style.marginM
signal toggled(bool expanded)
Layout.fillWidth: true
@@ -21,15 +21,15 @@ ColumnLayout {
Rectangle {
id: headerContainer
Layout.fillWidth: true
- Layout.preferredHeight: headerContent.implicitHeight + (Style.marginM * scaling * 2)
+ Layout.preferredHeight: headerContent.implicitHeight + (Style.marginM * 2)
// Material 3 style background
color: root.expanded ? Color.mSecondary : Color.mSurfaceVariant
- radius: Style.radiusL * scaling
+ radius: Style.radiusL
// Subtle border
border.color: root.expanded ? Color.mOnSecondary : Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
// Smooth color transitions
Behavior on color {
@@ -75,14 +75,14 @@ ColumnLayout {
RowLayout {
id: headerContent
anchors.fill: parent
- anchors.margins: Style.marginM * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginM
+ spacing: Style.marginM
// Expand/collapse icon with rotation animation
NIcon {
id: chevronIcon
icon: "chevron-right"
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: root.expanded ? Color.mOnSecondary : Color.mOnSurfaceVariant
Layout.alignment: Qt.AlignVCenter
@@ -105,11 +105,11 @@ ColumnLayout {
RowLayout {
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
NText {
text: root.label
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightSemiBold
color: root.expanded ? Color.mOnSecondary : Color.mOnSurface
wrapMode: Text.WordWrap
@@ -123,7 +123,7 @@ ColumnLayout {
NText {
text: root.description
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
font.weight: Style.fontWeightRegular
color: root.expanded ? Color.mOnSecondary : Color.mOnSurfaceVariant
Layout.fillWidth: true
@@ -145,16 +145,16 @@ ColumnLayout {
Rectangle {
id: contentContainer
Layout.fillWidth: true
- Layout.topMargin: Style.marginS * scaling
+ Layout.topMargin: Style.marginS
visible: root.expanded
color: Color.mSurface
- radius: Style.radiusL * scaling
+ radius: Style.radiusL
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
// Dynamic height based on content
- Layout.preferredHeight: visible ? contentLayout.implicitHeight + (Style.marginL * scaling * 2) : 0
+ Layout.preferredHeight: visible ? contentLayout.implicitHeight + (Style.marginL * 2) : 0
// Smooth height animation
Behavior on Layout.preferredHeight {
@@ -168,7 +168,7 @@ ColumnLayout {
ColumnLayout {
id: contentLayout
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
+ anchors.margins: Style.marginL
spacing: root.contentSpacing
}
diff --git a/Widgets/NColorPicker.qml b/Widgets/NColorPicker.qml
index 642d74a9..4aa9b46f 100644
--- a/Widgets/NColorPicker.qml
+++ b/Widgets/NColorPicker.qml
@@ -12,13 +12,13 @@ Rectangle {
signal colorSelected(color color)
- implicitWidth: 150 * scaling
- implicitHeight: Math.round(Style.baseWidgetSize * 1.1 * scaling)
+ implicitWidth: 150
+ implicitHeight: Math.round(Style.baseWidgetSize * 1.1)
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
color: Color.mSurface
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
// Minimized Look
MouseArea {
@@ -41,19 +41,19 @@ Rectangle {
RowLayout {
anchors.fill: parent
anchors {
- leftMargin: Style.marginL * scaling
- rightMargin: Style.marginL * scaling
+ leftMargin: Style.marginL
+ rightMargin: Style.marginL
}
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
// Color preview circle
Rectangle {
- Layout.preferredWidth: root.height * 0.6 * scaling
- Layout.preferredHeight: root.height * 0.6 * scaling
+ Layout.preferredWidth: root.height * 0.6
+ Layout.preferredHeight: root.height * 0.6
radius: Layout.preferredWidth * 0.5
color: root.selectedColor
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
}
NText {
diff --git a/Widgets/NColorPickerDialog.qml b/Widgets/NColorPickerDialog.qml
index de6bb0e9..364dd8f9 100644
--- a/Widgets/NColorPickerDialog.qml
+++ b/Widgets/NColorPickerDialog.qml
@@ -14,12 +14,12 @@ Popup {
signal colorSelected(color color)
- width: 580 * scaling
+ width: 580
height: {
const h = scrollView.implicitHeight + padding * 2
- Math.min(h, screen?.height - Style.barHeight * scaling - Style.marginL * 2)
+ Math.min(h, screen?.height - Style.barHeight - Style.marginL * 2)
}
- padding: Style.marginXL * scaling
+ padding: Style.marginXL
// Center popup in parent
x: (parent.width - width) * 0.5
@@ -112,9 +112,9 @@ Popup {
background: Rectangle {
color: Color.mSurface
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
border.color: Color.mPrimary
- border.width: Math.max(1, Style.borderM * scaling)
+ border.width: Math.max(1, Style.borderM)
}
contentItem: NScrollView {
@@ -126,24 +126,24 @@ Popup {
ColumnLayout {
width: scrollView.availableWidth
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
// Header
RowLayout {
Layout.fillWidth: true
RowLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
NIcon {
icon: "color-picker"
- pointSize: Style.fontSizeXXL * scaling
+ pointSize: Style.fontSizeXXL
color: Color.mPrimary
}
NText {
text: I18n.tr("widgets.color-picker.title")
- pointSize: Style.fontSizeXL * scaling
+ pointSize: Style.fontSizeXL
font.weight: Style.fontWeightBold
color: Color.mPrimary
}
@@ -162,11 +162,11 @@ Popup {
// Color preview section
Rectangle {
Layout.fillWidth: true
- Layout.preferredHeight: 80 * scaling
- radius: Style.radiusS * scaling
+ Layout.preferredHeight: 80
+ radius: Style.radiusS
color: root.selectedColor
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
ColumnLayout {
spacing: 0
@@ -179,7 +179,7 @@ Popup {
NText {
text: root.selectedColor.toString().toUpperCase()
family: Settings.data.ui.fontFixed
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Font.Bold
color: root.selectedColor.r + root.selectedColor.g + root.selectedColor.b > 1.5 ? "#000000" : "#FFFFFF"
Layout.alignment: Qt.AlignHCenter
@@ -188,7 +188,7 @@ Popup {
NText {
text: "RGB(" + Math.round(root.selectedColor.r * 255) + ", " + Math.round(root.selectedColor.g * 255) + ", " + Math.round(root.selectedColor.b * 255) + ")"
family: Settings.data.ui.fontFixed
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: root.selectedColor.r + root.selectedColor.g + root.selectedColor.b > 1.5 ? "#000000" : "#FFFFFF"
Layout.alignment: Qt.AlignHCenter
}
@@ -202,7 +202,7 @@ Popup {
// Hex input
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NLabel {
label: I18n.tr("widgets.color-picker.hex.label")
@@ -225,13 +225,13 @@ Popup {
// RGB sliders section
NBox {
Layout.fillWidth: true
- Layout.preferredHeight: slidersSection.implicitHeight + Style.marginL * scaling * 2
+ Layout.preferredHeight: slidersSection.implicitHeight + Style.marginL * 2
ColumnLayout {
id: slidersSection
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginM
NLabel {
label: I18n.tr("widgets.color-picker.rgb.label")
@@ -241,12 +241,12 @@ Popup {
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NText {
text: "R"
font.weight: Font.Bold
- Layout.preferredWidth: 20 * scaling
+ Layout.preferredWidth: 20
}
NValueSlider {
@@ -267,12 +267,12 @@ Popup {
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NText {
text: "G"
font.weight: Font.Bold
- Layout.preferredWidth: 20 * scaling
+ Layout.preferredWidth: 20
}
NValueSlider {
@@ -294,12 +294,12 @@ Popup {
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NText {
text: "B"
font.weight: Font.Bold
- Layout.preferredWidth: 20 * scaling
+ Layout.preferredWidth: 20
}
NValueSlider {
@@ -321,12 +321,12 @@ Popup {
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NText {
text: I18n.tr("widgets.color-picker.brightness")
font.weight: Font.Bold
- Layout.preferredWidth: 80 * scaling
+ Layout.preferredWidth: 80
}
NValueSlider {
@@ -361,13 +361,13 @@ Popup {
NBox {
Layout.fillWidth: true
- Layout.preferredHeight: themePalette.implicitHeight + Style.marginL * scaling * 2
+ Layout.preferredHeight: themePalette.implicitHeight + Style.marginL * 2
ColumnLayout {
id: themePalette
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
- spacing: Style.marginS * scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginS
NLabel {
label: I18n.tr("widgets.color-picker.theme-colors.label")
@@ -376,7 +376,7 @@ Popup {
}
Flow {
- spacing: 6 * scaling
+ spacing: 6
Layout.fillWidth: true
flow: Flow.LeftToRight
@@ -384,12 +384,12 @@ Popup {
model: [Color.mPrimary, Color.mSecondary, Color.mTertiary, Color.mError, Color.mSurface, Color.mSurfaceVariant, Color.mOutline, "#FFFFFF", "#000000"]
Rectangle {
- width: 24 * scaling
- height: 24 * scaling
- radius: 4 * scaling
+ width: 24
+ height: 24
+ radius: 4
color: modelData
border.color: root.selectedColor === modelData ? Color.mPrimary : Color.mOutline
- border.width: root.selectedColor === modelData ? 2 * scaling : 1 * scaling
+ border.width: root.selectedColor === modelData ? 2 : 1
MouseArea {
anchors.fill: parent
@@ -409,13 +409,13 @@ Popup {
NBox {
Layout.fillWidth: true
- Layout.preferredHeight: genericPalette.implicitHeight + Style.marginL * scaling * 2
+ Layout.preferredHeight: genericPalette.implicitHeight + Style.marginL * 2
ColumnLayout {
id: genericPalette
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
- spacing: Style.marginS * scaling
+ anchors.margins: Style.marginL
+ spacing: Style.marginS
NLabel {
label: I18n.tr("widgets.color-picker.palette.label")
@@ -426,19 +426,19 @@ Popup {
Flow {
Layout.fillWidth: true
Layout.fillHeight: true
- spacing: 6 * scaling
+ spacing: 6
flow: Flow.LeftToRight
Repeater {
model: ["#F44336", "#E91E63", "#9C27B0", "#673AB7", "#3F51B5", "#2196F3", "#03A9F4", "#00BCD4", "#009688", "#4CAF50", "#8BC34A", "#CDDC39", "#FFEB3B", "#FFC107", "#FF9800", "#FF5722", "#795548", "#9E9E9E", "#E74C3C", "#E67E22", "#F1C40F", "#2ECC71", "#1ABC9C", "#3498DB", "#2980B9", "#9B59B6", "#34495E", "#2C3E50", "#95A5A6", "#7F8C8D", "#FFFFFF", "#000000"]
Rectangle {
- width: 24 * scaling
- height: 24 * scaling
- radius: Style.radiusXXS * scaling
+ width: 24
+ height: 24
+ radius: Style.radiusXXS
color: modelData
border.color: root.selectedColor === modelData ? Color.mPrimary : Color.mOutline
- border.width: Math.max(1, root.selectedColor === modelData ? Style.borderM * scaling : Style.borderS * scaling)
+ border.width: Math.max(1, root.selectedColor === modelData ? Style.borderM : Style.borderS)
MouseArea {
anchors.fill: parent
@@ -458,9 +458,9 @@ Popup {
RowLayout {
Layout.fillWidth: true
- Layout.topMargin: 20 * scaling
- Layout.bottomMargin: 20 * scaling
- spacing: 10 * scaling
+ Layout.topMargin: 20
+ Layout.bottomMargin: 20
+ spacing: 10
Item {
Layout.fillWidth: true
diff --git a/Widgets/NComboBox.qml b/Widgets/NComboBox.qml
index a7a054b5..00f29bb1 100644
--- a/Widgets/NComboBox.qml
+++ b/Widgets/NComboBox.qml
@@ -8,8 +8,8 @@ import qs.Widgets
RowLayout {
id: root
- property real minimumWidth: 280 * scaling
- property real popupHeight: 180 * scaling
+ property real minimumWidth: 280 * Style.uiScaleRatio
+ property real popupHeight: 180 * Style.uiScaleRatio
property string label: ""
property string description: ""
@@ -17,11 +17,11 @@ RowLayout {
property string currentKey: ""
property string placeholder: ""
- readonly property real preferredHeight: Style.baseWidgetSize * 1.1 * scaling
+ readonly property real preferredHeight: Style.baseWidgetSize * 1.1 * Style.uiScaleRatio
signal selected(string key)
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
function itemCount() {
@@ -72,12 +72,12 @@ RowLayout {
}
background: Rectangle {
- implicitWidth: Style.baseWidgetSize * 3.75 * scaling
+ implicitWidth: Style.baseWidgetSize * 3.75
implicitHeight: preferredHeight
color: Color.mSurface
border.color: combo.activeFocus ? Color.mSecondary : Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
- radius: Style.radiusM * scaling
+ border.width: Math.max(1, Style.borderS)
+ radius: Style.radiusM
Behavior on border.color {
ColorAnimation {
@@ -87,9 +87,9 @@ RowLayout {
}
contentItem: NText {
- leftPadding: Style.marginL * scaling
- rightPadding: combo.indicator.width + Style.marginL * scaling
- pointSize: Style.fontSizeM * scaling
+ leftPadding: Style.marginL
+ rightPadding: combo.indicator.width + Style.marginL
+ pointSize: Style.fontSizeM
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
color: (combo.currentIndex >= 0 && combo.currentIndex < itemCount()) ? Color.mOnSurface : Color.mOnSurfaceVariant
@@ -97,17 +97,17 @@ RowLayout {
}
indicator: NIcon {
- x: combo.width - width - Style.marginM * scaling
+ x: combo.width - width - Style.marginM
y: combo.topPadding + (combo.availableHeight - height) / 2
icon: "caret-down"
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
}
popup: Popup {
y: combo.height
- implicitWidth: combo.width - Style.marginM * scaling
- implicitHeight: Math.min(root.popupHeight, contentItem.implicitHeight + Style.marginM * scaling * 2)
- padding: Style.marginM * scaling
+ implicitWidth: combo.width - Style.marginM
+ implicitHeight: Math.min(root.popupHeight, contentItem.implicitHeight + Style.marginM * 2)
+ padding: Style.marginM
onOpened: {
PanelService.willOpenPopup(root)
@@ -144,9 +144,9 @@ RowLayout {
}
background: Rectangle {
- width: combo.width - Style.marginM * scaling * 3
+ width: combo.width - Style.marginM * 3
color: highlighted ? Color.mTertiary : Color.transparent
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
Behavior on color {
ColorAnimation {
duration: Style.animationFast
@@ -159,7 +159,7 @@ RowLayout {
var item = root.getItem(index)
return item && item.name ? item.name : ""
}
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: highlighted ? Color.mOnTertiary : Color.mOnSurface
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
@@ -175,8 +175,8 @@ RowLayout {
background: Rectangle {
color: Color.mSurfaceVariant
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
- radius: Style.radiusM * scaling
+ border.width: Math.max(1, Style.borderS)
+ radius: Style.radiusM
}
}
diff --git a/Widgets/NContextMenu.qml b/Widgets/NContextMenu.qml
index 126f2892..9f8e833e 100644
--- a/Widgets/NContextMenu.qml
+++ b/Widgets/NContextMenu.qml
@@ -8,13 +8,13 @@ Popup {
id: root
property alias model: listView.model
- property real itemHeight: 36 * scaling
- property real itemPadding: Style.marginM * scaling
+ property real itemHeight: 36
+ property real itemPadding: Style.marginM
signal triggered(string action)
- width: 180 * scaling
- padding: Style.marginS * scaling
+ width: 180
+ padding: Style.marginS
onOpened: PanelService.willOpenPopup(root)
onClosed: PanelService.willClosePopup(root)
@@ -22,14 +22,14 @@ Popup {
background: Rectangle {
color: Color.mSurfaceVariant
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
- radius: Style.radiusM * scaling
+ border.width: Math.max(1, Style.borderS)
+ radius: Style.radiusM
}
contentItem: NListView {
id: listView
implicitHeight: contentHeight
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
interactive: contentHeight > root.height
delegate: ItemDelegate {
@@ -45,7 +45,7 @@ Popup {
background: Rectangle {
color: menuItem.hovered && menuItem.enabled ? Color.mTertiary : Color.transparent
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
Behavior on color {
ColorAnimation {
@@ -55,13 +55,13 @@ Popup {
}
contentItem: RowLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
// Optional icon
NIcon {
visible: modelData.icon !== undefined
icon: modelData.icon || ""
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: menuItem.hovered && menuItem.enabled ? Color.mOnTertiary : Color.mOnSurface
Layout.leftMargin: root.itemPadding
@@ -74,7 +74,7 @@ Popup {
NText {
text: modelData.label || modelData.text || ""
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: menuItem.hovered && menuItem.enabled ? Color.mOnTertiary : Color.mOnSurface
verticalAlignment: Text.AlignVCenter
Layout.fillWidth: true
diff --git a/Widgets/NDateTimeTokens.qml b/Widgets/NDateTimeTokens.qml
index 1ad1ec94..4f6c2b9e 100644
--- a/Widgets/NDateTimeTokens.qml
+++ b/Widgets/NDateTimeTokens.qml
@@ -7,8 +7,8 @@ Rectangle {
id: root
color: Color.mSurface
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
- radius: Style.radiusM * scaling
+ border.width: Math.max(1, Style.borderS)
+ radius: Style.radiusM
property date sampleDate: new Date() // Dec 25, 2023, 2:30:45.123 PM
@@ -18,8 +18,8 @@ Rectangle {
ColumnLayout {
id: column
anchors.fill: parent
- anchors.margins: Style.marginS * scaling
- spacing: Style.marginS * scaling
+ anchors.margins: Style.marginS
+ spacing: Style.marginS
NListView {
id: tokensList
@@ -174,8 +174,8 @@ Rectangle {
delegate: Rectangle {
id: tokenDelegate
width: tokensList.width
- height: layout.implicitHeight + Style.marginS * scaling
- radius: Style.radiusS * scaling
+ height: layout.implicitHeight + Style.marginS
+ radius: Style.radiusS
color: {
if (tokenMouseArea.containsMouse) {
return Qt.alpha(Color.mPrimary, 0.1)
@@ -216,16 +216,16 @@ Rectangle {
RowLayout {
id: layout
anchors.fill: parent
- anchors.margins: Style.marginXS * scaling
- spacing: Style.marginM * scaling
+ anchors.margins: Style.marginXS
+ spacing: Style.marginM
// Category badge
Rectangle {
Layout.alignment: Qt.AlignVCenter
- width: 70 * scaling
- height: 22 * scaling
+ width: 70
+ height: 22
color: getCategoryColor(modelData.category)[0]
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
opacity: tokenMouseArea.containsMouse ? 0.9 : 1.0
Behavior on opacity {
@@ -238,7 +238,7 @@ Rectangle {
anchors.centerIn: parent
text: modelData.category
color: getCategoryColor(modelData.category)[1]
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
}
}
@@ -246,10 +246,10 @@ Rectangle {
Rectangle {
id: tokenButton
Layout.alignment: Qt.AlignVCenter // Added this line
- width: 100 * scaling
- height: 22 * scaling
+ width: 100
+ height: 22
color: tokenMouseArea.containsMouse ? Color.mPrimary : Color.mOnSurface
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
Behavior on color {
ColorAnimation {
@@ -261,7 +261,7 @@ Rectangle {
anchors.centerIn: parent
text: modelData.token
color: tokenMouseArea.containsMouse ? Color.mOnPrimary : Color.mSurface
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
font.weight: Style.fontWeightBold
Behavior on color {
@@ -278,7 +278,7 @@ Rectangle {
Layout.alignment: Qt.AlignVCenter // Added this line
text: modelData.description
color: tokenMouseArea.containsMouse ? Color.mOnSurface : Color.mOnSurfaceVariant
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
wrapMode: Text.WordWrap
Behavior on color {
@@ -291,12 +291,12 @@ Rectangle {
// Live example
Rectangle {
Layout.alignment: Qt.AlignVCenter // Added this line
- width: 90 * scaling
- height: 22 * scaling
+ width: 90
+ height: 22
color: tokenMouseArea.containsMouse ? Color.mPrimary : Color.mOnSurfaceVariant
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
border.color: tokenMouseArea.containsMouse ? Color.mPrimary : Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
Behavior on color {
ColorAnimation {
@@ -314,7 +314,7 @@ Rectangle {
anchors.centerIn: parent
text: Qt.locale().toString(root.sampleDate, modelData.token)
color: tokenMouseArea.containsMouse ? Color.mOnPrimary : Color.mSurfaceVariant
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
Behavior on color {
ColorAnimation {
diff --git a/Widgets/NDivider.qml b/Widgets/NDivider.qml
index a95df11d..98f4d1d4 100644
--- a/Widgets/NDivider.qml
+++ b/Widgets/NDivider.qml
@@ -6,7 +6,7 @@ import qs.Services
Rectangle {
width: parent.width
- height: Math.max(1, Style.borderS * scaling)
+ height: Math.max(1, Style.borderS)
gradient: Gradient {
orientation: Gradient.Horizontal
GradientStop {
diff --git a/Widgets/NFilePicker.qml b/Widgets/NFilePicker.qml
index 4013c59c..4fd7875e 100644
--- a/Widgets/NFilePicker.qml
+++ b/Widgets/NFilePicker.qml
@@ -19,7 +19,7 @@ Popup {
property var nameFilters: ["*"]
property bool showDirs: true
property bool showHiddenFiles: false
- property real scaling: 1.0
+
property var selectedPaths: []
property string currentPath: initialPath
property bool shouldResetSelection: false
@@ -137,23 +137,23 @@ Popup {
}
}
- width: 900 * scaling
- height: 700 * scaling
+ width: 900
+ height: 700
modal: true
closePolicy: Popup.CloseOnEscape
anchors.centerIn: Overlay.overlay
background: Rectangle {
color: Color.mSurfaceVariant
- radius: Style.radiusL * scaling
+ radius: Style.radiusL
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
}
Rectangle {
id: filePickerPanel
anchors.fill: parent
- anchors.margins: Style.marginL * scaling
+ anchors.margins: Style.marginL
color: Color.transparent
property string filterText: ""
@@ -181,21 +181,21 @@ Popup {
ColumnLayout {
anchors.fill: parent
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Header
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NIcon {
icon: "filepicker-folder"
color: Color.mPrimary
- pointSize: Style.fontSizeXXL * scaling
+ pointSize: Style.fontSizeXXL
}
NText {
text: root.title
- pointSize: Style.fontSizeXL * scaling
+ pointSize: Style.fontSizeXL
font.weight: Style.fontWeightBold
color: Color.mPrimary
Layout.fillWidth: true
@@ -240,19 +240,19 @@ Popup {
// Navigation toolbar
Rectangle {
Layout.fillWidth: true
- Layout.preferredHeight: 45 * scaling
+ Layout.preferredHeight: 45
color: Color.mSurfaceVariant
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: Style.marginS * scaling
- anchors.rightMargin: Style.marginS * scaling
- spacing: Style.marginS * scaling
+ anchors.leftMargin: Style.marginS
+ anchors.rightMargin: Style.marginS
+ spacing: Style.marginS
NIconButton {
icon: "filepicker-arrow-up"
@@ -339,25 +339,25 @@ Popup {
// Search bar
Rectangle {
Layout.fillWidth: true
- Layout.preferredHeight: 45 * scaling
+ Layout.preferredHeight: 45
color: Color.mSurfaceVariant
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
visible: filePickerPanel.showSearchBar
RowLayout {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
- anchors.leftMargin: Style.marginS * scaling
- anchors.rightMargin: Style.marginS * scaling
- spacing: Style.marginS * scaling
+ anchors.leftMargin: Style.marginS
+ anchors.rightMargin: Style.marginS
+ spacing: Style.marginS
NIcon {
icon: "filepicker-search"
color: Color.mOnSurfaceVariant
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
}
NTextInput {
id: searchInput
@@ -396,9 +396,9 @@ Popup {
Layout.fillWidth: true
Layout.fillHeight: true
color: Color.mSurface
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
FolderListModel {
id: folderModel
@@ -447,9 +447,9 @@ Popup {
ScrollBar {
policy: ScrollBar.AsNeeded
contentItem: Rectangle {
- implicitWidth: 6 * scaling
+ implicitWidth: 6
implicitHeight: 100
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
color: parent.pressed ? Qt.alpha(Color.mTertiary, 0.8) : parent.hovered ? Qt.alpha(Color.mTertiary, 0.8) : Qt.alpha(Color.mTertiary, 0.8)
opacity: parent.policy === ScrollBar.AlwaysOn || parent.active ? 1.0 : 0.0
Behavior on opacity {
@@ -464,11 +464,11 @@ Popup {
}
}
background: Rectangle {
- implicitWidth: 6 * scaling
+ implicitWidth: 6
implicitHeight: 100
color: Color.transparent
opacity: parent.policy === ScrollBar.AlwaysOn || parent.active ? 0.3 : 0.0
- radius: (Style.radiusM * scaling) / 2
+ radius: (Style.radiusM) / 2
Behavior on opacity {
NumberAnimation {
duration: Style.animationFast
@@ -482,22 +482,22 @@ Popup {
GridView {
id: gridView
anchors.fill: parent
- anchors.margins: Style.marginM * scaling
+ anchors.margins: Style.marginM
model: filteredModel
visible: filePickerPanel.viewMode
clip: true
reuseItems: true
- property int columns: Math.max(1, Math.floor(width / (120 * scaling)))
- property int itemSize: Math.floor((width - leftMargin - rightMargin - (columns * Style.marginS * scaling)) / columns)
+ property int columns: Math.max(1, Math.floor(width / (120)))
+ property int itemSize: Math.floor((width - leftMargin - rightMargin - (columns * Style.marginS)) / columns)
cellWidth: Math.floor((width - leftMargin - rightMargin) / columns)
- cellHeight: Math.floor(itemSize * 0.8) + Style.marginXS * scaling + Style.fontSizeS * scaling + Style.marginM * scaling
+ cellHeight: Math.floor(itemSize * 0.8) + Style.marginXS + Style.fontSizeS + Style.marginM
- leftMargin: Style.marginS * scaling
- rightMargin: Style.marginS * scaling
- topMargin: Style.marginS * scaling
- bottomMargin: Style.marginS * scaling
+ leftMargin: Style.marginS
+ rightMargin: Style.marginS
+ topMargin: Style.marginS
+ bottomMargin: Style.marginS
ScrollBar.vertical: scrollBarComponent.createObject(gridView, {
"parent": gridView,
@@ -511,7 +511,7 @@ Popup {
width: gridView.itemSize
height: gridView.cellHeight
color: Color.transparent
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
property bool isSelected: filePickerPanel.currentSelection.includes(model.filePath)
@@ -520,7 +520,7 @@ Popup {
color: Color.transparent
radius: parent.radius
border.color: isSelected ? Color.mSecondary : Color.mSurface
- border.width: Math.max(1, Style.borderL * scaling)
+ border.width: Math.max(1, Style.borderL)
Behavior on color {
ColorAnimation {
duration: Style.animationFast
@@ -533,7 +533,7 @@ Popup {
color: (mouseArea.containsMouse && !isSelected) ? Color.mTertiary : Color.transparent
radius: parent.radius
border.color: (mouseArea.containsMouse && !isSelected) ? Color.mTertiary : Color.transparent
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
Behavior on color {
ColorAnimation {
duration: Style.animationFast
@@ -548,8 +548,8 @@ Popup {
ColumnLayout {
anchors.fill: parent
- anchors.margins: Style.marginS * scaling
- spacing: Style.marginXS * scaling
+ anchors.margins: Style.marginS
+ spacing: Style.marginXS
Rectangle {
id: iconContainer
@@ -567,15 +567,15 @@ Popup {
Image {
id: thumbnail
anchors.fill: parent
- anchors.margins: Style.marginXS * scaling
+ anchors.margins: Style.marginXS
source: iconContainer.isImage ? "file://" + model.filePath : ""
fillMode: Image.PreserveAspectFit
visible: iconContainer.isImage && status === Image.Ready
smooth: false
cache: true
asynchronous: true
- sourceSize.width: 120 * scaling
- sourceSize.height: 120 * scaling
+ sourceSize.width: 120
+ sourceSize.height: 120
onStatusChanged: {
if (status === Image.Error)
visible = false
@@ -584,11 +584,11 @@ Popup {
Rectangle {
anchors.fill: parent
color: Color.mSurfaceVariant
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
visible: thumbnail.status === Image.Loading
NIcon {
icon: "filepicker-photo"
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: Color.mOnSurfaceVariant
anchors.centerIn: parent
}
@@ -597,7 +597,7 @@ Popup {
NIcon {
icon: model.fileIsDir ? "filepicker-folder" : root.getFileIcon(model.fileName)
- pointSize: Style.fontSizeXXL * 2 * scaling
+ pointSize: Style.fontSizeXXL * 2
color: {
if (isSelected)
return Color.mSecondary
@@ -613,17 +613,17 @@ Popup {
Rectangle {
anchors.top: parent.top
anchors.right: parent.right
- anchors.margins: Style.marginS * scaling
- width: 24 * scaling
- height: 24 * scaling
+ anchors.margins: Style.marginS
+ width: 24
+ height: 24
radius: width / 2
color: Color.mSecondary
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
visible: isSelected
NIcon {
icon: "filepicker-check"
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
font.weight: Style.fontWeightBold
color: Color.mOnSecondary
anchors.centerIn: parent
@@ -641,7 +641,7 @@ Popup {
else
return Color.mOnSurfaceVariant
}
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
font.weight: isSelected ? Style.fontWeightBold : Style.fontWeightRegular
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
@@ -697,14 +697,14 @@ Popup {
NListView {
id: listView
anchors.fill: parent
- anchors.margins: Style.marginS * scaling
+ anchors.margins: Style.marginS
model: filteredModel
visible: !filePickerPanel.viewMode
delegate: Rectangle {
id: listItem
width: listView.width
- height: 40 * scaling
+ height: 40
color: {
if (filePickerPanel.currentSelection.includes(model.filePath))
return Color.mSecondary
@@ -712,7 +712,7 @@ Popup {
return Color.mTertiary
return Color.transparent
}
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
Behavior on color {
ColorAnimation {
duration: Style.animationFast
@@ -721,20 +721,20 @@ Popup {
RowLayout {
anchors.fill: parent
- anchors.leftMargin: Style.marginM * scaling
- anchors.rightMargin: Style.marginM * scaling
- spacing: Style.marginM * scaling
+ anchors.leftMargin: Style.marginM
+ anchors.rightMargin: Style.marginM
+ spacing: Style.marginM
NIcon {
icon: model.fileIsDir ? "filepicker-folder" : root.getFileIcon(model.fileName)
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
color: model.fileIsDir ? (filePickerPanel.currentSelection.includes(model.filePath) ? Color.mOnSecondary : Color.mPrimary) : Color.mOnSurfaceVariant
}
NText {
text: model.fileName
color: filePickerPanel.currentSelection.includes(model.filePath) ? Color.mOnSecondary : Color.mOnSurface
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: filePickerPanel.currentSelection.includes(model.filePath) ? Style.fontWeightBold : Style.fontWeightRegular
Layout.fillWidth: true
elide: Text.ElideRight
@@ -743,7 +743,7 @@ Popup {
NText {
text: model.fileIsDir ? "" : root.formatFileSize(model.fileSize)
color: filePickerPanel.currentSelection.includes(model.filePath) ? Color.mOnSecondary : Color.mOnSurfaceVariant
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
visible: !model.fileIsDir
Layout.preferredWidth: implicitWidth
}
@@ -795,7 +795,7 @@ Popup {
// Footer
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NText {
text: {
@@ -809,7 +809,7 @@ Popup {
}
}
color: filePickerPanel.searchText.length > 0 ? Color.mPrimary : Color.mOnSurfaceVariant
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
Layout.fillWidth: true
}
diff --git a/Widgets/NHeader.qml b/Widgets/NHeader.qml
index dfbcfd54..08d58e01 100644
--- a/Widgets/NHeader.qml
+++ b/Widgets/NHeader.qml
@@ -8,13 +8,13 @@ ColumnLayout {
property string label: ""
property string description: ""
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
- Layout.bottomMargin: Style.marginM * scaling
+ Layout.bottomMargin: Style.marginM
NText {
text: root.label
- pointSize: Style.fontSizeXL * scaling
+ pointSize: Style.fontSizeXL
font.weight: Style.fontWeightBold
color: Color.mSecondary
visible: root.label !== ""
@@ -22,7 +22,7 @@ ColumnLayout {
NText {
text: root.description
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
color: Color.mOnSurfaceVariant
wrapMode: Text.WordWrap
Layout.fillWidth: true
diff --git a/Widgets/NIcon.qml b/Widgets/NIcon.qml
index adca75f6..87e63c1f 100644
--- a/Widgets/NIcon.qml
+++ b/Widgets/NIcon.qml
@@ -7,7 +7,8 @@ Text {
id: root
property string icon: Icons.defaultIcon
- property real pointSize: Style.fontSizeL * scaling
+ property real pointSize: Style.fontSizeL
+ property bool applyUiScale: true
visible: (icon !== undefined) && (icon !== "")
text: {
@@ -22,7 +23,7 @@ Text {
return Icons.get(icon)
}
font.family: Icons.fontFamily
- font.pointSize: root.pointSize
+ font.pointSize: applyUiScale ? root.pointSize * Style.uiScaleRatio : root.pointSize
color: Color.mOnSurface
verticalAlignment: Text.AlignVCenter
}
diff --git a/Widgets/NIconButton.qml b/Widgets/NIconButton.qml
index e2d0d0fa..4a61c1df 100644
--- a/Widgets/NIconButton.qml
+++ b/Widgets/NIconButton.qml
@@ -8,14 +8,15 @@ Rectangle {
id: root
property real baseSize: Style.baseWidgetSize
+ property bool applyUiScale: true
property string icon
property string tooltipText
property string tooltipDirection: "auto"
+ property string density: ""
property bool enabled: true
property bool allowClickWhenDisabled: false
property bool hovering: false
- property bool compact: false
property color colorBg: Color.mSurfaceVariant
property color colorFg: Color.mPrimary
@@ -30,14 +31,14 @@ Rectangle {
signal rightClicked
signal middleClicked
- implicitWidth: Math.round(baseSize * scaling)
- implicitHeight: Math.round(baseSize * scaling)
+ implicitWidth: applyUiScale ? Math.round(baseSize * Style.uiScaleRatio) : Math.round(baseSize)
+ implicitHeight: applyUiScale ? Math.round(baseSize * Style.uiScaleRatio) : Math.round(baseSize)
opacity: root.enabled ? Style.opacityFull : Style.opacityMedium
color: root.enabled && root.hovering ? colorBgHover : colorBg
radius: width * 0.5
border.color: root.enabled && root.hovering ? colorBorderHover : colorBorder
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
Behavior on color {
ColorAnimation {
@@ -48,7 +49,15 @@ Rectangle {
NIcon {
icon: root.icon
- pointSize: Math.max(1, root.compact ? root.width * 0.65 : root.width * 0.48)
+ pointSize: {
+ switch (root.density) {
+ case "compact":
+ return Math.max(1, root.width * 0.65)
+ default:
+ return Math.max(1, root.width * 0.48)
+ }
+ }
+ applyUiScale: root.applyUiScale
color: root.enabled && root.hovering ? colorFgHover : colorFg
// Center horizontally
x: (root.width - width) / 2
diff --git a/Widgets/NIconButtonHot.qml b/Widgets/NIconButtonHot.qml
new file mode 100644
index 00000000..18df3bac
--- /dev/null
+++ b/Widgets/NIconButtonHot.qml
@@ -0,0 +1,174 @@
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import QtQuick.Effects
+import qs.Commons
+import qs.Services
+
+Rectangle {
+ id: root
+
+ // Public properties
+ property real baseSize: Style.baseWidgetSize
+ property bool applyUiScale: true
+ property string icon: ""
+ property string tooltipText: ""
+ property string tooltipDirection: "auto"
+ property string density: ""
+ property bool enabled: true
+ property bool allowClickWhenDisabled: false
+ property bool hot: false
+
+ // Internal properties
+ property bool hovering: false
+ property bool pressed: false
+
+ // Color properties
+ property color colorBg: Color.mSurfaceVariant
+ property color colorFg: Color.mPrimary
+ property color colorBgHover: Color.mTertiary
+ property color colorFgHover: Color.mOnTertiary
+ property color colorBorder: Color.mOutline
+ property color colorBorderHover: Color.mOutline
+
+ // Hot state colors
+ property color colorBgHot: Color.mPrimary
+ property color colorFgHot: Color.mOnPrimary
+
+ // Signals
+ signal entered
+ signal exited
+ signal clicked
+ signal rightClicked
+ signal middleClicked
+
+ // Dimensions
+ implicitWidth: applyUiScale ? Math.round(baseSize * Style.uiScaleRatio) : Math.round(baseSize)
+ implicitHeight: applyUiScale ? Math.round(baseSize * Style.uiScaleRatio) : Math.round(baseSize)
+
+ // Appearance
+ opacity: root.enabled ? Style.opacityFull : Style.opacityMedium
+ color: {
+ if (pressed) {
+ return colorBgHover
+ }
+ if (hot) {
+ return colorBgHot
+ }
+ if (root.enabled && root.hovering) {
+ return colorBgHover
+ }
+ return colorBg
+ }
+ radius: width * 0.5
+ border.color: root.enabled && root.hovering ? colorBorderHover : colorBorder
+ border.width: Math.max(1, Style.borderS)
+
+ Behavior on color {
+ ColorAnimation {
+ duration: Style.animationNormal
+ easing.type: Easing.InOutQuad
+ }
+ }
+
+ Behavior on scale {
+ NumberAnimation {
+ duration: Style.animationFast
+ easing.type: Easing.OutCubic
+ }
+ }
+
+ // Icon
+ NIcon {
+ icon: root.icon
+ pointSize: Math.max(1, Math.round(root.width * 0.48))
+ applyUiScale: root.applyUiScale
+ color: {
+ if (pressed) {
+ return colorFgHover
+ }
+ if (hot) {
+ return colorFgHot
+ }
+ if (root.enabled && root.hovering) {
+ return colorFgHover
+ }
+ return colorFg
+ }
+ // Center horizontally
+ x: (root.width - width) / 2
+ // Center vertically accounting for font metrics
+ y: (root.height - height) / 2 + (height - contentHeight) / 2
+
+ Behavior on color {
+ ColorAnimation {
+ duration: Style.animationFast
+ easing.type: Easing.InOutQuad
+ }
+ }
+ }
+
+ MouseArea {
+ // Always enabled to allow hover/tooltip even when the button is disabled
+ enabled: true
+ anchors.fill: parent
+ cursorShape: root.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
+ acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
+ hoverEnabled: true
+
+ onEntered: {
+ hovering = root.enabled ? true : false
+ if (tooltipText) {
+ TooltipService.show(Screen, parent, tooltipText, tooltipDirection)
+ }
+ root.entered()
+ }
+
+ onExited: {
+ hovering = false
+ if (tooltipText) {
+ TooltipService.hide()
+ }
+ root.exited()
+ }
+
+ onPressed: function (mouse) {
+ if (root.enabled) {
+ root.pressed = true
+ root.scale = 0.92
+ }
+ if (tooltipText) {
+ TooltipService.hide()
+ }
+ }
+
+ onReleased: function (mouse) {
+ root.scale = 1.0
+ root.pressed = false
+
+ if (!root.enabled && !allowClickWhenDisabled) {
+ return
+ }
+
+ // Only trigger actions if released while hovering
+ if (root.hovering) {
+ if (mouse.button === Qt.LeftButton) {
+ root.clicked()
+ } else if (mouse.button === Qt.RightButton) {
+ root.rightClicked()
+ } else if (mouse.button === Qt.MiddleButton) {
+ root.middleClicked()
+ }
+ }
+ }
+
+ onCanceled: {
+ root.hovering = false
+ root.pressed = false
+ root.scale = 1.0
+ if (tooltipText) {
+ TooltipService.hide()
+ }
+ }
+ }
+}
diff --git a/Widgets/NIconPicker.qml b/Widgets/NIconPicker.qml
index 6a5cc45d..2a4916e9 100644
--- a/Widgets/NIconPicker.qml
+++ b/Widgets/NIconPicker.qml
@@ -15,18 +15,10 @@ Popup {
signal iconSelected(string iconName)
- width: {
- var w = Math.round(Math.max(screen.width * 0.35, 900) * scaling)
- w = Math.min(w, screen.width - Style.marginL * 2)
- return w
- }
- height: {
- var h = Math.round(Math.max(screen.height * 0.65, 700) * scaling)
- h = Math.min(h, screen.height - Style.barHeight * scaling - Style.marginL * 2)
- return h
- }
+ width: 900 * Style.uiScaleRatio
+ height: 700 * Style.uiScaleRatio
anchors.centerIn: Overlay.overlay
- padding: Style.marginXL * scaling
+ padding: Style.marginXL
property string query: ""
property var allIcons: Object.keys(Icons.icons)
@@ -38,7 +30,7 @@ Popup {
}
readonly property int columns: 6
readonly property int cellW: Math.floor(grid.width / columns)
- readonly property int cellH: Math.round(cellW * 0.7 + 36 * scaling)
+ readonly property int cellH: Math.round(cellW * 0.7 + 36)
onOpened: {
selectedIcon = initialIcon
@@ -53,21 +45,21 @@ Popup {
background: Rectangle {
color: Color.mSurface
- radius: Style.radiusL * scaling
+ radius: Style.radiusL
border.color: Color.mPrimary
- border.width: Style.borderM * scaling
+ border.width: Style.borderM
}
ColumnLayout {
anchors.fill: parent
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
// Title row
RowLayout {
Layout.fillWidth: true
NText {
text: I18n.tr("widgets.icon-picker.title")
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: Color.mPrimary
Layout.fillWidth: true
@@ -84,7 +76,7 @@ Popup {
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
NTextInput {
id: searchInput
Layout.fillWidth: true
@@ -100,7 +92,7 @@ Popup {
id: grid
Layout.fillWidth: true
Layout.fillHeight: true
- Layout.margins: Style.marginM * scaling
+ Layout.margins: Style.marginM
cellWidth: root.cellW
cellHeight: root.cellH
model: root.filteredIcons
@@ -109,11 +101,11 @@ Popup {
delegate: Rectangle {
width: grid.cellWidth
height: grid.cellHeight
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
color: (root.selectedIcon === modelData) ? Qt.alpha(Color.mPrimary, 0.15) : Color.transparent
border.color: (root.selectedIcon === modelData) ? Color.mPrimary : Qt.rgba(0, 0, 0, 0)
- border.width: (root.selectedIcon === modelData) ? Style.borderS * scaling : 0
+ border.width: (root.selectedIcon === modelData) ? Style.borderS : 0
MouseArea {
anchors.fill: parent
@@ -127,27 +119,27 @@ Popup {
ColumnLayout {
anchors.fill: parent
- anchors.margins: Style.marginS * scaling
- spacing: Style.marginS * scaling
+ anchors.margins: Style.marginS
+ spacing: Style.marginS
Item {
Layout.fillHeight: true
- Layout.preferredHeight: 4 * scaling
+ Layout.preferredHeight: 4
}
NIcon {
Layout.alignment: Qt.AlignHCenter
icon: modelData
- pointSize: 42 * scaling
+ pointSize: 42
}
NText {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
- Layout.topMargin: Style.marginXS * scaling
+ Layout.topMargin: Style.marginXS
elide: Text.ElideRight
wrapMode: Text.NoWrap
maximumLineCount: 1
horizontalAlignment: Text.AlignHCenter
color: Color.mOnSurfaceVariant
- pointSize: Style.fontSizeXS * scaling
+ pointSize: Style.fontSizeXS
text: modelData
}
Item {
@@ -159,7 +151,7 @@ Popup {
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
Item {
Layout.fillWidth: true
}
diff --git a/Widgets/NImageCircled.qml b/Widgets/NImageCircled.qml
index eb0ee9bd..55ef7568 100644
--- a/Widgets/NImageCircled.qml
+++ b/Widgets/NImageCircled.qml
@@ -12,11 +12,11 @@ Rectangle {
property color borderColor: Color.transparent
property real borderWidth: 0
property string fallbackIcon: ""
- property real fallbackIconSize: Style.fontSizeXXL * scaling
+ property real fallbackIconSize: Style.fontSizeXXL
color: Color.transparent
radius: parent.width * 0.5
- anchors.margins: Style.marginXXS * scaling
+ anchors.margins: Style.marginXXS
Rectangle {
color: Color.transparent
diff --git a/Widgets/NImageRounded.qml b/Widgets/NImageRounded.qml
index ff55a571..32987e28 100644
--- a/Widgets/NImageRounded.qml
+++ b/Widgets/NImageRounded.qml
@@ -13,7 +13,7 @@ Rectangle {
property real borderWidth: 0
property real imageRadius: width * 0.5
property string fallbackIcon: ""
- property real fallbackIconSize: Style.fontSizeXXL * scaling
+ property real fallbackIconSize: Style.fontSizeXXL
property real scaledRadius: imageRadius * Settings.data.general.radiusRatio
@@ -21,7 +21,7 @@ Rectangle {
color: Color.transparent
radius: scaledRadius
- anchors.margins: Style.marginXXS * scaling
+ anchors.margins: Style.marginXXS
Rectangle {
color: Color.transparent
diff --git a/Widgets/NInputAction.qml b/Widgets/NInputAction.qml
index d689d304..a1e683da 100644
--- a/Widgets/NInputAction.qml
+++ b/Widgets/NInputAction.qml
@@ -22,8 +22,7 @@ RowLayout {
signal actionClicked
// Internal properties
- property real scaling: 1.0
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NTextInput {
id: textInput
diff --git a/Widgets/NLabel.qml b/Widgets/NLabel.qml
index 8348fd0c..f1a42440 100644
--- a/Widgets/NLabel.qml
+++ b/Widgets/NLabel.qml
@@ -10,12 +10,12 @@ ColumnLayout {
property color labelColor: Color.mOnSurface
property color descriptionColor: Color.mOnSurfaceVariant
- spacing: Style.marginXXS * scaling
+ spacing: Style.marginXXS
Layout.fillWidth: true
NText {
text: label
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
font.weight: Style.fontWeightBold
color: labelColor
visible: label !== ""
@@ -24,7 +24,7 @@ ColumnLayout {
NText {
text: description
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: descriptionColor
wrapMode: Text.WordWrap
visible: description !== ""
diff --git a/Widgets/NListView.qml b/Widgets/NListView.qml
index 6731d7ce..115bac49 100644
--- a/Widgets/NListView.qml
+++ b/Widgets/NListView.qml
@@ -10,8 +10,8 @@ Item {
property color handleHoverColor: handleColor
property color handlePressedColor: handleColor
property color trackColor: Color.transparent
- property real handleWidth: 6 * scaling
- property real handleRadius: Style.radiusM * scaling
+ property real handleWidth: 6
+ property real handleRadius: Style.radiusM
property int verticalPolicy: ScrollBar.AsNeeded
property int horizontalPolicy: ScrollBar.AsNeeded
diff --git a/Widgets/NPanel.qml b/Widgets/NPanel.qml
index 9c7bf2db..5651d8af 100644
--- a/Widgets/NPanel.qml
+++ b/Widgets/NPanel.qml
@@ -8,7 +8,6 @@ Loader {
id: root
property ShellScreen screen
- property real scaling: 1.0
property Component panelContent: null
property real preferredWidth: 700
@@ -27,8 +26,6 @@ Loader {
property bool panelAnchorLeft: false
property bool panelAnchorRight: false
- property bool isMasked: false
-
// Properties to support positioning relative to the opener (button)
property bool useButtonPosition: false
property point buttonPosition: Qt.point(0, 0)
@@ -39,10 +36,8 @@ Loader {
property bool backgroundClickEnabled: true
// Animation properties
- readonly property real originalScale: 0.7
- readonly property real originalOpacity: 0.0
+ readonly property real originalScale: 0.0
property real scaleValue: originalScale
- property real opacityValue: originalOpacity
property real dimmingOpacity: 0
signal opened
@@ -100,7 +95,6 @@ Loader {
function close() {
dimmingOpacity = 0
scaleValue = originalScale
- opacityValue = originalOpacity
root.closed()
active = false
useButtonPosition = false
@@ -131,58 +125,40 @@ Loader {
// -----------------------------------------
sourceComponent: Component {
+ // PanelWindow has its own screen property inherited of QsWindow
PanelWindow {
id: panelWindow
- // PanelWindow has its own screen property inherited of QsWindow
- property real scaling: ScalingService.getScreenScale(screen)
-
readonly property string barPosition: Settings.data.bar.position
readonly property bool isVertical: barPosition === "left" || barPosition === "right"
readonly property bool barIsVisible: (screen !== null) && (Settings.data.bar.monitors.includes(screen.name) || (Settings.data.bar.monitors.length === 0))
- readonly property real verticalBarWidth: Math.round(Style.barHeight * scaling)
+ readonly property real verticalBarWidth: Style.barHeight
Component.onCompleted: {
- Logger.log("NPanel", "Opened", root.objectName)
+ Logger.log("NPanel", "Opened", root.objectName, "on", screen.name)
dimmingOpacity = Style.opacityHeavy
}
- Connections {
- target: ScalingService
- function onScaleChanged(screenName, scale) {
- if ((screen !== null) && (screenName === screen.name)) {
- root.scaling = scaling = scale
- }
- }
- }
-
Connections {
target: panelWindow
function onScreenChanged() {
root.screen = screen
- root.scaling = scaling = ScalingService.getScreenScale(screen)
-
- // It's mandatory to force refresh the subloader to ensure the scaling is properly dispatched
- panelContentLoader.active = false
- panelContentLoader.active = true
// If called from IPC always reposition if screen is updated
if (buttonName) {
setPosition()
}
- // Logger.log("NPanel", "OnScreenChanged", root.screen.name)
+ Logger.log("NPanel", "OnScreenChanged", root.screen.name)
}
}
visible: true
- color: Settings.data.general.dimDesktop && !root.isMasked ? Qt.alpha(Color.mShadow, dimmingOpacity) : Color.transparent
+ color: Settings.data.general.dimDesktop ? Qt.alpha(Color.mShadow, dimmingOpacity) : Color.transparent
WlrLayershell.exclusionMode: ExclusionMode.Ignore
WlrLayershell.namespace: "noctalia-panel"
WlrLayershell.keyboardFocus: root.panelKeyboardFocus ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
- mask: root.isMasked ? maskRegion : null
-
Region {
id: maskRegion
}
@@ -217,9 +193,9 @@ Loader {
Rectangle {
id: panelBackground
color: panelBackgroundColor
- radius: Style.radiusL * scaling
+ radius: Style.radiusL
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
// Dragging support
property bool draggable: root.draggable
property bool isDragged: false
@@ -228,9 +204,9 @@ Loader {
width: {
var w
if (preferredWidthRatio !== undefined) {
- w = Math.round(Math.max(screen?.width * preferredWidthRatio, preferredWidth) * scaling)
+ w = Math.round(Math.max(screen?.width * preferredWidthRatio, preferredWidth))
} else {
- w = preferredWidth * scaling
+ w = preferredWidth
}
// Clamp width so it is never bigger than the screen
return Math.min(w, screen?.width - Style.marginL * 2)
@@ -238,17 +214,16 @@ Loader {
height: {
var h
if (preferredHeightRatio !== undefined) {
- h = Math.round(Math.max(screen?.height * preferredHeightRatio, preferredHeight) * scaling)
+ h = Math.round(Math.max(screen?.height * preferredHeightRatio, preferredHeight))
} else {
- h = preferredHeight * scaling
+ h = preferredHeight
}
// Clamp width so it is never bigger than the screen
- return Math.min(h, screen?.height - Style.barHeight * scaling - Style.marginL * 2)
+ return Math.min(h, screen?.height - Style.barHeight - Style.marginL * 2)
}
scale: root.scaleValue
- opacity: root.isMasked ? 0 : root.opacityValue
x: isDragged ? manualX : calculatedX
y: isDragged ? manualY : calculatedY
@@ -261,9 +236,9 @@ Loader {
}
switch (barPosition) {
case "top":
- return (Style.barHeight + Style.marginS) * scaling + (Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0)
+ return (Style.barHeight + Style.marginS) + (Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL : 0)
default:
- return Style.marginS * scaling
+ return Style.marginS
}
}
@@ -273,9 +248,9 @@ Loader {
}
switch (barPosition) {
case "bottom":
- return (Style.barHeight + Style.marginS) * scaling + (Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL * scaling : 0)
+ return (Style.barHeight + Style.marginS) + (Settings.data.bar.floating ? Settings.data.bar.marginVertical * Style.marginXL : 0)
default:
- return Style.marginS * scaling
+ return Style.marginS
}
}
@@ -285,9 +260,9 @@ Loader {
}
switch (barPosition) {
case "left":
- return (Style.barHeight + Style.marginS) * scaling + (Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0)
+ return (Style.barHeight + Style.marginS) + (Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0)
default:
- return Style.marginS * scaling
+ return Style.marginS
}
}
@@ -297,9 +272,9 @@ Loader {
}
switch (barPosition) {
case "right":
- return (Style.barHeight + Style.marginS) * scaling + (Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL * scaling : 0)
+ return (Style.barHeight + Style.marginS) + (Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * Style.marginXL : 0)
default:
- return Style.marginS * scaling
+ return Style.marginS
}
}
@@ -388,7 +363,6 @@ Loader {
// Animate in when component is completed
Component.onCompleted: {
root.scaleValue = 1.0
- root.opacityValue = 1.0
}
// Reset drag position when panel closes
@@ -454,14 +428,14 @@ Loader {
var ny = dragStartY + translation.y
// Calculate gaps so we never overlap the bar on any side
- var baseGap = Style.marginS * scaling
- var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * 2 * Style.marginXL * scaling : 0
- var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * 2 * Style.marginXL * scaling : 0
+ var baseGap = Style.marginS
+ var floatExtraH = Settings.data.bar.floating ? Settings.data.bar.marginHorizontal * 2 * Style.marginXL : 0
+ var floatExtraV = Settings.data.bar.floating ? Settings.data.bar.marginVertical * 2 * Style.marginXL : 0
- var insetLeft = baseGap + ((barIsVisible && barPosition === "left") ? (Style.barHeight * scaling + floatExtraH) : 0)
- var insetRight = baseGap + ((barIsVisible && barPosition === "right") ? (Style.barHeight * scaling + floatExtraH) : 0)
- var insetTop = baseGap + ((barIsVisible && barPosition === "top") ? (Style.barHeight * scaling + floatExtraV) : 0)
- var insetBottom = baseGap + ((barIsVisible && barPosition === "bottom") ? (Style.barHeight * scaling + floatExtraV) : 0)
+ var insetLeft = baseGap + ((barIsVisible && barPosition === "left") ? (Style.barHeight + floatExtraH) : 0)
+ var insetRight = baseGap + ((barIsVisible && barPosition === "right") ? (Style.barHeight + floatExtraH) : 0)
+ var insetTop = baseGap + ((barIsVisible && barPosition === "top") ? (Style.barHeight + floatExtraV) : 0)
+ var insetBottom = baseGap + ((barIsVisible && barPosition === "bottom") ? (Style.barHeight + floatExtraV) : 0)
// Clamp within screen bounds accounting for insets
var maxX = panelWindow.width - panelBackground.width - insetRight
@@ -480,7 +454,7 @@ Loader {
anchors.margins: 0
color: Color.transparent
border.color: Color.mPrimary
- border.width: Math.max(2, Style.borderL * scaling)
+ border.width: Math.max(2, Style.borderL)
radius: parent.radius
visible: panelBackground.isDragged && dragHandler.active
opacity: 0.8
@@ -492,7 +466,7 @@ Loader {
anchors.margins: 0
color: Color.transparent
border.color: Color.mPrimary
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
radius: parent.radius
opacity: 0.3
}
diff --git a/Widgets/NQuickSetting.qml b/Widgets/NQuickSetting.qml
deleted file mode 100644
index 7b559019..00000000
--- a/Widgets/NQuickSetting.qml
+++ /dev/null
@@ -1,326 +0,0 @@
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-import QtQuick.Effects
-import qs.Commons
-import qs.Services
-
-Rectangle {
- id: root
-
- // Public properties
- property string text: ""
- property string icon: ""
- property string tooltipText: ""
- property bool enabled: true
- property bool hot: false
- property string style: "modern" // "modern", "classic", or "compact"
-
- // Styling properties
- property real fontSize: (style === "classic") ? Style.fontSizeXS * scaling : Style.fontSizeS * scaling
- property int fontWeight: Style.fontWeightMedium
- property real iconSize: Style.fontSizeL * scaling
- property real cornerRadius: Style.radiusM * scaling
-
- // Internal properties
- property bool hovered: false
- property bool pressed: false
-
- // Colors - Style-dependent colors
- property color backgroundColor: {
- if (pressed) {
- return Color.mTertiary
- }
- if (hot) {
- return Color.mPrimary
- }
- if (style === "classic")
- return Color.mSurfaceVariant
- if (style === "compact")
- return Color.mSurface
- return Color.mSurface
- }
- property color textColor: {
- if (pressed) {
- return Color.mOnTertiary
- }
- if (hot) {
- return Color.mOnPrimary
- }
- return Color.mOnSurface
- }
- property color iconColor: {
- if (pressed) {
- return Color.mOnTertiary
- }
- if (hot) {
- return Color.mOnPrimary
- }
- if (style !== "compact")
- return Color.mPrimary
- return Color.mOnSurface
- }
- property color borderColor: Color.mOutline
- property color hoverColor: Color.mTertiary
- property color hoverTextColor: Color.mOnTertiary
- property color hoverIconColor: Color.mOnTertiary
-
- // Signals
- signal clicked
- signal rightClicked
- signal middleClicked
-
- // Dimensions - Style-dependent sizing
- implicitWidth: {
- if (style === "classic") {
- return Style.baseWidgetSize * scaling
- }
- if (style === "compact") {
- return Style.baseWidgetSize * 0.8 * scaling
- }
- return Math.max(120 * scaling, contentRow.implicitWidth + (Style.marginL * scaling))
- }
- implicitHeight: {
- if (style === "classic") {
- return Style.baseWidgetSize * scaling
- }
- if (style === "compact") {
- return Style.baseWidgetSize * 0.8 * scaling
- }
- return Math.max(48 * scaling, contentRow.implicitHeight + (Style.marginL * scaling))
- }
-
- // Appearance - Style-dependent styling
- radius: {
- if (style === "classic")
- return width * 0.5
- if (style === "compact")
- return Style.radiusS * scaling // Smaller radius for compact
- return cornerRadius
- }
- color: {
- if (!enabled)
- return Qt.lighter(Color.mSurface, 1.1)
- if (hovered)
- return hoverColor
- return backgroundColor
- }
-
- border.width: {
- if (style === "classic")
- return Math.max(1, Style.borderS * scaling)
- if (style === "compact")
- return 0
- return 0
- }
- border.color: {
- if (style === "classic")
- return borderColor
- return "transparent"
- }
-
- opacity: enabled ? (style === "classic" ? Style.opacityFull : 1.0) : (style === "classic" ? Style.opacityMedium : 0.6)
-
- Behavior on color {
- ColorAnimation {
- duration: Style.animationFast
- easing.type: style === "classic" ? Easing.InOutQuad : Easing.OutCubic
- }
- }
-
- Behavior on border.color {
- ColorAnimation {
- duration: Style.animationFast
- easing.type: style === "classic" ? Easing.InOutQuad : Easing.OutCubic
- }
- }
-
- Behavior on scale {
- NumberAnimation {
- duration: Style.animationFast
- easing.type: Easing.OutCubic
- }
- }
-
- // Modern style - icon above text
- ColumnLayout {
- id: contentRow
- anchors.centerIn: parent
- spacing: Style.marginXXS * scaling
- visible: root.style !== "classic" && root.style !== "compact"
-
- // Icon
- NIcon {
- Layout.alignment: Qt.AlignHCenter
- visible: root.icon !== ""
- icon: root.icon
- pointSize: root.iconSize
- color: {
- if (!root.enabled)
- return Color.mOnSurfaceVariant
- if (root.hovered)
- return root.hoverIconColor
- return root.iconColor
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Style.animationFast
- easing.type: Easing.OutCubic
- }
- }
- }
-
- // Modern - Text content
- NText {
- Layout.alignment: Qt.AlignHCenter
- visible: root.text !== ""
- text: root.text
- pointSize: root.fontSize
- font.weight: root.fontWeight
- color: {
- if (!root.enabled)
- return Color.mOnSurfaceVariant
- if (root.hovered)
- return root.hoverTextColor
- return root.textColor
- }
- elide: Text.ElideRight
-
- Behavior on color {
- ColorAnimation {
- duration: Style.animationFast
- easing.type: Easing.OutCubic
- }
- }
- }
- }
-
- // Compact style - icon only, small square button
- NIcon {
- id: compactIcon
- anchors.centerIn: parent
- visible: root.style === "compact" && root.icon !== ""
- icon: root.icon
- pointSize: Style.fontSizeM * scaling // Smaller icon for compact
- color: {
- if (!root.enabled)
- return Color.mOnSurfaceVariant
- if (root.hovered)
- return root.hoverIconColor
- return root.iconColor
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Style.animationFast
- easing.type: Easing.OutCubic
- }
- }
- }
-
- // Classic style - EXACTLY like NIconButton (icon + text)
- RowLayout {
- anchors.centerIn: parent
- visible: root.style === "classic"
- spacing: Style.marginXS * scaling
-
- NIcon {
- visible: root.icon !== ""
- icon: root.icon
- pointSize: Style.fontSizeM * scaling
- color: {
- if (!root.enabled)
- return Color.mOnSurfaceVariant
- if (root.hovered)
- return root.hoverIconColor
- return root.iconColor
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Style.animationFast
- easing.type: Easing.OutCubic
- }
- }
- }
-
- // Classic - Text content
- NText {
- visible: root.text !== ""
- text: root.text
- pointSize: root.fontSize
- font.weight: root.fontWeight
- color: {
- if (!root.enabled)
- return Color.mOnSurfaceVariant
- if (root.hovered)
- return root.hoverTextColor
- return root.textColor
- }
-
- Behavior on color {
- ColorAnimation {
- duration: Style.animationFast
- easing.type: Easing.OutCubic
- }
- }
- }
- }
-
- MouseArea {
- id: mouseArea
- anchors.fill: parent
- enabled: root.enabled
- hoverEnabled: true
- acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
- cursorShape: root.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
-
- onEntered: {
- root.hovered = true
- if (tooltipText) {
- TooltipService.show(Screen, root, root.tooltipText)
- }
- }
-
- onExited: {
- root.hovered = false
- if (tooltipText) {
- TooltipService.hide()
- }
- }
-
- onPressed: mouse => {
- root.pressed = true
- root.scale = 0.92
- if (tooltipText) {
- TooltipService.hide()
- }
- }
-
- onReleased: mouse => {
- root.scale = 1.0
- root.pressed = false
-
- // Only trigger actions if released while hovering
- if (root.hovered) {
- if (mouse.button === Qt.LeftButton) {
- root.clicked()
- } else if (mouse.button === Qt.RightButton) {
- root.rightClicked()
- } else if (mouse.button === Qt.MiddleButton) {
- root.middleClicked()
- }
- }
- }
-
- onCanceled: {
- root.hovered = false
- root.pressed = false
- root.scale = 1.0
- if (tooltipText) {
- TooltipService.hide()
- }
- }
- }
-}
diff --git a/Widgets/NRadioButton.qml b/Widgets/NRadioButton.qml
index d04ea777..59ff2205 100644
--- a/Widgets/NRadioButton.qml
+++ b/Widgets/NRadioButton.qml
@@ -10,12 +10,12 @@ RadioButton {
indicator: Rectangle {
id: outerCircle
- implicitWidth: Style.baseWidgetSize * 0.625 * scaling
- implicitHeight: Style.baseWidgetSize * 0.625 * scaling
+ implicitWidth: Style.baseWidgetSize * 0.625
+ implicitHeight: Style.baseWidgetSize * 0.625
radius: width * 0.5
color: Color.transparent
border.color: root.checked ? Color.mPrimary : Color.mOnSurface
- border.width: Math.max(1, Style.borderM * scaling)
+ border.width: Math.max(1, Style.borderM)
anchors.verticalCenter: parent.verticalCenter
Rectangle {
@@ -41,10 +41,10 @@ RadioButton {
contentItem: NText {
text: root.text
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
anchors.verticalCenter: parent.verticalCenter
anchors.left: outerCircle.right
anchors.right: parent.right
- anchors.leftMargin: Style.marginS * scaling
+ anchors.leftMargin: Style.marginS
}
}
diff --git a/Widgets/NReorderCheckboxes.qml b/Widgets/NReorderCheckboxes.qml
new file mode 100644
index 00000000..9a8c1abc
--- /dev/null
+++ b/Widgets/NReorderCheckboxes.qml
@@ -0,0 +1,299 @@
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Layouts
+import qs.Commons
+
+Item {
+ id: root
+
+ // Public API
+ property var model: []
+ property color activeColor: Color.mPrimary
+ property color activeOnColor: Color.mOnPrimary
+ property color dragHandleColor: Color.mOutline
+ property int baseSize: Style.baseWidgetSize * 0.7
+ property int spacing: Style.marginM
+
+ signal itemToggled(int index, bool enabled)
+ signal itemsReordered(int fromIndex, int toIndex)
+ signal dragPotentialStarted
+ signal dragPotentialEnded
+
+ implicitHeight: listView.contentHeight
+
+ function toggleItem(index) {
+ if (index < 0 || index >= root.model.length)
+ return
+
+ var item = root.model[index]
+ if (item.required)
+ return
+
+ // Create a new array to trigger binding update
+ var newModel = root.model.slice()
+ newModel[index] = Object.assign({}, item, {
+ "enabled": !item.enabled
+ })
+ root.model = newModel
+
+ root.itemToggled(index, newModel[index].enabled)
+ }
+
+ function moveItem(fromIndex, toIndex) {
+ if (fromIndex === toIndex)
+ return
+ if (fromIndex < 0 || fromIndex >= root.model.length)
+ return
+ if (toIndex < 0 || toIndex >= root.model.length)
+ return
+
+ // Create a new array with item moved
+ var newModel = root.model.slice()
+ var item = newModel.splice(fromIndex, 1)[0]
+ newModel.splice(toIndex, 0, item)
+ root.model = newModel
+
+ root.itemsReordered(fromIndex, toIndex)
+ }
+
+ ListView {
+ id: listView
+
+ anchors.fill: parent
+ spacing: root.spacing
+ interactive: false
+ clip: true
+ model: root.model
+
+ delegate: Item {
+ id: delegateItem
+
+ width: listView.width
+ height: checkboxRow.height
+
+ required property int index
+ required property var modelData
+
+ property string text: modelData.text || ""
+ property bool enabled: modelData.enabled || false
+ property bool required: modelData.required || false
+ property bool dragging: false
+ property int dragStartY: 0
+ property int dragStartIndex: -1
+ property int dragTargetIndex: -1
+ property int itemSpacing: root.spacing
+
+ RowLayout {
+ id: checkboxRow
+
+ width: parent.width
+ spacing: Style.marginS
+
+ // Drag handle
+ Rectangle {
+ id: dragHandle
+
+ Layout.preferredWidth: root.baseSize
+ Layout.preferredHeight: root.baseSize
+ radius: Style.radiusXS
+ color: dragHandleMouseArea.containsMouse ? Color.mSurfaceVariant : Color.transparent
+
+ Behavior on color {
+ ColorAnimation {
+ duration: Style.animationFast
+ }
+ }
+
+ ColumnLayout {
+ anchors.centerIn: parent
+ spacing: Style.marginS
+
+ Repeater {
+ model: 3
+ Rectangle {
+ Layout.preferredWidth: root.baseSize * 0.4
+ Layout.preferredHeight: 2
+ radius: 1
+ color: root.dragHandleColor
+ }
+ }
+ }
+
+ MouseArea {
+ id: dragHandleMouseArea
+
+ anchors.fill: parent
+ cursorShape: Qt.SizeVerCursor
+ hoverEnabled: true
+ preventStealing: false
+ z: 1000
+
+ onPressed: mouse => {
+ delegateItem.dragStartIndex = delegateItem.index
+ delegateItem.dragTargetIndex = delegateItem.index
+ delegateItem.dragStartY = delegateItem.y
+ delegateItem.dragging = true
+ delegateItem.z = 999
+
+ // Signal that interaction started (prevents panel close)
+ preventStealing = true
+ root.dragPotentialStarted()
+ }
+
+ onPositionChanged: mouse => {
+ if (delegateItem.dragging) {
+ var dy = mouse.y - dragHandle.height / 2
+ var newY = delegateItem.y + dy
+
+ // Constrain within bounds
+ newY = Math.max(0, Math.min(newY, listView.contentHeight - delegateItem.height))
+ delegateItem.y = newY
+
+ // Calculate target index (but don't apply yet)
+ var targetIndex = Math.floor((newY + delegateItem.height / 2) / (delegateItem.height + delegateItem.itemSpacing))
+ targetIndex = Math.max(0, Math.min(targetIndex, listView.count - 1))
+
+ delegateItem.dragTargetIndex = targetIndex
+ }
+ }
+
+ onReleased: {
+ // Always signal end of interaction
+ preventStealing = false
+ root.dragPotentialEnded()
+
+ // Apply the model change now that drag is complete
+ if (delegateItem.dragStartIndex !== -1 && delegateItem.dragTargetIndex !== -1 && delegateItem.dragStartIndex !== delegateItem.dragTargetIndex) {
+ root.moveItem(delegateItem.dragStartIndex, delegateItem.dragTargetIndex)
+ }
+
+ delegateItem.dragging = false
+ delegateItem.dragStartIndex = -1
+ delegateItem.dragTargetIndex = -1
+ delegateItem.z = 0
+ }
+
+ onCanceled: {
+ // Handle cancel (e.g., ESC key pressed during drag)
+ preventStealing = false
+ root.dragPotentialEnded()
+
+ delegateItem.dragging = false
+ delegateItem.dragStartIndex = -1
+ delegateItem.dragTargetIndex = -1
+ delegateItem.z = 0
+ }
+ }
+ }
+
+ // Checkbox
+ Rectangle {
+ id: box
+
+ Layout.preferredWidth: root.baseSize
+ Layout.preferredHeight: root.baseSize
+ radius: Style.radiusXS
+ color: delegateItem.enabled ? root.activeColor : Color.mSurface
+ border.color: delegateItem.required ? root.activeColor : Color.mOutline
+ border.width: Math.max(1, Style.borderS)
+ opacity: delegateItem.required ? 0.7 : 1.0
+
+ Behavior on color {
+ ColorAnimation {
+ duration: Style.animationFast
+ }
+ }
+
+ Behavior on border.color {
+ ColorAnimation {
+ duration: Style.animationFast
+ }
+ }
+
+ NIcon {
+ visible: delegateItem.enabled
+ anchors.centerIn: parent
+ anchors.horizontalCenterOffset: -1
+ icon: "check"
+ color: root.activeOnColor
+ pointSize: Math.max(Style.fontSizeXS, root.baseSize * 0.5)
+ font.weight: Style.fontWeightBold
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ cursorShape: delegateItem.required ? Qt.ForbiddenCursor : Qt.PointingHandCursor
+ enabled: !delegateItem.required
+
+ onClicked: {
+ root.toggleItem(delegateItem.index)
+ }
+ }
+ }
+
+ // Label
+ NText {
+ Layout.fillWidth: true
+ text: delegateItem.text
+ color: Color.mOnSurface
+ verticalAlignment: Text.AlignVCenter
+ elide: Text.ElideRight
+ }
+
+ // Required indicator
+ NText {
+ visible: delegateItem.required
+ text: "(required)"
+ color: Color.mOnSurfaceVariant
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
+
+ // Position binding for non-dragging state
+ y: {
+ if (delegateItem.dragging) {
+ return delegateItem.y
+ }
+
+ // Check if any item is being dragged
+ var draggedIndex = -1
+ var targetIndex = -1
+ for (var i = 0; i < listView.count; i++) {
+ var item = listView.itemAtIndex(i)
+ if (item && item.dragging) {
+ draggedIndex = item.dragStartIndex
+ targetIndex = item.dragTargetIndex
+ break
+ }
+ }
+
+ // If an item is being dragged, adjust positions
+ if (draggedIndex !== -1 && targetIndex !== -1 && draggedIndex !== targetIndex) {
+ var currentIndex = delegateItem.index
+
+ if (draggedIndex < targetIndex) {
+ // Dragging down: shift items up between draggedIndex and targetIndex
+ if (currentIndex > draggedIndex && currentIndex <= targetIndex) {
+ return (currentIndex - 1) * (delegateItem.height + delegateItem.itemSpacing)
+ }
+ } else {
+ // Dragging up: shift items down between targetIndex and draggedIndex
+ if (currentIndex >= targetIndex && currentIndex < draggedIndex) {
+ return (currentIndex + 1) * (delegateItem.height + delegateItem.itemSpacing)
+ }
+ }
+ }
+
+ return delegateItem.index * (delegateItem.height + delegateItem.itemSpacing)
+ }
+
+ Behavior on y {
+ enabled: !delegateItem.dragging
+ NumberAnimation {
+ duration: Style.animationNormal
+ easing.type: Easing.OutQuad
+ }
+ }
+ }
+ }
+}
diff --git a/Widgets/NScrollView.qml b/Widgets/NScrollView.qml
index 63e28819..af5371d9 100644
--- a/Widgets/NScrollView.qml
+++ b/Widgets/NScrollView.qml
@@ -10,8 +10,8 @@ T.ScrollView {
property color handleHoverColor: handleColor
property color handlePressedColor: handleColor
property color trackColor: Color.transparent
- property real handleWidth: 6 * scaling
- property real handleRadius: Style.radiusM * scaling
+ property real handleWidth: 6
+ property real handleRadius: Style.radiusM
property int verticalPolicy: ScrollBar.AsNeeded
property int horizontalPolicy: ScrollBar.AsNeeded
property bool preventHorizontalScroll: horizontalPolicy === ScrollBar.AlwaysOff
diff --git a/Widgets/NSearchableComboBox.qml b/Widgets/NSearchableComboBox.qml
index 3175f126..462d5a6b 100644
--- a/Widgets/NSearchableComboBox.qml
+++ b/Widgets/NSearchableComboBox.qml
@@ -9,8 +9,8 @@ import "../Helpers/FuzzySort.js" as Fuzzysort
RowLayout {
id: root
- property real minimumWidth: 280 * scaling
- property real popupHeight: 180 * scaling
+ property real minimumWidth: 280 * Style.uiScaleRatio
+ property real popupHeight: 180 * Style.uiScaleRatio
property string label: ""
property string description: ""
@@ -21,11 +21,11 @@ RowLayout {
property string placeholder: ""
property string searchPlaceholder: I18n.tr("placeholders.search")
- readonly property real preferredHeight: Style.baseWidgetSize * 1.1 * scaling
+ readonly property real preferredHeight: Style.baseWidgetSize * 1.1
signal selected(string key)
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
Layout.fillWidth: true
// Filtered model for search results
@@ -121,12 +121,12 @@ RowLayout {
}
background: Rectangle {
- implicitWidth: Style.baseWidgetSize * 3.75 * scaling
+ implicitWidth: Style.baseWidgetSize * 3.75 * Style.uiScaleRatio
implicitHeight: preferredHeight
color: Color.mSurface
border.color: combo.activeFocus ? Color.mSecondary : Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
- radius: Style.radiusM * scaling
+ border.width: Math.max(1, Style.borderS)
+ radius: Style.radiusM
Behavior on border.color {
ColorAnimation {
@@ -136,9 +136,9 @@ RowLayout {
}
contentItem: NText {
- leftPadding: Style.marginL * scaling
- rightPadding: combo.indicator.width + Style.marginL * scaling
- pointSize: Style.fontSizeM * scaling
+ leftPadding: Style.marginL
+ rightPadding: combo.indicator.width + Style.marginL
+ pointSize: Style.fontSizeM
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
color: (combo.currentIndex >= 0 && combo.currentIndex < filteredModel.count) ? Color.mOnSurface : Color.mOnSurfaceVariant
@@ -146,17 +146,17 @@ RowLayout {
}
indicator: NIcon {
- x: combo.width - width - Style.marginM * scaling
+ x: combo.width - width - Style.marginM
y: combo.topPadding + (combo.availableHeight - height) / 2
icon: "caret-down"
- pointSize: Style.fontSizeL * scaling
+ pointSize: Style.fontSizeL
}
popup: Popup {
y: combo.height
width: combo.width
- height: root.popupHeight + 60 * scaling
- padding: Style.marginM * scaling
+ height: root.popupHeight + 60
+ padding: Style.marginM
onOpened: {
PanelService.willOpenPopup(root)
@@ -167,7 +167,7 @@ RowLayout {
}
contentItem: ColumnLayout {
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
// Search input
NTextInput {
@@ -176,7 +176,7 @@ RowLayout {
placeholderText: root.searchPlaceholder
text: root.searchText
onTextChanged: root.searchText = text
- fontSize: Style.fontSizeS * scaling
+ fontSize: Style.fontSizeS
}
NListView {
@@ -206,8 +206,8 @@ RowLayout {
contentItem: NText {
text: name
- pointSize: Style.fontSizeM * scaling
- color: highlighted ? Color.mSurface : Color.mOnSurface
+ pointSize: Style.fontSizeM
+ color: highlighted ? Color.mOnTertiary : Color.mOnSurface
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
Behavior on color {
@@ -218,9 +218,9 @@ RowLayout {
}
background: Rectangle {
- width: listView.width * scaling
+ width: listView.width
color: highlighted ? Color.mTertiary : Color.transparent
- radius: Style.radiusS * scaling
+ radius: Style.radiusS
Behavior on color {
ColorAnimation {
duration: Style.animationFast
@@ -234,8 +234,8 @@ RowLayout {
background: Rectangle {
color: Color.mSurfaceVariant
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
- radius: Style.radiusM * scaling
+ border.width: Math.max(1, Style.borderS)
+ radius: Style.radiusM
}
}
diff --git a/Widgets/NSlider.qml b/Widgets/NSlider.qml
index 77393099..e91ecdb8 100644
--- a/Widgets/NSlider.qml
+++ b/Widgets/NSlider.qml
@@ -11,9 +11,9 @@ Slider {
property bool snapAlways: true
property real heightRatio: 0.7
- readonly property real knobDiameter: Math.round((Style.baseWidgetSize * heightRatio * scaling) / 2) * 2
- readonly property real trackHeight: Math.round((knobDiameter * 0.4) / 2) * 2
- readonly property real cutoutExtra: Math.round((Style.baseWidgetSize * 0.1 * scaling) / 2) * 2
+ readonly property real knobDiameter: Math.round((Style.baseWidgetSize * heightRatio * Style.uiScaleRatio) / 2) * 2
+ readonly property real trackHeight: Math.round((knobDiameter * 0.4 * Style.uiScaleRatio) / 2) * 2
+ readonly property real cutoutExtra: Math.round((Style.baseWidgetSize * 0.1 * Style.uiScaleRatio) / 2) * 2
padding: cutoutExtra / 2
@@ -30,7 +30,7 @@ Slider {
radius: height / 2
color: Qt.alpha(Color.mSurface, 0.5)
border.color: Qt.alpha(Color.mOutline, 0.5)
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
// A container composite shape that puts a semicircle on the end
Item {
@@ -116,7 +116,7 @@ Slider {
radius: width / 2
color: root.pressed ? Color.mTertiary : Color.mSurface
border.color: Color.mPrimary
- border.width: Math.max(1, Style.borderL * scaling)
+ border.width: Math.max(1, Style.borderL)
anchors.centerIn: parent
Behavior on color {
diff --git a/Widgets/NSpinBox.qml b/Widgets/NSpinBox.qml
index 8261135c..51310439 100644
--- a/Widgets/NSpinBox.qml
+++ b/Widgets/NSpinBox.qml
@@ -38,8 +38,8 @@ RowLayout {
// Main spinbox container
Rectangle {
id: spinBoxContainer
- implicitWidth: 120 * scaling
- implicitHeight: (root.baseSize - 4) * scaling
+ implicitWidth: 120
+ implicitHeight: (root.baseSize - 4)
radius: height * 0.5
color: Color.mSurfaceVariant
border.color: (root.hovering || decreaseArea.containsMouse || increaseArea.containsMouse) ? Color.mTertiary : Color.mOutline
@@ -153,7 +153,7 @@ RowLayout {
anchors.leftMargin: parent.width * 0.25
anchors.verticalCenter: parent.verticalCenter
icon: "chevron-left"
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: decreaseArea.containsMouse ? Color.mOnTertiary : Color.mPrimary
}
@@ -248,7 +248,7 @@ RowLayout {
anchors.rightMargin: parent.width * 0.25
anchors.verticalCenter: parent.verticalCenter
icon: "chevron-right"
- pointSize: Style.fontSizeS * scaling
+ pointSize: Style.fontSizeS
color: increaseArea.containsMouse ? Color.mOnTertiary : Color.mPrimary
}
@@ -271,7 +271,7 @@ RowLayout {
anchors.left: decreaseButton.right
anchors.right: increaseButton.left
anchors.verticalCenter: parent.verticalCenter
- anchors.margins: 4 * scaling
+ anchors.margins: 4
height: parent.height
color: Color.transparent
@@ -283,7 +283,7 @@ RowLayout {
NText {
text: root.prefix
family: Settings.data.ui.fontFixed
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightMedium
color: Color.mOnSurface
verticalAlignment: Text.AlignVCenter
@@ -296,7 +296,7 @@ RowLayout {
id: valueInput
text: valueInput.focus ? valueInput.text : root.value.toString()
font.family: Settings.data.ui.fontFixed
- font.pointSize: Style.fontSizeM * scaling
+ font.pointSize: Style.fontSizeM
font.weight: Style.fontWeightMedium
color: Color.mOnSurface
verticalAlignment: Text.AlignVCenter
@@ -342,7 +342,7 @@ RowLayout {
NText {
text: root.suffix
family: Settings.data.ui.fontFixed
- pointSize: Style.fontSizeM * scaling
+ pointSize: Style.fontSizeM
font.weight: Style.fontWeightMedium
color: Color.mOnSurface
verticalAlignment: Text.AlignVCenter
diff --git a/Widgets/NText.qml b/Widgets/NText.qml
index 9efd199e..4a9060ed 100644
--- a/Widgets/NText.qml
+++ b/Widgets/NText.qml
@@ -8,9 +8,14 @@ Text {
id: root
property string family: Settings.data.ui.fontDefault
- property real pointSize: Style.fontSizeM * scaling
+ property real pointSize: Style.fontSizeM
+ property bool applyUiScale: true
property real fontScale: {
- return (root.family === Settings.data.ui.fontDefault ? Settings.data.ui.fontDefaultScale : Settings.data.ui.fontFixedScale)
+ const fontScale = (root.family === Settings.data.ui.fontDefault ? Settings.data.ui.fontDefaultScale : Settings.data.ui.fontFixedScale)
+ if (applyUiScale) {
+ return fontScale * Style.uiScaleRatio
+ }
+ return fontScale
}
font.family: root.family
diff --git a/Widgets/NTextInput.qml b/Widgets/NTextInput.qml
index 7f2ec9d7..adb83cd3 100644
--- a/Widgets/NTextInput.qml
+++ b/Widgets/NTextInput.qml
@@ -14,7 +14,7 @@ ColumnLayout {
property color labelColor: Color.mOnSurface
property color descriptionColor: Color.mOnSurfaceVariant
property string fontFamily: Settings.data.ui.fontDefault
- property real fontSize: Style.fontSizeS * scaling
+ property real fontSize: Style.fontSizeS
property int fontWeight: Style.fontWeightRegular
property alias text: input.text
@@ -24,7 +24,7 @@ ColumnLayout {
signal editingFinished
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
NLabel {
label: root.label
@@ -40,8 +40,8 @@ ColumnLayout {
id: frameControl
Layout.fillWidth: true
- Layout.minimumWidth: 80 * scaling
- implicitHeight: Style.baseWidgetSize * 1.1 * scaling
+ Layout.minimumWidth: 80 * Style.uiScaleRatio
+ implicitHeight: Style.baseWidgetSize * 1.1 * Style.uiScaleRatio
// This is important - makes the control accept focus
focusPolicy: Qt.StrongFocus
@@ -50,10 +50,10 @@ ColumnLayout {
background: Rectangle {
id: frame
- radius: Style.radiusM * scaling
+ radius: Style.radiusM
color: Color.mSurface
border.color: input.activeFocus ? Color.mSecondary : Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
Behavior on border.color {
ColorAnimation {
@@ -79,7 +79,7 @@ ColumnLayout {
input.forceActiveFocus()
var inputPos = mapToItem(inputContainer, mouse.x, mouse.y)
if (inputPos.x >= 0 && inputPos.x <= inputContainer.width) {
- var textPos = inputPos.x - Style.marginM * scaling
+ var textPos = inputPos.x - Style.marginM
if (textPos >= 0 && textPos <= input.width) {
input.cursorPosition = input.positionAt(textPos, input.height / 2)
}
@@ -105,8 +105,8 @@ ColumnLayout {
Item {
id: inputContainer
anchors.fill: parent
- anchors.leftMargin: Style.marginM * scaling
- anchors.rightMargin: Style.marginM * scaling
+ anchors.leftMargin: Style.marginM
+ anchors.rightMargin: Style.marginM
z: 1
TextField {
@@ -131,7 +131,7 @@ ColumnLayout {
background: null
font.family: root.fontFamily
- font.pointSize: root.fontSize
+ font.pointSize: root.fontSize * Style.uiScaleRatio
font.weight: root.fontWeight
onEditingFinished: root.editingFinished()
diff --git a/Widgets/NTextInputButton.qml b/Widgets/NTextInputButton.qml
index 5e157c1e..89ec8ffd 100644
--- a/Widgets/NTextInputButton.qml
+++ b/Widgets/NTextInputButton.qml
@@ -21,7 +21,7 @@ ColumnLayout {
signal inputTextChanged(string text)
signal inputEditingFinished
- spacing: Style.marginS * scaling
+ spacing: Style.marginS
// Label and description
NLabel {
@@ -34,7 +34,7 @@ ColumnLayout {
// Input field with button
RowLayout {
Layout.fillWidth: true
- spacing: Style.marginM * scaling
+ spacing: Style.marginM
NTextInput {
id: input
diff --git a/Widgets/NToggle.qml b/Widgets/NToggle.qml
index 3e464bb8..18259ed6 100644
--- a/Widgets/NToggle.qml
+++ b/Widgets/NToggle.qml
@@ -11,7 +11,7 @@ RowLayout {
property string description: ""
property bool checked: false
property bool hovering: false
- property int baseSize: Math.round(Style.baseWidgetSize * 0.8)
+ property int baseSize: Math.round(Style.baseWidgetSize * 0.8 * Style.uiScaleRatio)
signal toggled(bool checked)
signal entered
@@ -27,12 +27,12 @@ RowLayout {
Rectangle {
id: switcher
- implicitWidth: Math.round(root.baseSize * .85 * scaling) * 2
- implicitHeight: Math.round(root.baseSize * scaling * .5) * 2
+ implicitWidth: Math.round(root.baseSize * .85) * 2
+ implicitHeight: Math.round(root.baseSize * .5) * 2
radius: height * 0.5
color: root.checked ? Color.mPrimary : Color.mSurface
border.color: Color.mOutline
- border.width: Math.max(1, Style.borderS * scaling)
+ border.width: Math.max(1, Style.borderS)
Behavior on color {
ColorAnimation {
@@ -48,15 +48,15 @@ RowLayout {
Rectangle {
- implicitWidth: Math.round(root.baseSize * 0.4 * scaling) * 2
- implicitHeight: Math.round(root.baseSize * 0.4 * scaling) * 2
+ implicitWidth: Math.round(root.baseSize * 0.4) * 2
+ implicitHeight: Math.round(root.baseSize * 0.4) * 2
radius: height * 0.5
color: root.checked ? Color.mOnPrimary : Color.mPrimary
border.color: root.checked ? Color.mSurface : Color.mSurface
- border.width: Math.max(1, Style.borderM * scaling)
+ border.width: Math.max(1, Style.borderM)
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: 0
- x: root.checked ? switcher.width - width - 3 * scaling : 3 * scaling
+ x: root.checked ? switcher.width - width - 3 : 3
Behavior on x {
NumberAnimation {
diff --git a/Widgets/NValueSlider.qml b/Widgets/NValueSlider.qml
index 3eb6538b..9449d699 100644
--- a/Widgets/NValueSlider.qml
+++ b/Widgets/NValueSlider.qml
@@ -16,7 +16,7 @@ RowLayout {
property bool snapAlways: true
property real heightRatio: 0.7
property string text: ""
- property real textSize: Style.fontSizeM * scaling
+ property real textSize: Style.fontSizeM
property real customHeight: -1
property real customHeightRatio: -1
@@ -24,7 +24,7 @@ RowLayout {
signal moved(real value)
signal pressedChanged(bool pressed, real value)
- spacing: Style.marginL * scaling
+ spacing: Style.marginL
implicitHeight: root.customHeight > 0 ? root.customHeight : slider.implicitHeight
NSlider {
@@ -47,7 +47,7 @@ RowLayout {
pointSize: root.textSize
family: Settings.data.ui.fontFixed
Layout.alignment: Qt.AlignVCenter
- Layout.preferredWidth: 45 * scaling
+ Layout.preferredWidth: 45 * Scale.uiScaleRatio
horizontalAlignment: Text.AlignRight
}
}