diff --git a/CLAUDE.md b/CLAUDE.md index 9884bae3..1de0975f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -64,8 +64,7 @@ quickshell -p shell.qml qs -p . # Code formatting and linting -./qmlformat-all.sh # Format all QML files using project script -qmlformat -i **/*.qml # Format all QML files in place +qmlfmt -t 4 -i 4 -b 250 -w /path/to/file.qml # Format a QML file (requires qmlfmt, do not use qmlformat) qmllint **/*.qml # Lint all QML files for syntax errors ``` @@ -221,6 +220,8 @@ shell.qml # Main entry point (minimal orchestration) - Properties before signal handlers before child components - Prefer property bindings over imperative code - **CRITICAL**: NEVER add comments unless absolutely essential for complex logic understanding. Code should be self-documenting through clear naming and structure. Comments are a code smell indicating unclear implementation. + - Use guard statements, example `if (abc) { something() return;} somethingElse();` + - Don't use crazy ternary stuff, but use it for simple if else only. `propertyVal: a ? b : c` 2. **Naming Conventions**: - **Services**: Use `Singleton` type with `id: root` @@ -228,9 +229,7 @@ shell.qml # Main entry point (minimal orchestration) - **Properties**: camelCase for properties, PascalCase for types 3. **Null-Safe Operations**: - - **Do NOT use** `?.` operator (not supported by qmlformat) - - **Use** `object && object.property` instead of `object?.property` - - **Example**: `activePlayer && activePlayer.trackTitle` instead of `activePlayer?.trackTitle` + - **Use** `object?.property` 4. **Component Structure**: ```qml diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..3a6924cd --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,24 @@ +# Contributing + +Contributions are welcome and encourages. + +## Formatting + +The preferred tool for formatting files is [qmlfmt](https://github.com/jesperhh/qmlfmt) (also available on aur as qmlfmt-git). It actually kinda sucks, but `qmlformat` doesn't work with null safe operators and ternarys and pragma statements and a bunch of other things that are supported. + +We need some consistent style, so this at least gives the same formatter that Qt Creator uses. + +You can configure it to format on save in vscode by configuring the "custom local formatters" extension then adding this to settings json. + +```json + "customLocalFormatters.formatters": [ + { + "command": "sh -c \"qmlfmt -t 4 -i 4 -b 250 | sed 's/pragma ComponentBehavior$/pragma ComponentBehavior: Bound/g'\"", + "languages": ["qml"] + } + ], + "[qml]": { + "editor.defaultFormatter": "jkillian.custom-local-formatters", + "editor.formatOnSave": true + }, +``` \ No newline at end of file diff --git a/Common/SettingsData.qml b/Common/SettingsData.qml index 15085819..dd2390db 100644 --- a/Common/SettingsData.qml +++ b/Common/SettingsData.qml @@ -1,4 +1,5 @@ pragma Singleton + pragma ComponentBehavior: Bound import QtCore @@ -98,18 +99,14 @@ Singleton { property var screenPreferences: ({}) readonly property string defaultFontFamily: "Inter Variable" readonly property string defaultMonoFontFamily: "Fira Code" - readonly property string _homeUrl: StandardPaths.writableLocation( - StandardPaths.HomeLocation) - readonly property string _configUrl: StandardPaths.writableLocation( - StandardPaths.ConfigLocation) - readonly property string _configDir: _configUrl.startsWith( - "file://") ? _configUrl.substring( - 7) : _configUrl + readonly property string _homeUrl: StandardPaths.writableLocation(StandardPaths.HomeLocation) + readonly property string _configUrl: StandardPaths.writableLocation(StandardPaths.ConfigLocation) + readonly property string _configDir: _configUrl.startsWith("file://") ? _configUrl.substring(7) : _configUrl signal forceTopBarLayoutRefresh signal widgetDataChanged signal workspaceIconsUpdated - + function getEffectiveTimeFormat() { if (use24HourClock) { return Locale.ShortFormat @@ -117,11 +114,11 @@ Singleton { return "h:mm AP" } } - + function getEffectiveClockDateFormat() { return clockDateFormat && clockDateFormat.length > 0 ? clockDateFormat : "ddd d" } - + function getEffectiveLockDateFormat() { return lockDateFormat && lockDateFormat.length > 0 ? lockDateFormat : Locale.LongFormat } @@ -139,7 +136,7 @@ Singleton { leftWidgetsModel.append(dummyItem) centerWidgetsModel.append(dummyItem) rightWidgetsModel.append(dummyItem) - + updateListModel(leftWidgetsModel, topBarLeftWidgets) updateListModel(centerWidgetsModel, topBarCenterWidgets) updateListModel(rightWidgetsModel, topBarRightWidgets) @@ -166,42 +163,20 @@ Singleton { currentThemeName = settings.currentThemeName !== undefined ? settings.currentThemeName : "blue" } customThemeFile = settings.customThemeFile !== undefined ? settings.customThemeFile : "" - topBarTransparency = settings.topBarTransparency - !== undefined ? (settings.topBarTransparency - > 1 ? settings.topBarTransparency - / 100 : settings.topBarTransparency) : 0.75 - topBarWidgetTransparency = settings.topBarWidgetTransparency - !== undefined ? (settings.topBarWidgetTransparency - > 1 ? settings.topBarWidgetTransparency - / 100 : settings.topBarWidgetTransparency) : 0.85 - popupTransparency = settings.popupTransparency - !== undefined ? (settings.popupTransparency - > 1 ? settings.popupTransparency - / 100 : settings.popupTransparency) : 0.92 - dockTransparency = settings.dockTransparency - !== undefined ? (settings.dockTransparency - > 1 ? settings.dockTransparency - / 100 : settings.dockTransparency) : 1 - use24HourClock = settings.use24HourClock - !== undefined ? settings.use24HourClock : true - useFahrenheit = settings.useFahrenheit - !== undefined ? settings.useFahrenheit : false - nightModeEnabled = settings.nightModeEnabled - !== undefined ? settings.nightModeEnabled : false - weatherLocation = settings.weatherLocation - !== undefined ? settings.weatherLocation : "New York, NY" - weatherCoordinates = settings.weatherCoordinates - !== undefined ? settings.weatherCoordinates : "40.7128,-74.0060" - useAutoLocation = settings.useAutoLocation - !== undefined ? settings.useAutoLocation : false - weatherEnabled = settings.weatherEnabled - !== undefined ? settings.weatherEnabled : true - showLauncherButton = settings.showLauncherButton - !== undefined ? settings.showLauncherButton : true - showWorkspaceSwitcher = settings.showWorkspaceSwitcher - !== undefined ? settings.showWorkspaceSwitcher : true - showFocusedWindow = settings.showFocusedWindow - !== undefined ? settings.showFocusedWindow : true + topBarTransparency = settings.topBarTransparency !== undefined ? (settings.topBarTransparency > 1 ? settings.topBarTransparency / 100 : settings.topBarTransparency) : 0.75 + topBarWidgetTransparency = settings.topBarWidgetTransparency !== undefined ? (settings.topBarWidgetTransparency > 1 ? settings.topBarWidgetTransparency / 100 : settings.topBarWidgetTransparency) : 0.85 + popupTransparency = settings.popupTransparency !== undefined ? (settings.popupTransparency > 1 ? settings.popupTransparency / 100 : settings.popupTransparency) : 0.92 + dockTransparency = settings.dockTransparency !== undefined ? (settings.dockTransparency > 1 ? settings.dockTransparency / 100 : settings.dockTransparency) : 1 + use24HourClock = settings.use24HourClock !== undefined ? settings.use24HourClock : true + useFahrenheit = settings.useFahrenheit !== undefined ? settings.useFahrenheit : false + nightModeEnabled = settings.nightModeEnabled !== undefined ? settings.nightModeEnabled : false + weatherLocation = settings.weatherLocation !== undefined ? settings.weatherLocation : "New York, NY" + weatherCoordinates = settings.weatherCoordinates !== undefined ? settings.weatherCoordinates : "40.7128,-74.0060" + useAutoLocation = settings.useAutoLocation !== undefined ? settings.useAutoLocation : false + weatherEnabled = settings.weatherEnabled !== undefined ? settings.weatherEnabled : true + showLauncherButton = settings.showLauncherButton !== undefined ? settings.showLauncherButton : true + showWorkspaceSwitcher = settings.showWorkspaceSwitcher !== undefined ? settings.showWorkspaceSwitcher : true + showFocusedWindow = settings.showFocusedWindow !== undefined ? settings.showFocusedWindow : true showWeather = settings.showWeather !== undefined ? settings.showWeather : true showMusic = settings.showMusic !== undefined ? settings.showMusic : true showClipboard = settings.showClipboard !== undefined ? settings.showClipboard : true @@ -209,68 +184,42 @@ Singleton { showMemUsage = settings.showMemUsage !== undefined ? settings.showMemUsage : true showCpuTemp = settings.showCpuTemp !== undefined ? settings.showCpuTemp : true showGpuTemp = settings.showGpuTemp !== undefined ? settings.showGpuTemp : true - selectedGpuIndex = settings.selectedGpuIndex - !== undefined ? settings.selectedGpuIndex : 0 - enabledGpuPciIds = settings.enabledGpuPciIds - !== undefined ? settings.enabledGpuPciIds : [] - showSystemTray = settings.showSystemTray - !== undefined ? settings.showSystemTray : true + selectedGpuIndex = settings.selectedGpuIndex !== undefined ? settings.selectedGpuIndex : 0 + enabledGpuPciIds = settings.enabledGpuPciIds !== undefined ? settings.enabledGpuPciIds : [] + showSystemTray = settings.showSystemTray !== undefined ? settings.showSystemTray : true showClock = settings.showClock !== undefined ? settings.showClock : true - showNotificationButton = settings.showNotificationButton - !== undefined ? settings.showNotificationButton : true + showNotificationButton = settings.showNotificationButton !== undefined ? settings.showNotificationButton : true showBattery = settings.showBattery !== undefined ? settings.showBattery : true - showControlCenterButton = settings.showControlCenterButton - !== undefined ? settings.showControlCenterButton : true - controlCenterShowNetworkIcon = settings.controlCenterShowNetworkIcon - !== undefined ? settings.controlCenterShowNetworkIcon : true - controlCenterShowBluetoothIcon = settings.controlCenterShowBluetoothIcon - !== undefined ? settings.controlCenterShowBluetoothIcon : true - controlCenterShowAudioIcon = settings.controlCenterShowAudioIcon - !== undefined ? settings.controlCenterShowAudioIcon : true - showWorkspaceIndex = settings.showWorkspaceIndex - !== undefined ? settings.showWorkspaceIndex : false - showWorkspacePadding = settings.showWorkspacePadding - !== undefined ? settings.showWorkspacePadding : false - showWorkspaceApps = settings.showWorkspaceApps - !== undefined ? settings.showWorkspaceApps : false - maxWorkspaceIcons = settings.maxWorkspaceIcons - !== undefined ? settings.maxWorkspaceIcons : 3 - workspaceNameIcons = settings.workspaceNameIcons - !== undefined ? settings.workspaceNameIcons : ({}) - clockCompactMode = settings.clockCompactMode - !== undefined ? settings.clockCompactMode : false - focusedWindowCompactMode = settings.focusedWindowCompactMode - !== undefined ? settings.focusedWindowCompactMode : false - runningAppsCompactMode = settings.runningAppsCompactMode - !== undefined ? settings.runningAppsCompactMode : true - runningAppsCurrentWorkspace = settings.runningAppsCurrentWorkspace - !== undefined ? settings.runningAppsCurrentWorkspace : false - clockDateFormat = settings.clockDateFormat - !== undefined ? settings.clockDateFormat : "" - lockDateFormat = settings.lockDateFormat - !== undefined ? settings.lockDateFormat : "" + showControlCenterButton = settings.showControlCenterButton !== undefined ? settings.showControlCenterButton : true + controlCenterShowNetworkIcon = settings.controlCenterShowNetworkIcon !== undefined ? settings.controlCenterShowNetworkIcon : true + controlCenterShowBluetoothIcon = settings.controlCenterShowBluetoothIcon !== undefined ? settings.controlCenterShowBluetoothIcon : true + controlCenterShowAudioIcon = settings.controlCenterShowAudioIcon !== undefined ? settings.controlCenterShowAudioIcon : true + showWorkspaceIndex = settings.showWorkspaceIndex !== undefined ? settings.showWorkspaceIndex : false + showWorkspacePadding = settings.showWorkspacePadding !== undefined ? settings.showWorkspacePadding : false + showWorkspaceApps = settings.showWorkspaceApps !== undefined ? settings.showWorkspaceApps : false + maxWorkspaceIcons = settings.maxWorkspaceIcons !== undefined ? settings.maxWorkspaceIcons : 3 + workspaceNameIcons = settings.workspaceNameIcons !== undefined ? settings.workspaceNameIcons : ({}) + clockCompactMode = settings.clockCompactMode !== undefined ? settings.clockCompactMode : false + focusedWindowCompactMode = settings.focusedWindowCompactMode !== undefined ? settings.focusedWindowCompactMode : false + runningAppsCompactMode = settings.runningAppsCompactMode !== undefined ? settings.runningAppsCompactMode : true + runningAppsCurrentWorkspace = settings.runningAppsCurrentWorkspace !== undefined ? settings.runningAppsCurrentWorkspace : false + clockDateFormat = settings.clockDateFormat !== undefined ? settings.clockDateFormat : "" + lockDateFormat = settings.lockDateFormat !== undefined ? settings.lockDateFormat : "" mediaSize = settings.mediaSize !== undefined ? settings.mediaSize : (settings.mediaCompactMode !== undefined ? (settings.mediaCompactMode ? 0 : 1) : 1) if (settings.topBarWidgetOrder) { topBarLeftWidgets = settings.topBarWidgetOrder.filter(w => { return ["launcherButton", "workspaceSwitcher", "focusedWindow"].includes(w) }) - topBarCenterWidgets = settings.topBarWidgetOrder.filter( - w => { - return ["clock", "music", "weather"].includes( - w) - }) - topBarRightWidgets = settings.topBarWidgetOrder.filter( - w => { - return ["systemTray", "clipboard", "systemResources", "notificationButton", "battery", "controlCenterButton"].includes( - w) - }) + topBarCenterWidgets = settings.topBarWidgetOrder.filter(w => { + return ["clock", "music", "weather"].includes(w) + }) + topBarRightWidgets = settings.topBarWidgetOrder.filter(w => { + return ["systemTray", "clipboard", "systemResources", "notificationButton", "battery", "controlCenterButton"].includes(w) + }) } else { - var leftWidgets = settings.topBarLeftWidgets - !== undefined ? settings.topBarLeftWidgets : ["launcherButton", "workspaceSwitcher", "focusedWindow"] - var centerWidgets = settings.topBarCenterWidgets - !== undefined ? settings.topBarCenterWidgets : ["music", "clock", "weather"] - var rightWidgets = settings.topBarRightWidgets - !== undefined ? settings.topBarRightWidgets : ["systemTray", "clipboard", "cpuUsage", "memUsage", "notificationButton", "battery", "controlCenterButton"] + var leftWidgets = settings.topBarLeftWidgets !== undefined ? settings.topBarLeftWidgets : ["launcherButton", "workspaceSwitcher", "focusedWindow"] + var centerWidgets = settings.topBarCenterWidgets !== undefined ? settings.topBarCenterWidgets : ["music", "clock", "weather"] + var rightWidgets = settings.topBarRightWidgets !== undefined ? settings.topBarRightWidgets : ["systemTray", "clipboard", "cpuUsage", "memUsage", "notificationButton", "battery", "controlCenterButton"] topBarLeftWidgets = leftWidgets topBarCenterWidgets = centerWidgets topBarRightWidgets = rightWidgets @@ -278,54 +227,35 @@ Singleton { updateListModel(centerWidgetsModel, centerWidgets) updateListModel(rightWidgetsModel, rightWidgets) } - appLauncherViewMode = settings.appLauncherViewMode - !== undefined ? settings.appLauncherViewMode : "list" - spotlightModalViewMode = settings.spotlightModalViewMode - !== undefined ? settings.spotlightModalViewMode : "list" - networkPreference = settings.networkPreference - !== undefined ? settings.networkPreference : "auto" + appLauncherViewMode = settings.appLauncherViewMode !== undefined ? settings.appLauncherViewMode : "list" + spotlightModalViewMode = settings.spotlightModalViewMode !== undefined ? settings.spotlightModalViewMode : "list" + networkPreference = settings.networkPreference !== undefined ? settings.networkPreference : "auto" iconTheme = settings.iconTheme !== undefined ? settings.iconTheme : "System Default" useOSLogo = settings.useOSLogo !== undefined ? settings.useOSLogo : false - osLogoColorOverride = settings.osLogoColorOverride - !== undefined ? settings.osLogoColorOverride : "" - osLogoBrightness = settings.osLogoBrightness - !== undefined ? settings.osLogoBrightness : 0.5 + osLogoColorOverride = settings.osLogoColorOverride !== undefined ? settings.osLogoColorOverride : "" + osLogoBrightness = settings.osLogoBrightness !== undefined ? settings.osLogoBrightness : 0.5 osLogoContrast = settings.osLogoContrast !== undefined ? settings.osLogoContrast : 1 - wallpaperDynamicTheming = settings.wallpaperDynamicTheming - !== undefined ? settings.wallpaperDynamicTheming : true - fontFamily = settings.fontFamily - !== undefined ? settings.fontFamily : defaultFontFamily - monoFontFamily = settings.monoFontFamily - !== undefined ? settings.monoFontFamily : defaultMonoFontFamily + wallpaperDynamicTheming = settings.wallpaperDynamicTheming !== undefined ? settings.wallpaperDynamicTheming : true + fontFamily = settings.fontFamily !== undefined ? settings.fontFamily : defaultFontFamily + monoFontFamily = settings.monoFontFamily !== undefined ? settings.monoFontFamily : defaultMonoFontFamily fontWeight = settings.fontWeight !== undefined ? settings.fontWeight : Font.Normal - gtkThemingEnabled = settings.gtkThemingEnabled - !== undefined ? settings.gtkThemingEnabled : false - qtThemingEnabled = settings.qtThemingEnabled - !== undefined ? settings.qtThemingEnabled : false + gtkThemingEnabled = settings.gtkThemingEnabled !== undefined ? settings.gtkThemingEnabled : false + qtThemingEnabled = settings.qtThemingEnabled !== undefined ? settings.qtThemingEnabled : false showDock = settings.showDock !== undefined ? settings.showDock : false dockAutoHide = settings.dockAutoHide !== undefined ? settings.dockAutoHide : false cornerRadius = settings.cornerRadius !== undefined ? settings.cornerRadius : 12 - notificationOverlayEnabled = settings.notificationOverlayEnabled - !== undefined ? settings.notificationOverlayEnabled : false - topBarAutoHide = settings.topBarAutoHide - !== undefined ? settings.topBarAutoHide : false - topBarVisible = settings.topBarVisible - !== undefined ? settings.topBarVisible : true - notificationTimeoutLow = settings.notificationTimeoutLow - !== undefined ? settings.notificationTimeoutLow : 5000 - notificationTimeoutNormal = settings.notificationTimeoutNormal - !== undefined ? settings.notificationTimeoutNormal : 5000 - notificationTimeoutCritical = settings.notificationTimeoutCritical - !== undefined ? settings.notificationTimeoutCritical : 0 + notificationOverlayEnabled = settings.notificationOverlayEnabled !== undefined ? settings.notificationOverlayEnabled : false + topBarAutoHide = settings.topBarAutoHide !== undefined ? settings.topBarAutoHide : false + topBarVisible = settings.topBarVisible !== undefined ? settings.topBarVisible : true + notificationTimeoutLow = settings.notificationTimeoutLow !== undefined ? settings.notificationTimeoutLow : 5000 + notificationTimeoutNormal = settings.notificationTimeoutNormal !== undefined ? settings.notificationTimeoutNormal : 5000 + notificationTimeoutCritical = settings.notificationTimeoutCritical !== undefined ? settings.notificationTimeoutCritical : 0 topBarSpacing = settings.topBarSpacing !== undefined ? settings.topBarSpacing : 4 topBarBottomGap = settings.topBarBottomGap !== undefined ? settings.topBarBottomGap : 0 topBarInnerPadding = settings.topBarInnerPadding !== undefined ? settings.topBarInnerPadding : 8 - topBarSquareCorners = settings.topBarSquareCorners - !== undefined ? settings.topBarSquareCorners : false - topBarNoBackground = settings.topBarNoBackground - !== undefined ? settings.topBarNoBackground : false - screenPreferences = settings.screenPreferences - !== undefined ? settings.screenPreferences : ({}) + topBarSquareCorners = settings.topBarSquareCorners !== undefined ? settings.topBarSquareCorners : false + topBarNoBackground = settings.topBarNoBackground !== undefined ? settings.topBarNoBackground : false + screenPreferences = settings.screenPreferences !== undefined ? settings.screenPreferences : ({}) applyStoredTheme() detectAvailableIconThemes() detectQtTools() @@ -434,7 +364,7 @@ Singleton { showWorkspaceApps = enabled saveSettings() } - + function setMaxWorkspaceIcons(maxIcons) { maxWorkspaceIcons = maxIcons saveSettings() @@ -526,7 +456,7 @@ Singleton { else Qt.callLater(() => { if (typeof Theme !== "undefined") - Theme.switchTheme(currentThemeName, false) + Theme.switchTheme(currentThemeName, false) }) } @@ -706,8 +636,7 @@ Singleton { var widgetId = typeof order[i] === "string" ? order[i] : order[i].id var enabled = typeof order[i] === "string" ? true : order[i].enabled var size = typeof order[i] === "string" ? undefined : order[i].size - var selectedGpuIndex = typeof order[i] - === "string" ? undefined : order[i].selectedGpuIndex + var selectedGpuIndex = typeof order[i] === "string" ? undefined : order[i].selectedGpuIndex var pciId = typeof order[i] === "string" ? undefined : order[i].pciId var item = { "widgetId": widgetId, @@ -834,8 +763,7 @@ Singleton { + " print \"icon_theme=\" theme; icon_theme_added = 1 \n" + " } \n" + " in_appearance = 0; print; next \n" + " }\n" + " in_appearance && /^icon_theme=/ { \n" + " if (!icon_theme_added) { \n" + " print \"icon_theme=\" theme; icon_theme_added = 1 \n" + " } \n" + " next \n" + " }\n" + " { print }\n" + " END { if (in_appearance && !icon_theme_added) print \"icon_theme=\" theme }\n" + " ' \"$config_file\" > \"$config_file.tmp\" && mv \"$config_file.tmp\" \"$config_file\"\n" + " else\n" + " printf '\\n[Appearance]\\nicon_theme=%s\\n' \"$theme_name\" >> \"$config_file\"\n" + " fi\n" + " else\n" + " printf '[Appearance]\\nicon_theme=%s\\n' \"$theme_name\" > \"$config_file\"\n" + " fi\n" + "}\n" + "update_qt_config " + _configDir + "/qt5ct/qt5ct.conf " + _shq( - qtThemeName) + "\n" + "update_qt_config " + _configDir + "/qt6ct/qt6ct.conf " + _shq(qtThemeName) + "\n" - + "rm -rf " + home + "/.cache/icon-cache " + home + "/.cache/thumbnails 2>/dev/null || true\n" + qtThemeName) + "\n" + "update_qt_config " + _configDir + "/qt6ct/qt6ct.conf " + _shq(qtThemeName) + "\n" + "rm -rf " + home + "/.cache/icon-cache " + home + "/.cache/thumbnails 2>/dev/null || true\n" Quickshell.execDetached(["sh", "-lc", script]) } @@ -1018,17 +946,14 @@ Singleton { onTriggered: { var availableFonts = Qt.fontFamilies() var missingFonts = [] - if (fontFamily === defaultFontFamily && !availableFonts.includes( - defaultFontFamily)) - missingFonts.push(defaultFontFamily) + if (fontFamily === defaultFontFamily && !availableFonts.includes(defaultFontFamily)) + missingFonts.push(defaultFontFamily) - if (monoFontFamily === defaultMonoFontFamily - && !availableFonts.includes(defaultMonoFontFamily)) - missingFonts.push(defaultMonoFontFamily) + if (monoFontFamily === defaultMonoFontFamily && !availableFonts.includes(defaultMonoFontFamily)) + missingFonts.push(defaultMonoFontFamily) if (missingFonts.length > 0) { - var message = "Missing fonts: " + missingFonts.join( - ", ") + ". Using system defaults." + var message = "Missing fonts: " + missingFonts.join(", ") + ". Using system defaults." ToastService.showWarning(message) } } @@ -1039,8 +964,7 @@ Singleton { FileView { id: settingsFile - path: StandardPaths.writableLocation( - StandardPaths.ConfigLocation) + "/DankMaterialShell/settings.json" + path: StandardPaths.writableLocation(StandardPaths.ConfigLocation) + "/DankMaterialShell/settings.json" blockLoading: true blockWrites: true watchChanges: true @@ -1049,13 +973,13 @@ Singleton { hasTriedDefaultSettings = false } onLoadFailed: error => { - if (!hasTriedDefaultSettings) { - hasTriedDefaultSettings = true - defaultSettingsCheckProcess.running = true - } else { - applyStoredTheme() - } - } + if (!hasTriedDefaultSettings) { + hasTriedDefaultSettings = true + defaultSettingsCheckProcess.running = true + } else { + applyStoredTheme() + } + } } Process { @@ -1064,12 +988,12 @@ Singleton { command: ["sh", "-c", "gsettings get org.gnome.desktop.interface icon-theme 2>/dev/null | sed \"s/'//g\" || echo ''"] running: false onExited: exitCode => { - if (exitCode === 0 && stdout && stdout.length > 0) - systemDefaultIconTheme = stdout.trim() - else - systemDefaultIconTheme = "" - iconThemeDetectionProcess.running = true - } + if (exitCode === 0 && stdout && stdout.length > 0) + systemDefaultIconTheme = stdout.trim() + else + systemDefaultIconTheme = "" + iconThemeDetectionProcess.running = true + } } Process { @@ -1085,9 +1009,8 @@ Singleton { var themes = text.trim().split('\n') for (var i = 0; i < themes.length; i++) { var theme = themes[i].trim() - if (theme && theme !== "" && theme !== "default" - && theme !== "hicolor" && theme !== "locolor") - detectedThemes.push(theme) + if (theme && theme !== "" && theme !== "default" && theme !== "hicolor" && theme !== "locolor") + detectedThemes.push(theme) } } availableIconThemes = detectedThemes @@ -1108,11 +1031,11 @@ Singleton { for (var i = 0; i < lines.length; i++) { var line = lines[i] if (line.startsWith('qt5ct:')) - qt5ctAvailable = line.split(':')[1] === 'true' + qt5ctAvailable = line.split(':')[1] === 'true' else if (line.startsWith('qt6ct:')) - qt6ctAvailable = line.split(':')[1] === 'true' + qt6ctAvailable = line.split(':')[1] === 'true' else if (line.startsWith('gtk:')) - gtkAvailable = line.split(':')[1] === 'true' + gtkAvailable = line.split(':')[1] === 'true' } } } @@ -1122,17 +1045,18 @@ Singleton { Process { id: defaultSettingsCheckProcess - command: ["sh", "-c", "CONFIG_DIR=\"" + _configDir + "/DankMaterialShell\"; if [ -f \"$CONFIG_DIR/default-settings.json\" ] && [ ! -f \"$CONFIG_DIR/settings.json\" ]; then cp \"$CONFIG_DIR/default-settings.json\" \"$CONFIG_DIR/settings.json\" && echo 'copied'; else echo 'not_found'; fi"] + command: ["sh", "-c", "CONFIG_DIR=\"" + _configDir + + "/DankMaterialShell\"; if [ -f \"$CONFIG_DIR/default-settings.json\" ] && [ ! -f \"$CONFIG_DIR/settings.json\" ]; then cp \"$CONFIG_DIR/default-settings.json\" \"$CONFIG_DIR/settings.json\" && echo 'copied'; else echo 'not_found'; fi"] running: false onExited: exitCode => { - if (exitCode === 0) { - console.log("Copied default-settings.json to settings.json") - settingsFile.reload() - } else { - // No default settings file found, just apply stored theme - applyStoredTheme() - } - } + if (exitCode === 0) { + console.log("Copied default-settings.json to settings.json") + settingsFile.reload() + } else { + // No default settings file found, just apply stored theme + applyStoredTheme() + } + } } IpcHandler { @@ -1157,5 +1081,4 @@ Singleton { target: "bar" } - } diff --git a/Modules/AppDrawer/AppDrawerPopout.qml b/Modules/AppDrawer/AppDrawerPopout.qml index 798d5a5c..e621709a 100644 --- a/Modules/AppDrawer/AppDrawerPopout.qml +++ b/Modules/AppDrawer/AppDrawerPopout.qml @@ -17,10 +17,6 @@ DankPopout { function show() { open() - appLauncher.searchQuery = "" - appLauncher.selectedIndex = 0 - appLauncher.setCategory("All") - appLauncher.keyboardNavigationActive = false } function setTriggerPosition(x, y, width, section, screen) { @@ -40,12 +36,18 @@ DankPopout { WlrLayershell.namespace: "quickshell-launcher" screen: triggerScreen - onOpened: { - Qt.callLater(() => { - if (contentLoader.item && contentLoader.item.searchField) { - contentLoader.item.searchField.forceActiveFocus() - } - }) + onShouldBeVisibleChanged: { + if (shouldBeVisible) { + appLauncher.searchQuery = "" + appLauncher.selectedIndex = 0 + appLauncher.setCategory("All") + Qt.callLater(() => { + if (contentLoader.item && contentLoader.item.searchField) { + contentLoader.item.searchField.text = "" + contentLoader.item.searchField.forceActiveFocus() + } + }) + } } AppLauncher { diff --git a/Modules/Lock/LockScreenContent.qml b/Modules/Lock/LockScreenContent.qml index 619c7d3a..0cd7dd80 100644 --- a/Modules/Lock/LockScreenContent.qml +++ b/Modules/Lock/LockScreenContent.qml @@ -120,7 +120,7 @@ Item { anchors.top: parent.top text: { if (SettingsData.use24HourClock) { - return systemClock.date.toLocaleTimeString(Qt.locale(), Locale.ShortFormat) + return systemClock.date.toLocaleTimeString(Qt.locale(), "HH:mm") } else { return systemClock.date.toLocaleTimeString(Qt.locale(), "h:mm AP") } diff --git a/Modules/Notifications/Center/KeyboardNavigatedNotificationList.qml b/Modules/Notifications/Center/KeyboardNavigatedNotificationList.qml index 4ddb2b16..1287a819 100644 --- a/Modules/Notifications/Center/KeyboardNavigatedNotificationList.qml +++ b/Modules/Notifications/Center/KeyboardNavigatedNotificationList.qml @@ -9,10 +9,15 @@ DankListView { property var keyboardController: null property bool keyboardActive: false property bool autoScrollDisabled: false + property alias count: listView.count + property alias listContentHeight: listView.contentHeight + + clip: true + model: NotificationService.groupedNotifications + spacing: Theme.spacingL onIsUserScrollingChanged: { - if (isUserScrolling && keyboardController - && keyboardController.keyboardNavigationActive) { + if (isUserScrolling && keyboardController && keyboardController.keyboardNavigationActive) { autoScrollDisabled = true } } @@ -21,24 +26,13 @@ DankListView { autoScrollDisabled = false } - property alias count: listView.count - property alias listContentHeight: listView.contentHeight - - clip: true - model: NotificationService.groupedNotifications - spacing: Theme.spacingL - Timer { id: positionPreservationTimer interval: 200 - running: keyboardController - && keyboardController.keyboardNavigationActive - && !autoScrollDisabled + running: keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled repeat: true onTriggered: { - if (keyboardController - && keyboardController.keyboardNavigationActive - && !autoScrollDisabled) { + if (keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled) { keyboardController.ensureVisible() } } @@ -50,107 +44,94 @@ DankListView { } onModelChanged: { - if (keyboardController && keyboardController.keyboardNavigationActive) { - keyboardController.rebuildFlatNavigation() - Qt.callLater(function () { - if (keyboardController - && keyboardController.keyboardNavigationActive - && !autoScrollDisabled) { - keyboardController.ensureVisible() - } - }) + if (!keyboardController || !keyboardController.keyboardNavigationActive) { + return } + keyboardController.rebuildFlatNavigation() + Qt.callLater(() => { + if (keyboardController && keyboardController.keyboardNavigationActive && !autoScrollDisabled) { + keyboardController.ensureVisible() + } + }) } delegate: Item { required property var modelData required property int index - readonly property bool isExpanded: NotificationService.expandedGroups[modelData?.key] - || false + readonly property bool isExpanded: (NotificationService.expandedGroups[modelData && modelData.key] || false) width: ListView.view.width - height: notificationCardWrapper.height + height: notificationCard.height - Item { - id: notificationCardWrapper + NotificationCard { + id: notificationCard width: parent.width - height: notificationCard.height + notificationGroup: modelData + keyboardNavigationActive: listView.keyboardActive - NotificationCard { - id: notificationCard - width: parent.width - notificationGroup: modelData + isGroupSelected: { + if (!keyboardController || !keyboardController.keyboardNavigationActive || !listView.keyboardActive) { + return false + } + keyboardController.selectionVersion + const selection = keyboardController.getCurrentSelection() + return selection.type === "group" && selection.groupIndex === index + } - isGroupSelected: { - if (!keyboardController - || !keyboardController.keyboardNavigationActive) - return false - keyboardController.selectionVersion - if (!listView.keyboardActive) - return false - const selection = keyboardController.getCurrentSelection() - return selection.type === "group" - && selection.groupIndex === index + selectedNotificationIndex: { + if (!keyboardController || !keyboardController.keyboardNavigationActive || !listView.keyboardActive) { + return -1 } - selectedNotificationIndex: { - if (!keyboardController - || !keyboardController.keyboardNavigationActive) - return -1 - keyboardController.selectionVersion - if (!listView.keyboardActive) - return -1 - const selection = keyboardController.getCurrentSelection() - return (selection.type === "notification" - && selection.groupIndex === index) ? selection.notificationIndex : -1 - } - keyboardNavigationActive: listView.keyboardActive + keyboardController.selectionVersion + const selection = keyboardController.getCurrentSelection() + return (selection.type === "notification" && selection.groupIndex === index) ? selection.notificationIndex : -1 } } } Connections { + target: NotificationService + function onGroupedNotificationsChanged() { - if (keyboardController) { - if (keyboardController.isTogglingGroup) { - keyboardController.rebuildFlatNavigation() - return - } + if (!keyboardController) { + return + } + if (keyboardController.isTogglingGroup) { keyboardController.rebuildFlatNavigation() + return + } - if (keyboardController.keyboardNavigationActive) { - Qt.callLater(function () { - if (!autoScrollDisabled) { - keyboardController.ensureVisible() - } - }) - } + keyboardController.rebuildFlatNavigation() + + if (keyboardController.keyboardNavigationActive) { + Qt.callLater(() => { + if (!autoScrollDisabled) { + keyboardController.ensureVisible() + } + }) } } function onExpandedGroupsChanged() { - if (keyboardController - && keyboardController.keyboardNavigationActive) { - Qt.callLater(function () { - if (!autoScrollDisabled) { - keyboardController.ensureVisible() - } - }) + if (keyboardController && keyboardController.keyboardNavigationActive) { + Qt.callLater(() => { + if (!autoScrollDisabled) { + keyboardController.ensureVisible() + } + }) } } function onExpandedMessagesChanged() { - if (keyboardController - && keyboardController.keyboardNavigationActive) { - Qt.callLater(function () { - if (!autoScrollDisabled) { - keyboardController.ensureVisible() - } - }) + if (keyboardController && keyboardController.keyboardNavigationActive) { + Qt.callLater(() => { + if (!autoScrollDisabled) { + keyboardController.ensureVisible() + } + }) } } - - target: NotificationService } } diff --git a/Modules/Notifications/Center/NotificationCard.qml b/Modules/Notifications/Center/NotificationCard.qml index 1ae5a1d1..22d411c4 100644 --- a/Modules/Notifications/Center/NotificationCard.qml +++ b/Modules/Notifications/Center/NotificationCard.qml @@ -11,13 +11,11 @@ Rectangle { id: root property var notificationGroup - property bool expanded: NotificationService.expandedGroups[notificationGroup?.key] - || false - property bool descriptionExpanded: NotificationService.expandedMessages[notificationGroup?.latestNotification?.notification?.id + "_desc"] - || false + property bool expanded: (NotificationService.expandedGroups[notificationGroup && notificationGroup.key] || false) + property bool descriptionExpanded: (NotificationService.expandedMessages[(notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.notification + && notificationGroup.latestNotification.notification.id) ? (notificationGroup.latestNotification.notification.id + "_desc") : ""] || false) property bool userInitiatedExpansion: false - // Selection properties for keyboard navigation property bool isGroupSelected: false property int selectedNotificationIndex: -1 property bool keyboardNavigationActive: false @@ -29,8 +27,7 @@ Rectangle { } const baseHeight = 116 if (descriptionExpanded) { - return baseHeight + descriptionText.contentHeight - - (descriptionText.font.pixelSize * 1.2 * 2) + return baseHeight + descriptionText.contentHeight - (descriptionText.font.pixelSize * 1.2 * 2) } return baseHeight } @@ -51,50 +48,33 @@ Rectangle { } color: { - // Keyboard selection highlighting for groups (both collapsed and expanded) if (isGroupSelected && keyboardNavigationActive) { - return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.2) + return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.2) } - // Very subtle group highlighting when navigating within expanded group - if (keyboardNavigationActive && expanded - && selectedNotificationIndex >= 0) { - return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.12) + if (keyboardNavigationActive && expanded && selectedNotificationIndex >= 0) { + return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.12) } - return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.1) + return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.1) } border.color: { - // Keyboard selection highlighting for groups (both collapsed and expanded) if (isGroupSelected && keyboardNavigationActive) { - return Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.5) + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.5) } - // Subtle group border when navigating within expanded group - if (keyboardNavigationActive && expanded - && selectedNotificationIndex >= 0) { - return Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.2) + if (keyboardNavigationActive && expanded && selectedNotificationIndex >= 0) { + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.2) } - // Critical notification styling if (notificationGroup?.latestNotification?.urgency === NotificationUrgency.Critical) { - return Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.3) + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3) } return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.05) } border.width: { - // Keyboard selection highlighting for groups (both collapsed and expanded) if (isGroupSelected && keyboardNavigationActive) { return 1.5 } - // Subtle group border when navigating within expanded group - if (keyboardNavigationActive && expanded - && selectedNotificationIndex >= 0) { + if (keyboardNavigationActive && expanded && selectedNotificationIndex >= 0) { return 1 } - // Critical notification styling if (notificationGroup?.latestNotification?.urgency === NotificationUrgency.Critical) { return 2 } @@ -142,8 +122,7 @@ Rectangle { width: 55 height: 55 radius: 27.5 - color: Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.1) + color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) border.color: "transparent" border.width: 0 anchors.left: parent.left @@ -158,9 +137,7 @@ Rectangle { return notificationGroup.latestNotification.cleanImage if (notificationGroup?.latestNotification?.appIcon) { const appIcon = notificationGroup.latestNotification.appIcon - if (appIcon.startsWith("file://") || appIcon.startsWith( - "http://") || appIcon.startsWith( - "https://")) + if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://")) return appIcon return Quickshell.iconPath(appIcon, true) } @@ -171,9 +148,7 @@ Rectangle { StyledText { anchors.centerIn: parent - visible: !parent.hasNotificationImage - && (!notificationGroup?.latestNotification?.appIcon - || notificationGroup.latestNotification.appIcon === "") + visible: !parent.hasNotificationImage && (!notificationGroup?.latestNotification?.appIcon || notificationGroup.latestNotification.appIcon === "") text: { const appName = notificationGroup?.appName || "?" return appName.charAt(0).toUpperCase() @@ -196,9 +171,7 @@ Rectangle { StyledText { anchors.centerIn: parent - text: (notificationGroup?.count - || 0) > 99 ? "99+" : (notificationGroup?.count - || 0).toString() + text: (notificationGroup?.count || 0) > 99 ? "99+" : (notificationGroup?.count || 0).toString() color: Theme.primaryText font.pixelSize: 9 font.weight: Font.Bold @@ -231,13 +204,9 @@ Rectangle { StyledText { width: parent.width text: { - const timeStr = notificationGroup?.latestNotification?.timeStr - || "" - if (timeStr.length > 0) - return (notificationGroup?.appName - || "") + " • " + timeStr - else - return notificationGroup?.appName || "" + const timeStr = (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.timeStr) || "" + const appName = (notificationGroup && notificationGroup.appName) || "" + return timeStr.length > 0 ? `${appName} • ${timeStr}` : appName } color: Theme.surfaceVariantText font.pixelSize: Theme.fontSizeSmall @@ -247,8 +216,7 @@ Rectangle { } StyledText { - text: notificationGroup?.latestNotification?.summary - || "" + text: (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.summary) || "" color: Theme.surfaceText font.pixelSize: Theme.fontSizeMedium font.weight: Font.Medium @@ -260,8 +228,7 @@ Rectangle { StyledText { id: descriptionText - property string fullText: notificationGroup?.latestNotification?.htmlBody - || "" + property string fullText: (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.htmlBody) || "" property bool hasMoreText: truncated text: fullText @@ -280,12 +247,10 @@ Rectangle { cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : (parent.hasMoreText || descriptionExpanded) ? Qt.PointingHandCursor : Qt.ArrowCursor onClicked: mouse => { - if (!parent.hoveredLink - && (parent.hasMoreText - || descriptionExpanded)) { - const messageId = notificationGroup?.latestNotification?.notification?.id + "_desc" - NotificationService.toggleMessageExpansion( - messageId) + if (!parent.hoveredLink && (parent.hasMoreText || descriptionExpanded)) { + const messageId = (notificationGroup && notificationGroup.latestNotification && notificationGroup.latestNotification.notification + && notificationGroup.latestNotification.notification.id) ? (notificationGroup.latestNotification.notification.id + "_desc") : "" + NotificationService.toggleMessageExpansion(messageId) } } @@ -350,9 +315,7 @@ Rectangle { StyledText { anchors.centerIn: parent - text: (notificationGroup?.count - || 0) > 99 ? "99+" : (notificationGroup?.count - || 0).toString() + text: (notificationGroup?.count || 0) > 99 ? "99+" : (notificationGroup?.count || 0).toString() color: Theme.primaryText font.pixelSize: 9 font.weight: Font.Bold @@ -371,8 +334,7 @@ Rectangle { delegate: Rectangle { required property var modelData required property int index - readonly property bool messageExpanded: NotificationService.expandedMessages[modelData?.notification?.id] - || false + readonly property bool messageExpanded: NotificationService.expandedMessages[modelData?.notification?.id] || false readonly property bool isSelected: root.selectedNotificationIndex === index width: parent.width @@ -388,17 +350,8 @@ Rectangle { return baseHeight } radius: Theme.cornerRadius - color: isSelected ? Qt.rgba(Theme.surfaceVariant.r, - Theme.surfaceVariant.g, - Theme.surfaceVariant.b, - 0.25) : "transparent" - border.color: isSelected ? Qt.rgba(Theme.primary.r, - Theme.primary.g, - Theme.primary.b, - 0.4) : Qt.rgba( - Theme.outline.r, - Theme.outline.g, - Theme.outline.b, 0.05) + color: isSelected ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.25) : "transparent" + border.color: isSelected ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.4) : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.05) border.width: isSelected ? 1 : 1 Behavior on color { @@ -427,8 +380,7 @@ Rectangle { Rectangle { id: messageIcon - readonly property bool hasNotificationImage: modelData?.image - && modelData.image !== "" + readonly property bool hasNotificationImage: modelData?.image && modelData.image !== "" width: 32 height: 32 @@ -436,11 +388,8 @@ Rectangle { anchors.left: parent.left anchors.top: parent.top anchors.topMargin: 32 - color: Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.1) - border.color: Qt.rgba(Theme.primary.r, - Theme.primary.g, - Theme.primary.b, 0.2) + color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) + border.color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.2) border.width: 1 IconImage { @@ -452,10 +401,7 @@ Rectangle { if (modelData?.appIcon) { const appIcon = modelData.appIcon - if (appIcon.startsWith("file://") - || appIcon.startsWith("http://") - || appIcon.startsWith( - "https://")) + if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://")) return appIcon return Quickshell.iconPath(appIcon, true) @@ -467,9 +413,7 @@ Rectangle { StyledText { anchors.centerIn: parent - visible: !parent.hasNotificationImage - && (!modelData?.appIcon - || modelData.appIcon === "") + visible: !parent.hasNotificationImage && (!modelData?.appIcon || modelData.appIcon === "") text: { const appName = modelData?.appName || "?" return appName.charAt(0).toUpperCase() @@ -531,19 +475,14 @@ Rectangle { wrapMode: Text.WordWrap visible: text.length > 0 linkColor: Theme.primary - onLinkActivated: link => Qt.openUrlExternally( - link) + onLinkActivated: link => Qt.openUrlExternally(link) MouseArea { anchors.fill: parent cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : (bodyText.hasMoreText || messageExpanded) ? Qt.PointingHandCursor : Qt.ArrowCursor onClicked: mouse => { - if (!parent.hoveredLink - && (bodyText.hasMoreText - || messageExpanded)) { - NotificationService.toggleMessageExpansion( - modelData?.notification?.id - || "") + if (!parent.hoveredLink && (bodyText.hasMoreText || messageExpanded)) { + NotificationService.toggleMessageExpansion(modelData?.notification?.id || "") } } @@ -580,26 +519,16 @@ Rectangle { Rectangle { property bool isHovered: false - width: Math.max( - actionText.implicitWidth + 12, - 50) + width: Math.max(actionText.implicitWidth + 12, 50) height: 24 radius: 4 - color: isHovered ? Qt.rgba( - Theme.primary.r, - Theme.primary.g, - Theme.primary.b, - 0.1) : "transparent" + color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) : "transparent" StyledText { id: actionText text: { - const baseText = modelData.text - || "View" - if (keyboardNavigationActive - && (isGroupSelected - || selectedNotificationIndex - >= 0)) { + const baseText = modelData.text || "View" + if (keyboardNavigationActive && (isGroupSelected || selectedNotificationIndex >= 0)) { return `${baseText} (${index + 1})` } return baseText @@ -618,8 +547,7 @@ Rectangle { onEntered: parent.isHovered = true onExited: parent.isHovered = false onClicked: { - if (modelData - && modelData.invoke) { + if (modelData && modelData.invoke) { modelData.invoke() } } @@ -630,16 +558,10 @@ Rectangle { Rectangle { property bool isHovered: false - width: Math.max( - clearText.implicitWidth + 12, - 50) + width: Math.max(clearText.implicitWidth + 12, 50) height: 24 radius: 4 - color: isHovered ? Qt.rgba( - Theme.primary.r, - Theme.primary.g, - Theme.primary.b, - 0.1) : "transparent" + color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) : "transparent" StyledText { id: clearText @@ -656,8 +578,7 @@ Rectangle { cursorShape: Qt.PointingHandCursor onEntered: parent.isHovered = true onExited: parent.isHovered = false - onClicked: NotificationService.dismissNotification( - modelData) + onClicked: NotificationService.dismissNotification(modelData) } } } @@ -686,8 +607,7 @@ Rectangle { width: Math.max(actionText.implicitWidth + 12, 50) height: 24 radius: 4 - color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.1) : "transparent" + color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) : "transparent" StyledText { id: actionText @@ -734,8 +654,7 @@ Rectangle { width: clearText.width + 16 height: clearText.height + 8 radius: 6 - color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.1) : "transparent" + color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) : "transparent" StyledText { id: clearText @@ -752,19 +671,16 @@ Rectangle { cursorShape: Qt.PointingHandCursor onEntered: clearButton.isHovered = true onExited: clearButton.isHovered = false - onClicked: NotificationService.dismissGroup( - notificationGroup?.key || "") + onClicked: NotificationService.dismissGroup(notificationGroup?.key || "") } } MouseArea { anchors.fill: parent - visible: !expanded && (notificationGroup?.count || 0) > 1 - && !descriptionExpanded + visible: !expanded && (notificationGroup?.count || 0) > 1 && !descriptionExpanded onClicked: { root.userInitiatedExpansion = true - NotificationService.toggleGroupExpansion( - notificationGroup?.key || "") + NotificationService.toggleGroupExpansion(notificationGroup?.key || "") } z: -1 } @@ -787,8 +703,7 @@ Rectangle { buttonSize: 28 onClicked: { root.userInitiatedExpansion = true - NotificationService.toggleGroupExpansion( - notificationGroup?.key || "") + NotificationService.toggleGroupExpansion(notificationGroup?.key || "") } } @@ -798,8 +713,7 @@ Rectangle { iconName: "close" iconSize: 18 buttonSize: 28 - onClicked: NotificationService.dismissGroup( - notificationGroup?.key || "") + onClicked: NotificationService.dismissGroup(notificationGroup?.key || "") } } diff --git a/Modules/Notifications/Center/NotificationCenterPopout.qml b/Modules/Notifications/Center/NotificationCenterPopout.qml index f55cb74d..86f5907a 100644 --- a/Modules/Notifications/Center/NotificationCenterPopout.qml +++ b/Modules/Notifications/Center/NotificationCenterPopout.qml @@ -20,9 +20,9 @@ DankPopout { id: keyboardController listView: null isOpen: notificationHistoryVisible - onClose: function () { - notificationHistoryVisible = false - } + onClose: () => { + notificationHistoryVisible = false + } } function setTriggerPosition(x, y, width, section, screen) { @@ -55,32 +55,27 @@ DankPopout { onShouldBeVisibleChanged: { if (shouldBeVisible) { NotificationService.onOverlayOpen() - // Set up keyboard controller when content is loaded - Qt.callLater(function () { - if (contentLoader.item) { - contentLoader.item.externalKeyboardController = keyboardController + Qt.callLater(() => { + if (contentLoader.item) { + contentLoader.item.externalKeyboardController = keyboardController - // Find the notification list and set up the connection - var notificationList = findChild(contentLoader.item, - "notificationList") - var notificationHeader = findChild(contentLoader.item, - "notificationHeader") + const notificationList = findChild(contentLoader.item, "notificationList") + const notificationHeader = findChild(contentLoader.item, "notificationHeader") - if (notificationList) { - keyboardController.listView = notificationList - notificationList.keyboardController = keyboardController - } - if (notificationHeader) { - notificationHeader.keyboardController = keyboardController - } + if (notificationList) { + keyboardController.listView = notificationList + notificationList.keyboardController = keyboardController + } + if (notificationHeader) { + notificationHeader.keyboardController = keyboardController + } - keyboardController.reset() - keyboardController.rebuildFlatNavigation() - } - }) + keyboardController.reset() + keyboardController.rebuildFlatNavigation() + } + }) } else { NotificationService.onOverlayClose() - // Reset keyboard state when closing keyboardController.keyboardNavigationActive = false } } @@ -89,9 +84,9 @@ DankPopout { if (parent.objectName === objectName) { return parent } - for (var i = 0; i < parent.children.length; i++) { - var child = parent.children[i] - var result = findChild(child, objectName) + for (let i = 0; i < parent.children.length; i++) { + const child = parent.children[i] + const result = findChild(child, objectName) if (result) { return result } @@ -112,44 +107,44 @@ DankPopout { baseHeight += (notificationSettings.expanded ? notificationSettings.contentHeight : 0) baseHeight += Theme.spacingM * 2 let listHeight = notificationList.listContentHeight - if (NotificationService.groupedNotifications.length === 0) + if (NotificationService.groupedNotifications.length === 0) { listHeight = 200 + } baseHeight += Math.min(listHeight, 600) - return Math.max( - 300, Math.min( - baseHeight, - root.screen ? root.screen.height * 0.8 : Screen.height * 0.8)) + const maxHeight = root.screen ? root.screen.height * 0.8 : Screen.height * 0.8 + return Math.max(300, Math.min(baseHeight, maxHeight)) } color: Theme.popupBackground() radius: Theme.cornerRadius - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.08) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) border.width: 1 focus: true Component.onCompleted: { - if (root.shouldBeVisible) + if (root.shouldBeVisible) { forceActiveFocus() - } - - Keys.onPressed: function (event) { - if (event.key === Qt.Key_Escape) { - root.close() - event.accepted = true - } else if (externalKeyboardController) { - externalKeyboardController.handleKey(event) } } + Keys.onPressed: event => { + if (event.key === Qt.Key_Escape) { + root.close() + event.accepted = true + } else if (externalKeyboardController) { + externalKeyboardController.handleKey(event) + } + } + Connections { function onShouldBeVisibleChanged() { - if (root.shouldBeVisible) - Qt.callLater(function () { - notificationContent.forceActiveFocus() - }) - else + if (root.shouldBeVisible) { + Qt.callLater(() => { + notificationContent.forceActiveFocus() + }) + } else { notificationContent.focus = false + } } target: root } @@ -182,8 +177,7 @@ DankPopout { objectName: "notificationList" width: parent.width - height: parent.height - notificationContent.cachedHeaderHeight - - notificationSettings.height - contentColumnInner.spacing * 2 + height: parent.height - notificationContent.cachedHeaderHeight - notificationSettings.height - contentColumnInner.spacing * 2 } } } @@ -194,7 +188,7 @@ DankPopout { anchors.left: parent.left anchors.right: parent.right anchors.margins: Theme.spacingL - showHints: externalKeyboardController ? externalKeyboardController.showKeyboardHints : false + showHints: (externalKeyboardController && externalKeyboardController.showKeyboardHints) || false z: 200 } diff --git a/Modules/Notifications/Center/NotificationEmptyState.qml b/Modules/Notifications/Center/NotificationEmptyState.qml index 47ce6f58..569bfa25 100644 --- a/Modules/Notifications/Center/NotificationEmptyState.qml +++ b/Modules/Notifications/Center/NotificationEmptyState.qml @@ -19,16 +19,14 @@ Item { anchors.horizontalCenter: parent.horizontalCenter name: "notifications_none" size: Theme.iconSizeLarge + 16 - color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, - Theme.surfaceText.b, 0.3) + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.3) } StyledText { anchors.horizontalCenter: parent.horizontalCenter text: "Nothing to see here" font.pixelSize: Theme.fontSizeLarge - color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, - Theme.surfaceText.b, 0.3) + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.3) font.weight: Font.Medium horizontalAlignment: Text.AlignHCenter } diff --git a/Modules/Notifications/Center/NotificationHeader.qml b/Modules/Notifications/Center/NotificationHeader.qml index 1b582009..b93051a8 100644 --- a/Modules/Notifications/Center/NotificationHeader.qml +++ b/Modules/Notifications/Center/NotificationHeader.qml @@ -47,7 +47,7 @@ Item { anchors.bottom: parent.top anchors.bottomMargin: Theme.spacingS anchors.horizontalCenter: parent.horizontalCenter - visible: doNotDisturbButton.children[1].containsMouse // Access StateLayer's containsMouse + visible: doNotDisturbButton.children[1].containsMouse opacity: visible ? 1 : 0 StyledText { @@ -76,12 +76,10 @@ Item { anchors.verticalCenter: parent.verticalCenter spacing: Theme.spacingXS - // Keyboard help button DankActionButton { id: helpButton iconName: "info" - iconColor: keyboardController - && keyboardController.showKeyboardHints ? Theme.primary : Theme.surfaceText + iconColor: (keyboardController && keyboardController.showKeyboardHints) ? Theme.primary : Theme.surfaceText buttonSize: 28 visible: keyboardController !== null anchors.verticalCenter: parent.verticalCenter @@ -92,7 +90,6 @@ Item { } } - // Settings button DankActionButton { id: settingsButton iconName: "settings" @@ -109,17 +106,8 @@ Item { height: 28 radius: Theme.cornerRadius visible: NotificationService.notifications.length > 0 - color: clearArea.containsMouse ? Qt.rgba(Theme.primary.r, - Theme.primary.g, - Theme.primary.b, - 0.12) : Qt.rgba( - Theme.surfaceVariant.r, - Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.3) - border.color: clearArea.containsMouse ? Theme.primary : Qt.rgba( - Theme.outline.r, - Theme.outline.g, - Theme.outline.b, 0.08) + color: clearArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3) + border.color: clearArea.containsMouse ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) border.width: 1 Row { diff --git a/Modules/Notifications/Center/NotificationKeyboardController.qml b/Modules/Notifications/Center/NotificationKeyboardController.qml index 1ffb17ed..6b04924a 100644 --- a/Modules/Notifications/Center/NotificationKeyboardController.qml +++ b/Modules/Notifications/Center/NotificationKeyboardController.qml @@ -25,15 +25,13 @@ QtObject { function rebuildFlatNavigation() { isRebuilding = true - var nav = [] - var groups = NotificationService.groupedNotifications + const nav = [] + const groups = NotificationService.groupedNotifications - for (var i = 0; i < groups.length; i++) { - var group = groups[i] - var isExpanded = NotificationService.expandedGroups[group.key] - || false + for (let i = 0; i < groups.length; i++) { + const group = groups[i] + const isExpanded = NotificationService.expandedGroups[group.key] || false - // Add the group itself nav.push({ "type": "group", "groupIndex": i, @@ -42,12 +40,10 @@ QtObject { "notificationId": "" }) - // If expanded, add individual notifications if (isExpanded) { - var notifications = group.notifications || [] - for (var j = 0; j < notifications.length; j++) { - var notifId = String( - notifications[j]?.notification?.id || "") + const notifications = group.notifications || [] + for (let j = 0; j < notifications.length; j++) { + const notifId = String(notifications[j] && notifications[j].notification && notifications[j].notification.id ? notifications[j].notification.id : "") nav.push({ "type": "notification", "groupIndex": i, @@ -65,22 +61,18 @@ QtObject { } function updateSelectedIndexFromId() { - if (!keyboardNavigationActive) + if (!keyboardNavigationActive) { return + } - // Find the index that matches our selected ID/key - for (var i = 0; i < flatNavigation.length; i++) { - var item = flatNavigation[i] + for (let i = 0; i < flatNavigation.length; i++) { + const item = flatNavigation[i] - if (selectedItemType === "group" && item.type === "group" - && item.groupKey === selectedGroupKey) { + if (selectedItemType === "group" && item.type === "group" && item.groupKey === selectedGroupKey) { selectedFlatIndex = i selectionVersion++ // Trigger UI update return - } else if (selectedItemType === "notification" - && item.type === "notification" && String( - item.notificationId) === String( - selectedNotificationId)) { + } else if (selectedItemType === "notification" && item.type === "notification" && String(item.notificationId) === String(selectedNotificationId)) { selectedFlatIndex = i selectionVersion++ // Trigger UI update return @@ -89,10 +81,9 @@ QtObject { // If not found, try to find the same group but select the group header instead if (selectedItemType === "notification") { - for (var j = 0; j < flatNavigation.length; j++) { - var groupItem = flatNavigation[j] - if (groupItem.type === "group" - && groupItem.groupKey === selectedGroupKey) { + for (let j = 0; j < flatNavigation.length; j++) { + const groupItem = flatNavigation[j] + if (groupItem.type === "group" && groupItem.groupKey === selectedGroupKey) { selectedFlatIndex = j selectedItemType = "group" selectedNotificationId = "" @@ -104,8 +95,7 @@ QtObject { // If still not found, clamp to valid range and update if (flatNavigation.length > 0) { - selectedFlatIndex = Math.min(selectedFlatIndex, - flatNavigation.length - 1) + selectedFlatIndex = Math.min(selectedFlatIndex, flatNavigation.length - 1) selectedFlatIndex = Math.max(selectedFlatIndex, 0) updateSelectedIdFromIndex() selectionVersion++ // Trigger UI update @@ -113,9 +103,8 @@ QtObject { } function updateSelectedIdFromIndex() { - if (selectedFlatIndex >= 0 - && selectedFlatIndex < flatNavigation.length) { - var item = flatNavigation[selectedFlatIndex] + if (selectedFlatIndex >= 0 && selectedFlatIndex < flatNavigation.length) { + const item = flatNavigation[selectedFlatIndex] selectedItemType = item.type selectedGroupKey = item.groupKey selectedNotificationId = item.notificationId @@ -143,8 +132,7 @@ QtObject { listView.enableAutoScroll() } - selectedFlatIndex = Math.min(selectedFlatIndex + 1, - flatNavigation.length - 1) + selectedFlatIndex = Math.min(selectedFlatIndex + 1, flatNavigation.length - 1) updateSelectedIdFromIndex() selectionVersion++ ensureVisible() @@ -167,8 +155,7 @@ QtObject { } function toggleGroupExpanded() { - if (flatNavigation.length === 0 - || selectedFlatIndex >= flatNavigation.length) + if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length) return const currentItem = flatNavigation[selectedFlatIndex] @@ -182,8 +169,7 @@ QtObject { if (notificationCount < 2) return - const wasExpanded = NotificationService.expandedGroups[group.key] - || false + const wasExpanded = NotificationService.expandedGroups[group.key] || false const groupIndex = currentItem.groupIndex isTogglingGroup = true @@ -193,18 +179,16 @@ QtObject { // Smart selection after toggle if (!wasExpanded) { // Just expanded - move to first notification in the group - for (var i = 0; i < flatNavigation.length; i++) { - if (flatNavigation[i].type === "notification" - && flatNavigation[i].groupIndex === groupIndex) { + for (let i = 0; i < flatNavigation.length; i++) { + if (flatNavigation[i].type === "notification" && flatNavigation[i].groupIndex === groupIndex) { selectedFlatIndex = i break } } } else { // Just collapsed - stay on the group header - for (var i = 0; i < flatNavigation.length; i++) { - if (flatNavigation[i].type === "group" - && flatNavigation[i].groupIndex === groupIndex) { + for (let i = 0; i < flatNavigation.length; i++) { + if (flatNavigation[i].type === "group" && flatNavigation[i].groupIndex === groupIndex) { selectedFlatIndex = i break } @@ -216,8 +200,7 @@ QtObject { } function handleEnterKey() { - if (flatNavigation.length === 0 - || selectedFlatIndex >= flatNavigation.length) + if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length) return const currentItem = flatNavigation[selectedFlatIndex] @@ -239,8 +222,7 @@ QtObject { } function toggleTextExpanded() { - if (flatNavigation.length === 0 - || selectedFlatIndex >= flatNavigation.length) + if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length) return const currentItem = flatNavigation[selectedFlatIndex] @@ -249,15 +231,12 @@ QtObject { if (!group) return - var messageId = "" + let messageId = "" if (currentItem.type === "group") { messageId = group.latestNotification?.notification?.id + "_desc" - } else if (currentItem.type === "notification" - && currentItem.notificationIndex >= 0 - && currentItem.notificationIndex < group.notifications.length) { - messageId = group.notifications[currentItem.notificationIndex]?.notification?.id - + "_desc" + } else if (currentItem.type === "notification" && currentItem.notificationIndex >= 0 && currentItem.notificationIndex < group.notifications.length) { + messageId = group.notifications[currentItem.notificationIndex]?.notification?.id + "_desc" } if (messageId) { @@ -266,8 +245,7 @@ QtObject { } function executeAction(actionIndex) { - if (flatNavigation.length === 0 - || selectedFlatIndex >= flatNavigation.length) + if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length) return const currentItem = flatNavigation[selectedFlatIndex] @@ -276,15 +254,12 @@ QtObject { if (!group) return - var actions = [] + let actions = [] if (currentItem.type === "group") { actions = group.latestNotification?.actions || [] - } else if (currentItem.type === "notification" - && currentItem.notificationIndex >= 0 - && currentItem.notificationIndex < group.notifications.length) { - actions = group.notifications[currentItem.notificationIndex]?.actions - || [] + } else if (currentItem.type === "notification" && currentItem.notificationIndex >= 0 && currentItem.notificationIndex < group.notifications.length) { + actions = group.notifications[currentItem.notificationIndex]?.actions || [] } if (actionIndex >= 0 && actionIndex < actions.length) { @@ -298,8 +273,7 @@ QtObject { } function clearSelected() { - if (flatNavigation.length === 0 - || selectedFlatIndex >= flatNavigation.length) + if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length) return const currentItem = flatNavigation[selectedFlatIndex] @@ -330,24 +304,20 @@ QtObject { } function ensureVisible() { - if (flatNavigation.length === 0 - || selectedFlatIndex >= flatNavigation.length || !listView) + if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length || !listView) return const currentItem = flatNavigation[selectedFlatIndex] - if (keyboardNavigationActive && currentItem - && currentItem.groupIndex >= 0) { + if (keyboardNavigationActive && currentItem && currentItem.groupIndex >= 0) { // Always center the selected item for better visibility // This ensures the selected item stays in view even when new notifications arrive if (currentItem.type === "notification") { // For individual notifications, center on the group but bias towards the notification - listView.positionViewAtIndex(currentItem.groupIndex, - ListView.Center) + listView.positionViewAtIndex(currentItem.groupIndex, ListView.Center) } else { // For group headers, center on the group - listView.positionViewAtIndex(currentItem.groupIndex, - ListView.Center) + listView.positionViewAtIndex(currentItem.groupIndex, ListView.Center) } // Force immediate update @@ -356,8 +326,7 @@ QtObject { } function handleKey(event) { - if ((event.key === Qt.Key_Delete || event.key === Qt.Key_Backspace) - && (event.modifiers & Qt.ShiftModifier)) { + if ((event.key === Qt.Key_Delete || event.key === Qt.Key_Backspace) && (event.modifiers & Qt.ShiftModifier)) { NotificationService.clearAllNotifications() rebuildFlatNavigation() if (flatNavigation.length === 0) { @@ -430,15 +399,13 @@ QtObject { if (event.key === Qt.Key_Space) { toggleGroupExpanded() event.accepted = true - } else if (event.key === Qt.Key_Return - || event.key === Qt.Key_Enter) { + } else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { handleEnterKey() event.accepted = true } else if (event.key === Qt.Key_E) { toggleTextExpanded() event.accepted = true - } else if (event.key === Qt.Key_Delete - || event.key === Qt.Key_Backspace) { + } else if (event.key === Qt.Key_Delete || event.key === Qt.Key_Backspace) { clearSelected() event.accepted = true } else if (event.key >= Qt.Key_1 && event.key <= Qt.Key_9) { @@ -456,8 +423,7 @@ QtObject { // Get current selection info for UI function getCurrentSelection() { - if (!keyboardNavigationActive || selectedFlatIndex < 0 - || selectedFlatIndex >= flatNavigation.length) { + if (!keyboardNavigationActive || selectedFlatIndex < 0 || selectedFlatIndex >= flatNavigation.length) { return { "type": "", "groupIndex": -1, diff --git a/Modules/Notifications/Center/NotificationKeyboardHints.qml b/Modules/Notifications/Center/NotificationKeyboardHints.qml index e99f0515..8c9c7ff3 100644 --- a/Modules/Notifications/Center/NotificationKeyboardHints.qml +++ b/Modules/Notifications/Center/NotificationKeyboardHints.qml @@ -9,8 +9,7 @@ Rectangle { height: 80 radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, - Theme.surfaceContainer.b, 0.95) + color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95) border.color: Theme.primary border.width: 2 opacity: showHints ? 1 : 0 diff --git a/Modules/Notifications/Center/NotificationSettings.qml b/Modules/Notifications/Center/NotificationSettings.qml index 5d06df94..414b9e2c 100644 --- a/Modules/Notifications/Center/NotificationSettings.qml +++ b/Modules/Notifications/Center/NotificationSettings.qml @@ -15,10 +15,8 @@ Rectangle { visible: expanded clip: true radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, - Theme.surfaceContainer.b, 0.3) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.1) + color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.3) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1) border.width: 1 Behavior on height { @@ -29,7 +27,6 @@ Rectangle { } } - // Ensure smooth opacity transition opacity: expanded ? 1 : 0 Behavior on opacity { NumberAnimation { @@ -82,17 +79,20 @@ Rectangle { return "5 seconds" } - for (var i = 0; i < timeoutOptions.length; i++) { + for (let i = 0; i < timeoutOptions.length; i++) { if (timeoutOptions[i].value === value) { return timeoutOptions[i].text } } - if (value === 0) + if (value === 0) { return "Never" - if (value < 1000) + } + if (value < 1000) { return value + "ms" - if (value < 60000) + } + if (value < 60000) { return Math.round(value / 1000) + " seconds" + } return Math.round(value / 60000) + " minutes" } @@ -139,16 +139,14 @@ Rectangle { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter checked: SessionData.doNotDisturb - onToggled: SessionData.setDoNotDisturb( - !SessionData.doNotDisturb) + onToggled: SessionData.setDoNotDisturb(!SessionData.doNotDisturb) } } Rectangle { width: parent.width height: 1 - color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.1) + color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1) } StyledText { @@ -165,10 +163,9 @@ Rectangle { currentValue: getTimeoutText(SettingsData.notificationTimeoutLow) options: timeoutOptions.map(opt => opt.text) onValueChanged: value => { - for (var i = 0; i < timeoutOptions.length; i++) { + for (let i = 0; i < timeoutOptions.length; i++) { if (timeoutOptions[i].text === value) { - SettingsData.setNotificationTimeoutLow( - timeoutOptions[i].value) + SettingsData.setNotificationTimeoutLow(timeoutOptions[i].value) break } } @@ -182,10 +179,9 @@ Rectangle { currentValue: getTimeoutText(SettingsData.notificationTimeoutNormal) options: timeoutOptions.map(opt => opt.text) onValueChanged: value => { - for (var i = 0; i < timeoutOptions.length; i++) { + for (let i = 0; i < timeoutOptions.length; i++) { if (timeoutOptions[i].text === value) { - SettingsData.setNotificationTimeoutNormal( - timeoutOptions[i].value) + SettingsData.setNotificationTimeoutNormal(timeoutOptions[i].value) break } } @@ -196,14 +192,12 @@ Rectangle { width: parent.width text: "Critical Priority" description: "Timeout for critical priority notifications" - currentValue: getTimeoutText( - SettingsData.notificationTimeoutCritical) + currentValue: getTimeoutText(SettingsData.notificationTimeoutCritical) options: timeoutOptions.map(opt => opt.text) onValueChanged: value => { - for (var i = 0; i < timeoutOptions.length; i++) { + for (let i = 0; i < timeoutOptions.length; i++) { if (timeoutOptions[i].text === value) { - SettingsData.setNotificationTimeoutCritical( - timeoutOptions[i].value) + SettingsData.setNotificationTimeoutCritical(timeoutOptions[i].value) break } } @@ -213,8 +207,7 @@ Rectangle { Rectangle { width: parent.width height: 1 - color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.1) + color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1) } Item { @@ -255,8 +248,7 @@ Rectangle { anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter checked: SettingsData.notificationOverlayEnabled - onToggled: toggled => SettingsData.setNotificationOverlayEnabled( - toggled) + onToggled: toggled => SettingsData.setNotificationOverlayEnabled(toggled) } } } diff --git a/Modules/Notifications/Popup/NotificationPopup.qml b/Modules/Notifications/Popup/NotificationPopup.qml index 45125ddf..79a2aeb3 100644 --- a/Modules/Notifications/Popup/NotificationPopup.qml +++ b/Modules/Notifications/Popup/NotificationPopup.qml @@ -13,8 +13,7 @@ PanelWindow { required property var notificationData required property string notificationId - readonly property bool hasValidData: notificationData - && notificationData.notification + readonly property bool hasValidData: notificationData && notificationData.notification property int screenY: 0 property bool exiting: false property bool _isDestroying: false @@ -24,20 +23,20 @@ PanelWindow { signal exitFinished function startExit() { - if (exiting || _isDestroying) + if (exiting || _isDestroying) { return - + } exiting = true exitAnim.restart() exitWatchdog.restart() if (NotificationService.removeFromVisibleNotifications) - NotificationService.removeFromVisibleNotifications( - win.notificationData) + NotificationService.removeFromVisibleNotifications(win.notificationData) } function forceExit() { - if (_isDestroying) + if (_isDestroying) { return + } _isDestroying = true exiting = true visible = false @@ -46,8 +45,9 @@ PanelWindow { } function finalizeExit(reason) { - if (_finalized) + if (_finalized) { return + } _finalized = true _isDestroying = true @@ -64,8 +64,7 @@ PanelWindow { SettingsData.notificationOverlayEnabled - const shouldUseOverlay = (SettingsData.notificationOverlayEnabled) - || (notificationData.urgency === NotificationUrgency.Critical) + const shouldUseOverlay = (SettingsData.notificationOverlayEnabled) || (notificationData.urgency === NotificationUrgency.Critical) return shouldUseOverlay ? WlrLayershell.Overlay : WlrLayershell.Top } @@ -77,38 +76,33 @@ PanelWindow { onScreenYChanged: margins.top = Theme.barHeight - 4 + SettingsData.topBarSpacing + 4 + screenY onHasValidDataChanged: { if (!hasValidData && !exiting && !_isDestroying) { - forceExit() } } Component.onCompleted: { if (hasValidData) { - Qt.callLater(() => { - return enterX.restart() - }) + Qt.callLater(() => enterX.restart()) } else { - forceExit() } } onNotificationDataChanged: { if (!_isDestroying) { wrapperConn.target = win.notificationData || null - notificationConn.target = (win.notificationData - && win.notificationData.notification - && win.notificationData.notification.Retainable) - || null + notificationConn.target = (win.notificationData && win.notificationData.notification && win.notificationData.notification.Retainable) || null } } onEntered: { - if (!_isDestroying) + if (!_isDestroying) { enterDelay.start() + } } Component.onDestruction: { _isDestroying = true exitWatchdog.stop() - if (notificationData && notificationData.timer) + if (notificationData && notificationData.timer) { notificationData.timer.stop() + } } anchors { @@ -136,18 +130,8 @@ PanelWindow { anchors.margins: 4 radius: Theme.cornerRadius color: Theme.popupBackground() - border.color: notificationData && notificationData.urgency - === NotificationUrgency.Critical ? Qt.rgba( - Theme.primary.r, - Theme.primary.g, - Theme.primary.b, - 0.3) : Qt.rgba( - Theme.outline.r, - Theme.outline.g, - Theme.outline.b, - 0.08) - border.width: notificationData - && notificationData.urgency === NotificationUrgency.Critical ? 2 : 1 + border.color: notificationData && notificationData.urgency === NotificationUrgency.Critical ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3) : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) + border.width: notificationData && notificationData.urgency === NotificationUrgency.Critical ? 2 : 1 clip: true Rectangle { @@ -179,8 +163,7 @@ PanelWindow { anchors.fill: parent color: "transparent" - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.12) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) border.width: 1 radius: parent.radius z: -1 @@ -189,8 +172,7 @@ PanelWindow { Rectangle { anchors.fill: parent radius: parent.radius - visible: notificationData - && notificationData.urgency === NotificationUrgency.Critical + visible: notificationData && notificationData.urgency === NotificationUrgency.Critical opacity: 1 gradient: Gradient { @@ -227,15 +209,12 @@ PanelWindow { Rectangle { id: iconContainer - readonly property bool hasNotificationImage: notificationData - && notificationData.image - && notificationData.image !== "" + readonly property bool hasNotificationImage: notificationData && notificationData.image && notificationData.image !== "" width: 55 height: 55 radius: 27.5 - color: Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.1) + color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) border.color: "transparent" border.width: 0 anchors.left: parent.left @@ -256,9 +235,7 @@ PanelWindow { if (notificationData.appIcon) { const appIcon = notificationData.appIcon - if (appIcon.startsWith("file://") - || appIcon.startsWith("http://") - || appIcon.startsWith("https://")) + if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://")) return appIcon return Quickshell.iconPath(appIcon, true) @@ -270,13 +247,9 @@ PanelWindow { StyledText { anchors.centerIn: parent - visible: !parent.hasNotificationImage - && (!notificationData - || !notificationData.appIcon - || notificationData.appIcon === "") + visible: !parent.hasNotificationImage && (!notificationData || !notificationData.appIcon || notificationData.appIcon === "") text: { - const appName = notificationData - && notificationData.appName ? notificationData.appName : "?" + const appName = notificationData && notificationData.appName ? notificationData.appName : "?" return appName.charAt(0).toUpperCase() } font.pixelSize: 20 @@ -313,10 +286,8 @@ PanelWindow { if (!notificationData) return "" - const appName = notificationData.appName - || "" - const timeStr = notificationData.timeStr - || "" + const appName = notificationData.appName || "" + const timeStr = notificationData.timeStr || "" if (timeStr.length > 0) return appName + " • " + timeStr else @@ -330,8 +301,7 @@ PanelWindow { } StyledText { - text: notificationData ? (notificationData.summary - || "") : "" + text: notificationData ? (notificationData.summary || "") : "" color: Theme.surfaceText font.pixelSize: Theme.fontSizeMedium font.weight: Font.Medium @@ -342,8 +312,7 @@ PanelWindow { } StyledText { - text: notificationData ? (notificationData.htmlBody - || "") : "" + text: notificationData ? (notificationData.htmlBody || "") : "" color: Theme.surfaceVariantText font.pixelSize: Theme.fontSizeSmall width: parent.width @@ -353,8 +322,7 @@ PanelWindow { visible: text.length > 0 linkColor: Theme.primary onLinkActivated: link => { - return Qt.openUrlExternally( - link) + return Qt.openUrlExternally(link) } MouseArea { @@ -394,8 +362,7 @@ PanelWindow { z: 20 Repeater { - model: notificationData ? (notificationData.actions - || []) : [] + model: notificationData ? (notificationData.actions || []) : [] Rectangle { property bool isHovered: false @@ -403,10 +370,7 @@ PanelWindow { width: Math.max(actionText.implicitWidth + 12, 50) height: 24 radius: 4 - color: isHovered ? Qt.rgba(Theme.primary.r, - Theme.primary.g, - Theme.primary.b, - 0.1) : "transparent" + color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) : "transparent" StyledText { id: actionText @@ -450,8 +414,7 @@ PanelWindow { width: Math.max(clearText.implicitWidth + 12, 50) height: 24 radius: 4 - color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.1) : "transparent" + color: isHovered ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1) : "transparent" z: 20 StyledText { @@ -473,8 +436,7 @@ PanelWindow { onExited: clearButton.isHovered = false onClicked: { if (notificationData && !win.exiting) - NotificationService.dismissNotification( - notificationData) + NotificationService.dismissNotification(notificationData) } } } @@ -492,8 +454,7 @@ PanelWindow { notificationData.timer.stop() } onExited: { - if (notificationData && notificationData.popup - && notificationData.timer) + if (notificationData && notificationData.popup && notificationData.timer) notificationData.timer.restart() } onClicked: { @@ -587,8 +548,7 @@ PanelWindow { forceExit() } - target: (win.notificationData && win.notificationData.notification - && win.notificationData.notification.Retainable) || null + target: (win.notificationData && win.notificationData.notification && win.notificationData.notification.Retainable) || null ignoreUnknownSignals: true enabled: !win._isDestroying } @@ -599,8 +559,7 @@ PanelWindow { interval: 160 repeat: false onTriggered: { - if (notificationData && notificationData.timer && !exiting - && !_isDestroying) + if (notificationData && notificationData.timer && !exiting && !_isDestroying) notificationData.timer.start() } } diff --git a/Modules/Notifications/Popup/NotificationPopupManager.qml b/Modules/Notifications/Popup/NotificationPopupManager.qml index b12fb406..aad4f7c1 100644 --- a/Modules/Notifications/Popup/NotificationPopupManager.qml +++ b/Modules/Notifications/Popup/NotificationPopupManager.qml @@ -38,125 +38,120 @@ QtObject { running: false repeat: true onTriggered: { - let toRemove = [] - for (let p of popupWindows) { - if (!p) { toRemove.push(p); continue } - const isZombie = - p.status === Component.Null || - (!p.visible && !p.exiting) || - (!p.notificationData && !p._isDestroying) || - (!p.hasValidData && !p._isDestroying) + const toRemove = [] + for (const p of popupWindows) { + if (!p) { + toRemove.push(p) + continue + } + const isZombie = p.status === Component.Null || (!p.visible && !p.exiting) || (!p.notificationData && !p._isDestroying) || (!p.hasValidData && !p._isDestroying) if (isZombie) { toRemove.push(p) - if (p.forceExit) p.forceExit() - else if (p.destroy) { try { p.destroy() } catch(e) {} } + if (p.forceExit) { + p.forceExit() + } else if (p.destroy) { + try { + p.destroy() + } catch (e) { + + } + } } } if (toRemove.length) { popupWindows = popupWindows.filter(p => toRemove.indexOf(p) === -1) - const survivors = _active().sort((a,b)=>a.screenY-b.screenY) - for (var k=0; k a.screenY - b.screenY) + for (let k = 0; k < survivors.length; ++k) { survivors[k].screenY = topMargin + k * baseNotificationHeight + } + } + if (popupWindows.length === 0) { + sweeper.stop() } - if (popupWindows.length === 0) sweeper.stop() } } function _hasWindowFor(w) { - return popupWindows.some(p => { - return p && p.notificationData === w - && !p._isDestroying - && p.status !== Component.Null - }) + return popupWindows.some(p => p && p.notificationData === w && !p._isDestroying && p.status !== Component.Null) } function _isValidWindow(p) { - return p && p.status !== Component.Null && !p._isDestroying - && p.hasValidData + return p && p.status !== Component.Null && !p._isDestroying && p.hasValidData } function _canMakeRoomFor(wrapper) { const activeWindows = _active() - if (activeWindows.length < maxTargetNotifications) + if (activeWindows.length < maxTargetNotifications) { return true - - if (!wrapper || !wrapper.notification) + } + if (!wrapper || !wrapper.notification) { return false - + } const incomingUrgency = wrapper.notification.urgency || 0 - - for (let p of activeWindows) { - if (!p.notificationData || !p.notificationData.notification) + for (const p of activeWindows) { + if (!p.notificationData || !p.notificationData.notification) { continue - + } const existingUrgency = p.notificationData.notification.urgency || 0 - - if (existingUrgency < incomingUrgency) + if (existingUrgency < incomingUrgency) { return true - + } if (existingUrgency === incomingUrgency) { const timer = p.notificationData.timer - if (timer && !timer.running) + if (timer && !timer.running) { return true + } } } - return false } function _makeRoomForNew(wrapper) { const activeWindows = _active() - if (activeWindows.length < maxTargetNotifications) + if (activeWindows.length < maxTargetNotifications) { return - + } const toRemove = _selectPopupToRemove(activeWindows, wrapper) if (toRemove && !toRemove.exiting) { toRemove.notificationData.removedByLimit = true toRemove.notificationData.popup = false - if (toRemove.notificationData.timer) + if (toRemove.notificationData.timer) { toRemove.notificationData.timer.stop() + } } } function _selectPopupToRemove(activeWindows, incomingWrapper) { - const incomingUrgency = (incomingWrapper && incomingWrapper.notification) - ? incomingWrapper.notification.urgency || 0 : 0 - + const incomingUrgency = (incomingWrapper && incomingWrapper.notification) ? incomingWrapper.notification.urgency || 0 : 0 const sortedWindows = activeWindows.slice().sort((a, b) => { - const aUrgency = (a.notificationData && a.notificationData.notification) - ? a.notificationData.notification.urgency || 0 : 0 - const bUrgency = (b.notificationData && b.notificationData.notification) - ? b.notificationData.notification.urgency || 0 : 0 - - if (aUrgency !== bUrgency) - return aUrgency - bUrgency - - const aTimer = a.notificationData && a.notificationData.timer - const bTimer = b.notificationData && b.notificationData.timer - const aRunning = aTimer && aTimer.running - const bRunning = bTimer && bTimer.running - - if (aRunning !== bRunning) - return aRunning ? 1 : -1 - - return b.screenY - a.screenY - }) - + const aUrgency = (a.notificationData && a.notificationData.notification) ? a.notificationData.notification.urgency || 0 : 0 + const bUrgency = (b.notificationData && b.notificationData.notification) ? b.notificationData.notification.urgency || 0 : 0 + if (aUrgency !== bUrgency) { + return aUrgency - bUrgency + } + const aTimer = a.notificationData && a.notificationData.timer + const bTimer = b.notificationData && b.notificationData.timer + const aRunning = aTimer && aTimer.running + const bRunning = bTimer && bTimer.running + if (aRunning !== bRunning) { + return aRunning ? 1 : -1 + } + return b.screenY - a.screenY + }) return sortedWindows[0] } function _sync(newWrappers) { - for (let w of newWrappers) { - if (w && !_hasWindowFor(w)) + for (const w of newWrappers) { + if (w && !_hasWindowFor(w)) { insertNewestAtTop(w) + } } - - for (let p of popupWindows.slice()) { - if (!_isValidWindow(p)) + for (const p of popupWindows.slice()) { + if (!_isValidWindow(p)) { continue - - if (p.notificationData && newWrappers.indexOf( - p.notificationData) === -1 && !p.exiting) { + } + if (p.notificationData && newWrappers.indexOf(p.notificationData) === -1 && !p.exiting) { p.notificationData.removedByLimit = true p.notificationData.popup = false } @@ -165,21 +160,18 @@ QtObject { function insertNewestAtTop(wrapper) { if (!wrapper) { - return } - - for (let p of popupWindows) { - if (!_isValidWindow(p)) + for (const p of popupWindows) { + if (!_isValidWindow(p)) { continue - - if (p.exiting) + } + if (p.exiting) { continue - + } p.screenY = p.screenY + baseNotificationHeight } - const notificationId = wrapper - && wrapper.notification ? wrapper.notification.id : "" + const notificationId = wrapper && wrapper.notification ? wrapper.notification.id : "" const win = popupComponent.createObject(null, { "notificationData": wrapper, "notificationId": notificationId, @@ -187,30 +179,26 @@ QtObject { "screen": manager.modelData }) if (!win) { - return } if (!win.hasValidData) { - win.destroy() return } popupWindows.push(win) - if (!sweeper.running) + if (!sweeper.running) { sweeper.start() + } } function _active() { - return popupWindows.filter(p => { - return _isValidWindow(p) - && p.notificationData - && p.notificationData.popup && !p.exiting - }) + return popupWindows.filter(p => _isValidWindow(p) && p.notificationData && p.notificationData.popup && !p.exiting) } function _bottom() { - let b = null, maxY = -1 - for (let p of _active()) { + let b = null + let maxY = -1 + for (const p of _active()) { if (p.screenY > maxY) { maxY = p.screenY b = p @@ -219,26 +207,25 @@ QtObject { return b } - function _onPopupEntered(p) { - } + function _onPopupEntered(p) {} function _onPopupExitFinished(p) { - if (!p) + if (!p) { return - + } const windowId = p.toString() - if (destroyingWindows.has(windowId)) + if (destroyingWindows.has(windowId)) { return - + } destroyingWindows.add(windowId) const i = popupWindows.indexOf(p) if (i !== -1) { popupWindows.splice(i, 1) popupWindows = popupWindows.slice() } - if (NotificationService.releaseWrapper && p.notificationData) + if (NotificationService.releaseWrapper && p.notificationData) { NotificationService.releaseWrapper(p.notificationData) - + } Qt.callLater(() => { if (p && p.destroy) { try { @@ -247,27 +234,24 @@ QtObject { } } - Qt.callLater(() => { - destroyingWindows.delete(windowId) - }) + Qt.callLater(() => destroyingWindows.delete(windowId)) }) - const survivors = _active().sort((a, b) => { - return a.screenY - b.screenY - }) - for (var k = 0; k < survivors.length; ++k) { + const survivors = _active().sort((a, b) => a.screenY - b.screenY) + for (let k = 0; k < survivors.length; ++k) { survivors[k].screenY = topMargin + k * baseNotificationHeight } } function cleanupAllWindows() { sweeper.stop() - for (let p of popupWindows.slice()) { + for (const p of popupWindows.slice()) { if (p) { try { - if (p.forceExit) + if (p.forceExit) { p.forceExit() - else if (p.destroy) + } else if (p.destroy) { p.destroy() + } } catch (e) { } @@ -278,9 +262,10 @@ QtObject { } onPopupWindowsChanged: { - if (popupWindows.length > 0 && !sweeper.running) + if (popupWindows.length > 0 && !sweeper.running) { sweeper.start() - else if (popupWindows.length === 0 && sweeper.running) + } else if (popupWindows.length === 0 && sweeper.running) { sweeper.stop() + } } } diff --git a/Modules/OSD/BrightnessOSD.qml b/Modules/OSD/BrightnessOSD.qml index d272839a..8e32f0d3 100644 --- a/Modules/OSD/BrightnessOSD.qml +++ b/Modules/OSD/BrightnessOSD.qml @@ -24,7 +24,6 @@ DankOSD { } } - Connections { target: DisplayService function onBrightnessChanged() { @@ -54,12 +53,13 @@ DankOSD { anchors.centerIn: parent name: { const deviceInfo = DisplayService.getCurrentDeviceInfo() - if (!deviceInfo || deviceInfo.class === "backlight" || deviceInfo.class === "ddc") + if (!deviceInfo || deviceInfo.class === "backlight" || deviceInfo.class === "ddc") { return "brightness_medium" - else if (deviceInfo.name.includes("kbd")) + } else if (deviceInfo.name.includes("kbd")) { return "keyboard" - else + } else { return "lightbulb" + } } size: Theme.iconSize color: Theme.primary @@ -80,40 +80,43 @@ DankOSD { unit: "%" Component.onCompleted: { - if (DisplayService.brightnessAvailable) - value = DisplayService.brightnessLevel - } - - onSliderValueChanged: function(newValue) { if (DisplayService.brightnessAvailable) { - root.brightnessDebounceTimer.pendingValue = newValue - root.brightnessDebounceTimer.restart() - resetHideTimer() + value = DisplayService.brightnessLevel } } + onSliderValueChanged: newValue => { + if (DisplayService.brightnessAvailable) { + root.brightnessDebounceTimer.pendingValue = newValue + root.brightnessDebounceTimer.restart() + resetHideTimer() + } + } + onContainsMouseChanged: { setChildHovered(containsMouse) } - onSliderDragFinished: function(finalValue) { - if (DisplayService.brightnessAvailable) { - root.brightnessDebounceTimer.stop() - DisplayService.setBrightnessInternal(finalValue, DisplayService.lastIpcDevice) - } - } + onSliderDragFinished: finalValue => { + if (DisplayService.brightnessAvailable) { + root.brightnessDebounceTimer.stop() + DisplayService.setBrightnessInternal(finalValue, DisplayService.lastIpcDevice) + } + } Connections { target: DisplayService function onBrightnessChanged() { - if (!brightnessSlider.pressed) + if (!brightnessSlider.pressed) { brightnessSlider.value = DisplayService.brightnessLevel + } } function onDeviceSwitched() { - if (!brightnessSlider.pressed) + if (!brightnessSlider.pressed) { brightnessSlider.value = DisplayService.brightnessLevel + } } } } @@ -122,9 +125,10 @@ DankOSD { onOsdShown: { if (DisplayService.brightnessAvailable && contentLoader.item) { - let slider = contentLoader.item.children[0].children[1] - if (slider) + const slider = contentLoader.item.children[0].children[1] + if (slider) { slider.value = DisplayService.brightnessLevel + } } } -} \ No newline at end of file +} diff --git a/Modules/OSD/IdleInhibitorOSD.qml b/Modules/OSD/IdleInhibitorOSD.qml index 87cf7144..cbf4ab4d 100644 --- a/Modules/OSD/IdleInhibitorOSD.qml +++ b/Modules/OSD/IdleInhibitorOSD.qml @@ -24,4 +24,4 @@ DankOSD { size: Theme.iconSize color: SessionService.idleInhibited ? Theme.primary : Theme.outline } -} \ No newline at end of file +} diff --git a/Modules/OSD/MicMuteOSD.qml b/Modules/OSD/MicMuteOSD.qml index a14dff0c..d60db81a 100644 --- a/Modules/OSD/MicMuteOSD.qml +++ b/Modules/OSD/MicMuteOSD.qml @@ -24,4 +24,4 @@ DankOSD { size: Theme.iconSize color: AudioService.source && AudioService.source.audio && AudioService.source.audio.muted ? Theme.error : Theme.primary } -} \ No newline at end of file +} diff --git a/Modules/OSD/VolumeOSD.qml b/Modules/OSD/VolumeOSD.qml index 46c612d9..9550595f 100644 --- a/Modules/OSD/VolumeOSD.qml +++ b/Modules/OSD/VolumeOSD.qml @@ -11,7 +11,6 @@ DankOSD { autoHideInterval: 3000 enableMouseInteraction: true - Connections { target: AudioService @@ -20,8 +19,9 @@ DankOSD { } function onSinkChanged() { - if (root.shouldBeVisible) + if (root.shouldBeVisible) { root.show() + } } } @@ -80,17 +80,18 @@ DankOSD { unit: "%" Component.onCompleted: { - if (AudioService.sink && AudioService.sink.audio) - value = Math.round(AudioService.sink.audio.volume * 100) - } - - onSliderValueChanged: function(newValue) { if (AudioService.sink && AudioService.sink.audio) { - AudioService.sink.audio.volume = newValue / 100 - resetHideTimer() + value = Math.round(AudioService.sink.audio.volume * 100) } } + onSliderValueChanged: newValue => { + if (AudioService.sink && AudioService.sink.audio) { + AudioService.sink.audio.volume = newValue / 100 + resetHideTimer() + } + } + onContainsMouseChanged: { setChildHovered(containsMouse || muteButton.containsMouse) } @@ -99,8 +100,9 @@ DankOSD { target: AudioService.sink && AudioService.sink.audio ? AudioService.sink.audio : null function onVolumeChanged() { - if (volumeSlider && !volumeSlider.pressed) + if (volumeSlider && !volumeSlider.pressed) { volumeSlider.value = Math.round(AudioService.sink.audio.volume * 100) + } } } } @@ -109,9 +111,10 @@ DankOSD { onOsdShown: { if (AudioService.sink && AudioService.sink.audio && contentLoader.item) { - let slider = contentLoader.item.children[0].children[1] - if (slider) + const slider = contentLoader.item.children[0].children[1] + if (slider) { slider.value = Math.round(AudioService.sink.audio.volume * 100) + } } } -} \ No newline at end of file +} diff --git a/Modules/ProcessList/PerformanceTab.qml b/Modules/ProcessList/PerformanceTab.qml index 6efd9019..e18c3147 100644 --- a/Modules/ProcessList/PerformanceTab.qml +++ b/Modules/ProcessList/PerformanceTab.qml @@ -6,42 +6,42 @@ import qs.Widgets Column { function formatNetworkSpeed(bytesPerSec) { - if (bytesPerSec < 1024) - return bytesPerSec.toFixed(0) + " B/s" - else if (bytesPerSec < 1024 * 1024) - return (bytesPerSec / 1024).toFixed(1) + " KB/s" - else if (bytesPerSec < 1024 * 1024 * 1024) - return (bytesPerSec / (1024 * 1024)).toFixed(1) + " MB/s" - else - return (bytesPerSec / (1024 * 1024 * 1024)).toFixed(1) + " GB/s" + if (bytesPerSec < 1024) { + return bytesPerSec.toFixed(0) + " B/s"; + } else if (bytesPerSec < 1024 * 1024) { + return (bytesPerSec / 1024).toFixed(1) + " KB/s"; + } else if (bytesPerSec < 1024 * 1024 * 1024) { + return (bytesPerSec / (1024 * 1024)).toFixed(1) + " MB/s"; + } else { + return (bytesPerSec / (1024 * 1024 * 1024)).toFixed(1) + " GB/s"; + } } function formatDiskSpeed(bytesPerSec) { - if (bytesPerSec < 1024 * 1024) - return (bytesPerSec / 1024).toFixed(1) + " KB/s" - else if (bytesPerSec < 1024 * 1024 * 1024) - return (bytesPerSec / (1024 * 1024)).toFixed(1) + " MB/s" - else - return (bytesPerSec / (1024 * 1024 * 1024)).toFixed(1) + " GB/s" + if (bytesPerSec < 1024 * 1024) { + return (bytesPerSec / 1024).toFixed(1) + " KB/s"; + } else if (bytesPerSec < 1024 * 1024 * 1024) { + return (bytesPerSec / (1024 * 1024)).toFixed(1) + " MB/s"; + } else { + return (bytesPerSec / (1024 * 1024 * 1024)).toFixed(1) + " GB/s"; + } } anchors.fill: parent spacing: Theme.spacingM Component.onCompleted: { - DgopService.addRef(["cpu", "memory", "network", "disk"]) + DgopService.addRef(["cpu", "memory", "network", "disk"]); } Component.onDestruction: { - DgopService.removeRef(["cpu", "memory", "network", "disk"]) + DgopService.removeRef(["cpu", "memory", "network", "disk"]); } Rectangle { width: parent.width height: 200 radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.04) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.06) + color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.04) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.06) border.width: 1 Column { @@ -66,17 +66,17 @@ Column { width: 80 height: 24 radius: Theme.cornerRadius - color: Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.12) + color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) anchors.verticalCenter: parent.verticalCenter StyledText { - text: DgopService.cpuUsage.toFixed(1) + "%" + text: `${DgopService.cpuUsage.toFixed(1)}%` font.pixelSize: Theme.fontSizeSmall font.weight: Font.Bold color: Theme.primary anchors.centerIn: parent } + } Item { @@ -85,11 +85,12 @@ Column { } StyledText { - text: DgopService.cpuCores + " cores" + text: `${DgopService.cpuCores} cores` font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceVariantText anchors.verticalCenter: parent.verticalCenter } + } DankFlickable { @@ -100,6 +101,7 @@ Column { Column { id: coreUsageColumn + width: parent.width spacing: 6 @@ -112,7 +114,7 @@ Column { spacing: Theme.spacingS StyledText { - text: "C" + index + text: `C${index}` font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceVariantText width: 24 @@ -123,38 +125,37 @@ Column { width: parent.width - 80 height: 6 radius: 3 - color: Qt.rgba(Theme.outline.r, - Theme.outline.g, - Theme.outline.b, 0.2) + color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) anchors.verticalCenter: parent.verticalCenter Rectangle { - width: parent.width * Math.min( - 1, modelData / 100) + width: parent.width * Math.min(1, modelData / 100) height: parent.height radius: parent.radius color: { - const usage = modelData - if (usage > 80) - return Theme.error - - if (usage > 60) - return Theme.warning - - return Theme.primary + const usage = modelData; + if (usage > 80) { + return Theme.error; + } + if (usage > 60) { + return Theme.warning; + } + return Theme.primary; } Behavior on width { NumberAnimation { duration: Theme.shortDuration } + } + } + } StyledText { - text: modelData ? modelData.toFixed( - 0) + "%" : "0%" + text: modelData ? `${modelData.toFixed(0)}%` : "0%" font.pixelSize: Theme.fontSizeSmall font.weight: Font.Medium color: Theme.surfaceText @@ -162,21 +163,25 @@ Column { horizontalAlignment: Text.AlignRight anchors.verticalCenter: parent.verticalCenter } + } + } + } + } + } + } Rectangle { width: parent.width height: 80 radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.04) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.06) + color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.04) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.06) border.width: 1 Row { @@ -196,12 +201,11 @@ Column { } StyledText { - text: DgopService.formatSystemMemory( - DgopService.usedMemoryKB) + " / " + DgopService.formatSystemMemory( - DgopService.totalMemoryKB) + text: `${DgopService.formatSystemMemory(DgopService.usedMemoryKB)} / ${DgopService.formatSystemMemory(DgopService.totalMemoryKB)}` font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceVariantText } + } Item { @@ -218,45 +222,41 @@ Column { width: parent.width height: 16 radius: 8 - color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.2) + color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) Rectangle { - width: DgopService.totalMemoryKB - > 0 ? parent.width * (DgopService.usedMemoryKB - / DgopService.totalMemoryKB) : 0 + width: DgopService.totalMemoryKB > 0 ? parent.width * (DgopService.usedMemoryKB / DgopService.totalMemoryKB) : 0 height: parent.height radius: parent.radius color: { - const usage = DgopService.totalMemoryKB - > 0 ? (DgopService.usedMemoryKB - / DgopService.totalMemoryKB) : 0 - if (usage > 0.9) - return Theme.error - - if (usage > 0.7) - return Theme.warning - - return Theme.secondary + const usage = DgopService.totalMemoryKB > 0 ? (DgopService.usedMemoryKB / DgopService.totalMemoryKB) : 0; + if (usage > 0.9) { + return Theme.error; + } + if (usage > 0.7) { + return Theme.warning; + } + return Theme.secondary; } Behavior on width { NumberAnimation { duration: Theme.mediumDuration } + } + } + } StyledText { - text: DgopService.totalMemoryKB - > 0 ? ((DgopService.usedMemoryKB - / DgopService.totalMemoryKB) * 100).toFixed( - 1) + "% used" : "No data" + text: DgopService.totalMemoryKB > 0 ? `${((DgopService.usedMemoryKB / DgopService.totalMemoryKB) * 100).toFixed(1)}% used` : "No data" font.pixelSize: Theme.fontSizeSmall font.weight: Font.Bold color: Theme.surfaceText } + } Item { @@ -276,14 +276,11 @@ Column { } StyledText { - text: DgopService.totalSwapKB - > 0 ? DgopService.formatSystemMemory( - DgopService.usedSwapKB) + " / " - + DgopService.formatSystemMemory( - DgopService.totalSwapKB) : "No swap configured" + text: DgopService.totalSwapKB > 0 ? `${DgopService.formatSystemMemory(DgopService.usedSwapKB)} / ${DgopService.formatSystemMemory(DgopService.totalSwapKB)}` : "No swap configured" font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceVariantText } + } Item { @@ -300,49 +297,48 @@ Column { width: parent.width height: 16 radius: 8 - color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.2) + color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) Rectangle { - width: DgopService.totalSwapKB - > 0 ? parent.width * (DgopService.usedSwapKB - / DgopService.totalSwapKB) : 0 + width: DgopService.totalSwapKB > 0 ? parent.width * (DgopService.usedSwapKB / DgopService.totalSwapKB) : 0 height: parent.height radius: parent.radius color: { - if (!DgopService.totalSwapKB) - return Qt.rgba(Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, 0.3) - - const usage = DgopService.usedSwapKB / DgopService.totalSwapKB - if (usage > 0.9) - return Theme.error - - if (usage > 0.7) - return Theme.warning - - return Theme.info + if (!DgopService.totalSwapKB) { + return Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.3); + } + const usage = DgopService.usedSwapKB / DgopService.totalSwapKB; + if (usage > 0.9) { + return Theme.error; + } + if (usage > 0.7) { + return Theme.warning; + } + return Theme.info; } Behavior on width { NumberAnimation { duration: Theme.mediumDuration } + } + } + } StyledText { - text: DgopService.totalSwapKB - > 0 ? ((DgopService.usedSwapKB / DgopService.totalSwapKB) * 100).toFixed( - 1) + "% used" : "Not available" + text: DgopService.totalSwapKB > 0 ? `${((DgopService.usedSwapKB / DgopService.totalSwapKB) * 100).toFixed(1)}% used` : "Not available" font.pixelSize: Theme.fontSizeSmall font.weight: Font.Bold color: Theme.surfaceText } + } + } + } Row { @@ -354,10 +350,8 @@ Column { width: (parent.width - Theme.spacingM) / 2 height: 80 radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.04) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.06) + color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.04) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.06) border.width: 1 Column { @@ -386,13 +380,12 @@ Column { } StyledText { - text: DgopService.networkRxRate - > 0 ? formatNetworkSpeed( - DgopService.networkRxRate) : "0 B/s" + text: DgopService.networkRxRate > 0 ? formatNetworkSpeed(DgopService.networkRxRate) : "0 B/s" font.pixelSize: Theme.fontSizeSmall font.weight: Font.Bold color: Theme.surfaceText } + } Row { @@ -405,26 +398,26 @@ Column { } StyledText { - text: DgopService.networkTxRate - > 0 ? formatNetworkSpeed( - DgopService.networkTxRate) : "0 B/s" + text: DgopService.networkTxRate > 0 ? formatNetworkSpeed(DgopService.networkTxRate) : "0 B/s" font.pixelSize: Theme.fontSizeSmall font.weight: Font.Bold color: Theme.surfaceText } + } + } + } + } Rectangle { width: (parent.width - Theme.spacingM) / 2 height: 80 radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.04) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.06) + color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.04) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.06) border.width: 1 Column { @@ -458,6 +451,7 @@ Column { font.weight: Font.Bold color: Theme.surfaceText } + } Row { @@ -475,9 +469,15 @@ Column { font.weight: Font.Bold color: Theme.surfaceText } + } + } + } + } + } + } diff --git a/Modules/ProcessList/ProcessContextMenu.qml b/Modules/ProcessList/ProcessContextMenu.qml index 8af1de65..14b8f1a5 100644 --- a/Modules/ProcessList/ProcessContextMenu.qml +++ b/Modules/ProcessList/ProcessContextMenu.qml @@ -12,25 +12,27 @@ Popup { property var processData: null function show(x, y) { - if (!processContextMenu.parent && typeof Overlay !== "undefined" - && Overlay.overlay) - processContextMenu.parent = Overlay.overlay + if (!processContextMenu.parent && typeof Overlay !== "undefined" && Overlay.overlay) { + processContextMenu.parent = Overlay.overlay; + } - const menuWidth = 180 - const menuHeight = menuColumn.implicitHeight + Theme.spacingS * 2 - const screenWidth = Screen.width - const screenHeight = Screen.height - let finalX = x - let finalY = y - if (x + menuWidth > screenWidth - 20) - finalX = x - menuWidth + const menuWidth = 180; + const menuHeight = menuColumn.implicitHeight + Theme.spacingS * 2; + const screenWidth = Screen.width; + const screenHeight = Screen.height; + let finalX = x; + let finalY = y; + if (x + menuWidth > screenWidth - 20) { + finalX = x - menuWidth; + } - if (y + menuHeight > screenHeight - 20) - finalY = y - menuHeight + if (y + menuHeight > screenHeight - 20) { + finalY = y - menuHeight; + } - processContextMenu.x = Math.max(20, finalX) - processContextMenu.y = Math.max(20, finalY) - open() + processContextMenu.x = Math.max(20, finalX); + processContextMenu.y = Math.max(20, finalY); + open(); } width: 180 @@ -39,10 +41,10 @@ Popup { modal: false closePolicy: Popup.CloseOnEscape onClosed: { - closePolicy = Popup.CloseOnEscape + closePolicy = Popup.CloseOnEscape; } onOpened: { - outsideClickTimer.start() + outsideClickTimer.start(); } Timer { @@ -50,7 +52,7 @@ Popup { interval: 100 onTriggered: { - processContextMenu.closePolicy = Popup.CloseOnEscape | Popup.CloseOnPressOutside + processContextMenu.closePolicy = Popup.CloseOnEscape | Popup.CloseOnPressOutside; } } @@ -63,8 +65,7 @@ Popup { color: Theme.popupBackground() radius: Theme.cornerRadius - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.08) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) border.width: 1 Column { @@ -78,10 +79,7 @@ Popup { width: parent.width height: 28 radius: Theme.cornerRadius - color: copyPidArea.containsMouse ? Qt.rgba(Theme.primary.r, - Theme.primary.g, - Theme.primary.b, - 0.12) : "transparent" + color: copyPidArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" StyledText { anchors.left: parent.left @@ -100,25 +98,21 @@ Popup { hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { - if (processContextMenu.processData) - Quickshell.execDetached( - ["wl-copy", processContextMenu.processData.pid.toString( - )]) + if (processContextMenu.processData) { + Quickshell.execDetached(["wl-copy", processContextMenu.processData.pid.toString()]); + } - processContextMenu.close() + processContextMenu.close(); } } + } Rectangle { width: parent.width height: 28 radius: Theme.cornerRadius - color: copyNameArea.containsMouse ? Qt.rgba( - Theme.primary.r, - Theme.primary.g, - Theme.primary.b, - 0.12) : "transparent" + color: copyNameArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" StyledText { anchors.left: parent.left @@ -138,13 +132,13 @@ Popup { cursorShape: Qt.PointingHandCursor onClicked: { if (processContextMenu.processData) { - let processName = processContextMenu.processData.displayName - || processContextMenu.processData.command - Quickshell.execDetached(["wl-copy", processName]) + const processName = processContextMenu.processData.displayName || processContextMenu.processData.command; + Quickshell.execDetached(["wl-copy", processName]); } - processContextMenu.close() + processContextMenu.close(); } } + } Rectangle { @@ -157,19 +151,16 @@ Popup { anchors.centerIn: parent width: parent.width height: 1 - color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.2) + color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) } + } Rectangle { width: parent.width height: 28 radius: Theme.cornerRadius - color: killArea.containsMouse ? Qt.rgba(Theme.error.r, - Theme.error.g, - Theme.error.b, - 0.12) : "transparent" + color: killArea.containsMouse ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12) : "transparent" enabled: processContextMenu.processData opacity: enabled ? 1 : 0.5 @@ -179,10 +170,7 @@ Popup { anchors.verticalCenter: parent.verticalCenter text: "Kill Process" font.pixelSize: Theme.fontSizeSmall - color: parent.enabled ? (killArea.containsMouse ? Theme.error : Theme.surfaceText) : Qt.rgba( - Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, 0.5) + color: parent.enabled ? (killArea.containsMouse ? Theme.error : Theme.surfaceText) : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5) font.weight: Font.Normal } @@ -194,27 +182,22 @@ Popup { cursorShape: parent.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor enabled: parent.enabled onClicked: { - if (processContextMenu.processData) - Quickshell.execDetached( - ["kill", processContextMenu.processData.pid.toString( - )]) + if (processContextMenu.processData) { + Quickshell.execDetached(["kill", processContextMenu.processData.pid.toString()]); + } - processContextMenu.close() + processContextMenu.close(); } } + } Rectangle { width: parent.width height: 28 radius: Theme.cornerRadius - color: forceKillArea.containsMouse ? Qt.rgba( - Theme.error.r, - Theme.error.g, - Theme.error.b, - 0.12) : "transparent" - enabled: processContextMenu.processData - && processContextMenu.processData.pid > 1000 + color: forceKillArea.containsMouse ? Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12) : "transparent" + enabled: processContextMenu.processData && processContextMenu.processData.pid > 1000 opacity: enabled ? 1 : 0.5 StyledText { @@ -223,10 +206,7 @@ Popup { anchors.verticalCenter: parent.verticalCenter text: "Force Kill Process" font.pixelSize: Theme.fontSizeSmall - color: parent.enabled ? (forceKillArea.containsMouse ? Theme.error : Theme.surfaceText) : Qt.rgba( - Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, 0.5) + color: parent.enabled ? (forceKillArea.containsMouse ? Theme.error : Theme.surfaceText) : Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5) font.weight: Font.Normal } @@ -238,15 +218,18 @@ Popup { cursorShape: parent.enabled ? Qt.PointingHandCursor : Qt.ArrowCursor enabled: parent.enabled onClicked: { - if (processContextMenu.processData) - Quickshell.execDetached( - ["kill", "-9", processContextMenu.processData.pid.toString( - )]) + if (processContextMenu.processData) { + Quickshell.execDetached(["kill", "-9", processContextMenu.processData.pid.toString()]); + } - processContextMenu.close() + processContextMenu.close(); } } + } + } + } + } diff --git a/Modules/ProcessList/ProcessListItem.qml b/Modules/ProcessList/ProcessListItem.qml index 7588c87a..fbfb4722 100644 --- a/Modules/ProcessList/ProcessListItem.qml +++ b/Modules/ProcessList/ProcessListItem.qml @@ -12,14 +12,8 @@ Rectangle { width: parent ? parent.width : 0 height: 40 radius: Theme.cornerRadius - color: processMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, - Theme.primary.g, - Theme.primary.b, - 0.08) : "transparent" - border.color: processMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, - Theme.primary.g, - Theme.primary.b, - 0.12) : "transparent" + color: processMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent" + border.color: processMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent" border.width: 1 MouseArea { @@ -29,25 +23,21 @@ Rectangle { hoverEnabled: true cursorShape: Qt.PointingHandCursor acceptedButtons: Qt.LeftButton | Qt.RightButton - onClicked: mouse => { - if (mouse.button === Qt.RightButton) { - if (process && process.pid > 0 && contextMenu) { - contextMenu.processData = process - let globalPos = processMouseArea.mapToGlobal( - mouse.x, mouse.y) - let localPos = contextMenu.parent ? contextMenu.parent.mapFromGlobal( - globalPos.x, - globalPos.y) : globalPos - contextMenu.show(localPos.x, localPos.y) - } - } - } + onClicked: (mouse) => { + if (mouse.button === Qt.RightButton) { + if (process && process.pid > 0 && contextMenu) { + contextMenu.processData = process; + const globalPos = processMouseArea.mapToGlobal(mouse.x, mouse.y); + const localPos = contextMenu.parent ? contextMenu.parent.mapFromGlobal(globalPos.x, globalPos.y) : globalPos; + contextMenu.show(localPos.x, localPos.y); + } + } + } onPressAndHold: { if (process && process.pid > 0 && contextMenu) { - contextMenu.processData = process - let globalPos = processMouseArea.mapToGlobal( - processMouseArea.width / 2, processMouseArea.height / 2) - contextMenu.show(globalPos.x, globalPos.y) + contextMenu.processData = process; + const globalPos = processMouseArea.mapToGlobal(processMouseArea.width / 2, processMouseArea.height / 2); + contextMenu.show(globalPos.x, globalPos.y); } } } @@ -62,10 +52,10 @@ Rectangle { name: DgopService.getProcessIcon(process ? process.command : "") size: Theme.iconSize - 4 color: { - if (process && process.cpu > 80) - return Theme.error - - return Theme.surfaceText + if (process && process.cpu > 80) { + return Theme.error; + } + return Theme.surfaceText; } opacity: 0.8 anchors.left: parent.left @@ -92,12 +82,10 @@ Rectangle { height: 20 radius: Theme.cornerRadius color: { - if (process && process.cpu > 80) - return Qt.rgba(Theme.error.r, Theme.error.g, - Theme.error.b, 0.12) - - return Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, - Theme.surfaceText.b, 0.08) + if (process && process.cpu > 80) { + return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12); + } + return Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.08); } anchors.right: parent.right anchors.rightMargin: 194 @@ -109,13 +97,14 @@ Rectangle { font.family: SettingsData.monoFontFamily font.weight: Font.Bold color: { - if (process && process.cpu > 80) - return Theme.error - - return Theme.surfaceText + if (process && process.cpu > 80) { + return Theme.error; + } + return Theme.surfaceText; } anchors.centerIn: parent } + } Rectangle { @@ -125,31 +114,29 @@ Rectangle { height: 20 radius: Theme.cornerRadius color: { - if (process && process.memoryKB > 1024 * 1024) - return Qt.rgba(Theme.error.r, Theme.error.g, - Theme.error.b, 0.12) - - return Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, - Theme.surfaceText.b, 0.08) + if (process && process.memoryKB > 1024 * 1024) { + return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12); + } + return Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.08); } anchors.right: parent.right anchors.rightMargin: 102 anchors.verticalCenter: parent.verticalCenter StyledText { - text: DgopService.formatMemoryUsage( - process ? process.memoryKB : 0) + text: DgopService.formatMemoryUsage(process ? process.memoryKB : 0) font.pixelSize: Theme.fontSizeSmall font.family: SettingsData.monoFontFamily font.weight: Font.Bold color: { - if (process && process.memoryKB > 1024 * 1024) - return Theme.error - - return Theme.surfaceText + if (process && process.memoryKB > 1024 * 1024) { + return Theme.error; + } + return Theme.surfaceText; } anchors.centerIn: parent } + } StyledText { @@ -171,10 +158,7 @@ Rectangle { width: 28 height: 28 radius: Theme.cornerRadius - color: menuButtonArea.containsMouse ? Qt.rgba(Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, - 0.08) : "transparent" + color: menuButtonArea.containsMouse ? Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.08) : "transparent" anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter @@ -194,13 +178,10 @@ Rectangle { cursorShape: Qt.PointingHandCursor onClicked: { if (process && process.pid > 0 && contextMenu) { - contextMenu.processData = process - let globalPos = menuButtonArea.mapToGlobal( - menuButtonArea.width / 2, menuButtonArea.height) - let localPos = contextMenu.parent ? contextMenu.parent.mapFromGlobal( - globalPos.x, - globalPos.y) : globalPos - contextMenu.show(localPos.x, localPos.y) + contextMenu.processData = process; + const globalPos = menuButtonArea.mapToGlobal(menuButtonArea.width / 2, menuButtonArea.height); + const localPos = contextMenu.parent ? contextMenu.parent.mapFromGlobal(globalPos.x, globalPos.y) : globalPos; + contextMenu.show(localPos.x, localPos.y); } } } @@ -209,7 +190,11 @@ Rectangle { ColorAnimation { duration: Theme.shortDuration } + } + } + } + } diff --git a/Modules/ProcessList/ProcessListPopout.qml b/Modules/ProcessList/ProcessListPopout.qml index e61f814a..2b4015d6 100644 --- a/Modules/ProcessList/ProcessListPopout.qml +++ b/Modules/ProcessList/ProcessListPopout.qml @@ -19,21 +19,22 @@ DankPopout { property var triggerScreen: null function setTriggerPosition(x, y, width, section, screen) { - triggerX = x - triggerY = y - triggerWidth = width - triggerSection = section - triggerScreen = screen + triggerX = x; + triggerY = y; + triggerWidth = width; + triggerSection = section; + triggerScreen = screen; } function hide() { - close() - if (processContextMenu.visible) - processContextMenu.close() + close(); + if (processContextMenu.visible) { + processContextMenu.close(); + } } function show() { - open() + open(); } popupWidth: 600 @@ -51,39 +52,43 @@ DankPopout { service: DgopService } + ProcessContextMenu { + id: processContextMenu + } + content: Component { Rectangle { id: processListContent radius: Theme.cornerRadius color: Theme.popupBackground() - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.08) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) border.width: 1 clip: true antialiasing: true smooth: true focus: true - Component.onCompleted: { - if (processListPopout.shouldBeVisible) - forceActiveFocus() + if (processListPopout.shouldBeVisible) { + forceActiveFocus(); + } } - - Keys.onPressed: function (event) { + Keys.onPressed: (event) => { if (event.key === Qt.Key_Escape) { - processListPopout.close() - event.accepted = true + processListPopout.close(); + event.accepted = true; } } Connections { function onShouldBeVisibleChanged() { - if (processListPopout.shouldBeVisible) - Qt.callLater(function () { - processListContent.forceActiveFocus() - }) + if (processListPopout.shouldBeVisible) { + Qt.callLater(() => { + processListContent.forceActiveFocus(); + }); + } } + target: processListPopout } @@ -96,11 +101,8 @@ DankPopout { Layout.fillWidth: true height: systemOverview.height + Theme.spacingM * 2 radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceVariant.r, - Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.2) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.08) + color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.2) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08) border.width: 1 SystemOverview { @@ -109,17 +111,15 @@ DankPopout { anchors.centerIn: parent width: parent.width - Theme.spacingM * 2 } + } Rectangle { Layout.fillWidth: true Layout.fillHeight: true radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceVariant.r, - Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.1) - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.05) + color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.1) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.05) border.width: 1 ProcessListView { @@ -127,12 +127,13 @@ DankPopout { anchors.margins: Theme.spacingS contextMenu: processContextMenu } + } + } + } + } - ProcessContextMenu { - id: processContextMenu - } } diff --git a/Modules/ProcessList/ProcessListView.qml b/Modules/ProcessList/ProcessListView.qml index 55b00708..063fd6ca 100644 --- a/Modules/ProcessList/ProcessListView.qml +++ b/Modules/ProcessList/ProcessListView.qml @@ -10,10 +10,10 @@ Column { property var contextMenu: null Component.onCompleted: { - DgopService.addRef(["processes"]) + DgopService.addRef(["processes"]); } Component.onDestruction: { - DgopService.removeRef(["processes"]) + DgopService.removeRef(["processes"]); } Item { @@ -28,14 +28,9 @@ Column { height: 20 color: { if (DgopService.currentSort === "name") { - return Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.12) + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12); } - return processHeaderArea.containsMouse ? Qt.rgba( - Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, - 0.08) : "transparent" + return processHeaderArea.containsMouse ? Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.08) : "transparent"; } radius: Theme.cornerRadius anchors.left: parent.left @@ -59,7 +54,7 @@ Column { hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { - DgopService.setSortBy("name") + DgopService.setSortBy("name"); } } @@ -67,7 +62,9 @@ Column { ColorAnimation { duration: Theme.shortDuration } + } + } Rectangle { @@ -75,14 +72,9 @@ Column { height: 20 color: { if (DgopService.currentSort === "cpu") { - return Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.12) + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12); } - return cpuHeaderArea.containsMouse ? Qt.rgba( - Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, - 0.08) : "transparent" + return cpuHeaderArea.containsMouse ? Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.08) : "transparent"; } radius: Theme.cornerRadius anchors.right: parent.right @@ -106,7 +98,7 @@ Column { hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { - DgopService.setSortBy("cpu") + DgopService.setSortBy("cpu"); } } @@ -114,7 +106,9 @@ Column { ColorAnimation { duration: Theme.shortDuration } + } + } Rectangle { @@ -122,14 +116,9 @@ Column { height: 20 color: { if (DgopService.currentSort === "memory") { - return Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.12) + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12); } - return memoryHeaderArea.containsMouse ? Qt.rgba( - Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, - 0.08) : "transparent" + return memoryHeaderArea.containsMouse ? Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.08) : "transparent"; } radius: Theme.cornerRadius anchors.right: parent.right @@ -153,7 +142,7 @@ Column { hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { - DgopService.setSortBy("memory") + DgopService.setSortBy("memory"); } } @@ -161,7 +150,9 @@ Column { ColorAnimation { duration: Theme.shortDuration } + } + } Rectangle { @@ -169,14 +160,9 @@ Column { height: 20 color: { if (DgopService.currentSort === "pid") { - return Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.12) + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12); } - return pidHeaderArea.containsMouse ? Qt.rgba( - Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, - 0.08) : "transparent" + return pidHeaderArea.containsMouse ? Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.08) : "transparent"; } radius: Theme.cornerRadius anchors.right: parent.right @@ -201,7 +187,7 @@ Column { hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { - DgopService.setSortBy("pid") + DgopService.setSortBy("pid"); } } @@ -209,17 +195,16 @@ Column { ColorAnimation { duration: Theme.shortDuration } + } + } Rectangle { width: 28 height: 28 radius: Theme.cornerRadius - color: sortOrderArea.containsMouse ? Qt.rgba(Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, - 0.08) : "transparent" + color: sortOrderArea.containsMouse ? Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.08) : "transparent" anchors.right: parent.right anchors.rightMargin: 8 anchors.verticalCenter: parent.verticalCenter @@ -232,14 +217,14 @@ Column { } MouseArea { + // TODO: Re-implement sort order toggle + id: sortOrderArea anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: { - - // ! TODO - we lost this with dgop } } @@ -247,8 +232,11 @@ Column { ColorAnimation { duration: Theme.shortDuration } + } + } + } DankListView { @@ -266,5 +254,7 @@ Column { process: modelData contextMenu: root.contextMenu } + } + } diff --git a/Modules/ProcessList/ProcessesTab.qml b/Modules/ProcessList/ProcessesTab.qml index 6819b88d..987dd90a 100644 --- a/Modules/ProcessList/ProcessesTab.qml +++ b/Modules/ProcessList/ProcessesTab.qml @@ -19,7 +19,7 @@ ColumnLayout { ProcessListView { Layout.fillWidth: true Layout.fillHeight: true - contextMenu: processesTab.contextMenu || localContextMenu + contextMenu: processesTab.contextMenu } ProcessContextMenu { diff --git a/Modules/ProcessList/SystemOverview.qml b/Modules/ProcessList/SystemOverview.qml index cfdc6e53..cf813a93 100644 --- a/Modules/ProcessList/SystemOverview.qml +++ b/Modules/ProcessList/SystemOverview.qml @@ -8,10 +8,10 @@ Row { width: parent.width spacing: Theme.spacingM Component.onCompleted: { - DgopService.addRef(["cpu", "memory", "system"]) + DgopService.addRef(["cpu", "memory", "system"]); } Component.onDestruction: { - DgopService.removeRef(["cpu", "memory", "system"]) + DgopService.removeRef(["cpu", "memory", "system"]); } Rectangle { @@ -19,23 +19,15 @@ Row { height: 80 radius: Theme.cornerRadius color: { - if (DgopService.sortBy === "cpu") - return Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.16) - else if (cpuCardMouseArea.containsMouse) - return Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.12) - else - return Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.08) + if (DgopService.sortBy === "cpu") { + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16); + } else if (cpuCardMouseArea.containsMouse) { + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12); + } else { + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08); + } } - border.color: DgopService.sortBy === "cpu" ? Qt.rgba(Theme.primary.r, - Theme.primary.g, - Theme.primary.b, - 0.4) : Qt.rgba( - Theme.primary.r, - Theme.primary.g, - Theme.primary.b, 0.2) + border.color: DgopService.sortBy === "cpu" ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.4) : Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.2) border.width: DgopService.sortBy === "cpu" ? 2 : 1 MouseArea { @@ -44,7 +36,9 @@ Row { anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor - onClicked: DgopService.setSortBy("cpu") + onClicked: { + DgopService.setSortBy("cpu"); + } } Column { @@ -66,10 +60,10 @@ Row { StyledText { text: { - if (DgopService.cpuUsage === undefined - || DgopService.cpuUsage === null) - return "--%" - return DgopService.cpuUsage.toFixed(1) + "%" + if (DgopService.cpuUsage === undefined || DgopService.cpuUsage === null) { + return "--%"; + } + return DgopService.cpuUsage.toFixed(1) + "%"; } font.pixelSize: Theme.fontSizeLarge font.family: SettingsData.monoFontFamily @@ -81,56 +75,58 @@ Row { Rectangle { width: 1 height: 20 - color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, - Theme.surfaceText.b, 0.3) + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.3) anchors.verticalCenter: parent.verticalCenter } StyledText { text: { - if (DgopService.cpuTemperature === undefined - || DgopService.cpuTemperature === null - || DgopService.cpuTemperature <= 0) - return "--°" - - return Math.round(DgopService.cpuTemperature) + "°" + if (DgopService.cpuTemperature === undefined || DgopService.cpuTemperature === null || DgopService.cpuTemperature <= 0) { + return "--°"; + } + return Math.round(DgopService.cpuTemperature) + "°"; } font.pixelSize: Theme.fontSizeMedium font.family: SettingsData.monoFontFamily font.weight: Font.Medium color: { - if (DgopService.cpuTemperature > 80) - return Theme.error - - if (DgopService.cpuTemperature > 60) - return Theme.warning - - return Theme.surfaceText + if (DgopService.cpuTemperature > 80) { + return Theme.error; + } + if (DgopService.cpuTemperature > 60) { + return Theme.warning; + } + return Theme.surfaceText; } anchors.verticalCenter: parent.verticalCenter } + } StyledText { - text: DgopService.cpuCores + " cores" + text: `${DgopService.cpuCores} cores` font.pixelSize: Theme.fontSizeSmall font.family: SettingsData.monoFontFamily color: Theme.surfaceText opacity: 0.7 } + } Behavior on color { ColorAnimation { duration: Theme.shortDuration } + } Behavior on border.color { ColorAnimation { duration: Theme.shortDuration } + } + } Rectangle { @@ -138,25 +134,15 @@ Row { height: 80 radius: Theme.cornerRadius color: { - if (DgopService.sortBy === "memory") - return Qt.rgba(Theme.primary.r, Theme.primary.g, - Theme.primary.b, 0.16) - else if (memoryCardMouseArea.containsMouse) - return Qt.rgba(Theme.secondary.r, Theme.secondary.g, - Theme.secondary.b, 0.12) - else - return Qt.rgba(Theme.secondary.r, Theme.secondary.g, - Theme.secondary.b, 0.08) + if (DgopService.sortBy === "memory") { + return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.16); + } else if (memoryCardMouseArea.containsMouse) { + return Qt.rgba(Theme.secondary.r, Theme.secondary.g, Theme.secondary.b, 0.12); + } else { + return Qt.rgba(Theme.secondary.r, Theme.secondary.g, Theme.secondary.b, 0.08); + } } - border.color: DgopService.sortBy === "memory" ? Qt.rgba( - Theme.primary.r, - Theme.primary.g, - Theme.primary.b, - 0.4) : Qt.rgba( - Theme.secondary.r, - Theme.secondary.g, - Theme.secondary.b, - 0.2) + border.color: DgopService.sortBy === "memory" ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.4) : Qt.rgba(Theme.secondary.r, Theme.secondary.g, Theme.secondary.b, 0.2) border.width: DgopService.sortBy === "memory" ? 2 : 1 MouseArea { @@ -165,7 +151,9 @@ Row { anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor - onClicked: DgopService.setSortBy("memory") + onClicked: { + DgopService.setSortBy("memory"); + } } Column { @@ -186,8 +174,7 @@ Row { spacing: Theme.spacingS StyledText { - text: DgopService.formatSystemMemory( - DgopService.usedMemoryKB) + text: DgopService.formatSystemMemory(DgopService.usedMemoryKB) font.pixelSize: Theme.fontSizeLarge font.family: SettingsData.monoFontFamily font.weight: Font.Bold @@ -198,15 +185,13 @@ Row { Rectangle { width: 1 height: 20 - color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, - Theme.surfaceText.b, 0.3) + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.3) anchors.verticalCenter: parent.verticalCenter visible: DgopService.totalSwapKB > 0 } StyledText { - text: DgopService.totalSwapKB > 0 ? DgopService.formatSystemMemory( - DgopService.usedSwapKB) : "" + text: DgopService.totalSwapKB > 0 ? DgopService.formatSystemMemory(DgopService.usedSwapKB) : "" font.pixelSize: Theme.fontSizeMedium font.family: SettingsData.monoFontFamily font.weight: Font.Medium @@ -214,35 +199,38 @@ Row { anchors.verticalCenter: parent.verticalCenter visible: DgopService.totalSwapKB > 0 } + } StyledText { text: { - if (DgopService.totalSwapKB > 0) - return "of " + DgopService.formatSystemMemory( - DgopService.totalMemoryKB) + " + swap" - - return "of " + DgopService.formatSystemMemory( - DgopService.totalMemoryKB) + if (DgopService.totalSwapKB > 0) { + return "of " + DgopService.formatSystemMemory(DgopService.totalMemoryKB) + " + swap"; + } + return "of " + DgopService.formatSystemMemory(DgopService.totalMemoryKB); } font.pixelSize: Theme.fontSizeSmall font.family: SettingsData.monoFontFamily color: Theme.surfaceText opacity: 0.7 } + } Behavior on color { ColorAnimation { duration: Theme.shortDuration } + } Behavior on border.color { ColorAnimation { duration: Theme.shortDuration } + } + } Rectangle { @@ -250,74 +238,54 @@ Row { height: 80 radius: Theme.cornerRadius color: { - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) { - if (gpuCardMouseArea.containsMouse - && DgopService.availableGpus.length > 1) - return Qt.rgba(Theme.surfaceVariant.r, - Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.16) - else - return Qt.rgba(Theme.surfaceVariant.r, - Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.08) + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + if (gpuCardMouseArea.containsMouse && DgopService.availableGpus.length > 1) { + return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.16); + } else { + return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08); + } } - var gpu = DgopService.availableGpus[Math.min( - SessionData.selectedGpuIndex, - DgopService.availableGpus.length - 1)] - var vendor = gpu.vendor.toLowerCase() + const gpu = DgopService.availableGpus[Math.min(SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)]; + const vendor = gpu.vendor.toLowerCase(); if (vendor.includes("nvidia")) { - if (gpuCardMouseArea.containsMouse - && DgopService.availableGpus.length > 1) - return Qt.rgba(Theme.success.r, Theme.success.g, - Theme.success.b, 0.2) - else - return Qt.rgba(Theme.success.r, Theme.success.g, - Theme.success.b, 0.12) + if (gpuCardMouseArea.containsMouse && DgopService.availableGpus.length > 1) { + return Qt.rgba(Theme.success.r, Theme.success.g, Theme.success.b, 0.2); + } else { + return Qt.rgba(Theme.success.r, Theme.success.g, Theme.success.b, 0.12); + } } else if (vendor.includes("amd")) { - if (gpuCardMouseArea.containsMouse - && DgopService.availableGpus.length > 1) - return Qt.rgba(Theme.error.r, Theme.error.g, - Theme.error.b, 0.2) - else - return Qt.rgba(Theme.error.r, Theme.error.g, - Theme.error.b, 0.12) + if (gpuCardMouseArea.containsMouse && DgopService.availableGpus.length > 1) { + return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.2); + } else { + return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12); + } } else if (vendor.includes("intel")) { - if (gpuCardMouseArea.containsMouse - && DgopService.availableGpus.length > 1) - return Qt.rgba(Theme.info.r, Theme.info.g, - Theme.info.b, 0.2) - else - return Qt.rgba(Theme.info.r, Theme.info.g, - Theme.info.b, 0.12) + if (gpuCardMouseArea.containsMouse && DgopService.availableGpus.length > 1) { + return Qt.rgba(Theme.info.r, Theme.info.g, Theme.info.b, 0.2); + } else { + return Qt.rgba(Theme.info.r, Theme.info.g, Theme.info.b, 0.12); + } + } + if (gpuCardMouseArea.containsMouse && DgopService.availableGpus.length > 1) { + return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.16); + } else { + return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08); } - if (gpuCardMouseArea.containsMouse - && DgopService.availableGpus.length > 1) - return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.16) - else - return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.08) } border.color: { - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) - return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.2) - - var gpu = DgopService.availableGpus[Math.min( - SessionData.selectedGpuIndex, - DgopService.availableGpus.length - 1)] - var vendor = gpu.vendor.toLowerCase() - if (vendor.includes("nvidia")) - return Qt.rgba(Theme.success.r, Theme.success.g, - Theme.success.b, 0.3) - else if (vendor.includes("amd")) - return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.3) - else if (vendor.includes("intel")) - return Qt.rgba(Theme.info.r, Theme.info.g, Theme.info.b, 0.3) - return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, - Theme.surfaceVariant.b, 0.2) + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.2); + } + const gpu = DgopService.availableGpus[Math.min(SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)]; + const vendor = gpu.vendor.toLowerCase(); + if (vendor.includes("nvidia")) { + return Qt.rgba(Theme.success.r, Theme.success.g, Theme.success.b, 0.3); + } else if (vendor.includes("amd")) { + return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.3); + } else if (vendor.includes("intel")) { + return Qt.rgba(Theme.info.r, Theme.info.g, Theme.info.b, 0.3); + } + return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.2); } border.width: 1 @@ -327,19 +295,17 @@ Row { anchors.fill: parent hoverEnabled: true acceptedButtons: Qt.LeftButton | Qt.RightButton - cursorShape: DgopService.availableGpus.length - > 1 ? Qt.PointingHandCursor : Qt.ArrowCursor - onClicked: mouse => { - if (mouse.button === Qt.LeftButton) { - if (DgopService.availableGpus.length > 1) { - var nextIndex = (SessionData.selectedGpuIndex + 1) - % DgopService.availableGpus.length - SessionData.setSelectedGpuIndex(nextIndex) - } - } else if (mouse.button === Qt.RightButton) { - gpuContextMenu.popup() - } - } + cursorShape: DgopService.availableGpus.length > 1 ? Qt.PointingHandCursor : Qt.ArrowCursor + onClicked: (mouse) => { + if (mouse.button === Qt.LeftButton) { + if (DgopService.availableGpus.length > 1) { + const nextIndex = (SessionData.selectedGpuIndex + 1) % DgopService.availableGpus.length; + SessionData.setSelectedGpuIndex(nextIndex); + } + } else if (mouse.button === Qt.RightButton) { + gpuContextMenu.popup(); + } + } } Column { @@ -358,69 +324,54 @@ Row { StyledText { text: { - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) - return "No GPU" - - var gpu = DgopService.availableGpus[Math.min( - SessionData.selectedGpuIndex, - DgopService.availableGpus.length - 1)] + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + return "No GPU"; + } + const gpu = DgopService.availableGpus[Math.min(SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)]; // Check if temperature monitoring is enabled for this GPU - var tempEnabled = SessionData.enabledGpuPciIds - && SessionData.enabledGpuPciIds.indexOf( - gpu.pciId) !== -1 - var temp = gpu.temperature - var hasTemp = tempEnabled && temp !== undefined - && temp !== null && temp !== 0 - if (hasTemp) - return Math.round(temp) + "°" - else - return gpu.vendor + const tempEnabled = SessionData.enabledGpuPciIds && SessionData.enabledGpuPciIds.indexOf(gpu.pciId) !== -1; + const temp = gpu.temperature; + const hasTemp = tempEnabled && temp !== undefined && temp !== null && temp !== 0; + if (hasTemp) { + return Math.round(temp) + "°"; + } else { + return gpu.vendor; + } } font.pixelSize: Theme.fontSizeLarge font.family: SettingsData.monoFontFamily font.weight: Font.Bold color: { - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) - return Theme.surfaceText - - var gpu = DgopService.availableGpus[Math.min( - SessionData.selectedGpuIndex, - DgopService.availableGpus.length - 1)] - var tempEnabled = SessionData.enabledGpuPciIds - && SessionData.enabledGpuPciIds.indexOf( - gpu.pciId) !== -1 - var temp = gpu.temperature || 0 - if (tempEnabled && temp > 80) - return Theme.error - - if (tempEnabled && temp > 60) - return Theme.warning - - return Theme.surfaceText + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + return Theme.surfaceText; + } + const gpu = DgopService.availableGpus[Math.min(SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)]; + const tempEnabled = SessionData.enabledGpuPciIds && SessionData.enabledGpuPciIds.indexOf(gpu.pciId) !== -1; + const temp = gpu.temperature || 0; + if (tempEnabled && temp > 80) { + return Theme.error; + } + if (tempEnabled && temp > 60) { + return Theme.warning; + } + return Theme.surfaceText; } } StyledText { text: { - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) - return "No GPUs detected" - - var gpu = DgopService.availableGpus[Math.min( - SessionData.selectedGpuIndex, - DgopService.availableGpus.length - 1)] - var tempEnabled = SessionData.enabledGpuPciIds - && SessionData.enabledGpuPciIds.indexOf( - gpu.pciId) !== -1 - var temp = gpu.temperature - var hasTemp = tempEnabled && temp !== undefined - && temp !== null && temp !== 0 - if (hasTemp) - return gpu.vendor + " " + gpu.displayName - else - return gpu.displayName + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + return "No GPUs detected"; + } + const gpu = DgopService.availableGpus[Math.min(SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)]; + const tempEnabled = SessionData.enabledGpuPciIds && SessionData.enabledGpuPciIds.indexOf(gpu.pciId) !== -1; + const temp = gpu.temperature; + const hasTemp = tempEnabled && temp !== undefined && temp !== null && temp !== 0; + if (hasTemp) { + return gpu.vendor + " " + gpu.displayName; + } else { + return gpu.displayName; + } } font.pixelSize: Theme.fontSizeSmall font.family: SettingsData.monoFontFamily @@ -430,6 +381,7 @@ Row { elide: Text.ElideRight maximumLineCount: 1 } + } Menu { @@ -439,53 +391,45 @@ Row { text: "Enable GPU Temperature" checkable: true checked: { - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) { - return false + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + return false; } - - var gpu = DgopService.availableGpus[Math.min( - SessionData.selectedGpuIndex, - DgopService.availableGpus.length - 1)] - if (!gpu.pciId) - return false - - return SessionData.enabledGpuPciIds ? SessionData.enabledGpuPciIds.indexOf( - gpu.pciId) !== -1 : false + const gpu = DgopService.availableGpus[Math.min(SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)]; + if (!gpu.pciId) { + return false; + } + return SessionData.enabledGpuPciIds ? SessionData.enabledGpuPciIds.indexOf(gpu.pciId) !== -1 : false; } onTriggered: { - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) { - return + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + return; } - - var gpu = DgopService.availableGpus[Math.min( - SessionData.selectedGpuIndex, - DgopService.availableGpus.length - 1)] - if (!gpu.pciId) - return - - var enabledIds = SessionData.enabledGpuPciIds ? SessionData.enabledGpuPciIds.slice( - ) : [] - var index = enabledIds.indexOf(gpu.pciId) - + const gpu = DgopService.availableGpus[Math.min(SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)]; + if (!gpu.pciId) { + return; + } + const enabledIds = SessionData.enabledGpuPciIds ? SessionData.enabledGpuPciIds.slice() : []; + const index = enabledIds.indexOf(gpu.pciId); if (checked && index === -1) { - enabledIds.push(gpu.pciId) - DgopService.addGpuPciId(gpu.pciId) + enabledIds.push(gpu.pciId); + DgopService.addGpuPciId(gpu.pciId); } else if (!checked && index !== -1) { - enabledIds.splice(index, 1) - DgopService.removeGpuPciId(gpu.pciId) + enabledIds.splice(index, 1); + DgopService.removeGpuPciId(gpu.pciId); } - - SessionData.setEnabledGpuPciIds(enabledIds) + SessionData.setEnabledGpuPciIds(enabledIds); } } + } Behavior on color { ColorAnimation { duration: Theme.shortDuration } + } + } + } diff --git a/Modules/ProcessList/SystemTab.qml b/Modules/ProcessList/SystemTab.qml index 0ff1b05c..6c1c7a2a 100644 --- a/Modules/ProcessList/SystemTab.qml +++ b/Modules/ProcessList/SystemTab.qml @@ -8,14 +8,15 @@ DankFlickable { anchors.fill: parent contentHeight: systemColumn.implicitHeight Component.onCompleted: { - DgopService.addRef(["system", "hardware", "diskmounts"]) + DgopService.addRef(["system", "hardware", "diskmounts"]); } Component.onDestruction: { - DgopService.removeRef(["system", "hardware", "diskmounts"]) + DgopService.removeRef(["system", "hardware", "diskmounts"]); } Column { id: systemColumn + width: parent.width spacing: Theme.spacingM @@ -23,8 +24,7 @@ DankFlickable { width: parent.width height: systemInfoColumn.implicitHeight + 2 * Theme.spacingL radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, - Theme.surfaceContainer.b, 0.6) + color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.6) border.width: 0 Column { @@ -60,46 +60,37 @@ DankFlickable { } StyledText { - text: DgopService.distribution + " • " + DgopService.architecture - + " • " + DgopService.kernelVersion + text: `${DgopService.distribution} • ${DgopService.architecture} • ${DgopService.kernelVersion}` font.pixelSize: Theme.fontSizeMedium font.family: SettingsData.monoFontFamily - color: Qt.rgba(Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, 0.7) + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7) verticalAlignment: Text.AlignVCenter } StyledText { - text: "Up " + UserInfoService.uptime + " • Boot: " - + DgopService.bootTime + text: `Up ${UserInfoService.uptime} • Boot: ${DgopService.bootTime}` font.pixelSize: Theme.fontSizeSmall font.family: SettingsData.monoFontFamily - color: Qt.rgba(Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, 0.6) + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6) verticalAlignment: Text.AlignVCenter } StyledText { - text: "Load: " + DgopService.loadAverage + " • " - + DgopService.processCount + " processes, " - + DgopService.threadCount + " threads" + text: `Load: ${DgopService.loadAverage} • ${DgopService.processCount} processes, ${DgopService.threadCount} threads` font.pixelSize: Theme.fontSizeSmall font.family: SettingsData.monoFontFamily - color: Qt.rgba(Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, 0.6) + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6) verticalAlignment: Text.AlignVCenter } + } + } Rectangle { width: parent.width height: 1 - color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.2) + color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2) } Row { @@ -110,12 +101,9 @@ DankFlickable { width: (parent.width - Theme.spacingXL) / 2 height: hardwareColumn.implicitHeight + Theme.spacingL radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceContainerHigh.r, - Theme.surfaceContainerHigh.g, - Theme.surfaceContainerHigh.b, 0.4) + color: Qt.rgba(Theme.surfaceContainerHigh.r, Theme.surfaceContainerHigh.g, Theme.surfaceContainerHigh.b, 0.4) border.width: 1 - border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.1) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1) Column { id: hardwareColumn @@ -145,6 +133,7 @@ DankFlickable { color: Theme.primary anchors.verticalCenter: parent.verticalCenter } + } StyledText { @@ -164,9 +153,7 @@ DankFlickable { text: DgopService.motherboard font.pixelSize: Theme.fontSizeSmall font.family: SettingsData.monoFontFamily - color: Qt.rgba(Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, 0.8) + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.8) width: parent.width elide: Text.ElideRight wrapMode: Text.NoWrap @@ -175,30 +162,27 @@ DankFlickable { } StyledText { - text: "BIOS " + DgopService.biosVersion + text: `BIOS ${DgopService.biosVersion}` font.pixelSize: Theme.fontSizeSmall font.family: SettingsData.monoFontFamily - color: Qt.rgba(Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, 0.7) + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7) width: parent.width elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } StyledText { - text: DgopService.formatSystemMemory( - DgopService.totalMemoryKB) + " RAM" + text: `${DgopService.formatSystemMemory(DgopService.totalMemoryKB)} RAM` font.pixelSize: Theme.fontSizeSmall font.family: SettingsData.monoFontFamily - color: Qt.rgba(Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, 0.8) + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.8) width: parent.width elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } + } + } Rectangle { @@ -206,100 +190,58 @@ DankFlickable { height: gpuColumn.implicitHeight + Theme.spacingL radius: Theme.cornerRadius color: { - var baseColor = Qt.rgba( - Theme.surfaceContainerHigh.r, - Theme.surfaceContainerHigh.g, - Theme.surfaceContainerHigh.b, 0.4) - var hoverColor = Qt.rgba( - Theme.surfaceContainerHigh.r, - Theme.surfaceContainerHigh.g, - Theme.surfaceContainerHigh.b, 0.6) - - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) { - return gpuCardMouseArea.containsMouse - && DgopService.availableGpus.length - > 1 ? hoverColor : baseColor + const baseColor = Qt.rgba(Theme.surfaceContainerHigh.r, Theme.surfaceContainerHigh.g, Theme.surfaceContainerHigh.b, 0.4); + const hoverColor = Qt.rgba(Theme.surfaceContainerHigh.r, Theme.surfaceContainerHigh.g, Theme.surfaceContainerHigh.b, 0.6); + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + return gpuCardMouseArea.containsMouse && DgopService.availableGpus.length > 1 ? hoverColor : baseColor; } - var gpu = DgopService.availableGpus[Math.min( - SessionData.selectedGpuIndex, - DgopService.availableGpus.length - - 1)] - var vendor = gpu.fullName.split( - ' ')[0].toLowerCase() - var tintColor - + const gpu = DgopService.availableGpus[Math.min(SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)]; + const vendor = gpu.fullName.split(' ')[0].toLowerCase(); + let tintColor; if (vendor.includes("nvidia")) { - tintColor = Theme.success + tintColor = Theme.success; } else if (vendor.includes("amd")) { - tintColor = Theme.error + tintColor = Theme.error; } else if (vendor.includes("intel")) { - tintColor = Theme.info + tintColor = Theme.info; } else { - return gpuCardMouseArea.containsMouse - && DgopService.availableGpus.length - > 1 ? hoverColor : baseColor + return gpuCardMouseArea.containsMouse && DgopService.availableGpus.length > 1 ? hoverColor : baseColor; } - - if (gpuCardMouseArea.containsMouse - && DgopService.availableGpus.length > 1) { - return Qt.rgba( - (hoverColor.r + tintColor.r * 0.1) / 1.1, - (hoverColor.g + tintColor.g * 0.1) / 1.1, - (hoverColor.b + tintColor.b * 0.1) / 1.1, - 0.6) + if (gpuCardMouseArea.containsMouse && DgopService.availableGpus.length > 1) { + return Qt.rgba((hoverColor.r + tintColor.r * 0.1) / 1.1, (hoverColor.g + tintColor.g * 0.1) / 1.1, (hoverColor.b + tintColor.b * 0.1) / 1.1, 0.6); } else { - return Qt.rgba( - (baseColor.r + tintColor.r * 0.08) / 1.08, - (baseColor.g + tintColor.g * 0.08) / 1.08, - (baseColor.b + tintColor.b * 0.08) / 1.08, - 0.4) + return Qt.rgba((baseColor.r + tintColor.r * 0.08) / 1.08, (baseColor.g + tintColor.g * 0.08) / 1.08, (baseColor.b + tintColor.b * 0.08) / 1.08, 0.4); } } border.width: 1 border.color: { - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) { - return Qt.rgba(Theme.outline.r, - Theme.outline.g, - Theme.outline.b, 0.1) + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1); } - var gpu = DgopService.availableGpus[Math.min( - SessionData.selectedGpuIndex, - DgopService.availableGpus.length - - 1)] - var vendor = gpu.fullName.split( - ' ')[0].toLowerCase() - + const gpu = DgopService.availableGpus[Math.min(SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)]; + const vendor = gpu.fullName.split(' ')[0].toLowerCase(); if (vendor.includes("nvidia")) { - return Qt.rgba(Theme.success.r, - Theme.success.g, - Theme.success.b, 0.3) + return Qt.rgba(Theme.success.r, Theme.success.g, Theme.success.b, 0.3); } else if (vendor.includes("amd")) { - return Qt.rgba(Theme.error.r, Theme.error.g, - Theme.error.b, 0.3) + return Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.3); } else if (vendor.includes("intel")) { - return Qt.rgba(Theme.info.r, Theme.info.g, - Theme.info.b, 0.3) + return Qt.rgba(Theme.info.r, Theme.info.g, Theme.info.b, 0.3); } - - return Qt.rgba(Theme.outline.r, Theme.outline.g, - Theme.outline.b, 0.1) + return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1); } MouseArea { id: gpuCardMouseArea + anchors.fill: parent hoverEnabled: true - cursorShape: DgopService.availableGpus.length - > 1 ? Qt.PointingHandCursor : Qt.ArrowCursor + cursorShape: DgopService.availableGpus.length > 1 ? Qt.PointingHandCursor : Qt.ArrowCursor onClicked: { if (DgopService.availableGpus.length > 1) { - var nextIndex = (SessionData.selectedGpuIndex + 1) - % DgopService.availableGpus.length - SessionData.setSelectedGpuIndex(nextIndex) + const nextIndex = (SessionData.selectedGpuIndex + 1) % DgopService.availableGpus.length; + SessionData.setSelectedGpuIndex(nextIndex); } } } @@ -332,17 +274,17 @@ DankFlickable { color: Theme.secondary anchors.verticalCenter: parent.verticalCenter } + } StyledText { text: { - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) { - return "No GPUs detected" + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + return "No GPUs detected"; } - var gpu = DgopService.availableGpus[Math.min( - SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)] - return gpu.fullName + + const gpu = DgopService.availableGpus[Math.min(SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)]; + return gpu.fullName; } font.pixelSize: Theme.fontSizeSmall font.family: SettingsData.monoFontFamily @@ -356,19 +298,16 @@ DankFlickable { StyledText { text: { - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) { - return "Device: N/A" + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + return "Device: N/A"; } - var gpu = DgopService.availableGpus[Math.min( - SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)] - return "Device: " + gpu.pciId + + const gpu = DgopService.availableGpus[Math.min(SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)]; + return `Device: ${gpu.pciId}`; } font.pixelSize: Theme.fontSizeSmall font.family: SettingsData.monoFontFamily - color: Qt.rgba(Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, 0.8) + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.8) width: parent.width elide: Text.ElideRight verticalAlignment: Text.AlignVCenter @@ -377,19 +316,16 @@ DankFlickable { StyledText { text: { - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) { - return "Driver: N/A" + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + return "Driver: N/A"; } - var gpu = DgopService.availableGpus[Math.min( - SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)] - return "Driver: " + gpu.driver + + const gpu = DgopService.availableGpus[Math.min(SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)]; + return `Driver: ${gpu.driver}`; } font.pixelSize: Theme.fontSizeSmall font.family: SettingsData.monoFontFamily - color: Qt.rgba(Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, 0.8) + color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.8) width: parent.width elide: Text.ElideRight verticalAlignment: Text.AlignVCenter @@ -397,60 +333,60 @@ DankFlickable { StyledText { text: { - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) { - return "Temp: --°" + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + return "Temp: --°"; } - var gpu = DgopService.availableGpus[Math.min( - SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)] - var temp = gpu.temperature - return "Temp: " + ((temp === undefined - || temp === null - || temp === 0) ? "--°" : Math.round( - temp) + "°C") + + const gpu = DgopService.availableGpus[Math.min(SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)]; + const temp = gpu.temperature; + return `Temp: ${(temp === undefined || temp === null || temp === 0) ? '--°' : `${Math.round(temp)}°C`}`; } font.pixelSize: Theme.fontSizeSmall font.family: SettingsData.monoFontFamily color: { - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) { - return Qt.rgba(Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, 0.7) + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + return Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7); } - var gpu = DgopService.availableGpus[Math.min( - SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)] - var temp = gpu.temperature || 0 - if (temp > 80) - return Theme.error - if (temp > 60) - return Theme.warning - return Qt.rgba(Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, 0.7) + + const gpu = DgopService.availableGpus[Math.min(SessionData.selectedGpuIndex, DgopService.availableGpus.length - 1)]; + const temp = gpu.temperature || 0; + if (temp > 80) { + return Theme.error; + } + + if (temp > 60) { + return Theme.warning; + } + + return Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7); } width: parent.width elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } + } Behavior on color { ColorAnimation { duration: Theme.shortDuration } + } + } + } + } + } Rectangle { width: parent.width height: storageColumn.implicitHeight + 2 * Theme.spacingL radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, - Theme.surfaceContainer.b, 0.6) + color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.6) border.width: 0 Column { @@ -481,6 +417,7 @@ DankFlickable { color: Theme.surfaceText anchors.verticalCenter: parent.verticalCenter } + } Column { @@ -557,6 +494,7 @@ DankFlickable { elide: Text.ElideRight verticalAlignment: Text.AlignVCenter } + } Repeater { @@ -568,11 +506,7 @@ DankFlickable { width: parent.width height: 24 radius: Theme.cornerRadius - color: diskMouseArea.containsMouse ? Qt.rgba( - Theme.surfaceText.r, - Theme.surfaceText.g, - Theme.surfaceText.b, - 0.04) : "transparent" + color: diskMouseArea.containsMouse ? Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.04) : "transparent" MouseArea { id: diskMouseArea @@ -645,26 +579,35 @@ DankFlickable { font.pixelSize: Theme.fontSizeSmall font.family: SettingsData.monoFontFamily color: { - const percent = parseInt( - modelData.percent) - if (percent > 90) - return Theme.error + const percent = parseInt(modelData.percent); + if (percent > 90) { + return Theme.error; + } - if (percent > 75) - return Theme.warning + if (percent > 75) { + return Theme.warning; + } - return Theme.surfaceText + return Theme.surfaceText; } width: parent.width * 0.1 elide: Text.ElideRight anchors.verticalCenter: parent.verticalCenter verticalAlignment: Text.AlignVCenter } + } + } + } + } + } + } + } + } diff --git a/Modules/TopBar/AudioVisualization.qml b/Modules/TopBar/AudioVisualization.qml index 559342a3..8c471d4b 100644 --- a/Modules/TopBar/AudioVisualization.qml +++ b/Modules/TopBar/AudioVisualization.qml @@ -8,19 +8,21 @@ Item { readonly property MprisPlayer activePlayer: MprisController.activePlayer readonly property bool hasActiveMedia: activePlayer !== null - readonly property bool isPlaying: hasActiveMedia && activePlayer - && activePlayer.playbackState === MprisPlaybackState.Playing + readonly property bool isPlaying: hasActiveMedia && activePlayer && activePlayer.playbackState === MprisPlaybackState.Playing width: 20 height: Theme.iconSize Loader { active: isPlaying + sourceComponent: Component { Ref { service: CavaService } + } + } Timer { @@ -30,10 +32,7 @@ Item { interval: 256 repeat: true onTriggered: { - CavaService.values = [Math.random() * 40 + 10, Math.random( - ) * 60 + 20, Math.random() * 50 + 15, Math.random( - ) * 35 + 20, Math.random() * 45 + 15, Math.random( - ) * 55 + 25] + CavaService.values = [Math.random() * 40 + 10, Math.random() * 60 + 20, Math.random() * 50 + 15, Math.random() * 35 + 20, Math.random() * 45 + 15, Math.random() * 55 + 25]; } } @@ -48,15 +47,13 @@ Item { width: 2 height: { if (root.isPlaying && CavaService.values.length > index) { - const rawLevel = CavaService.values[index] || 0 - const scaledLevel = Math.sqrt( - Math.min(Math.max(rawLevel, 0), - 100) / 100) * 100 - const maxHeight = Theme.iconSize - 2 - const minHeight = 3 - return minHeight + (scaledLevel / 100) * (maxHeight - minHeight) + const rawLevel = CavaService.values[index] || 0; + const scaledLevel = Math.sqrt(Math.min(Math.max(rawLevel, 0), 100) / 100) * 100; + const maxHeight = Theme.iconSize - 2; + const minHeight = 3; + return minHeight + (scaledLevel / 100) * (maxHeight - minHeight); } - return 3 + return 3; } radius: 1.5 color: Theme.primary @@ -68,8 +65,13 @@ Item { easing.type: Easing.BezierSpline easing.bezierCurve: Anims.standardDecel } + } + } + } + } + } diff --git a/Modules/TopBar/Battery.qml b/Modules/TopBar/Battery.qml index 776c45e9..98e5d669 100644 --- a/Modules/TopBar/Battery.qml +++ b/Modules/TopBar/Battery.qml @@ -15,113 +15,156 @@ Rectangle { property real barHeight: 48 readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30)) - signal toggleBatteryPopup + signal toggleBatteryPopup() width: batteryContent.implicitWidth + horizontalPadding * 2 height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = batteryArea.containsMouse - || batteryPopupVisible ? Theme.primaryPressed : Theme.secondaryHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) + return "transparent"; + + const baseColor = batteryArea.containsMouse || batteryPopupVisible ? Theme.primaryPressed : Theme.secondaryHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } visible: true Row { id: batteryContent + anchors.centerIn: parent spacing: SettingsData.topBarNoBackground ? 1 : 2 DankIcon { name: { - if (!BatteryService.batteryAvailable) - return "power" + if (!BatteryService.batteryAvailable) { + return "power"; + } if (BatteryService.isCharging) { - if (BatteryService.batteryLevel >= 90) - return "battery_charging_full" - if (BatteryService.batteryLevel >= 80) - return "battery_charging_90" - if (BatteryService.batteryLevel >= 60) - return "battery_charging_80" - if (BatteryService.batteryLevel >= 50) - return "battery_charging_60" - if (BatteryService.batteryLevel >= 30) - return "battery_charging_50" - if (BatteryService.batteryLevel >= 20) - return "battery_charging_30" - return "battery_charging_20" - } + if (BatteryService.batteryLevel >= 90) { + return "battery_charging_full"; + } + if (BatteryService.batteryLevel >= 80) { + return "battery_charging_90"; + } + + if (BatteryService.batteryLevel >= 60) { + return "battery_charging_80"; + } + + if (BatteryService.batteryLevel >= 50) { + return "battery_charging_60"; + } + + if (BatteryService.batteryLevel >= 30) { + return "battery_charging_50"; + } + + if (BatteryService.batteryLevel >= 20) { + return "battery_charging_30"; + } + + return "battery_charging_20"; + } // Check if plugged in but not charging (like at 80% charge limit) if (BatteryService.isPluggedIn) { - if (BatteryService.batteryLevel >= 90) - return "battery_charging_full" - if (BatteryService.batteryLevel >= 80) - return "battery_charging_90" - if (BatteryService.batteryLevel >= 60) - return "battery_charging_80" - if (BatteryService.batteryLevel >= 50) - return "battery_charging_60" - if (BatteryService.batteryLevel >= 30) - return "battery_charging_50" - if (BatteryService.batteryLevel >= 20) - return "battery_charging_30" - return "battery_charging_20" + if (BatteryService.batteryLevel >= 90) { + return "battery_charging_full"; + } + + if (BatteryService.batteryLevel >= 80) { + return "battery_charging_90"; + } + + if (BatteryService.batteryLevel >= 60) { + return "battery_charging_80"; + } + + if (BatteryService.batteryLevel >= 50) { + return "battery_charging_60"; + } + + if (BatteryService.batteryLevel >= 30) { + return "battery_charging_50"; + } + + if (BatteryService.batteryLevel >= 20) { + return "battery_charging_30"; + } + + return "battery_charging_20"; + } + // On battery power + if (BatteryService.batteryLevel >= 95) { + return "battery_full"; } - // On battery power - if (BatteryService.batteryLevel >= 95) - return "battery_full" - if (BatteryService.batteryLevel >= 85) - return "battery_6_bar" - if (BatteryService.batteryLevel >= 70) - return "battery_5_bar" - if (BatteryService.batteryLevel >= 55) - return "battery_4_bar" - if (BatteryService.batteryLevel >= 40) - return "battery_3_bar" - if (BatteryService.batteryLevel >= 25) - return "battery_2_bar" - return "battery_1_bar" + if (BatteryService.batteryLevel >= 85) { + return "battery_6_bar"; + } + + if (BatteryService.batteryLevel >= 70) { + return "battery_5_bar"; + } + + if (BatteryService.batteryLevel >= 55) { + return "battery_4_bar"; + } + + if (BatteryService.batteryLevel >= 40) { + return "battery_3_bar"; + } + + if (BatteryService.batteryLevel >= 25) { + return "battery_2_bar"; + } + + return "battery_1_bar"; } size: Theme.iconSize - 6 color: { - if (!BatteryService.batteryAvailable) - return Theme.surfaceText + if (!BatteryService.batteryAvailable) { + return Theme.surfaceText; + } - if (BatteryService.isLowBattery && !BatteryService.isCharging) - return Theme.error + if (BatteryService.isLowBattery && !BatteryService.isCharging) { + return Theme.error; + } - if (BatteryService.isCharging || BatteryService.isPluggedIn) - return Theme.primary + if (BatteryService.isCharging || BatteryService.isPluggedIn) { + return Theme.primary; + } - return Theme.surfaceText + return Theme.surfaceText; } anchors.verticalCenter: parent.verticalCenter } StyledText { - text: BatteryService.batteryLevel + "%" + text: `${BatteryService.batteryLevel}%` font.pixelSize: Theme.fontSizeSmall font.weight: Font.Medium color: { - if (!BatteryService.batteryAvailable) - return Theme.surfaceText + if (!BatteryService.batteryAvailable) { + return Theme.surfaceText; + } - if (BatteryService.isLowBattery && !BatteryService.isCharging) - return Theme.error + if (BatteryService.isLowBattery && !BatteryService.isCharging) { + return Theme.error; + } - if (BatteryService.isCharging) - return Theme.primary + if (BatteryService.isCharging) { + return Theme.primary; + } - return Theme.surfaceText + return Theme.surfaceText; } anchors.verticalCenter: parent.verticalCenter visible: BatteryService.batteryAvailable } + } MouseArea { @@ -132,15 +175,13 @@ Rectangle { cursorShape: Qt.PointingHandCursor onPressed: { if (popupTarget && popupTarget.setTriggerPosition) { - var globalPos = mapToGlobal(0, 0) - var currentScreen = parentScreen || Screen - var screenX = currentScreen.x || 0 - var relativeX = globalPos.x - screenX - popupTarget.setTriggerPosition( - relativeX, barHeight + Theme.spacingXS, - width, section, currentScreen) + const globalPos = mapToGlobal(0, 0); + const currentScreen = parentScreen || Screen; + const screenX = currentScreen.x || 0; + const relativeX = globalPos.x - screenX; + popupTarget.setTriggerPosition(relativeX, barHeight + Theme.spacingXS, width, section, currentScreen); } - toggleBatteryPopup() + toggleBatteryPopup(); } } @@ -168,30 +209,33 @@ Rectangle { text: { if (!BatteryService.batteryAvailable) { - if (typeof PowerProfiles === "undefined") - return "Power Management" + if (typeof PowerProfiles === "undefined") { + return "Power Management"; + } switch (PowerProfiles.profile) { case PowerProfile.PowerSaver: - return "Power Profile: Power Saver" + return "Power Profile: Power Saver"; case PowerProfile.Performance: - return "Power Profile: Performance" + return "Power Profile: Performance"; default: - return "Power Profile: Balanced" + return "Power Profile: Balanced"; } } - let status = BatteryService.batteryStatus - let level = BatteryService.batteryLevel + "%" - let time = BatteryService.formatTimeRemaining() - if (time !== "Unknown") - return status + " • " + level + " • " + time - else - return status + " • " + level + const status = BatteryService.batteryStatus; + const level = `${BatteryService.batteryLevel}%`; + const time = BatteryService.formatTimeRemaining(); + if (time !== "Unknown") { + return `${status} • ${level} • ${time}`; + } else { + return `${status} • ${level}`; + } } font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceText horizontalAlignment: Text.AlignHCenter } + } Behavior on opacity { @@ -199,7 +243,9 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } + } Behavior on color { @@ -207,5 +253,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } + } diff --git a/Modules/TopBar/BatteryPopout.qml b/Modules/TopBar/BatteryPopout.qml index ad6640c5..4bde89d0 100644 --- a/Modules/TopBar/BatteryPopout.qml +++ b/Modules/TopBar/BatteryPopout.qml @@ -15,28 +15,31 @@ DankPopout { property var triggerScreen: null function setTriggerPosition(x, y, width, section, screen) { - triggerX = x - triggerY = y - triggerWidth = width - triggerSection = section - triggerScreen = screen + triggerX = x; + triggerY = y; + triggerWidth = width; + triggerSection = section; + triggerScreen = screen; } function isActiveProfile(profile) { - if (typeof PowerProfiles === "undefined") - return false + if (typeof PowerProfiles === "undefined") { + return false; + } - return PowerProfiles.profile === profile + return PowerProfiles.profile === profile; } function setProfile(profile) { if (typeof PowerProfiles === "undefined") { - ToastService.showError("power-profiles-daemon not available") - return + ToastService.showError("power-profiles-daemon not available"); + return ; } - PowerProfiles.profile = profile - if (PowerProfiles.profile !== profile) - ToastService.showError("Failed to set power profile") + PowerProfiles.profile = profile; + if (PowerProfiles.profile !== profile) { + ToastService.showError("Failed to set power profile"); + } + } popupWidth: 400 @@ -62,26 +65,29 @@ DankPopout { antialiasing: true smooth: true focus: true - Component.onCompleted: { - if (root.shouldBeVisible) - forceActiveFocus() - } + if (root.shouldBeVisible) { + forceActiveFocus(); + } - Keys.onPressed: function (event) { + } + Keys.onPressed: function(event) { if (event.key === Qt.Key_Escape) { - root.close() - event.accepted = true + root.close(); + event.accepted = true; } } Connections { function onShouldBeVisibleChanged() { - if (root.shouldBeVisible) - Qt.callLater(function () { - batteryContent.forceActiveFocus() - }) + if (root.shouldBeVisible) { + Qt.callLater(function() { + batteryContent.forceActiveFocus(); + }); + } + } + target: root } @@ -116,6 +122,7 @@ DankPopout { Column { id: contentColumn + anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top @@ -156,23 +163,21 @@ DankPopout { hoverEnabled: true cursorShape: Qt.PointingHandCursor onPressed: { - root.close() + root.close(); } } + } + } Rectangle { width: parent.width height: 80 radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceVariant.r, - Theme.surfaceVariant.g, - Theme.surfaceVariant.b, - Theme.getContentBackgroundAlpha() * 0.4) + color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, Theme.getContentBackgroundAlpha() * 0.4) border.color: BatteryService.isCharging ? Theme.primary : (BatteryService.isLowBattery ? Theme.error : Theme.outlineMedium) - border.width: BatteryService.isCharging - || BatteryService.isLowBattery ? 2 : 1 + border.width: BatteryService.isCharging || BatteryService.isLowBattery ? 2 : 1 visible: BatteryService.batteryAvailable Row { @@ -184,67 +189,99 @@ DankPopout { DankIcon { name: { if (!BatteryService.batteryAvailable) - return "power" + return "power"; // Check if plugged in but not charging (like at 80% charge limit) - if (!BatteryService.isCharging - && BatteryService.isPluggedIn) { - if (BatteryService.batteryLevel >= 90) - return "battery_charging_full" - if (BatteryService.batteryLevel >= 80) - return "battery_charging_90" - if (BatteryService.batteryLevel >= 60) - return "battery_charging_80" - if (BatteryService.batteryLevel >= 50) - return "battery_charging_60" - if (BatteryService.batteryLevel >= 30) - return "battery_charging_50" - if (BatteryService.batteryLevel >= 20) - return "battery_charging_30" - return "battery_charging_20" - } + if (!BatteryService.isCharging && BatteryService.isPluggedIn) { + if (BatteryService.batteryLevel >= 90) { + return "battery_charging_full"; + } + if (BatteryService.batteryLevel >= 80) { + return "battery_charging_90"; + } + + if (BatteryService.batteryLevel >= 60) { + return "battery_charging_80"; + } + + if (BatteryService.batteryLevel >= 50) { + return "battery_charging_60"; + } + + if (BatteryService.batteryLevel >= 30) { + return "battery_charging_50"; + } + + if (BatteryService.batteryLevel >= 20) { + return "battery_charging_30"; + } + + return "battery_charging_20"; + } if (BatteryService.isCharging) { - if (BatteryService.batteryLevel >= 90) - return "battery_charging_full" - if (BatteryService.batteryLevel >= 80) - return "battery_charging_90" - if (BatteryService.batteryLevel >= 60) - return "battery_charging_80" - if (BatteryService.batteryLevel >= 50) - return "battery_charging_60" - if (BatteryService.batteryLevel >= 30) - return "battery_charging_50" - if (BatteryService.batteryLevel >= 20) - return "battery_charging_30" - return "battery_charging_20" + if (BatteryService.batteryLevel >= 90) { + return "battery_charging_full"; + } + + if (BatteryService.batteryLevel >= 80) { + return "battery_charging_90"; + } + + if (BatteryService.batteryLevel >= 60) { + return "battery_charging_80"; + } + + if (BatteryService.batteryLevel >= 50) { + return "battery_charging_60"; + } + + if (BatteryService.batteryLevel >= 30) { + return "battery_charging_50"; + } + + if (BatteryService.batteryLevel >= 20) { + return "battery_charging_30"; + } + + return "battery_charging_20"; } else { - if (BatteryService.batteryLevel >= 95) - return "battery_full" - if (BatteryService.batteryLevel >= 85) - return "battery_6_bar" - if (BatteryService.batteryLevel >= 70) - return "battery_5_bar" - if (BatteryService.batteryLevel >= 55) - return "battery_4_bar" - if (BatteryService.batteryLevel >= 40) - return "battery_3_bar" - if (BatteryService.batteryLevel >= 25) - return "battery_2_bar" - return "battery_1_bar" + if (BatteryService.batteryLevel >= 95) { + return "battery_full"; + } + + if (BatteryService.batteryLevel >= 85) { + return "battery_6_bar"; + } + + if (BatteryService.batteryLevel >= 70) { + return "battery_5_bar"; + } + + if (BatteryService.batteryLevel >= 55) { + return "battery_4_bar"; + } + + if (BatteryService.batteryLevel >= 40) { + return "battery_3_bar"; + } + + if (BatteryService.batteryLevel >= 25) { + return "battery_2_bar"; + } + + return "battery_1_bar"; } } size: Theme.iconSizeLarge color: { - if (BatteryService.isLowBattery - && !BatteryService.isCharging) - return Theme.error + if (BatteryService.isLowBattery && !BatteryService.isCharging) + return Theme.error; - if (BatteryService.isCharging - || BatteryService.isPluggedIn) - return Theme.primary + if (BatteryService.isCharging || BatteryService.isPluggedIn) + return Theme.primary; - return Theme.surfaceText + return Theme.surfaceText; } anchors.verticalCenter: parent.verticalCenter } @@ -257,17 +294,18 @@ DankPopout { spacing: Theme.spacingM StyledText { - text: BatteryService.batteryLevel + "%" + text: `${BatteryService.batteryLevel}%` font.pixelSize: Theme.fontSizeLarge color: { - if (BatteryService.isLowBattery - && !BatteryService.isCharging) - return Theme.error + if (BatteryService.isLowBattery && !BatteryService.isCharging) { + return Theme.error; + } - if (BatteryService.isCharging) - return Theme.primary + if (BatteryService.isCharging) { + return Theme.primary; + } - return Theme.surfaceText + return Theme.surfaceText; } font.weight: Font.Bold } @@ -276,44 +314,47 @@ DankPopout { text: BatteryService.batteryStatus font.pixelSize: Theme.fontSizeMedium color: { - if (BatteryService.isLowBattery - && !BatteryService.isCharging) - return Theme.error + if (BatteryService.isLowBattery && !BatteryService.isCharging) { + return Theme.error; + } - if (BatteryService.isCharging) - return Theme.primary + if (BatteryService.isCharging) { + return Theme.primary; + } - return Theme.surfaceText + return Theme.surfaceText; } font.weight: Font.Medium anchors.verticalCenter: parent.verticalCenter } + } StyledText { text: { - let time = BatteryService.formatTimeRemaining() - if (time !== "Unknown") - return BatteryService.isCharging ? "Time until full: " + time : "Time remaining: " + time + const time = BatteryService.formatTimeRemaining(); + if (time !== "Unknown") { + return BatteryService.isCharging ? `Time until full: ${time}` : `Time remaining: ${time}`; + } - return "" + return ""; } font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceTextMedium visible: text.length > 0 } + } + } + } Rectangle { width: parent.width height: 80 radius: Theme.cornerRadius - color: Qt.rgba(Theme.surfaceVariant.r, - Theme.surfaceVariant.g, - Theme.surfaceVariant.b, - Theme.getContentBackgroundAlpha() * 0.4) + color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, Theme.getContentBackgroundAlpha() * 0.4) border.color: Theme.outlineMedium border.width: 1 visible: !BatteryService.batteryAvailable @@ -345,8 +386,11 @@ DankPopout { font.pixelSize: Theme.fontSizeMedium color: Theme.surfaceTextMedium } + } + } + } Column { @@ -380,14 +424,15 @@ DankPopout { text: BatteryService.batteryHealth font.pixelSize: Theme.fontSizeMedium color: { - if (BatteryService.batteryHealth === "N/A") - return Theme.surfaceText + if (BatteryService.batteryHealth === "N/A") { + return Theme.surfaceText; + } - var healthNum = parseInt( - BatteryService.batteryHealth) - return healthNum < 80 ? Theme.error : Theme.surfaceText + const healthNum = parseInt(BatteryService.batteryHealth); + return healthNum < 80 ? Theme.error : Theme.surfaceText; } } + } Column { @@ -402,14 +447,15 @@ DankPopout { } StyledText { - text: BatteryService.batteryCapacity - > 0 ? BatteryService.batteryCapacity.toFixed( - 1) + " Wh" : "Unknown" + text: BatteryService.batteryCapacity > 0 ? `${BatteryService.batteryCapacity.toFixed(1)} Wh` : "Unknown" font.pixelSize: Theme.fontSizeMedium color: Theme.surfaceText } + } + } + } Column { @@ -436,10 +482,8 @@ DankPopout { height: 50 radius: Theme.cornerRadius color: profileArea.containsMouse ? Theme.primaryHoverLight : (root.isActiveProfile(modelData) ? Theme.primaryPressed : Theme.surfaceLight) - border.color: root.isActiveProfile( - modelData) ? Theme.primary : Theme.outlineLight - border.width: root.isActiveProfile( - modelData) ? 2 : 1 + border.color: root.isActiveProfile(modelData) ? Theme.primary : Theme.outlineLight + border.width: root.isActiveProfile(modelData) ? 2 : 1 Row { anchors.left: parent.left @@ -448,11 +492,9 @@ DankPopout { spacing: Theme.spacingM DankIcon { - name: Theme.getPowerProfileIcon( - modelData) + name: Theme.getPowerProfileIcon(modelData) size: Theme.iconSize - color: root.isActiveProfile( - modelData) ? Theme.primary : Theme.surfaceText + color: root.isActiveProfile(modelData) ? Theme.primary : Theme.surfaceText anchors.verticalCenter: parent.verticalCenter } @@ -461,22 +503,20 @@ DankPopout { anchors.verticalCenter: parent.verticalCenter StyledText { - text: Theme.getPowerProfileLabel( - modelData) + text: Theme.getPowerProfileLabel(modelData) font.pixelSize: Theme.fontSizeMedium - color: root.isActiveProfile( - modelData) ? Theme.primary : Theme.surfaceText - font.weight: root.isActiveProfile( - modelData) ? Font.Medium : Font.Normal + color: root.isActiveProfile(modelData) ? Theme.primary : Theme.surfaceText + font.weight: root.isActiveProfile(modelData) ? Font.Medium : Font.Normal } StyledText { - text: Theme.getPowerProfileDescription( - modelData) + text: Theme.getPowerProfileDescription(modelData) font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceTextMedium } + } + } MouseArea { @@ -486,12 +526,16 @@ DankPopout { hoverEnabled: true cursorShape: Qt.PointingHandCursor onPressed: { - root.setProfile(modelData) + root.setProfile(modelData); } } + } + } + } + } Rectangle { @@ -501,9 +545,7 @@ DankPopout { color: Theme.errorHover border.color: Theme.primarySelected border.width: 1 - visible: (typeof PowerProfiles !== "undefined") - && PowerProfiles.degradationReason - !== PerformanceDegradationReason.None + visible: (typeof PowerProfiles !== "undefined") && PowerProfiles.degradationReason !== PerformanceDegradationReason.None Row { anchors.left: parent.left @@ -530,17 +572,21 @@ DankPopout { } StyledText { - text: (typeof PowerProfiles - !== "undefined") ? PerformanceDegradationReason.toString( - PowerProfiles.degradationReason) : "" + text: (typeof PowerProfiles !== "undefined") ? PerformanceDegradationReason.toString(PowerProfiles.degradationReason) : "" font.pixelSize: Theme.fontSizeSmall - color: Qt.rgba(Theme.error.r, Theme.error.g, - Theme.error.b, 0.8) + color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.8) } + } + } + } + } + } + } + } diff --git a/Modules/TopBar/Clock.qml b/Modules/TopBar/Clock.qml index 6e3a7e6a..fb71d4af 100644 --- a/Modules/TopBar/Clock.qml +++ b/Modules/TopBar/Clock.qml @@ -21,10 +21,12 @@ Rectangle { height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" + if (SettingsData.topBarNoBackground) { + return "transparent" + } + const baseColor = clockMouseArea.containsMouse ? Theme.primaryHover : Theme.surfaceTextHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency) } Component.onCompleted: { root.currentDate = systemClock.date @@ -39,7 +41,7 @@ Rectangle { StyledText { text: { if (SettingsData.use24HourClock) { - return root.currentDate.toLocaleTimeString(Qt.locale(), Locale.ShortFormat) + return root.currentDate.toLocaleTimeString(Qt.locale(), "HH:mm") } else { return root.currentDate.toLocaleTimeString(Qt.locale(), "h:mm AP") } @@ -62,6 +64,7 @@ Rectangle { if (SettingsData.clockDateFormat && SettingsData.clockDateFormat.length > 0) { return root.currentDate.toLocaleDateString(Qt.locale(), SettingsData.clockDateFormat) } + return root.currentDate.toLocaleDateString(Qt.locale(), "ddd d") } font.pixelSize: Theme.fontSizeMedium - 1 @@ -86,13 +89,11 @@ Rectangle { cursorShape: Qt.PointingHandCursor onPressed: { if (popupTarget && popupTarget.setTriggerPosition) { - var globalPos = mapToGlobal(0, 0) - var currentScreen = parentScreen || Screen - var screenX = currentScreen.x || 0 - var relativeX = globalPos.x - screenX - popupTarget.setTriggerPosition( - relativeX, barHeight + Theme.spacingXS, - width, section, currentScreen) + const globalPos = mapToGlobal(0, 0) + const currentScreen = parentScreen || Screen + const screenX = currentScreen.x || 0 + const relativeX = globalPos.x - screenX + popupTarget.setTriggerPosition(relativeX, barHeight + Theme.spacingXS, width, section, currentScreen) } root.clockClicked() } diff --git a/Modules/TopBar/ControlCenterButton.qml b/Modules/TopBar/ControlCenterButton.qml index 00dff339..26456450 100644 --- a/Modules/TopBar/ControlCenterButton.qml +++ b/Modules/TopBar/ControlCenterButton.qml @@ -11,7 +11,6 @@ Rectangle { property var popupTarget: null property var parentScreen: null property var widgetData: null - property bool showNetworkIcon: SettingsData.controlCenterShowNetworkIcon property bool showBluetoothIcon: SettingsData.controlCenterShowBluetoothIcon property bool showAudioIcon: SettingsData.controlCenterShowAudioIcon @@ -19,17 +18,18 @@ Rectangle { property real barHeight: 48 readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30)) - signal clicked + signal clicked() width: controlIndicators.implicitWidth + horizontalPadding * 2 height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = controlCenterArea.containsMouse - || root.isActive ? Theme.primaryPressed : Theme.secondaryHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = controlCenterArea.containsMouse || root.isActive ? Theme.primaryPressed : Theme.secondaryHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } Row { @@ -40,21 +40,29 @@ Rectangle { DankIcon { id: networkIcon + name: { - if (NetworkService.wifiToggling) - return "sync" - if (NetworkService.networkStatus === "ethernet") - return "lan" - return NetworkService.wifiSignalIcon + if (NetworkService.wifiToggling) { + return "sync"; + } + + if (NetworkService.networkStatus === "ethernet") { + return "lan"; + } + + return NetworkService.wifiSignalIcon; } size: Theme.iconSize - 8 color: { - if (NetworkService.wifiToggling) return Theme.primary - return NetworkService.networkStatus !== "disconnected" ? Theme.primary : Theme.outlineButton + if (NetworkService.wifiToggling) { + return Theme.primary; + } + + return NetworkService.networkStatus !== "disconnected" ? Theme.primary : Theme.outlineButton; } anchors.verticalCenter: parent.verticalCenter visible: root.showNetworkIcon - + RotationAnimation on rotation { running: NetworkService.wifiToggling loops: Animation.Infinite @@ -62,10 +70,12 @@ Rectangle { to: 360 duration: 1000 } + } DankIcon { id: bluetoothIcon + name: "bluetooth" size: Theme.iconSize - 8 color: BluetoothService.enabled ? Theme.primary : Theme.outlineButton @@ -85,15 +95,15 @@ Rectangle { name: { if (AudioService.sink && AudioService.sink.audio) { - if (AudioService.sink.audio.muted - || AudioService.sink.audio.volume === 0) - return "volume_off" - else if (AudioService.sink.audio.volume * 100 < 33) - return "volume_down" - else - return "volume_up" + if (AudioService.sink.audio.muted || AudioService.sink.audio.volume === 0) { + return "volume_off"; + } else if (AudioService.sink.audio.volume * 100 < 33) { + return "volume_down"; + } else { + return "volume_up"; + } } - return "volume_up" + return "volume_up"; } size: Theme.iconSize - 8 color: Theme.surfaceText @@ -106,25 +116,24 @@ Rectangle { anchors.fill: parent hoverEnabled: true acceptedButtons: Qt.NoButton - onWheel: function (wheelEvent) { - let delta = wheelEvent.angleDelta.y - let currentVolume = (AudioService.sink - && AudioService.sink.audio - && AudioService.sink.audio.volume * 100) - || 0 - let newVolume - if (delta > 0) - newVolume = Math.min(100, currentVolume + 5) - else - newVolume = Math.max(0, currentVolume - 5) - if (AudioService.sink && AudioService.sink.audio) { - AudioService.sink.audio.muted = false - AudioService.sink.audio.volume = newVolume / 100 - AudioService.volumeChanged() + onWheel: function(wheelEvent) { + let delta = wheelEvent.angleDelta.y; + let currentVolume = (AudioService.sink && AudioService.sink.audio && AudioService.sink.audio.volume * 100) || 0; + let newVolume; + if (delta > 0) { + newVolume = Math.min(100, currentVolume + 5); + } else { + newVolume = Math.max(0, currentVolume - 5); } - wheelEvent.accepted = true + if (AudioService.sink && AudioService.sink.audio) { + AudioService.sink.audio.muted = false; + AudioService.sink.audio.volume = newVolume / 100; + AudioService.volumeChanged(); + } + wheelEvent.accepted = true; } } + } DankIcon { @@ -143,6 +152,7 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter visible: !root.showNetworkIcon && !root.showBluetoothIcon && !root.showAudioIcon } + } MouseArea { @@ -153,16 +163,13 @@ Rectangle { cursorShape: Qt.PointingHandCursor onPressed: { if (popupTarget && popupTarget.setTriggerPosition) { - var globalPos = mapToGlobal(0, 0) - var currentScreen = parentScreen || Screen - var screenX = currentScreen.x || 0 - var relativeX = globalPos.x - screenX - popupTarget.setTriggerPosition( - relativeX, barHeight + Theme.spacingXS, - width, section, currentScreen) + const globalPos = mapToGlobal(0, 0); + const currentScreen = parentScreen || Screen; + const screenX = currentScreen.x || 0; + const relativeX = globalPos.x - screenX; + popupTarget.setTriggerPosition(relativeX, barHeight + Theme.spacingXS, width, section, currentScreen); } - - root.clicked() + root.clicked(); } } @@ -171,5 +178,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } + } diff --git a/Modules/TopBar/CpuMonitor.qml b/Modules/TopBar/CpuMonitor.qml index 8b5baa91..e8543333 100644 --- a/Modules/TopBar/CpuMonitor.qml +++ b/Modules/TopBar/CpuMonitor.qml @@ -21,16 +21,18 @@ Rectangle { height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = cpuArea.containsMouse ? Theme.primaryPressed : Theme.secondaryHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = cpuArea.containsMouse ? Theme.primaryPressed : Theme.secondaryHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } Component.onCompleted: { - DgopService.addRef(["cpu"]) + DgopService.addRef(["cpu"]); } Component.onDestruction: { - DgopService.removeRef(["cpu"]) + DgopService.removeRef(["cpu"]); } MouseArea { @@ -41,22 +43,23 @@ Rectangle { cursorShape: Qt.PointingHandCursor onPressed: { if (popupTarget && popupTarget.setTriggerPosition) { - var globalPos = mapToGlobal(0, 0) - var currentScreen = parentScreen || Screen - var screenX = currentScreen.x || 0 - var relativeX = globalPos.x - screenX - popupTarget.setTriggerPosition( - relativeX, barHeight + Theme.spacingXS, - width, section, currentScreen) + const globalPos = mapToGlobal(0, 0); + const currentScreen = parentScreen || Screen; + const screenX = currentScreen.x || 0; + const relativeX = globalPos.x - screenX; + popupTarget.setTriggerPosition(relativeX, barHeight + Theme.spacingXS, width, section, currentScreen); } - DgopService.setSortBy("cpu") - if (root.toggleProcessList) - root.toggleProcessList() + DgopService.setSortBy("cpu"); + if (root.toggleProcessList) { + root.toggleProcessList(); + } + } } Row { id: cpuContent + anchors.centerIn: parent spacing: 3 @@ -64,30 +67,33 @@ Rectangle { name: "memory" size: Theme.iconSize - 8 color: { - if (DgopService.cpuUsage > 80) - return Theme.tempDanger + if (DgopService.cpuUsage > 80) { + return Theme.tempDanger; + } - if (DgopService.cpuUsage > 60) - return Theme.tempWarning + if (DgopService.cpuUsage > 60) { + return Theme.tempWarning; + } - return Theme.surfaceText + return Theme.surfaceText; } anchors.verticalCenter: parent.verticalCenter } StyledText { text: { - if (DgopService.cpuUsage === undefined - || DgopService.cpuUsage === null - || DgopService.cpuUsage === 0) { - return "--%" + if (DgopService.cpuUsage === undefined || DgopService.cpuUsage === null || DgopService.cpuUsage === 0) { + return "--%"; } - return DgopService.cpuUsage.toFixed(0) + "%" + + return DgopService.cpuUsage.toFixed(0) + "%"; } font.pixelSize: Theme.fontSizeSmall font.weight: Font.Medium color: Theme.surfaceText anchors.verticalCenter: parent.verticalCenter } + } + } diff --git a/Modules/TopBar/CpuTemperature.qml b/Modules/TopBar/CpuTemperature.qml index 8d6d2fec..19a0beb8 100644 --- a/Modules/TopBar/CpuTemperature.qml +++ b/Modules/TopBar/CpuTemperature.qml @@ -21,16 +21,18 @@ Rectangle { height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = cpuTempArea.containsMouse ? Theme.primaryPressed : Theme.secondaryHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = cpuTempArea.containsMouse ? Theme.primaryPressed : Theme.secondaryHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } Component.onCompleted: { - DgopService.addRef(["cpu"]) + DgopService.addRef(["cpu"]); } Component.onDestruction: { - DgopService.removeRef(["cpu"]) + DgopService.removeRef(["cpu"]); } MouseArea { @@ -41,22 +43,23 @@ Rectangle { cursorShape: Qt.PointingHandCursor onPressed: { if (popupTarget && popupTarget.setTriggerPosition) { - var globalPos = mapToGlobal(0, 0) - var currentScreen = parentScreen || Screen - var screenX = currentScreen.x || 0 - var relativeX = globalPos.x - screenX - popupTarget.setTriggerPosition( - relativeX, barHeight + Theme.spacingXS, - width, section, currentScreen) + const globalPos = mapToGlobal(0, 0); + const currentScreen = parentScreen || Screen; + const screenX = currentScreen.x || 0; + const relativeX = globalPos.x - screenX; + popupTarget.setTriggerPosition(relativeX, barHeight + Theme.spacingXS, width, section, currentScreen); } - DgopService.setSortBy("cpu") - if (root.toggleProcessList) - root.toggleProcessList() + DgopService.setSortBy("cpu"); + if (root.toggleProcessList) { + root.toggleProcessList(); + } + } } Row { id: cpuTempContent + anchors.centerIn: parent spacing: 3 @@ -64,31 +67,33 @@ Rectangle { name: "memory" size: Theme.iconSize - 8 color: { - if (DgopService.cpuTemperature > 85) - return Theme.tempDanger + if (DgopService.cpuTemperature > 85) { + return Theme.tempDanger; + } - if (DgopService.cpuTemperature > 69) - return Theme.tempWarning + if (DgopService.cpuTemperature > 69) { + return Theme.tempWarning; + } - return Theme.surfaceText + return Theme.surfaceText; } anchors.verticalCenter: parent.verticalCenter } StyledText { text: { - if (DgopService.cpuTemperature === undefined - || DgopService.cpuTemperature === null - || DgopService.cpuTemperature < 0) { - return "--°" + if (DgopService.cpuTemperature === undefined || DgopService.cpuTemperature === null || DgopService.cpuTemperature < 0) { + return "--°"; } - return Math.round(DgopService.cpuTemperature) + "°" + + return Math.round(DgopService.cpuTemperature) + "°"; } font.pixelSize: Theme.fontSizeSmall font.weight: Font.Medium color: Theme.surfaceText anchors.verticalCenter: parent.verticalCenter } + } Behavior on color { @@ -96,5 +101,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } + } diff --git a/Modules/TopBar/FocusedApp.qml b/Modules/TopBar/FocusedApp.qml index 85731777..eb44ed69 100644 --- a/Modules/TopBar/FocusedApp.qml +++ b/Modules/TopBar/FocusedApp.qml @@ -1,6 +1,6 @@ +import QtQuick import Quickshell import Quickshell.Wayland -import QtQuick import qs.Common import qs.Services import qs.Widgets @@ -17,19 +17,20 @@ Rectangle { readonly property int maxCompactWidth: 288 readonly property Toplevel activeWindow: ToplevelManager.activeToplevel - width: compactMode ? Math.min(baseWidth, - maxCompactWidth) : Math.min(baseWidth, - maxNormalWidth) + width: compactMode ? Math.min(baseWidth, maxCompactWidth) : Math.min(baseWidth, maxNormalWidth) height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (!activeWindow || !activeWindow.title) - return "transparent" - - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = mouseArea.containsMouse ? Theme.primaryHover : Theme.surfaceTextHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (!activeWindow || !activeWindow.title) { + return "transparent"; + } + + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = mouseArea.containsMouse ? Theme.primaryHover : Theme.surfaceTextHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } clip: true visible: activeWindow && activeWindow.title @@ -44,12 +45,12 @@ Rectangle { id: appText text: { - if (!activeWindow || !activeWindow.appId) - return "" + if (!activeWindow || !activeWindow.appId) { + return ""; + } - var desktopEntry = DesktopEntries.heuristicLookup(activeWindow.appId) - return desktopEntry - && desktopEntry.name ? desktopEntry.name : activeWindow.appId + const desktopEntry = DesktopEntries.heuristicLookup(activeWindow.appId); + return desktopEntry && desktopEntry.name ? desktopEntry.name : activeWindow.appId; } font.pixelSize: Theme.fontSizeSmall font.weight: Font.Medium @@ -73,24 +74,22 @@ Rectangle { id: titleText text: { - var title = activeWindow && activeWindow.title ? activeWindow.title : "" - var appName = appText.text - - if (!title || !appName) - return title + const title = activeWindow && activeWindow.title ? activeWindow.title : ""; + const appName = appText.text; + if (!title || !appName) { + return title; + } // Remove app name from end of title if it exists there if (title.endsWith(" - " + appName)) { - return title.substring( - 0, title.length - (" - " + appName).length) - } - if (title.endsWith(appName)) { - return title.substring( - 0, title.length - appName.length).replace( - / - $/, "") + return title.substring(0, title.length - (" - " + appName).length); } - return title + if (title.endsWith(appName)) { + return title.substring(0, title.length - appName.length).replace(/ - $/, ""); + } + + return title; } font.pixelSize: Theme.fontSizeSmall font.weight: Font.Medium @@ -101,6 +100,7 @@ Rectangle { width: Math.min(implicitWidth, compactMode ? 280 : 250) visible: text.length > 0 } + } MouseArea { @@ -115,6 +115,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } Behavior on width { @@ -122,5 +123,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } + } diff --git a/Modules/TopBar/GpuTemperature.qml b/Modules/TopBar/GpuTemperature.qml index 9d2b6e72..0c00322a 100644 --- a/Modules/TopBar/GpuTemperature.qml +++ b/Modules/TopBar/GpuTemperature.qml @@ -16,64 +16,97 @@ Rectangle { property var widgetData: null property real barHeight: 48 property real widgetHeight: 30 - property int selectedGpuIndex: (widgetData && widgetData.selectedGpuIndex - !== undefined) ? widgetData.selectedGpuIndex : 0 - - Connections { - target: SettingsData - function onWidgetDataChanged() { - // Force property re-evaluation by triggering change detection - root.selectedGpuIndex = Qt.binding(() => { - return (root.widgetData - && root.widgetData.selectedGpuIndex !== undefined) ? root.widgetData.selectedGpuIndex : 0 - }) + property int selectedGpuIndex: (widgetData && widgetData.selectedGpuIndex !== undefined) ? widgetData.selectedGpuIndex : 0 + readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30)) + property real displayTemp: { + if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) { + return 0; } + + if (selectedGpuIndex >= 0 && selectedGpuIndex < DgopService.availableGpus.length) { + return DgopService.availableGpus[selectedGpuIndex].temperature || 0; + } + + return 0; } - readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30)) + function updateWidgetPciId(pciId) { + // Find and update this widget's pciId in the settings + const sections = ["left", "center", "right"]; + for (let s = 0; s < sections.length; s++) { + const sectionId = sections[s]; + let widgets = []; + if (sectionId === "left") { + widgets = SettingsData.topBarLeftWidgets.slice(); + } else if (sectionId === "center") { + widgets = SettingsData.topBarCenterWidgets.slice(); + } else if (sectionId === "right") { + widgets = SettingsData.topBarRightWidgets.slice(); + } + for (let i = 0; i < widgets.length; i++) { + const widget = widgets[i]; + if (typeof widget === "object" && widget.id === "gpuTemp" && (!widget.pciId || widget.pciId === "")) { + widgets[i] = { + "id": widget.id, + "enabled": widget.enabled !== undefined ? widget.enabled : true, + "selectedGpuIndex": 0, + "pciId": pciId + }; + if (sectionId === "left") { + SettingsData.setTopBarLeftWidgets(widgets); + } else if (sectionId === "center") { + SettingsData.setTopBarCenterWidgets(widgets); + } else if (sectionId === "right") { + SettingsData.setTopBarRightWidgets(widgets); + } + return ; + } + } + } + } width: gpuTempContent.implicitWidth + horizontalPadding * 2 height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = gpuArea.containsMouse ? Theme.primaryPressed : Theme.secondaryHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = gpuArea.containsMouse ? Theme.primaryPressed : Theme.secondaryHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } Component.onCompleted: { - DgopService.addRef(["gpu"]) - console.log("GpuTemperature widget - pciId:", - widgetData ? widgetData.pciId : "no widgetData", - "selectedGpuIndex:", - widgetData ? widgetData.selectedGpuIndex : "no widgetData") + DgopService.addRef(["gpu"]); + console.log("GpuTemperature widget - pciId:", widgetData ? widgetData.pciId : "no widgetData", "selectedGpuIndex:", widgetData ? widgetData.selectedGpuIndex : "no widgetData"); // Add this widget's PCI ID to the service if (widgetData && widgetData.pciId) { - console.log("Adding GPU PCI ID to service:", widgetData.pciId) - DgopService.addGpuPciId(widgetData.pciId) + console.log("Adding GPU PCI ID to service:", widgetData.pciId); + DgopService.addGpuPciId(widgetData.pciId); } else { - console.log("No PCI ID in widget data, starting auto-detection") + console.log("No PCI ID in widget data, starting auto-detection"); // No PCI ID saved, auto-detect and save the first GPU - autoSaveTimer.running = true + autoSaveTimer.running = true; } } Component.onDestruction: { - DgopService.removeRef(["gpu"]) + DgopService.removeRef(["gpu"]); // Remove this widget's PCI ID from the service if (widgetData && widgetData.pciId) { - DgopService.removeGpuPciId(widgetData.pciId) + DgopService.removeGpuPciId(widgetData.pciId); } + } - property real displayTemp: { - if (!DgopService.availableGpus - || DgopService.availableGpus.length === 0) - return 0 - if (selectedGpuIndex >= 0 - && selectedGpuIndex < DgopService.availableGpus.length) { - return DgopService.availableGpus[selectedGpuIndex].temperature || 0 + Connections { + function onWidgetDataChanged() { + // Force property re-evaluation by triggering change detection + root.selectedGpuIndex = Qt.binding(() => { + return (root.widgetData && root.widgetData.selectedGpuIndex !== undefined) ? root.widgetData.selectedGpuIndex : 0; + }); } - return 0 + + target: SettingsData } MouseArea { @@ -84,22 +117,23 @@ Rectangle { cursorShape: Qt.PointingHandCursor onPressed: { if (popupTarget && popupTarget.setTriggerPosition) { - var globalPos = mapToGlobal(0, 0) - var currentScreen = parentScreen || Screen - var screenX = currentScreen.x || 0 - var relativeX = globalPos.x - screenX - popupTarget.setTriggerPosition( - relativeX, barHeight + Theme.spacingXS, - width, section, currentScreen) + const globalPos = mapToGlobal(0, 0); + const currentScreen = parentScreen || Screen; + const screenX = currentScreen.x || 0; + const relativeX = globalPos.x - screenX; + popupTarget.setTriggerPosition(relativeX, barHeight + Theme.spacingXS, width, section, currentScreen); } - DgopService.setSortBy("cpu") - if (root.toggleProcessList) - root.toggleProcessList() + DgopService.setSortBy("cpu"); + if (root.toggleProcessList) { + root.toggleProcessList(); + } + } } Row { id: gpuTempContent + anchors.centerIn: parent spacing: 3 @@ -107,30 +141,50 @@ Rectangle { name: "auto_awesome_mosaic" size: Theme.iconSize - 8 color: { - if (root.displayTemp > 80) - return Theme.tempDanger + if (root.displayTemp > 80) { + return Theme.tempDanger; + } - if (root.displayTemp > 65) - return Theme.tempWarning + if (root.displayTemp > 65) { + return Theme.tempWarning; + } - return Theme.surfaceText + return Theme.surfaceText; } anchors.verticalCenter: parent.verticalCenter } StyledText { text: { - if (root.displayTemp === undefined || root.displayTemp === null - || root.displayTemp === 0) { - return "--°" + if (root.displayTemp === undefined || root.displayTemp === null || root.displayTemp === 0) { + return "--°"; } - return Math.round(root.displayTemp) + "°" + + return Math.round(root.displayTemp) + "°"; } font.pixelSize: Theme.fontSizeSmall font.weight: Font.Medium color: Theme.surfaceText anchors.verticalCenter: parent.verticalCenter } + + } + + Timer { + id: autoSaveTimer + + interval: 100 + running: false + onTriggered: { + if (DgopService.availableGpus && DgopService.availableGpus.length > 0) { + const firstGpu = DgopService.availableGpus[0]; + if (firstGpu && firstGpu.pciId) { + // Save the first GPU's PCI ID to this widget's settings + updateWidgetPciId(firstGpu.pciId); + DgopService.addGpuPciId(firstGpu.pciId); + } + } + } } Behavior on color { @@ -138,58 +192,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } - Timer { - id: autoSaveTimer - interval: 100 - running: false - onTriggered: { - if (DgopService.availableGpus - && DgopService.availableGpus.length > 0) { - const firstGpu = DgopService.availableGpus[0] - if (firstGpu && firstGpu.pciId) { - // Save the first GPU's PCI ID to this widget's settings - updateWidgetPciId(firstGpu.pciId) - DgopService.addGpuPciId(firstGpu.pciId) - } - } - } - } - - function updateWidgetPciId(pciId) { - // Find and update this widget's pciId in the settings - var sections = ["left", "center", "right"] - for (var s = 0; s < sections.length; s++) { - var sectionId = sections[s] - var widgets = [] - if (sectionId === "left") - widgets = SettingsData.topBarLeftWidgets.slice() - else if (sectionId === "center") - widgets = SettingsData.topBarCenterWidgets.slice() - else if (sectionId === "right") - widgets = SettingsData.topBarRightWidgets.slice() - - for (var i = 0; i < widgets.length; i++) { - var widget = widgets[i] - if (typeof widget === "object" && widget.id === "gpuTemp" - && (!widget.pciId || widget.pciId === "")) { - widgets[i] = { - "id": widget.id, - "enabled": widget.enabled !== undefined ? widget.enabled : true, - "selectedGpuIndex": 0, - "pciId": pciId - } - - if (sectionId === "left") - SettingsData.setTopBarLeftWidgets(widgets) - else if (sectionId === "center") - SettingsData.setTopBarCenterWidgets(widgets) - else if (sectionId === "right") - SettingsData.setTopBarRightWidgets(widgets) - return - } - } - } - } } diff --git a/Modules/TopBar/IdleInhibitor.qml b/Modules/TopBar/IdleInhibitor.qml index c178ebe6..8d073a06 100644 --- a/Modules/TopBar/IdleInhibitor.qml +++ b/Modules/TopBar/IdleInhibitor.qml @@ -18,14 +18,17 @@ Rectangle { height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = mouseArea.containsMouse ? Theme.primaryPressed : (SessionService.idleInhibited ? Theme.primaryHover : Theme.secondaryHover) - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = mouseArea.containsMouse ? Theme.primaryPressed : (SessionService.idleInhibited ? Theme.primaryHover : Theme.secondaryHover); + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } DankIcon { id: idleIcon + anchors.centerIn: parent name: SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle" size: Theme.iconSize - 6 @@ -38,9 +41,8 @@ Rectangle { anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor - onClicked: { - SessionService.toggleIdleInhibit() + SessionService.toggleIdleInhibit(); } } @@ -49,5 +51,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } + } diff --git a/Modules/TopBar/KeyboardLayoutName.qml b/Modules/TopBar/KeyboardLayoutName.qml index 95e23591..f45f152a 100644 --- a/Modules/TopBar/KeyboardLayoutName.qml +++ b/Modules/TopBar/KeyboardLayoutName.qml @@ -1,9 +1,9 @@ import QtQuick import QtQuick.Controls import qs.Common +import qs.Modules.ProcessList import qs.Services import qs.Widgets -import qs.Modules.ProcessList Rectangle { id: root @@ -13,12 +13,13 @@ Rectangle { width: contentRow.implicitWidth + horizontalPadding * 2 height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius - color: { - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = mouseArea.containsMouse ? Theme.primaryPressed : Theme.secondaryHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = mouseArea.containsMouse ? Theme.primaryPressed : Theme.secondaryHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } MouseArea { @@ -27,9 +28,8 @@ Rectangle { anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor - onClicked: { - NiriService.cycleKeyboardLayout() + NiriService.cycleKeyboardLayout(); } } @@ -45,6 +45,7 @@ Rectangle { color: Theme.surfaceText anchors.verticalCenter: parent.verticalCenter } + } Behavior on color { @@ -52,5 +53,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } + } diff --git a/Modules/TopBar/LauncherButton.qml b/Modules/TopBar/LauncherButton.qml index 5120cb78..d8721360 100644 --- a/Modules/TopBar/LauncherButton.qml +++ b/Modules/TopBar/LauncherButton.qml @@ -14,41 +14,42 @@ Item { property real barHeight: 48 readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30)) - signal clicked + signal clicked() width: Theme.iconSize + horizontalPadding * 2 height: widgetHeight MouseArea { id: launcherArea + anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor acceptedButtons: Qt.LeftButton - onPressed: { if (popupTarget && popupTarget.setTriggerPosition) { - var globalPos = mapToGlobal(0, 0) - var currentScreen = parentScreen || Screen - var screenX = currentScreen.x || 0 - var relativeX = globalPos.x - screenX - popupTarget.setTriggerPosition( - relativeX, barHeight + Theme.spacingXS, - width, section, currentScreen) + const globalPos = mapToGlobal(0, 0); + const currentScreen = parentScreen || Screen; + const screenX = currentScreen.x || 0; + const relativeX = globalPos.x - screenX; + popupTarget.setTriggerPosition(relativeX, barHeight + Theme.spacingXS, width, section, currentScreen); } - root.clicked() + root.clicked(); } } Rectangle { id: launcherContent + anchors.fill: parent radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = launcherArea.containsMouse ? Theme.primaryPressed : (SessionService.idleInhibited ? Theme.primaryHover : Theme.secondaryHover) - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = launcherArea.containsMouse ? Theme.primaryPressed : (SessionService.idleInhibited ? Theme.primaryHover : Theme.secondaryHover); + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } SystemLogo { @@ -74,6 +75,9 @@ Item { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } + } + } diff --git a/Modules/TopBar/Media.qml b/Modules/TopBar/Media.qml index 8bbe667f..266266fb 100644 --- a/Modules/TopBar/Media.qml +++ b/Modules/TopBar/Media.qml @@ -13,21 +13,21 @@ Rectangle { readonly property int textWidth: { switch (SettingsData.mediaSize) { case 0: - return 0 // No text in small mode + return 0; // No text in small mode case 2: - return 180 // Large text area + return 180; // Large text area default: - return 120 // Medium text area + return 120; // Medium text area } } - readonly property int currentContentWidth: { // Calculate actual content width: // AudioViz (20) + spacing + [text + spacing] + controls (prev:20 + spacing + play:24 + spacing + next:20) + padding - const controlsWidth = 20 + Theme.spacingXS + 24 + Theme.spacingXS + 20 // ~72px total - const audioVizWidth = 20 - const contentWidth = audioVizWidth + Theme.spacingXS + controlsWidth - return contentWidth + (textWidth > 0 ? textWidth + Theme.spacingXS : 0) + horizontalPadding * 2 + const controlsWidth = 20 + Theme.spacingXS + 24 + Theme.spacingXS + 20; + // ~72px total + const audioVizWidth = 20; + const contentWidth = audioVizWidth + Theme.spacingXS + controlsWidth; + return contentWidth + (textWidth > 0 ? textWidth + Theme.spacingXS : 0) + horizontalPadding * 2; } property string section: "center" property var popupTarget: null @@ -36,15 +36,17 @@ Rectangle { property real widgetHeight: 30 readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30)) - signal clicked + signal clicked() height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = Theme.surfaceTextHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = Theme.surfaceTextHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } states: [ State { @@ -56,6 +58,7 @@ Rectangle { opacity: 1 width: currentContentWidth } + }, State { name: "hidden" @@ -66,6 +69,7 @@ Rectangle { opacity: 0 width: 0 } + } ] transitions: [ @@ -83,7 +87,9 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } + }, Transition { from: "hidden" @@ -94,6 +100,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } ] @@ -115,6 +122,25 @@ Rectangle { Rectangle { id: textContainer + property string displayText: { + if (!activePlayer || !activePlayer.trackTitle) { + return ""; + } + + let identity = activePlayer.identity || ""; + let isWebMedia = identity.toLowerCase().includes("firefox") || identity.toLowerCase().includes("chrome") || identity.toLowerCase().includes("chromium") || identity.toLowerCase().includes("edge") || identity.toLowerCase().includes("safari"); + let title = ""; + let subtitle = ""; + if (isWebMedia && activePlayer.trackTitle) { + title = activePlayer.trackTitle; + subtitle = activePlayer.trackArtist || identity; + } else { + title = activePlayer.trackTitle || "Unknown Track"; + subtitle = activePlayer.trackArtist || ""; + } + return subtitle.length > 0 ? title + " • " + subtitle : title; + } + anchors.verticalCenter: parent.verticalCenter width: textWidth height: 20 @@ -122,48 +148,28 @@ Rectangle { clip: true color: "transparent" - property string displayText: { - if (!activePlayer || !activePlayer.trackTitle) - return "" - - let identity = activePlayer.identity || "" - let isWebMedia = identity.toLowerCase().includes("firefox") - || identity.toLowerCase().includes( - "chrome") || identity.toLowerCase( - ).includes("chromium") - || identity.toLowerCase().includes( - "edge") || identity.toLowerCase().includes("safari") - let title = "" - let subtitle = "" - if (isWebMedia && activePlayer.trackTitle) { - title = activePlayer.trackTitle - subtitle = activePlayer.trackArtist || identity - } else { - title = activePlayer.trackTitle || "Unknown Track" - subtitle = activePlayer.trackArtist || "" - } - return subtitle.length > 0 ? title + " • " + subtitle : title - } - StyledText { id: mediaText + property bool needsScrolling: implicitWidth > textContainer.width + property real scrollOffset: 0 + anchors.verticalCenter: parent.verticalCenter text: textContainer.displayText font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceText font.weight: Font.Medium wrapMode: Text.NoWrap - - property bool needsScrolling: implicitWidth > textContainer.width - property real scrollOffset: 0 - x: needsScrolling ? -scrollOffset : 0 + onTextChanged: { + scrollOffset = 0; + scrollAnimation.restart(); + } SequentialAnimation { id: scrollAnimation - running: mediaText.needsScrolling - && textContainer.visible + + running: mediaText.needsScrolling && textContainer.visible loops: Animation.Infinite PauseAnimation { @@ -175,9 +181,7 @@ Rectangle { property: "scrollOffset" from: 0 to: mediaText.implicitWidth - textContainer.width + 5 - duration: Math.max( - 1000, - (mediaText.implicitWidth - textContainer.width + 5) * 60) + duration: Math.max(1000, (mediaText.implicitWidth - textContainer.width + 5) * 60) easing.type: Easing.Linear } @@ -189,41 +193,33 @@ Rectangle { target: mediaText property: "scrollOffset" to: 0 - duration: Math.max( - 1000, - (mediaText.implicitWidth - textContainer.width + 5) * 60) + duration: Math.max(1000, (mediaText.implicitWidth - textContainer.width + 5) * 60) easing.type: Easing.Linear } + } - onTextChanged: { - scrollOffset = 0 - scrollAnimation.restart() - } } MouseArea { anchors.fill: parent - enabled: root.playerAvailable && root.opacity > 0 - && root.width > 0 && textContainer.visible + enabled: root.playerAvailable && root.opacity > 0 && root.width > 0 && textContainer.visible hoverEnabled: enabled cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor onPressed: { - if (root.popupTarget - && root.popupTarget.setTriggerPosition) { - var globalPos = mapToGlobal(0, 0) - var currentScreen = root.parentScreen || Screen - var screenX = currentScreen.x || 0 - var relativeX = globalPos.x - screenX - root.popupTarget.setTriggerPosition( - relativeX, - barHeight + Theme.spacingXS, - root.width, root.section, currentScreen) + if (root.popupTarget && root.popupTarget.setTriggerPosition) { + const globalPos = mapToGlobal(0, 0); + const currentScreen = root.parentScreen || Screen; + const screenX = currentScreen.x || 0; + const relativeX = globalPos.x - screenX; + root.popupTarget.setTriggerPosition(relativeX, barHeight + Theme.spacingXS, root.width, root.section, currentScreen); } - root.clicked() + root.clicked(); } } + } + } Row { @@ -254,10 +250,12 @@ Rectangle { hoverEnabled: enabled cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor onClicked: { - if (activePlayer) - activePlayer.previous() + if (activePlayer) { + activePlayer.previous(); + } } } + } Rectangle { @@ -265,18 +263,15 @@ Rectangle { height: 24 radius: 12 anchors.verticalCenter: parent.verticalCenter - color: activePlayer - && activePlayer.playbackState === 1 ? Theme.primary : Theme.primaryHover + color: activePlayer && activePlayer.playbackState === 1 ? Theme.primary : Theme.primaryHover visible: root.playerAvailable opacity: activePlayer ? 1 : 0.3 DankIcon { anchors.centerIn: parent - name: activePlayer - && activePlayer.playbackState === 1 ? "pause" : "play_arrow" + name: activePlayer && activePlayer.playbackState === 1 ? "pause" : "play_arrow" size: 14 - color: activePlayer - && activePlayer.playbackState === 1 ? Theme.background : Theme.primary + color: activePlayer && activePlayer.playbackState === 1 ? Theme.background : Theme.primary } MouseArea { @@ -285,10 +280,12 @@ Rectangle { hoverEnabled: enabled cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor onClicked: { - if (activePlayer) - activePlayer.togglePlaying() + if (activePlayer) { + activePlayer.togglePlaying(); + } } } + } Rectangle { @@ -315,12 +312,16 @@ Rectangle { hoverEnabled: enabled cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor onClicked: { - if (activePlayer) - activePlayer.next() + if (activePlayer) { + activePlayer.next(); + } } } + } + } + } Behavior on color { @@ -328,6 +329,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } Behavior on width { @@ -335,5 +337,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } + } diff --git a/Modules/TopBar/NetworkMonitor.qml b/Modules/TopBar/NetworkMonitor.qml index e9c4c74f..a10b9bec 100644 --- a/Modules/TopBar/NetworkMonitor.qml +++ b/Modules/TopBar/NetworkMonitor.qml @@ -1,9 +1,9 @@ import QtQuick import QtQuick.Controls import qs.Common +import qs.Modules.ProcessList import qs.Services import qs.Widgets -import qs.Modules.ProcessList Rectangle { id: root @@ -11,37 +11,36 @@ Rectangle { property int availableWidth: 400 readonly property int baseWidth: contentRow.implicitWidth + Theme.spacingS * 2 readonly property int maxNormalWidth: 456 + readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30)) function formatNetworkSpeed(bytesPerSec) { - if (bytesPerSec < 1024) - return bytesPerSec.toFixed(0) + " B/s" - else if (bytesPerSec < 1024 * 1024) - return (bytesPerSec / 1024).toFixed(1) + " KB/s" - else if (bytesPerSec < 1024 * 1024 * 1024) - return (bytesPerSec / (1024 * 1024)).toFixed(1) + " MB/s" - else - return (bytesPerSec / (1024 * 1024 * 1024)).toFixed(1) + " GB/s" + if (bytesPerSec < 1024) { + return bytesPerSec.toFixed(0) + " B/s"; + } else if (bytesPerSec < 1024 * 1024) { + return (bytesPerSec / 1024).toFixed(1) + " KB/s"; + } else if (bytesPerSec < 1024 * 1024 * 1024) { + return (bytesPerSec / (1024 * 1024)).toFixed(1) + " MB/s"; + } else { + return (bytesPerSec / (1024 * 1024 * 1024)).toFixed(1) + " GB/s"; + } } - readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30)) - width: contentRow.implicitWidth + horizontalPadding * 2 height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius - color: { - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = networkArea.containsMouse ? Theme.primaryPressed : Theme.secondaryHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) - } + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + const baseColor = networkArea.containsMouse ? Theme.primaryPressed : Theme.secondaryHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); + } Component.onCompleted: { - DgopService.addRef(["network"]) + DgopService.addRef(["network"]); } - Component.onDestruction: { - DgopService.removeRef(["network"]) + DgopService.removeRef(["network"]); } MouseArea { @@ -76,13 +75,13 @@ Rectangle { } StyledText { - text: DgopService.networkRxRate > 0 ? formatNetworkSpeed( - DgopService.networkRxRate) : "0 B/s" + text: DgopService.networkRxRate > 0 ? formatNetworkSpeed(DgopService.networkRxRate) : "0 B/s" font.pixelSize: Theme.fontSizeSmall font.weight: Font.Medium color: Theme.surfaceText anchors.verticalCenter: parent.verticalCenter } + } Row { @@ -96,14 +95,15 @@ Rectangle { } StyledText { - text: DgopService.networkTxRate > 0 ? formatNetworkSpeed( - DgopService.networkTxRate) : "0 B/s" + text: DgopService.networkTxRate > 0 ? formatNetworkSpeed(DgopService.networkTxRate) : "0 B/s" font.pixelSize: Theme.fontSizeSmall font.weight: Font.Medium color: Theme.surfaceText anchors.verticalCenter: parent.verticalCenter } + } + } Behavior on color { @@ -111,5 +111,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } + } diff --git a/Modules/TopBar/NotepadButton.qml b/Modules/TopBar/NotepadButton.qml index 827c38af..25ae8b41 100644 --- a/Modules/TopBar/NotepadButton.qml +++ b/Modules/TopBar/NotepadButton.qml @@ -13,21 +13,23 @@ Rectangle { property real barHeight: 48 readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30)) - signal clicked + signal clicked() width: notepadIcon.width + horizontalPadding * 2 height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = notepadArea.containsMouse - || root.isActive ? Theme.primaryPressed : Theme.secondaryHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = notepadArea.containsMouse || root.isActive ? Theme.primaryPressed : Theme.secondaryHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } DankIcon { id: notepadIcon + anchors.centerIn: parent name: "assignment" size: Theme.iconSize - 6 @@ -54,7 +56,7 @@ Rectangle { hoverEnabled: true cursorShape: Qt.PointingHandCursor onPressed: { - root.clicked() + root.clicked(); } } @@ -63,5 +65,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } -} \ No newline at end of file + +} diff --git a/Modules/TopBar/NotificationCenterButton.qml b/Modules/TopBar/NotificationCenterButton.qml index 1df23e74..c70c8f6d 100644 --- a/Modules/TopBar/NotificationCenterButton.qml +++ b/Modules/TopBar/NotificationCenterButton.qml @@ -14,26 +14,27 @@ Rectangle { property real barHeight: 48 readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30)) - signal clicked + signal clicked() width: notificationIcon.width + horizontalPadding * 2 height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = notificationArea.containsMouse - || root.isActive ? Theme.primaryPressed : Theme.secondaryHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = notificationArea.containsMouse || root.isActive ? Theme.primaryPressed : Theme.secondaryHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } DankIcon { id: notificationIcon + anchors.centerIn: parent name: SessionData.doNotDisturb ? "notifications_off" : "notifications" size: Theme.iconSize - 6 - color: SessionData.doNotDisturb ? Theme.error : (notificationArea.containsMouse - || root.isActive ? Theme.primary : Theme.surfaceText) + color: SessionData.doNotDisturb ? Theme.error : (notificationArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText) } Rectangle { @@ -56,15 +57,13 @@ Rectangle { cursorShape: Qt.PointingHandCursor onPressed: { if (popupTarget && popupTarget.setTriggerPosition) { - var globalPos = mapToGlobal(0, 0) - var currentScreen = parentScreen || Screen - var screenX = currentScreen.x || 0 - var relativeX = globalPos.x - screenX - popupTarget.setTriggerPosition( - relativeX, barHeight + Theme.spacingXS, - width, section, currentScreen) + const globalPos = mapToGlobal(0, 0); + const currentScreen = parentScreen || Screen; + const screenX = currentScreen.x || 0; + const relativeX = globalPos.x - screenX; + popupTarget.setTriggerPosition(relativeX, barHeight + Theme.spacingXS, width, section, currentScreen); } - root.clicked() + root.clicked(); } } @@ -73,5 +72,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } + } diff --git a/Modules/TopBar/PrivacyIndicator.qml b/Modules/TopBar/PrivacyIndicator.qml index afe4f345..10296920 100644 --- a/Modules/TopBar/PrivacyIndicator.qml +++ b/Modules/TopBar/PrivacyIndicator.qml @@ -12,10 +12,8 @@ Rectangle { property var parentScreen: null property real widgetHeight: 30 readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 2 : Theme.spacingS - readonly property bool hasActivePrivacy: PrivacyService.anyPrivacyActive - readonly property int activeCount: PrivacyService.microphoneActive + PrivacyService.cameraActive - + PrivacyService.screensharingActive + readonly property int activeCount: PrivacyService.microphoneActive + PrivacyService.cameraActive + PrivacyService.screensharingActive readonly property real contentWidth: hasActivePrivacy ? (activeCount * 18 + (activeCount - 1) * Theme.spacingXS) : 0 width: hasActivePrivacy ? (contentWidth + horizontalPadding * 2) : 0 @@ -24,18 +22,17 @@ Rectangle { visible: hasActivePrivacy opacity: hasActivePrivacy ? 1 : 0 enabled: hasActivePrivacy - color: { - if (SettingsData.topBarNoBackground) return "transparent" - return Qt.rgba( - privacyArea.containsMouse ? Theme.errorPressed.r : Theme.errorHover.r, - privacyArea.containsMouse ? Theme.errorPressed.g : Theme.errorHover.g, - privacyArea.containsMouse ? Theme.errorPressed.b : Theme.errorHover.b, - (privacyArea.containsMouse ? Theme.errorPressed.a : Theme.errorHover.a) - * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + return Qt.rgba(privacyArea.containsMouse ? Theme.errorPressed.r : Theme.errorHover.r, privacyArea.containsMouse ? Theme.errorPressed.g : Theme.errorHover.g, privacyArea.containsMouse ? Theme.errorPressed.b : Theme.errorHover.b, (privacyArea.containsMouse ? Theme.errorPressed.a : Theme.errorHover.a) * Theme.widgetTransparency); } MouseArea { + // Privacy indicator click handler + id: privacyArea anchors.fill: parent @@ -43,7 +40,6 @@ Rectangle { enabled: hasActivePrivacy cursorShape: Qt.PointingHandCursor onClicked: { - } } @@ -65,6 +61,7 @@ Rectangle { filled: true anchors.centerIn: parent } + } Item { @@ -91,6 +88,7 @@ Rectangle { anchors.rightMargin: -2 anchors.topMargin: -1 } + } Item { @@ -106,15 +104,9 @@ Rectangle { filled: true anchors.centerIn: parent } - } - } - Behavior on width { - enabled: hasActivePrivacy && visible - NumberAnimation { - duration: Theme.mediumDuration - easing.type: Theme.emphasizedEasing } + } Rectangle { @@ -129,26 +121,18 @@ Rectangle { visible: false opacity: privacyArea.containsMouse && hasActivePrivacy ? 1 : 0 z: 100 - x: (parent.width - width) / 2 y: -height - Theme.spacingXS StyledText { id: tooltipText + anchors.centerIn: parent text: PrivacyService.getPrivacySummary() font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceText } - Behavior on opacity { - enabled: hasActivePrivacy && root.visible - NumberAnimation { - duration: Theme.shortDuration - easing.type: Theme.standardEasing - } - } - Rectangle { width: 8 height: 8 @@ -160,5 +144,27 @@ Rectangle { anchors.top: parent.bottom anchors.topMargin: -4 } + + Behavior on opacity { + enabled: hasActivePrivacy && root.visible + + NumberAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } + + } + } + + Behavior on width { + enabled: hasActivePrivacy && visible + + NumberAnimation { + duration: Theme.mediumDuration + easing.type: Theme.emphasizedEasing + } + + } + } diff --git a/Modules/TopBar/RamMonitor.qml b/Modules/TopBar/RamMonitor.qml index b23d7832..89bf7ae5 100644 --- a/Modules/TopBar/RamMonitor.qml +++ b/Modules/TopBar/RamMonitor.qml @@ -21,16 +21,18 @@ Rectangle { height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = ramArea.containsMouse ? Theme.primaryPressed : Theme.secondaryHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = ramArea.containsMouse ? Theme.primaryPressed : Theme.secondaryHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } Component.onCompleted: { - DgopService.addRef(["memory"]) + DgopService.addRef(["memory"]); } Component.onDestruction: { - DgopService.removeRef(["memory"]) + DgopService.removeRef(["memory"]); } MouseArea { @@ -41,22 +43,23 @@ Rectangle { cursorShape: Qt.PointingHandCursor onPressed: { if (popupTarget && popupTarget.setTriggerPosition) { - var globalPos = mapToGlobal(0, 0) - var currentScreen = parentScreen || Screen - var screenX = currentScreen.x || 0 - var relativeX = globalPos.x - screenX - popupTarget.setTriggerPosition( - relativeX, barHeight + Theme.spacingXS, - width, section, currentScreen) + const globalPos = mapToGlobal(0, 0); + const currentScreen = parentScreen || Screen; + const screenX = currentScreen.x || 0; + const relativeX = globalPos.x - screenX; + popupTarget.setTriggerPosition(relativeX, barHeight + Theme.spacingXS, width, section, currentScreen); } - DgopService.setSortBy("memory") - if (root.toggleProcessList) - root.toggleProcessList() + DgopService.setSortBy("memory"); + if (root.toggleProcessList) { + root.toggleProcessList(); + } + } } Row { id: ramContent + anchors.centerIn: parent spacing: 3 @@ -64,30 +67,33 @@ Rectangle { name: "developer_board" size: Theme.iconSize - 8 color: { - if (DgopService.memoryUsage > 90) - return Theme.tempDanger + if (DgopService.memoryUsage > 90) { + return Theme.tempDanger; + } - if (DgopService.memoryUsage > 75) - return Theme.tempWarning + if (DgopService.memoryUsage > 75) { + return Theme.tempWarning; + } - return Theme.surfaceText + return Theme.surfaceText; } anchors.verticalCenter: parent.verticalCenter } StyledText { text: { - if (DgopService.memoryUsage === undefined - || DgopService.memoryUsage === null - || DgopService.memoryUsage === 0) { - return "--%" + if (DgopService.memoryUsage === undefined || DgopService.memoryUsage === null || DgopService.memoryUsage === 0) { + return "--%"; } - return DgopService.memoryUsage.toFixed(0) + "%" + + return DgopService.memoryUsage.toFixed(0) + "%"; } font.pixelSize: Theme.fontSizeSmall font.weight: Font.Medium color: Theme.surfaceText anchors.verticalCenter: parent.verticalCenter } + } + } diff --git a/Modules/TopBar/RunningApps.qml b/Modules/TopBar/RunningApps.qml index 45802417..2f8e7ffc 100644 --- a/Modules/TopBar/RunningApps.qml +++ b/Modules/TopBar/RunningApps.qml @@ -19,20 +19,21 @@ Rectangle { // The visual root for this window property Item windowRoot: (Window.window ? Window.window.contentItem : null) readonly property var sortedToplevels: { - if (SettingsData.runningAppsCurrentWorkspace){ - return CompositorService.filterCurrentWorkspace(CompositorService.sortedToplevels, parentScreen.name) - } - return CompositorService.sortedToplevels + if (SettingsData.runningAppsCurrentWorkspace) { + return CompositorService.filterCurrentWorkspace(CompositorService.sortedToplevels, parentScreen.name); + } + return CompositorService.sortedToplevels; } readonly property int windowCount: sortedToplevels.length readonly property int calculatedWidth: { - if (windowCount === 0) - return 0 + if (windowCount === 0) { + return 0; + } if (SettingsData.runningAppsCompactMode) { - return windowCount * 24 + (windowCount - 1) * Theme.spacingXS + horizontalPadding * 2 + return windowCount * 24 + (windowCount - 1) * Theme.spacingXS + horizontalPadding * 2; } else { return windowCount * (24 + Theme.spacingXS + 120) - + (windowCount - 1) * Theme.spacingXS + horizontalPadding * 2 + + (windowCount - 1) * Theme.spacingXS + horizontalPadding * 2; } } @@ -42,13 +43,16 @@ Rectangle { visible: windowCount > 0 clip: false color: { - if (windowCount === 0) - return "transparent" + if (windowCount === 0) { + return "transparent"; + } - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = Theme.secondaryHover + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + const baseColor = Theme.secondaryHover; return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + baseColor.a * Theme.widgetTransparency); } MouseArea { @@ -60,26 +64,26 @@ Rectangle { property real touchpadThreshold: 500 onWheel: (wheel) => { - const deltaY = wheel.angleDelta.y + const deltaY = wheel.angleDelta.y; const isMouseWheel = Math.abs(deltaY) >= 120 - && (Math.abs(deltaY) % 120) === 0 + && (Math.abs(deltaY) % 120) === 0; - var windows = root.sortedToplevels; + const windows = root.sortedToplevels; if (windows.length < 2) { return; } if (isMouseWheel) { // Direct mouse wheel action - var currentIndex = -1; - for (var i = 0; i < windows.length; i++) { + let currentIndex = -1; + for (let i = 0; i < windows.length; i++) { if (windows[i].activated) { currentIndex = i; break; } } - var nextIndex; + let nextIndex; if (deltaY < 0) { if (currentIndex === -1) { nextIndex = 0; @@ -94,24 +98,24 @@ Rectangle { } } - var nextWindow = windows[nextIndex]; + const nextWindow = windows[nextIndex]; if (nextWindow) { nextWindow.activate(); } } else { // Touchpad - accumulate small deltas - scrollAccumulator += deltaY + scrollAccumulator += deltaY; if (Math.abs(scrollAccumulator) >= touchpadThreshold) { - var currentIndex = -1; - for (var i = 0; i < windows.length; i++) { + let currentIndex = -1; + for (let i = 0; i < windows.length; i++) { if (windows[i].activated) { currentIndex = i; break; } } - var nextIndex; + let nextIndex; if (scrollAccumulator < 0) { if (currentIndex === -1) { nextIndex = 0; @@ -126,16 +130,16 @@ Rectangle { } } - var nextWindow = windows[nextIndex]; + const nextWindow = windows[nextIndex]; if (nextWindow) { nextWindow.activate(); } - scrollAccumulator = 0 + scrollAccumulator = 0; } } - wheel.accepted = true + wheel.accepted = true; } } @@ -158,11 +162,11 @@ Rectangle { property string windowTitle: modelData.title || "(Unnamed)" property var toplevelObject: modelData property string tooltipText: { - var appName = "Unknown" + let appName = "Unknown"; if (appId) { - var desktopEntry = DesktopEntries.heuristicLookup(appId) + const desktopEntry = DesktopEntries.heuristicLookup(appId); appName = desktopEntry - && desktopEntry.name ? desktopEntry.name : appId + && desktopEntry.name ? desktopEntry.name : appId; } return appName + (windowTitle ? " • " + windowTitle : "") } @@ -174,7 +178,7 @@ Rectangle { anchors.fill: parent radius: Theme.cornerRadius color: { - if (isFocused) + if (isFocused) { return mouseArea.containsMouse ? Qt.rgba( Theme.primary.r, Theme.primary.g, @@ -183,13 +187,14 @@ Rectangle { Theme.primary.r, Theme.primary.g, Theme.primary.b, - 0.2) - else + 0.2); + } else { return mouseArea.containsMouse ? Qt.rgba( Theme.primaryHover.r, Theme.primaryHover.g, Theme.primaryHover.b, - 0.1) : "transparent" + 0.1) : "transparent"; + } } Behavior on color { @@ -220,14 +225,16 @@ Rectangle { anchors.centerIn: parent visible: !iconImg.visible text: { - if (!appId) - return "?" + if (!appId) { + return "?"; + } - var desktopEntry = DesktopEntries.heuristicLookup(appId) - if (desktopEntry && desktopEntry.name) - return desktopEntry.name.charAt(0).toUpperCase() + const desktopEntry = DesktopEntries.heuristicLookup(appId); + if (desktopEntry && desktopEntry.name) { + return desktopEntry.name.charAt(0).toUpperCase(); + } - return appId.charAt(0).toUpperCase() + return appId.charAt(0).toUpperCase(); } font.pixelSize: 10 color: Theme.surfaceText @@ -260,45 +267,47 @@ Rectangle { onClicked: (mouse) => { if (mouse.button === Qt.LeftButton) { if (toplevelObject) { - toplevelObject.activate() + toplevelObject.activate(); } } else if (mouse.button === Qt.RightButton) { - if (tooltipLoader.item) - tooltipLoader.item.hideTooltip() - tooltipLoader.active = false + if (tooltipLoader.item) { + tooltipLoader.item.hideTooltip(); + } + tooltipLoader.active = false; - windowContextMenuLoader.active = true + windowContextMenuLoader.active = true; if (windowContextMenuLoader.item) { - windowContextMenuLoader.item.currentWindow = toplevelObject - var globalPos = delegateItem.mapToGlobal(delegateItem.width / 2, 0) - var screenX = root.parentScreen ? root.parentScreen.x : 0 - var screenY = root.parentScreen ? root.parentScreen.y : 0 - var relativeX = globalPos.x - screenX - var yPos = Theme.barHeight + SettingsData.topBarSpacing - 7 - windowContextMenuLoader.item.showAt(relativeX, yPos) + windowContextMenuLoader.item.currentWindow = toplevelObject; + const globalPos = delegateItem.mapToGlobal(delegateItem.width / 2, 0); + const screenX = root.parentScreen ? root.parentScreen.x : 0; + const screenY = root.parentScreen ? root.parentScreen.y : 0; + const relativeX = globalPos.x - screenX; + const yPos = Theme.barHeight + SettingsData.topBarSpacing - 7; + windowContextMenuLoader.item.showAt(relativeX, yPos); } } } onEntered: { - root.hoveredItem = delegateItem - var globalPos = delegateItem.mapToGlobal( - delegateItem.width / 2, delegateItem.height) - tooltipLoader.active = true + root.hoveredItem = delegateItem; + const globalPos = delegateItem.mapToGlobal( + delegateItem.width / 2, delegateItem.height); + tooltipLoader.active = true; if (tooltipLoader.item) { - var tooltipY = Theme.barHeight - + SettingsData.topBarSpacing + Theme.spacingXS + const tooltipY = Theme.barHeight + + SettingsData.topBarSpacing + Theme.spacingXS; tooltipLoader.item.showTooltip( delegateItem.tooltipText, globalPos.x, - tooltipY, root.parentScreen) + tooltipY, root.parentScreen); } } onExited: { if (root.hoveredItem === delegateItem) { - root.hoveredItem = null - if (tooltipLoader.item) - tooltipLoader.item.hideTooltip() + root.hoveredItem = null; + if (tooltipLoader.item) { + tooltipLoader.item.hideTooltip(); + } - tooltipLoader.active = false + tooltipLoader.active = false; } } } @@ -325,16 +334,16 @@ Rectangle { property point anchorPos: Qt.point(0, 0) function showAt(x, y) { - screen = root.parentScreen - anchorPos = Qt.point(x, y) - isVisible = true - visible = true + screen = root.parentScreen; + anchorPos = Qt.point(x, y); + isVisible = true; + visible = true; } function close() { - isVisible = false - visible = false - windowContextMenuLoader.active = false + isVisible = false; + visible = false; + windowContextMenuLoader.active = false; } implicitWidth: 100 @@ -355,15 +364,15 @@ Rectangle { MouseArea { anchors.fill: parent - onClicked: contextMenuWindow.close() + onClicked: contextMenuWindow.close(); } Rectangle { x: { - var left = 10 - var right = contextMenuWindow.width - width - 10 - var want = contextMenuWindow.anchorPos.x - width / 2 - return Math.max(left, Math.min(right, want)) + const left = 10; + const right = contextMenuWindow.width - width - 10; + const want = contextMenuWindow.anchorPos.x - width / 2; + return Math.max(left, Math.min(right, want)); } y: contextMenuWindow.anchorPos.y width: 100 @@ -394,9 +403,9 @@ Rectangle { cursorShape: Qt.PointingHandCursor onClicked: { if (contextMenuWindow.currentWindow) { - contextMenuWindow.currentWindow.close() + contextMenuWindow.currentWindow.close(); } - contextMenuWindow.close() + contextMenuWindow.close(); } } } diff --git a/Modules/TopBar/RunningAppsTooltip.qml b/Modules/TopBar/RunningAppsTooltip.qml index 67145117..f16e047a 100644 --- a/Modules/TopBar/RunningAppsTooltip.qml +++ b/Modules/TopBar/RunningAppsTooltip.qml @@ -12,28 +12,23 @@ PanelWindow { property var targetScreen: null function showTooltip(text, x, y, screen) { - tooltipText = text - targetScreen = screen - - var screenX = screen ? screen.x : 0 - targetX = x - screenX - targetY = y - - visible = true + tooltipText = text; + targetScreen = screen; + const screenX = screen ? screen.x : 0; + targetX = x - screenX; + targetY = y; + visible = true; } function hideTooltip() { - visible = false + visible = false; } screen: targetScreen - implicitWidth: Math.min(300, Math.max( - 120, - textContent.implicitWidth + Theme.spacingM * 2)) + implicitWidth: Math.min(300, Math.max(120, textContent.implicitWidth + Theme.spacingM * 2)) implicitHeight: textContent.implicitHeight + Theme.spacingS * 2 color: "transparent" visible: false - WlrLayershell.layer: WlrLayershell.Overlay WlrLayershell.exclusiveZone: -1 @@ -56,6 +51,7 @@ PanelWindow { Text { id: textContent + anchors.centerIn: parent text: root.tooltipText font.pixelSize: Theme.fontSizeSmall @@ -65,5 +61,7 @@ PanelWindow { elide: Text.ElideRight width: parent.width - Theme.spacingM * 2 } + } + } diff --git a/Modules/TopBar/SystemTrayBar.qml b/Modules/TopBar/SystemTrayBar.qml index d8f9fd6c..2508d8fa 100644 --- a/Modules/TopBar/SystemTrayBar.qml +++ b/Modules/TopBar/SystemTrayBar.qml @@ -11,22 +11,22 @@ Rectangle { property var parentScreen: null property real widgetHeight: 30 readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 2 : Theme.spacingS - - readonly property int calculatedWidth: SystemTray.items.values.length - > 0 ? SystemTray.items.values.length - * 24 + horizontalPadding * 2 : 0 + readonly property int calculatedWidth: SystemTray.items.values.length > 0 ? SystemTray.items.values.length * 24 + horizontalPadding * 2 : 0 width: calculatedWidth height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SystemTray.items.values.length === 0) - return "transparent" - - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = Theme.secondaryHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (SystemTray.items.values.length === 0) { + return "transparent"; + } + + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = Theme.secondaryHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } visible: SystemTray.items.values.length > 0 @@ -42,21 +42,22 @@ Rectangle { delegate: Item { property var trayItem: modelData property string iconSource: { - let icon = trayItem && trayItem.icon + let icon = trayItem && trayItem.icon; if (typeof icon === 'string' || icon instanceof String) { if (icon.includes("?path=")) { - const split = icon.split("?path=") - if (split.length !== 2) - return icon - const name = split[0] - const path = split[1] - const fileName = name.substring( - name.lastIndexOf("/") + 1) - return `file://${path}/${fileName}` + const split = icon.split("?path="); + if (split.length !== 2) { + return icon; + } + + const name = split[0]; + const path = split[1]; + const fileName = name.substring(name.lastIndexOf("/") + 1); + return `file://${path}/${fileName}`; } - return icon + return icon; } - return "" + return ""; } width: 24 @@ -74,7 +75,9 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } + } IconImage { @@ -94,37 +97,36 @@ Rectangle { acceptedButtons: Qt.LeftButton | Qt.RightButton hoverEnabled: true cursorShape: Qt.PointingHandCursor - onClicked: mouse => { - if (!trayItem) - return + onClicked: (mouse) => { + if (!trayItem) { + return; + } - if (mouse.button === Qt.LeftButton - && !trayItem.onlyMenu) { - trayItem.activate() - return - } - - if (trayItem.hasMenu) { - var globalPos = mapToGlobal(0, 0) - var currentScreen = parentScreen - || Screen - var screenX = currentScreen.x || 0 - var relativeX = globalPos.x - screenX - menuAnchor.menu = trayItem.menu - menuAnchor.anchor.window = parentWindow - menuAnchor.anchor.rect = Qt.rect( - relativeX, - Theme.barHeight + Theme.spacingS, - parent.width, 1) - menuAnchor.open() - } - } + if (mouse.button === Qt.LeftButton && !trayItem.onlyMenu) { + trayItem.activate(); + return ; + } + if (trayItem.hasMenu) { + const globalPos = mapToGlobal(0, 0); + const currentScreen = parentScreen || Screen; + const screenX = currentScreen.x || 0; + const relativeX = globalPos.x - screenX; + menuAnchor.menu = trayItem.menu; + menuAnchor.anchor.window = parentWindow; + menuAnchor.anchor.rect = Qt.rect(relativeX, Theme.barHeight + Theme.spacingS, parent.width, 1); + menuAnchor.open(); + } + } } + } + } + } QsMenuAnchor { id: menuAnchor } + } diff --git a/Modules/TopBar/TopBar.qml b/Modules/TopBar/TopBar.qml index 3e9083a0..4be9cef7 100644 --- a/Modules/TopBar/TopBar.qml +++ b/Modules/TopBar/TopBar.qml @@ -20,88 +20,53 @@ PanelWindow { property var modelData property string screenName: modelData.name readonly property int notificationCount: NotificationService.notifications.length - readonly property real effectiveBarHeight: Math.max( - root.widgetHeight - + SettingsData.topBarInnerPadding + 4, - Theme.barHeight - 4 - - (8 - SettingsData.topBarInnerPadding)) - readonly property real widgetHeight: Math.max( - 20, - 26 + SettingsData.topBarInnerPadding * 0.6) + readonly property real effectiveBarHeight: Math.max(root.widgetHeight + SettingsData.topBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.topBarInnerPadding)) + readonly property real widgetHeight: Math.max(20, 26 + SettingsData.topBarInnerPadding * 0.6) screen: modelData implicitHeight: effectiveBarHeight + SettingsData.topBarSpacing color: "transparent" Component.onCompleted: { - let fonts = Qt.fontFamilies() - if (fonts.indexOf("Material Symbols Rounded") === -1) - ToastService.showError( - "Please install Material Symbols Rounded and Restart your Shell. See README.md for instructions") + const fonts = Qt.fontFamilies() + if (fonts.indexOf("Material Symbols Rounded") === -1) { + ToastService.showError("Please install Material Symbols Rounded and Restart your Shell. See README.md for instructions") + } - SettingsData.forceTopBarLayoutRefresh.connect(function () { - Qt.callLater(() => { - leftSection.visible = false - centerSection.visible = false - rightSection.visible = false - Qt.callLater(() => { - leftSection.visible = true - centerSection.visible = true - rightSection.visible = true - }) - }) - }) + SettingsData.forceTopBarLayoutRefresh.connect(() => { + Qt.callLater(() => { + leftSection.visible = false + centerSection.visible = false + rightSection.visible = false + Qt.callLater(() => { + leftSection.visible = true + centerSection.visible = true + rightSection.visible = true + }) + }) + }) - // Configure GPU temperature monitoring based on widget configuration updateGpuTempConfig() - - // Force widget initialization after brief delay to ensure services are loaded - Qt.callLater(() => { - Qt.callLater(() => { - forceWidgetRefresh() - }) - }) + Qt.callLater(() => Qt.callLater(forceWidgetRefresh)) } function forceWidgetRefresh() { - // Force reload of all widget sections to handle race condition on desktop hardware - if (leftSection) - leftSection.visible = false - if (centerSection) - centerSection.visible = false - if (rightSection) - rightSection.visible = false - - Qt.callLater(() => { - if (leftSection) - leftSection.visible = true - if (centerSection) - centerSection.visible = true - if (rightSection) - rightSection.visible = true - }) + const sections = [leftSection, centerSection, rightSection] + sections.forEach(section => section && (section.visible = false)) + Qt.callLater(() => sections.forEach(section => section && (section.visible = true))) } function updateGpuTempConfig() { - const allWidgets = [...(SettingsData.topBarLeftWidgets - || []), ...(SettingsData.topBarCenterWidgets - || []), ...(SettingsData.topBarRightWidgets - || [])] + const allWidgets = [...(SettingsData.topBarLeftWidgets || []), ...(SettingsData.topBarCenterWidgets || []), ...(SettingsData.topBarRightWidgets || [])] const hasGpuTempWidget = allWidgets.some(widget => { - const widgetId = typeof widget - === "string" ? widget : widget.id + const widgetId = typeof widget === "string" ? widget : widget.id const widgetEnabled = typeof widget === "string" ? true : (widget.enabled !== false) - return widgetId === "gpuTemp" - && widgetEnabled + return widgetId === "gpuTemp" && widgetEnabled }) - DgopService.gpuTempEnabled = hasGpuTempWidget - || SessionData.nvidiaGpuTempEnabled - || SessionData.nonNvidiaGpuTempEnabled - DgopService.nvidiaGpuTempEnabled = hasGpuTempWidget - || SessionData.nvidiaGpuTempEnabled - DgopService.nonNvidiaGpuTempEnabled = hasGpuTempWidget - || SessionData.nonNvidiaGpuTempEnabled + DgopService.gpuTempEnabled = hasGpuTempWidget || SessionData.nvidiaGpuTempEnabled || SessionData.nonNvidiaGpuTempEnabled + DgopService.nvidiaGpuTempEnabled = hasGpuTempWidget || SessionData.nvidiaGpuTempEnabled + DgopService.nonNvidiaGpuTempEnabled = hasGpuTempWidget || SessionData.nonNvidiaGpuTempEnabled } Connections { @@ -135,27 +100,19 @@ PanelWindow { Connections { target: root.screen function onGeometryChanged() { - // Re-layout center widgets when screen geometry changes - if (centerSection && centerSection.width > 0) { + if (centerSection?.width > 0) { Qt.callLater(centerSection.updateLayout) } } } - QtObject { - id: notificationHistory - - property int count: 0 - } - anchors { top: true left: true right: true } - exclusiveZone: topBarCore.autoHide ? -1 : root.effectiveBarHeight + SettingsData.topBarSpacing - - 2 + SettingsData.topBarBottomGap + exclusiveZone: topBarCore.autoHide ? -1 : root.effectiveBarHeight + SettingsData.topBarSpacing - 2 + SettingsData.topBarBottomGap mask: Region { item: topBarMouseArea @@ -167,30 +124,38 @@ PanelWindow { property real backgroundTransparency: SettingsData.topBarTransparency property bool autoHide: SettingsData.topBarAutoHide - property bool reveal: SettingsData.topBarVisible - && (!autoHide || topBarMouseArea.containsMouse || hasActivePopout) - + property bool reveal: SettingsData.topBarVisible && (!autoHide || topBarMouseArea.containsMouse || hasActivePopout) + readonly property bool hasActivePopout: { - var result = false - if (typeof appDrawerLoader !== "undefined" && appDrawerLoader.item) - result = result || appDrawerLoader.item.shouldBeVisible - if (typeof centcomPopoutLoader !== "undefined" && centcomPopoutLoader.item) - result = result || centcomPopoutLoader.item.shouldBeVisible - if (typeof processListPopoutLoader !== "undefined" && processListPopoutLoader.item) - result = result || processListPopoutLoader.item.shouldBeVisible - if (typeof notificationCenterLoader !== "undefined" && notificationCenterLoader.item) - result = result || notificationCenterLoader.item.shouldBeVisible - if (typeof batteryPopoutLoader !== "undefined" && batteryPopoutLoader.item) - result = result || batteryPopoutLoader.item.shouldBeVisible - if (typeof vpnPopoutLoader !== "undefined" && vpnPopoutLoader.item) - result = result || vpnPopoutLoader.item.shouldBeVisible - if (typeof controlCenterLoader !== "undefined" && controlCenterLoader.item) - result = result || controlCenterLoader.item.shouldBeVisible - if (typeof notepadSlideoutLoader !== "undefined" && notepadSlideoutLoader.item) - result = result || notepadSlideoutLoader.item.notepadVisible - if (typeof clipboardHistoryModalPopup !== "undefined" && clipboardHistoryModalPopup.item) - result = result || clipboardHistoryModalPopup.item.visible - return result + const loaders = [{ + "loader": appDrawerLoader, + "prop": "shouldBeVisible" + }, { + "loader": centcomPopoutLoader, + "prop": "shouldBeVisible" + }, { + "loader": processListPopoutLoader, + "prop": "shouldBeVisible" + }, { + "loader": notificationCenterLoader, + "prop": "shouldBeVisible" + }, { + "loader": batteryPopoutLoader, + "prop": "shouldBeVisible" + }, { + "loader": vpnPopoutLoader, + "prop": "shouldBeVisible" + }, { + "loader": controlCenterLoader, + "prop": "shouldBeVisible" + }, { + "loader": notepadSlideoutLoader, + "prop": "notepadVisible" + }, { + "loader": clipboardHistoryModalPopup, + "prop": "visible" + }] + return loaders.some(item => item.loader?.item[item.prop]) } Connections { @@ -244,10 +209,7 @@ PanelWindow { Rectangle { anchors.fill: parent radius: SettingsData.topBarSquareCorners ? 0 : Theme.cornerRadius - color: Qt.rgba(Theme.surfaceContainer.r, - Theme.surfaceContainer.g, - Theme.surfaceContainer.b, - topBarCore.backgroundTransparency) + color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, topBarCore.backgroundTransparency) layer.enabled: true Rectangle { @@ -260,9 +222,7 @@ PanelWindow { Rectangle { anchors.fill: parent - color: Qt.rgba(Theme.surfaceTint.r, - Theme.surfaceTint.g, - Theme.surfaceTint.b, 0.04) + color: Qt.rgba(Theme.surfaceTint.r, Theme.surfaceTint.g, Theme.surfaceTint.b, 0.04) radius: parent.radius SequentialAnimation on opacity { @@ -305,152 +265,85 @@ PanelWindow { readonly property int clockWidth: 120 // Approximate clock width readonly property int mediaMaxWidth: 280 // Normal max width readonly property int weatherWidth: 80 // Approximate weather width - readonly property bool validLayout: availableWidth > 100 - && estimatedLeftSectionWidth > 0 - && rightSectionWidth > 0 + readonly property bool validLayout: availableWidth > 100 && estimatedLeftSectionWidth > 0 && rightSectionWidth > 0 readonly property int clockLeftEdge: (availableWidth - clockWidth) / 2 readonly property int clockRightEdge: clockLeftEdge + clockWidth readonly property int leftSectionRightEdge: estimatedLeftSectionWidth - readonly property int mediaLeftEdge: clockLeftEdge - mediaMaxWidth - - Theme.spacingS - readonly property int rightSectionLeftEdge: availableWidth - - rightSectionWidth - readonly property int leftToClockGap: Math.max( - 0, - clockLeftEdge - - leftSectionRightEdge) + readonly property int mediaLeftEdge: clockLeftEdge - mediaMaxWidth - Theme.spacingS + readonly property int rightSectionLeftEdge: availableWidth - rightSectionWidth + readonly property int leftToClockGap: Math.max(0, clockLeftEdge - leftSectionRightEdge) readonly property int leftToMediaGap: mediaMaxWidth > 0 ? Math.max(0, mediaLeftEdge - leftSectionRightEdge) : leftToClockGap - readonly property int mediaToClockGap: mediaMaxWidth - > 0 ? Theme.spacingS : 0 + readonly property int mediaToClockGap: mediaMaxWidth > 0 ? Theme.spacingS : 0 readonly property int clockToRightGap: validLayout ? Math.max(0, rightSectionLeftEdge - clockRightEdge) : 1000 - readonly property bool spacingTight: validLayout - && (leftToMediaGap < 150 - || clockToRightGap < 100) - readonly property bool overlapping: validLayout - && (leftToMediaGap < 100 - || clockToRightGap < 50) + readonly property bool spacingTight: validLayout && (leftToMediaGap < 150 || clockToRightGap < 100) + readonly property bool overlapping: validLayout && (leftToMediaGap < 100 || clockToRightGap < 50) function getWidgetEnabled(enabled) { - return enabled !== undefined ? enabled : true + return enabled !== false } + function getWidgetSection(parentItem) { + if (!parentItem?.parent) { + return "left" + } + if (parentItem.parent === leftSection) { + return "left" + } + if (parentItem.parent === rightSection) { + return "right" + } + if (parentItem.parent === centerSection) { + return "center" + } + return "left" + } + + readonly property var widgetVisibility: ({ + "cpuUsage": DgopService.dgopAvailable, + "memUsage": DgopService.dgopAvailable, + "cpuTemp": DgopService.dgopAvailable, + "gpuTemp": DgopService.dgopAvailable, + "network_speed_monitor": DgopService.dgopAvailable + }) + function getWidgetVisible(widgetId) { - switch (widgetId) { - case "launcherButton": - return true - case "workspaceSwitcher": - return true - case "focusedWindow": - return true - case "runningApps": - return true - case "clock": - return true - case "music": - return true - case "weather": - return true - case "systemTray": - return true - case "privacyIndicator": - return true - case "clipboard": - return true - case "cpuUsage": - return DgopService.dgopAvailable - case "memUsage": - return DgopService.dgopAvailable - case "cpuTemp": - return DgopService.dgopAvailable - case "gpuTemp": - return DgopService.dgopAvailable - case "notificationButton": - return true - case "battery": - return true - case "controlCenterButton": - return true - case "idleInhibitor": - return true - case "spacer": - return true - case "separator": - return true - case "network_speed_monitor": - return DgopService.dgopAvailable - case "keyboard_layout_name": - return true - case "vpn": - return true - case "notepadButton": - return true - default: - return false - } + return widgetVisibility[widgetId] ?? true } + readonly property var componentMap: ({ + "launcherButton": launcherButtonComponent, + "workspaceSwitcher": workspaceSwitcherComponent, + "focusedWindow": focusedWindowComponent, + "runningApps": runningAppsComponent, + "clock": clockComponent, + "music": mediaComponent, + "weather": weatherComponent, + "systemTray": systemTrayComponent, + "privacyIndicator": privacyIndicatorComponent, + "clipboard": clipboardComponent, + "cpuUsage": cpuUsageComponent, + "memUsage": memUsageComponent, + "cpuTemp": cpuTempComponent, + "gpuTemp": gpuTempComponent, + "notificationButton": notificationButtonComponent, + "battery": batteryComponent, + "controlCenterButton": controlCenterButtonComponent, + "idleInhibitor": idleInhibitorComponent, + "spacer": spacerComponent, + "separator": separatorComponent, + "network_speed_monitor": networkComponent, + "keyboard_layout_name": keyboardLayoutNameComponent, + "vpn": vpnComponent, + "notepadButton": notepadButtonComponent + }) + function getWidgetComponent(widgetId) { - switch (widgetId) { - case "launcherButton": - return launcherButtonComponent - case "workspaceSwitcher": - return workspaceSwitcherComponent - case "focusedWindow": - return focusedWindowComponent - case "runningApps": - return runningAppsComponent - case "clock": - return clockComponent - case "music": - return mediaComponent - case "weather": - return weatherComponent - case "systemTray": - return systemTrayComponent - case "privacyIndicator": - return privacyIndicatorComponent - case "clipboard": - return clipboardComponent - case "cpuUsage": - return cpuUsageComponent - case "memUsage": - return memUsageComponent - case "cpuTemp": - return cpuTempComponent - case "gpuTemp": - return gpuTempComponent - case "notificationButton": - return notificationButtonComponent - case "battery": - return batteryComponent - case "controlCenterButton": - return controlCenterButtonComponent - case "idleInhibitor": - return idleInhibitorComponent - case "spacer": - return spacerComponent - case "separator": - return separatorComponent - case "network_speed_monitor": - return networkComponent - case "keyboard_layout_name": - return keyboardLayoutNameComponent - case "vpn": - return vpnComponent - case "notepadButton": - return notepadButtonComponent - default: - return null - } + return componentMap[widgetId] || null } anchors.fill: parent - anchors.leftMargin: Math.max( - Theme.spacingXS, - SettingsData.topBarInnerPadding * 0.8) - anchors.rightMargin: Math.max( - Theme.spacingXS, - SettingsData.topBarInnerPadding * 0.8) + anchors.leftMargin: Math.max(Theme.spacingXS, SettingsData.topBarInnerPadding * 0.8) + anchors.rightMargin: Math.max(Theme.spacingXS, SettingsData.topBarInnerPadding * 0.8) anchors.topMargin: SettingsData.topBarInnerPadding / 2 anchors.bottomMargin: SettingsData.topBarInnerPadding / 2 clip: true @@ -472,12 +365,9 @@ PanelWindow { property int spacerSize: model.size || 20 anchors.verticalCenter: parent ? parent.verticalCenter : undefined - active: topBarContent.getWidgetVisible( - model.widgetId) - sourceComponent: topBarContent.getWidgetComponent( - model.widgetId) - opacity: topBarContent.getWidgetEnabled( - model.enabled) ? 1 : 0 + active: topBarContent.getWidgetVisible(model.widgetId) + sourceComponent: topBarContent.getWidgetComponent(model.widgetId) + opacity: topBarContent.getWidgetEnabled(model.enabled) ? 1 : 0 asynchronous: false } } @@ -492,7 +382,6 @@ PanelWindow { property real spacing: SettingsData.topBarNoBackground ? 2 : Theme.spacingS function updateLayout() { - // Defer layout if dimensions are invalid if (width <= 0 || height <= 0 || !visible) { Qt.callLater(updateLayout) return @@ -501,70 +390,67 @@ PanelWindow { centerWidgets = [] totalWidgets = 0 totalWidth = 0 + for (var i = 0; i < centerRepeater.count; i++) { - let item = centerRepeater.itemAt(i) - if (item && item.active && item.item) { + const item = centerRepeater.itemAt(i) + if (item?.active && item.item) { centerWidgets.push(item.item) totalWidgets++ totalWidth += item.item.width } } - if (totalWidgets > 1) - totalWidth += spacing * (totalWidgets - 1) + if (totalWidgets > 1) { + totalWidth += spacing * (totalWidgets - 1) + } positionWidgets() } function positionWidgets() { - if (totalWidgets === 0 || width <= 0) + if (totalWidgets === 0 || width <= 0) { return + } - let parentCenterX = width / 2 - if (totalWidgets % 2 === 1) { - let middleIndex = Math.floor( - totalWidgets / 2) - let currentX = parentCenterX - - (centerWidgets[middleIndex].width / 2) - centerWidgets[middleIndex].x = currentX - centerWidgets[middleIndex].anchors.horizontalCenter = undefined - currentX = centerWidgets[middleIndex].x + const parentCenterX = width / 2 + const isOdd = totalWidgets % 2 === 1 + + centerWidgets.forEach(widget => widget.anchors.horizontalCenter = undefined) + + if (isOdd) { + const middleIndex = Math.floor(totalWidgets / 2) + const middleWidget = centerWidgets[middleIndex] + middleWidget.x = parentCenterX - (middleWidget.width / 2) + + let currentX = middleWidget.x for (var i = middleIndex - 1; i >= 0; i--) { currentX -= (spacing + centerWidgets[i].width) centerWidgets[i].x = currentX - centerWidgets[i].anchors.horizontalCenter = undefined } - currentX = centerWidgets[middleIndex].x - + centerWidgets[middleIndex].width + + currentX = middleWidget.x + middleWidget.width for (var i = middleIndex + 1; i < totalWidgets; i++) { currentX += spacing centerWidgets[i].x = currentX - centerWidgets[i].anchors.horizontalCenter = undefined currentX += centerWidgets[i].width } } else { - let leftMiddleIndex = (totalWidgets / 2) - 1 - let rightMiddleIndex = totalWidgets / 2 - let gapCenter = parentCenterX - let halfSpacing = spacing / 2 - centerWidgets[leftMiddleIndex].x = gapCenter - - halfSpacing - centerWidgets[leftMiddleIndex].width - centerWidgets[leftMiddleIndex].anchors.horizontalCenter - = undefined - centerWidgets[rightMiddleIndex].x = gapCenter + halfSpacing - centerWidgets[rightMiddleIndex].anchors.horizontalCenter - = undefined - let currentX = centerWidgets[leftMiddleIndex].x - for (var i = leftMiddleIndex - 1; i >= 0; i--) { + const leftIndex = (totalWidgets / 2) - 1 + const rightIndex = totalWidgets / 2 + const halfSpacing = spacing / 2 + + centerWidgets[leftIndex].x = parentCenterX - halfSpacing - centerWidgets[leftIndex].width + centerWidgets[rightIndex].x = parentCenterX + halfSpacing + + let currentX = centerWidgets[leftIndex].x + for (var i = leftIndex - 1; i >= 0; i--) { currentX -= (spacing + centerWidgets[i].width) centerWidgets[i].x = currentX - centerWidgets[i].anchors.horizontalCenter = undefined } - currentX = centerWidgets[rightMiddleIndex].x - + centerWidgets[rightMiddleIndex].width - for (var i = rightMiddleIndex + 1; i < totalWidgets; i++) { + + currentX = centerWidgets[rightIndex].x + centerWidgets[rightIndex].width + for (var i = rightIndex + 1; i < totalWidgets; i++) { currentX += spacing centerWidgets[i].x = currentX - centerWidgets[i].anchors.horizontalCenter = undefined currentX += centerWidgets[i].width } } @@ -602,26 +488,20 @@ PanelWindow { property int spacerSize: model.size || 20 anchors.verticalCenter: parent ? parent.verticalCenter : undefined - active: topBarContent.getWidgetVisible( - model.widgetId) - sourceComponent: topBarContent.getWidgetComponent( - model.widgetId) - opacity: topBarContent.getWidgetEnabled( - model.enabled) ? 1 : 0 + active: topBarContent.getWidgetVisible(model.widgetId) + sourceComponent: topBarContent.getWidgetComponent(model.widgetId) + opacity: topBarContent.getWidgetEnabled(model.enabled) ? 1 : 0 asynchronous: false onLoaded: { - if (item) { - item.onWidthChanged.connect( - centerSection.updateLayout) - if (model.widgetId === "spacer") - item.spacerSize = Qt.binding( - () => { - return model.size - || 20 - }) - Qt.callLater(centerSection.updateLayout) + if (!item) { + return } + item.onWidthChanged.connect(centerSection.updateLayout) + if (model.widgetId === "spacer") { + item.spacerSize = Qt.binding(() => model.size || 20) + } + Qt.callLater(centerSection.updateLayout) } onActiveChanged: { Qt.callLater(centerSection.updateLayout) @@ -655,12 +535,9 @@ PanelWindow { property int spacerSize: model.size || 20 anchors.verticalCenter: parent ? parent.verticalCenter : undefined - active: topBarContent.getWidgetVisible( - model.widgetId) - sourceComponent: topBarContent.getWidgetComponent( - model.widgetId) - opacity: topBarContent.getWidgetEnabled( - model.enabled) ? 1 : 0 + active: topBarContent.getWidgetVisible(model.widgetId) + sourceComponent: topBarContent.getWidgetComponent(model.widgetId) + opacity: topBarContent.getWidgetEnabled(model.enabled) ? 1 : 0 asynchronous: false } } @@ -675,13 +552,11 @@ PanelWindow { height: root.widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) + if (SettingsData.topBarNoBackground) { return "transparent" + } const baseColor = clipboardArea.containsMouse ? Theme.primaryHover : Theme.secondaryHover - return Qt.rgba( - baseColor.r, baseColor.g, - baseColor.b, - baseColor.a * Theme.widgetTransparency) + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency) } DankIcon { @@ -719,23 +594,12 @@ PanelWindow { isActive: false widgetHeight: root.widgetHeight barHeight: root.effectiveBarHeight - section: { - if (parent && parent.parent) { - if (parent.parent === leftSection) - return "left" - if (parent.parent === rightSection) - return "right" - if (parent.parent === centerSection) - return "center" - } - return "left" - } + section: topBarContent.getWidgetSection(parent) popupTarget: appDrawerLoader.item parentScreen: root.screen onClicked: { appDrawerLoader.active = true - if (appDrawerLoader.item) - appDrawerLoader.item.toggle() + appDrawerLoader.item?.toggle() } } } @@ -748,7 +612,7 @@ PanelWindow { widgetHeight: root.widgetHeight } } - + Component { id: focusedWindowComponent @@ -763,17 +627,7 @@ PanelWindow { RunningApps { widgetHeight: root.widgetHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "left" - } + section: topBarContent.getWidgetSection(parent) parentScreen: root.screen topBar: topBarContent } @@ -786,17 +640,7 @@ PanelWindow { compactMode: topBarContent.overlapping barHeight: root.effectiveBarHeight widgetHeight: root.widgetHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "center" - } + section: topBarContent.getWidgetSection(parent) || "center" popupTarget: { centcomPopoutLoader.active = true return centcomPopoutLoader.item @@ -805,8 +649,7 @@ PanelWindow { onClockClicked: { centcomPopoutLoader.active = true if (centcomPopoutLoader.item) { - centcomPopoutLoader.item.calendarVisible - = !centcomPopoutLoader.item.calendarVisible + centcomPopoutLoader.item.calendarVisible = !centcomPopoutLoader.item.calendarVisible } } } @@ -816,21 +659,10 @@ PanelWindow { id: mediaComponent Media { - compactMode: topBarContent.spacingTight - || topBarContent.overlapping + compactMode: topBarContent.spacingTight || topBarContent.overlapping barHeight: root.effectiveBarHeight widgetHeight: root.widgetHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "center" - } + section: topBarContent.getWidgetSection(parent) || "center" popupTarget: { centcomPopoutLoader.active = true return centcomPopoutLoader.item @@ -839,8 +671,7 @@ PanelWindow { onClicked: { centcomPopoutLoader.active = true if (centcomPopoutLoader.item) { - centcomPopoutLoader.item.calendarVisible - = !centcomPopoutLoader.item.calendarVisible + centcomPopoutLoader.item.calendarVisible = !centcomPopoutLoader.item.calendarVisible } } } @@ -852,17 +683,7 @@ PanelWindow { Weather { barHeight: root.effectiveBarHeight widgetHeight: root.widgetHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "center" - } + section: topBarContent.getWidgetSection(parent) || "center" popupTarget: { centcomPopoutLoader.active = true return centcomPopoutLoader.item @@ -871,8 +692,7 @@ PanelWindow { onClicked: { centcomPopoutLoader.active = true if (centcomPopoutLoader.item) { - centcomPopoutLoader.item.calendarVisible - = !centcomPopoutLoader.item.calendarVisible + centcomPopoutLoader.item.calendarVisible = !centcomPopoutLoader.item.calendarVisible } } } @@ -893,17 +713,7 @@ PanelWindow { PrivacyIndicator { widgetHeight: root.widgetHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "right" - } + section: topBarContent.getWidgetSection(parent) || "right" parentScreen: root.screen } } @@ -914,17 +724,7 @@ PanelWindow { CpuMonitor { barHeight: root.effectiveBarHeight widgetHeight: root.widgetHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "right" - } + section: topBarContent.getWidgetSection(parent) || "right" popupTarget: { processListPopoutLoader.active = true return processListPopoutLoader.item @@ -932,8 +732,7 @@ PanelWindow { parentScreen: root.screen toggleProcessList: () => { processListPopoutLoader.active = true - if (processListPopoutLoader.item) - return processListPopoutLoader.item.toggle() + return processListPopoutLoader.item?.toggle() } } } @@ -944,17 +743,7 @@ PanelWindow { RamMonitor { barHeight: root.effectiveBarHeight widgetHeight: root.widgetHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "right" - } + section: topBarContent.getWidgetSection(parent) || "right" popupTarget: { processListPopoutLoader.active = true return processListPopoutLoader.item @@ -962,8 +751,7 @@ PanelWindow { parentScreen: root.screen toggleProcessList: () => { processListPopoutLoader.active = true - if (processListPopoutLoader.item) - return processListPopoutLoader.item.toggle() + return processListPopoutLoader.item?.toggle() } } } @@ -974,17 +762,7 @@ PanelWindow { CpuTemperature { barHeight: root.effectiveBarHeight widgetHeight: root.widgetHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "right" - } + section: topBarContent.getWidgetSection(parent) || "right" popupTarget: { processListPopoutLoader.active = true return processListPopoutLoader.item @@ -992,8 +770,7 @@ PanelWindow { parentScreen: root.screen toggleProcessList: () => { processListPopoutLoader.active = true - if (processListPopoutLoader.item) - return processListPopoutLoader.item.toggle() + return processListPopoutLoader.item?.toggle() } } } @@ -1004,17 +781,7 @@ PanelWindow { GpuTemperature { barHeight: root.effectiveBarHeight widgetHeight: root.widgetHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "right" - } + section: topBarContent.getWidgetSection(parent) || "right" popupTarget: { processListPopoutLoader.active = true return processListPopoutLoader.item @@ -1023,8 +790,7 @@ PanelWindow { widgetData: parent.widgetData toggleProcessList: () => { processListPopoutLoader.active = true - if (processListPopoutLoader.item) - return processListPopoutLoader.item.toggle() + return processListPopoutLoader.item?.toggle() } } } @@ -1043,17 +809,7 @@ PanelWindow { isActive: notificationCenterLoader.item ? notificationCenterLoader.item.shouldBeVisible : false widgetHeight: root.widgetHeight barHeight: root.effectiveBarHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "right" - } + section: topBarContent.getWidgetSection(parent) || "right" popupTarget: { notificationCenterLoader.active = true return notificationCenterLoader.item @@ -1061,9 +817,7 @@ PanelWindow { parentScreen: root.screen onClicked: { notificationCenterLoader.active = true - if (notificationCenterLoader.item) { - notificationCenterLoader.item.toggle() - } + notificationCenterLoader.item?.toggle() } } } @@ -1075,17 +829,7 @@ PanelWindow { batteryPopupVisible: batteryPopoutLoader.item ? batteryPopoutLoader.item.shouldBeVisible : false widgetHeight: root.widgetHeight barHeight: root.effectiveBarHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "right" - } + section: topBarContent.getWidgetSection(parent) || "right" popupTarget: { batteryPopoutLoader.active = true return batteryPopoutLoader.item @@ -1093,9 +837,7 @@ PanelWindow { parentScreen: root.screen onToggleBatteryPopup: { batteryPopoutLoader.active = true - if (batteryPopoutLoader.item) { - batteryPopoutLoader.item.toggle() - } + batteryPopoutLoader.item?.toggle() } } } @@ -1106,17 +848,7 @@ PanelWindow { Vpn { widgetHeight: root.widgetHeight barHeight: root.effectiveBarHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "right" - } + section: topBarContent.getWidgetSection(parent) || "right" popupTarget: { vpnPopoutLoader.active = true return vpnPopoutLoader.item @@ -1124,9 +856,7 @@ PanelWindow { parentScreen: root.screen onToggleVpnPopup: { vpnPopoutLoader.active = true - if (vpnPopoutLoader.item) { - vpnPopoutLoader.item.toggle() - } + vpnPopoutLoader.item?.toggle() } } } @@ -1138,17 +868,7 @@ PanelWindow { isActive: controlCenterLoader.item ? controlCenterLoader.item.shouldBeVisible : false widgetHeight: root.widgetHeight barHeight: root.effectiveBarHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "right" - } + section: topBarContent.getWidgetSection(parent) || "right" popupTarget: { controlCenterLoader.active = true return controlCenterLoader.item @@ -1157,13 +877,13 @@ PanelWindow { widgetData: parent.widgetData onClicked: { controlCenterLoader.active = true - if (controlCenterLoader.item) { - controlCenterLoader.item.triggerScreen = root.screen - controlCenterLoader.item.toggle() - if (controlCenterLoader.item.shouldBeVisible) { - if (NetworkService.wifiEnabled) - NetworkService.scanWifi() - } + if (!controlCenterLoader.item) { + return + } + controlCenterLoader.item.triggerScreen = root.screen + controlCenterLoader.item.toggle() + if (controlCenterLoader.item.shouldBeVisible && NetworkService.wifiEnabled) { + NetworkService.scanWifi() } } } @@ -1174,17 +894,7 @@ PanelWindow { IdleInhibitor { widgetHeight: root.widgetHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "right" - } + section: topBarContent.getWidgetSection(parent) || "right" parentScreen: root.screen } } @@ -1199,9 +909,7 @@ PanelWindow { Rectangle { anchors.fill: parent color: "transparent" - border.color: Qt.rgba(Theme.outline.r, - Theme.outline.g, - Theme.outline.b, 0.1) + border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.1) border.width: 1 radius: 2 visible: false @@ -1240,17 +948,7 @@ PanelWindow { isActive: notepadSlideoutLoader.item ? notepadSlideoutLoader.item.notepadVisible : false widgetHeight: root.widgetHeight barHeight: root.effectiveBarHeight - section: { - if (parent && parent.parent === leftSection) - return "left" - if (parent - && parent.parent === rightSection) - return "right" - if (parent - && parent.parent === centerSection) - return "center" - return "right" - } + section: topBarContent.getWidgetSection(parent) || "right" popupTarget: { notepadSlideoutLoader.active = true return notepadSlideoutLoader.item @@ -1258,9 +956,7 @@ PanelWindow { parentScreen: root.screen onClicked: { notepadSlideoutLoader.active = true - if (notepadSlideoutLoader.item) { - notepadSlideoutLoader.item.toggle() - } + notepadSlideoutLoader.item?.toggle() } } } diff --git a/Modules/TopBar/Vpn.qml b/Modules/TopBar/Vpn.qml index ce929484..4aa36265 100644 --- a/Modules/TopBar/Vpn.qml +++ b/Modules/TopBar/Vpn.qml @@ -13,22 +13,25 @@ Rectangle { property string section: "right" property var popupTarget: null property var parentScreen: null + readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30)) signal toggleVpnPopup() - readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetHeight / 30)) - width: Theme.iconSize + horizontalPadding * 2 height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" - const base = clickArea.containsMouse || (popupTarget && popupTarget.shouldBeVisible) ? Theme.primaryPressed : Theme.secondaryHover - return Qt.rgba(base.r, base.g, base.b, base.a * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const base = clickArea.containsMouse || (popupTarget && popupTarget.shouldBeVisible) ? Theme.primaryPressed : Theme.secondaryHover; + return Qt.rgba(base.r, base.g, base.b, base.a * Theme.widgetTransparency); } DankIcon { id: icon + name: VpnService.isBusy ? "sync" : (VpnService.connected ? "vpn_lock" : "vpn_key_off") size: Theme.iconSize - 6 color: VpnService.connected ? Theme.primary : Theme.surfaceText @@ -41,27 +44,30 @@ Rectangle { to: 360 duration: 900 } + } MouseArea { id: clickArea + anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onPressed: { if (popupTarget && popupTarget.setTriggerPosition) { - var globalPos = mapToGlobal(0, 0) - var currentScreen = parentScreen || Screen - var screenX = currentScreen.x || 0 - var relativeX = globalPos.x - screenX - popupTarget.setTriggerPosition(relativeX, barHeight + Theme.spacingXS, width, section, currentScreen) + const globalPos = mapToGlobal(0, 0); + const currentScreen = parentScreen || Screen; + const screenX = currentScreen.x || 0; + const relativeX = globalPos.x - screenX; + popupTarget.setTriggerPosition(relativeX, barHeight + Theme.spacingXS, width, section, currentScreen); } - root.toggleVpnPopup() + root.toggleVpnPopup(); } } Rectangle { id: tooltip + width: Math.max(120, tooltipText.contentWidth + Theme.spacingM * 2) height: tooltipText.contentHeight + Theme.spacingS * 2 radius: Theme.cornerRadius @@ -76,19 +82,32 @@ Rectangle { Text { id: tooltipText + anchors.centerIn: parent text: { - if (!VpnService.connected) return "VPN Disconnected" - const names = VpnService.activeNames || [] - if (names.length <= 1) return "VPN Connected • " + (names[0] || "") - return "VPN Connected • " + names[0] + " +" + (names.length - 1) + if (!VpnService.connected) { + return "VPN Disconnected"; + } + + const names = VpnService.activeNames || []; + if (names.length <= 1) { + return "VPN Connected • " + (names[0] || ""); + } + + return "VPN Connected • " + names[0] + " +" + (names.length - 1); } font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceText } Behavior on opacity { - NumberAnimation { duration: Theme.shortDuration; easing.type: Theme.standardEasing } + NumberAnimation { + duration: Theme.shortDuration + easing.type: Theme.standardEasing + } + } + } + } diff --git a/Modules/TopBar/VpnPopout.qml b/Modules/TopBar/VpnPopout.qml index 446fbce5..9ff91579 100644 --- a/Modules/TopBar/VpnPopout.qml +++ b/Modules/TopBar/VpnPopout.qml @@ -1,13 +1,14 @@ +// No external details import; content inlined for consistency + import QtQuick import QtQuick.Controls import QtQuick.Layouts import Quickshell import Quickshell.Wayland import Quickshell.Widgets -import qs.Widgets import qs.Common import qs.Services -// No external details import; content inlined for consistency +import qs.Widgets DankPopout { id: root @@ -16,11 +17,11 @@ DankPopout { property var triggerScreen: null function setTriggerPosition(x, y, width, section, screen) { - triggerX = x - triggerY = y - triggerWidth = width - triggerSection = section - triggerScreen = screen + triggerX = x; + triggerY = y; + triggerWidth = width; + triggerSection = section; + triggerScreen = screen; } popupWidth: 360 @@ -37,6 +38,7 @@ DankPopout { content: Component { Rectangle { id: content + implicitHeight: contentColumn.height + Theme.spacingL * 2 color: Theme.popupBackground() radius: Theme.cornerRadius @@ -45,11 +47,10 @@ DankPopout { antialiasing: true smooth: true focus: true - - Keys.onPressed: function (event) { + Keys.onPressed: function(event) { if (event.key === Qt.Key_Escape) { - root.close() - event.accepted = true + root.close(); + event.accepted = true; } } @@ -85,6 +86,7 @@ DankPopout { Column { id: contentColumn + anchors.left: parent.left anchors.right: parent.right anchors.top: parent.top @@ -94,6 +96,7 @@ DankPopout { Item { width: parent.width height: 32 + StyledText { text: "VPN Connections" font.pixelSize: Theme.fontSizeLarge @@ -120,17 +123,21 @@ DankPopout { MouseArea { id: closeArea + anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onPressed: root.close() } + } + } // Inlined VPN details Rectangle { id: vpnDetail + width: parent.width implicitHeight: detailsColumn.implicitHeight + Theme.spacingM * 2 radius: Theme.cornerRadius @@ -141,6 +148,7 @@ DankPopout { Column { id: detailsColumn + anchors.fill: parent anchors.margins: Theme.spacingM spacing: Theme.spacingS @@ -151,20 +159,32 @@ DankPopout { StyledText { text: { - if (!VpnService.connected) return "Active: None" - const names = VpnService.activeNames || [] - if (names.length <= 1) return "Active: " + (names[0] || "VPN") - return "Active: " + names[0] + " +" + (names.length - 1) + if (!VpnService.connected) { + return "Active: None"; + } + + const names = VpnService.activeNames || []; + if (names.length <= 1) { + return "Active: " + (names[0] || "VPN"); + } + + return "Active: " + names[0] + " +" + (names.length - 1); } font.pixelSize: Theme.fontSizeMedium color: Theme.surfaceText font.weight: Font.Medium } - Item { Layout.fillWidth: true; height: 1 } + Item { + Layout.fillWidth: true + height: 1 + } // Removed Quick Connect for clarity - Item { width: 1; height: 1 } + Item { + width: 1 + height: 1 + } // Disconnect all (shown only when any active) Rectangle { @@ -180,21 +200,40 @@ DankPopout { Row { anchors.centerIn: parent spacing: Theme.spacingXS - DankIcon { name: "link_off"; size: Theme.fontSizeSmall; color: Theme.surfaceText } - StyledText { text: "Disconnect"; font.pixelSize: Theme.fontSizeSmall; color: Theme.surfaceText; font.weight: Font.Medium } + + DankIcon { + name: "link_off" + size: Theme.fontSizeSmall + color: Theme.surfaceText + } + + StyledText { + text: "Disconnect" + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceText + font.weight: Font.Medium + } + } MouseArea { id: discAllArea + anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: VpnService.disconnectAllActive() } + } + } - Rectangle { height: 1; width: parent.width; color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) } + Rectangle { + height: 1 + width: parent.width + color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12) + } DankFlickable { width: parent.width @@ -204,6 +243,7 @@ DankPopout { Column { id: listCol + width: parent.width spacing: Theme.spacingXS @@ -215,16 +255,38 @@ DankPopout { Column { anchors.centerIn: parent spacing: Theme.spacingS - DankIcon { name: "playlist_remove"; size: 36; color: Theme.surfaceVariantText; anchors.horizontalCenter: parent.horizontalCenter } - StyledText { text: "No VPN profiles found"; font.pixelSize: Theme.fontSizeMedium; color: Theme.surfaceVariantText; anchors.horizontalCenter: parent.horizontalCenter } - StyledText { text: "Add a VPN in NetworkManager"; font.pixelSize: Theme.fontSizeSmall; color: Theme.surfaceVariantText; anchors.horizontalCenter: parent.horizontalCenter } + + DankIcon { + name: "playlist_remove" + size: 36 + color: Theme.surfaceVariantText + anchors.horizontalCenter: parent.horizontalCenter + } + + StyledText { + text: "No VPN profiles found" + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceVariantText + anchors.horizontalCenter: parent.horizontalCenter + } + + StyledText { + text: "Add a VPN in NetworkManager" + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceVariantText + anchors.horizontalCenter: parent.horizontalCenter + } + } + } Repeater { model: VpnService.profiles + delegate: Rectangle { required property var modelData + width: parent ? parent.width : 300 height: 50 radius: Theme.cornerRadius @@ -249,56 +311,109 @@ DankPopout { Column { spacing: 2 Layout.alignment: Qt.AlignVCenter - - StyledText { - text: modelData.name - font.pixelSize: Theme.fontSizeMedium - color: VpnService.isActiveUuid(modelData.uuid) ? Theme.primary : Theme.surfaceText + + StyledText { + text: modelData.name + font.pixelSize: Theme.fontSizeMedium + color: VpnService.isActiveUuid(modelData.uuid) ? Theme.primary : Theme.surfaceText + } + + StyledText { + text: { + if (modelData.type === "wireguard") { + return "WireGuard"; + } + + const svc = modelData.serviceType || ""; + if (svc.indexOf("openvpn") !== -1) { + return "OpenVPN"; + } + + if (svc.indexOf("wireguard") !== -1) { + return "WireGuard (plugin)"; + } + + if (svc.indexOf("openconnect") !== -1) { + return "OpenConnect"; + } + + if (svc.indexOf("fortissl") !== -1 || svc.indexOf("forti") !== -1) { + return "Fortinet"; + } + + if (svc.indexOf("strongswan") !== -1) { + return "IPsec (strongSwan)"; + } + + if (svc.indexOf("libreswan") !== -1) { + return "IPsec (Libreswan)"; + } + + if (svc.indexOf("l2tp") !== -1) { + return "L2TP/IPsec"; + } + + if (svc.indexOf("pptp") !== -1) { + return "PPTP"; + } + + if (svc.indexOf("vpnc") !== -1) { + return "Cisco (vpnc)"; + } + + if (svc.indexOf("sstp") !== -1) { + return "SSTP"; + } + + if (svc) { + const parts = svc.split('.'); + return parts[parts.length - 1]; + } + return "VPN"; + } + font.pixelSize: Theme.fontSizeSmall + color: Theme.surfaceTextMedium + } + } - StyledText { - text: { - if (modelData.type === "wireguard") return "WireGuard" - var svc = modelData.serviceType || "" - if (svc.indexOf("openvpn") !== -1) return "OpenVPN" - if (svc.indexOf("wireguard") !== -1) return "WireGuard (plugin)" - if (svc.indexOf("openconnect") !== -1) return "OpenConnect" - if (svc.indexOf("fortissl") !== -1 || svc.indexOf("forti") !== -1) return "Fortinet" - if (svc.indexOf("strongswan") !== -1) return "IPsec (strongSwan)" - if (svc.indexOf("libreswan") !== -1) return "IPsec (Libreswan)" - if (svc.indexOf("l2tp") !== -1) return "L2TP/IPsec" - if (svc.indexOf("pptp") !== -1) return "PPTP" - if (svc.indexOf("vpnc") !== -1) return "Cisco (vpnc)" - if (svc.indexOf("sstp") !== -1) return "SSTP" - if (svc) { - var parts = svc.split('.') - return parts[parts.length-1] - } - return "VPN" - } - font.pixelSize: Theme.fontSizeSmall - color: Theme.surfaceTextMedium + Item { + Layout.fillWidth: true + height: 1 } - } - Item { Layout.fillWidth: true; height: 1 } + } MouseArea { id: rowArea + anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: VpnService.toggle(modelData.uuid) } + } + + } + + Item { + height: 1 + width: 1 } - Item { height: 1; width: 1 } } + } + } + } + } + } + } + } diff --git a/Modules/TopBar/Weather.qml b/Modules/TopBar/Weather.qml index e55460f1..afd348af 100644 --- a/Modules/TopBar/Weather.qml +++ b/Modules/TopBar/Weather.qml @@ -13,18 +13,19 @@ Rectangle { property real widgetHeight: 30 readonly property real horizontalPadding: SettingsData.topBarNoBackground ? 2 : Theme.spacingS - signal clicked + signal clicked() visible: SettingsData.weatherEnabled - width: visible ? Math.min(100, - weatherRow.implicitWidth + horizontalPadding * 2) : 0 + width: visible ? Math.min(100, weatherRow.implicitWidth + horizontalPadding * 2) : 0 height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" - const baseColor = weatherArea.containsMouse ? Theme.primaryHover : Theme.surfaceTextHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + if (SettingsData.topBarNoBackground) { + return "transparent"; + } + + const baseColor = weatherArea.containsMouse ? Theme.primaryHover : Theme.surfaceTextHover; + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency); } Ref { @@ -46,16 +47,18 @@ Rectangle { StyledText { text: { - var temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp + const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp; if (temp === undefined || temp === null || temp === 0) { - return "--°" + (SettingsData.useFahrenheit ? "F" : "C") + return "--°" + (SettingsData.useFahrenheit ? "F" : "C"); } - return temp + "°" + (SettingsData.useFahrenheit ? "F" : "C") + + return temp + "°" + (SettingsData.useFahrenheit ? "F" : "C"); } font.pixelSize: Theme.fontSizeSmall color: Theme.surfaceText anchors.verticalCenter: parent.verticalCenter } + } MouseArea { @@ -66,15 +69,13 @@ Rectangle { cursorShape: Qt.PointingHandCursor onPressed: { if (popupTarget && popupTarget.setTriggerPosition) { - var globalPos = mapToGlobal(0, 0) - var currentScreen = parentScreen || Screen - var screenX = currentScreen.x || 0 - var relativeX = globalPos.x - screenX - popupTarget.setTriggerPosition( - relativeX, barHeight + Theme.spacingXS, - width, section, currentScreen) + const globalPos = mapToGlobal(0, 0); + const currentScreen = parentScreen || Screen; + const screenX = currentScreen.x || 0; + const relativeX = globalPos.x - screenX; + popupTarget.setTriggerPosition(relativeX, barHeight + Theme.spacingXS, width, section, currentScreen); } - root.clicked() + root.clicked(); } } @@ -83,6 +84,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } Behavior on width { @@ -90,5 +92,7 @@ Rectangle { duration: Theme.shortDuration easing.type: Theme.standardEasing } + } + } diff --git a/Modules/TopBar/WorkspaceSwitcher.qml b/Modules/TopBar/WorkspaceSwitcher.qml index 2140ab15..d4ef0167 100644 --- a/Modules/TopBar/WorkspaceSwitcher.qml +++ b/Modules/TopBar/WorkspaceSwitcher.qml @@ -22,260 +22,190 @@ Rectangle { } property var workspaceList: { if (CompositorService.isNiri) { - var baseList = getNiriWorkspaces() + const baseList = getNiriWorkspaces() return SettingsData.showWorkspacePadding ? padWorkspaces(baseList) : baseList - } else if (CompositorService.isHyprland) { - var workspaces = Hyprland.workspaces ? Hyprland.workspaces.values : [] + } + if (CompositorService.isHyprland) { + const workspaces = Hyprland.workspaces?.values || [] if (workspaces.length === 0) { - return [{id: 1, name: "1"}] + return [{ + "id": 1, + "name": "1" + }] } - var sorted = workspaces.slice().sort((a, b) => a.id - b.id) + const sorted = workspaces.slice().sort((a, b) => a.id - b.id) return SettingsData.showWorkspacePadding ? padWorkspaces(sorted) : sorted } return [1] } function getWorkspaceIcons(ws) { - if (!SettingsData.showWorkspaceApps) return [] - - var chunks = [] - if (!ws) return chunks + if (!SettingsData.showWorkspaceApps || !ws) { + return [] + } - var targetWorkspaceId + let targetWorkspaceId if (CompositorService.isNiri) { - // For Niri, we need to find the workspace ID from allWorkspaces - var wsNumber = typeof ws === "number" ? ws : -1 - if (wsNumber > 0) { - for (var j = 0; j < NiriService.allWorkspaces.length; j++) { - var workspace = NiriService.allWorkspaces[j] - if (workspace.idx + 1 === wsNumber && workspace.output === root.screenName) { - targetWorkspaceId = workspace.id - break - } - } + const wsNumber = typeof ws === "number" ? ws : -1 + if (wsNumber <= 0) { + return [] } - if (targetWorkspaceId === undefined) return chunks + const workspace = NiriService.allWorkspaces.find(w => w.idx + 1 === wsNumber && w.output === root.screenName) + if (!workspace) { + return [] + } + targetWorkspaceId = workspace.id } else if (CompositorService.isHyprland) { targetWorkspaceId = ws.id !== undefined ? ws.id : ws } else { - return chunks + return [] } - var wins = [] - if (CompositorService.isNiri) { - wins = NiriService.windows || [] - } else if (CompositorService.isHyprland) { - wins = Hyprland.clients ? Hyprland.clients.values : [] - } + const wins = CompositorService.isNiri ? (NiriService.windows || []) : (Hyprland.clients?.values || []) - var byApp = {} - var isActiveWs = false - if (CompositorService.isNiri) { - for (var j = 0; j < NiriService.allWorkspaces.length; j++) { - var ws2 = NiriService.allWorkspaces[j] - if (ws2.id === targetWorkspaceId && ws2.is_active) { - isActiveWs = true - break - } - } - } else if (CompositorService.isHyprland) { - isActiveWs = targetWorkspaceId === root.currentWorkspace - } + const byApp = {} + const isActiveWs = CompositorService.isNiri ? NiriService.allWorkspaces.some(ws => ws.id === targetWorkspaceId && ws.is_active) : targetWorkspaceId === root.currentWorkspace - for (var i = 0; i < wins.length; i++) { - var w = wins[i] - if (!w) continue + wins.forEach((w, i) => { + if (!w) { + return + } - var winWs - if (CompositorService.isNiri) { - winWs = w.workspace_id - } else if (CompositorService.isHyprland) { - winWs = w.workspace && w.workspace.id !== undefined ? w.workspace.id : w.workspaceId - } - - if (winWs === undefined || winWs === null) continue - if (winWs !== targetWorkspaceId) continue + const winWs = CompositorService.isNiri ? w.workspace_id : (w.workspace?.id ?? w.workspaceId) - var keyBase = (w.app_id || w.appId || w.class || w.windowClass || w.exe || "unknown").toLowerCase() - var key = isActiveWs ? keyBase + "_" + i : keyBase + if (winWs === undefined || winWs === null || winWs !== targetWorkspaceId) { + return + } - if (!byApp[key]) { - var icon = Quickshell.iconPath(DesktopEntries.heuristicLookup(Paths.moddedAppId(keyBase))?.icon, true) - byApp[key] = { - type: "icon", - icon: icon, - active: !!w.is_focused || !!w.activated, - count: 1, - windowId: w.id || w.address, - fallbackText: w.app_id || w.appId || w.class || w.title || "" - } - } else { - byApp[key].count++ - if (w.is_focused || w.activated) byApp[key].active = true - } - } + const keyBase = (w.app_id || w.appId || w.class || w.windowClass || w.exe || "unknown").toLowerCase() + const key = isActiveWs ? `${keyBase}_${i}` : keyBase - for (var k in byApp) - chunks.push(byApp[k]) + if (!byApp[key]) { + const icon = Quickshell.iconPath(DesktopEntries.heuristicLookup(Paths.moddedAppId(keyBase))?.icon, true) + byApp[key] = { + "type": "icon", + "icon": icon, + "active": !!(w.is_focused || w.activated), + "count": 1, + "windowId": w.id || w.address, + "fallbackText": w.app_id || w.appId || w.class || w.title || "" + } + } else { + byApp[key].count++ + if (w.is_focused || w.activated) { + byApp[key].active = true + } + } + }) - return chunks + return Object.values(byApp) } function padWorkspaces(list) { - var padded = list.slice() + const padded = list.slice() + const placeholder = CompositorService.isHyprland ? { + "id": -1, + "name": "" + } : -1 while (padded.length < 3) { - if (CompositorService.isHyprland) { - padded.push({id: -1, name: ""}) - } else { - padded.push(-1) - } + padded.push(placeholder) } return padded } function getNiriWorkspaces() { - if (NiriService.allWorkspaces.length === 0) + if (NiriService.allWorkspaces.length === 0) { return [1, 2] - - if (!root.screenName) - return NiriService.getCurrentOutputWorkspaceNumbers() - - var displayWorkspaces = [] - for (var i = 0; i < NiriService.allWorkspaces.length; i++) { - var ws = NiriService.allWorkspaces[i] - if (ws.output === root.screenName) - displayWorkspaces.push(ws.idx + 1) } + + if (!root.screenName) { + return NiriService.getCurrentOutputWorkspaceNumbers() + } + + const displayWorkspaces = NiriService.allWorkspaces.filter(ws => ws.output === root.screenName).map(ws => ws.idx + 1) return displayWorkspaces.length > 0 ? displayWorkspaces : [1, 2] } function getNiriActiveWorkspace() { - if (NiriService.allWorkspaces.length === 0) + if (NiriService.allWorkspaces.length === 0) { return 1 - - if (!root.screenName) - return NiriService.getCurrentWorkspaceNumber() - - for (var i = 0; i < NiriService.allWorkspaces.length; i++) { - var ws = NiriService.allWorkspaces[i] - if (ws.output === root.screenName && ws.is_active) - return ws.idx + 1 } - return 1 + + if (!root.screenName) { + return NiriService.getCurrentWorkspaceNumber() + } + + const activeWs = NiriService.allWorkspaces.find(ws => ws.output === root.screenName && ws.is_active) + return activeWs ? activeWs.idx + 1 : 1 } readonly property real padding: (widgetHeight - workspaceRow.implicitHeight) / 2 - + + function getRealWorkspaces() { + return root.workspaceList.filter(ws => { + if (CompositorService.isHyprland) { + return ws && ws.id !== -1 + } + return ws !== -1 + }) + } + + function switchWorkspace(direction) { + if (CompositorService.isNiri) { + const realWorkspaces = getRealWorkspaces() + if (realWorkspaces.length < 2) { + return + } + + const currentIndex = realWorkspaces.findIndex(ws => ws === root.currentWorkspace) + const validIndex = currentIndex === -1 ? 0 : currentIndex + const nextIndex = direction > 0 ? (validIndex + 1) % realWorkspaces.length : (validIndex - 1 + realWorkspaces.length) % realWorkspaces.length + + NiriService.switchToWorkspace(realWorkspaces[nextIndex] - 1) + } else if (CompositorService.isHyprland) { + const command = direction > 0 ? "workspace r+1" : "workspace r-1" + Hyprland.dispatch(command) + } + } + width: workspaceRow.implicitWidth + padding * 2 height: widgetHeight radius: SettingsData.topBarNoBackground ? 0 : Theme.cornerRadius color: { - if (SettingsData.topBarNoBackground) return "transparent" + if (SettingsData.topBarNoBackground) + return "transparent" const baseColor = Theme.surfaceTextHover - return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, - baseColor.a * Theme.widgetTransparency) + return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency) } visible: CompositorService.isNiri || CompositorService.isHyprland - MouseArea { anchors.fill: parent hoverEnabled: true acceptedButtons: Qt.NoButton - + property real scrollAccumulator: 0 property real touchpadThreshold: 500 - - onWheel: (wheel) => { - const deltaY = wheel.angleDelta.y - const isMouseWheel = Math.abs(deltaY) >= 120 - && (Math.abs(deltaY) % 120) === 0 - - if (isMouseWheel) { - // Direct mouse wheel action - if (CompositorService.isNiri) { - var realWorkspaces = []; - for (var i = 0; i < root.workspaceList.length; i++) { - if (root.workspaceList[i] !== -1) { - realWorkspaces.push(root.workspaceList[i]); - } - } - if (realWorkspaces.length < 2) return; + onWheel: wheel => { + const deltaY = wheel.angleDelta.y + const isMouseWheel = Math.abs(deltaY) >= 120 && (Math.abs(deltaY) % 120) === 0 + const direction = deltaY < 0 ? 1 : -1 - var currentIndex = -1; - for (var i = 0; i < realWorkspaces.length; i++) { - if (realWorkspaces[i] === root.currentWorkspace) { - currentIndex = i; - break; - } - } - if (currentIndex === -1) currentIndex = 0; + if (isMouseWheel) { + switchWorkspace(direction) + } else { + scrollAccumulator += deltaY - var nextIndex; - if (deltaY < 0) { - nextIndex = (currentIndex + 1) % realWorkspaces.length; - } else { - nextIndex = (currentIndex - 1 + realWorkspaces.length) % realWorkspaces.length; - } - NiriService.switchToWorkspace(realWorkspaces[nextIndex] - 1); + if (Math.abs(scrollAccumulator) >= touchpadThreshold) { + const touchDirection = scrollAccumulator < 0 ? 1 : -1 + switchWorkspace(touchDirection) + scrollAccumulator = 0 + } + } - } else if (CompositorService.isHyprland) { - if (deltaY < 0) { - Hyprland.dispatch("workspace r+1"); - } else { - Hyprland.dispatch("workspace r-1"); - } - } - } else { - // Touchpad - accumulate small deltas - scrollAccumulator += deltaY - - if (Math.abs(scrollAccumulator) >= touchpadThreshold) { - if (CompositorService.isNiri) { - var realWorkspaces = []; - for (var i = 0; i < root.workspaceList.length; i++) { - if (root.workspaceList[i] !== -1) { - realWorkspaces.push(root.workspaceList[i]); - } - } - - if (realWorkspaces.length < 2) { - scrollAccumulator = 0; - return; - } - - var currentIndex = -1; - for (var i = 0; i < realWorkspaces.length; i++) { - if (realWorkspaces[i] === root.currentWorkspace) { - currentIndex = i; - break; - } - } - if (currentIndex === -1) currentIndex = 0; - - var nextIndex; - if (scrollAccumulator < 0) { - nextIndex = (currentIndex + 1) % realWorkspaces.length; - } else { - nextIndex = (currentIndex - 1 + realWorkspaces.length) % realWorkspaces.length; - } - NiriService.switchToWorkspace(realWorkspaces[nextIndex] - 1); - - } else if (CompositorService.isHyprland) { - if (scrollAccumulator < 0) { - Hyprland.dispatch("workspace r+1"); - } else { - Hyprland.dispatch("workspace r-1"); - } - } - - scrollAccumulator = 0 - } - } - - wheel.accepted = true - } + wheel.accepted = true + } } Row { @@ -302,23 +232,16 @@ Rectangle { } property bool isHovered: mouseArea.containsMouse property var workspaceData: { - if (isPlaceholder) + if (isPlaceholder) { return null - - if (CompositorService.isNiri) { - for (var i = 0; i < NiriService.allWorkspaces.length; i++) { - var ws = NiriService.allWorkspaces[i] - if (ws.idx + 1 === modelData && ws.output === root.screenName) - return ws - } - } else if (CompositorService.isHyprland) { - return modelData } - return null + + if (CompositorService.isNiri) { + return NiriService.allWorkspaces.find(ws => ws.idx + 1 === modelData && ws.output === root.screenName) || null + } + return CompositorService.isHyprland ? modelData : null } - property var iconData: workspaceData - && workspaceData.name ? SettingsData.getWorkspaceNameIcon( - workspaceData.name) : null + property var iconData: workspaceData?.name ? SettingsData.getWorkspaceNameIcon(workspaceData.name) : null property bool hasIcon: iconData !== null property var icons: SettingsData.showWorkspaceApps ? root.getWorkspaceIcons(CompositorService.isHyprland ? modelData : (modelData === -1 ? null : modelData)) : [] @@ -344,14 +267,14 @@ Rectangle { cursorShape: isPlaceholder ? Qt.ArrowCursor : Qt.PointingHandCursor enabled: !isPlaceholder onClicked: { - if (!isPlaceholder) { - if (CompositorService.isNiri) { - NiriService.switchToWorkspace(modelData - 1) - } else if (CompositorService.isHyprland) { - if (modelData && modelData.id) { - Hyprland.dispatch(`workspace ${modelData.id}`) - } - } + if (isPlaceholder) { + return + } + + if (CompositorService.isNiri) { + NiriService.switchToWorkspace(modelData - 1) + } else if (CompositorService.isHyprland && modelData?.id) { + Hyprland.dispatch(`workspace ${modelData.id}`) } } } @@ -416,53 +339,36 @@ Rectangle { DankIcon { visible: hasIcon && iconData.type === "icon" && (!SettingsData.showWorkspaceApps || icons.length === 0) anchors.centerIn: parent - name: hasIcon - && iconData.type === "icon" ? iconData.value : "" + name: (hasIcon && iconData.type === "icon") ? iconData.value : "" size: Theme.fontSizeSmall - color: isActive ? Qt.rgba(Theme.surfaceContainer.r, - Theme.surfaceContainer.g, - Theme.surfaceContainer.b, - 0.95) : Theme.surfaceTextMedium + color: isActive ? Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95) : Theme.surfaceTextMedium weight: isActive && !isPlaceholder ? 500 : 400 } StyledText { visible: hasIcon && iconData.type === "text" && (!SettingsData.showWorkspaceApps || icons.length === 0) anchors.centerIn: parent - text: hasIcon - && iconData.type === "text" ? iconData.value : "" - color: isActive ? Qt.rgba(Theme.surfaceContainer.r, - Theme.surfaceContainer.g, - Theme.surfaceContainer.b, - 0.95) : Theme.surfaceTextMedium + text: (hasIcon && iconData.type === "text") ? iconData.value : "" + color: isActive ? Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95) : Theme.surfaceTextMedium font.pixelSize: Theme.fontSizeSmall - font.weight: isActive - && !isPlaceholder ? Font.DemiBold : Font.Normal + font.weight: (isActive && !isPlaceholder) ? Font.DemiBold : Font.Normal } StyledText { visible: (SettingsData.showWorkspaceIndex && !hasIcon && (!SettingsData.showWorkspaceApps || icons.length === 0)) anchors.centerIn: parent text: { - if (CompositorService.isHyprland) { - if (modelData && modelData.id === -1) { - return index + 1 - } - return modelData && modelData.id ? modelData.id : "" - } - if (modelData === -1) { + const isPlaceholder = CompositorService.isHyprland ? (modelData?.id === -1) : (modelData === -1) + + if (isPlaceholder) { return index + 1 } - return modelData - 1 + + return CompositorService.isHyprland ? (modelData?.id || "") : (modelData - 1) } - color: isActive ? Qt.rgba( - Theme.surfaceContainer.r, - Theme.surfaceContainer.g, - Theme.surfaceContainer.b, - 0.95) : isPlaceholder ? Theme.surfaceTextAlpha : Theme.surfaceTextMedium + color: isActive ? Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, 0.95) : isPlaceholder ? Theme.surfaceTextAlpha : Theme.surfaceTextMedium font.pixelSize: Theme.fontSizeSmall - font.weight: isActive - && !isPlaceholder ? Font.DemiBold : Font.Normal + font.weight: (isActive && !isPlaceholder) ? Font.DemiBold : Font.Normal } Behavior on width { @@ -481,4 +387,4 @@ Rectangle { } } } -} \ No newline at end of file +} diff --git a/Services/AppSearchService.qml b/Services/AppSearchService.qml index c45e4937..7f53e9a9 100644 --- a/Services/AppSearchService.qml +++ b/Services/AppSearchService.qml @@ -17,43 +17,38 @@ Singleton { if (applications.length === 0) return [] - const queryLower = query.toLowerCase() + const queryLower = query.toLowerCase().trim() const scoredApps = [] - + for (const app of applications) { const name = (app.name || "").toLowerCase() const genericName = (app.genericName || "").toLowerCase() const comment = (app.comment || "").toLowerCase() const keywords = app.keywords ? app.keywords.map(k => k.toLowerCase()) : [] - + let score = 0 let matched = false - + const nameWords = name.trim().split(/\s+/).filter(w => w.length > 0) const containsAsWord = nameWords.includes(queryLower) const startsWithAsWord = nameWords.some(word => word.startsWith(queryLower)) - + if (name === queryLower) { score = 10000 matched = true - } - else if (containsAsWord) { + } else if (containsAsWord) { score = 9500 + (100 - Math.min(name.length, 100)) matched = true - } - else if (name.startsWith(queryLower)) { + } else if (name.startsWith(queryLower)) { score = 9000 + (100 - Math.min(name.length, 100)) matched = true - } - else if (startsWithAsWord) { + } else if (startsWithAsWord) { score = 8500 + (100 - Math.min(name.length, 100)) matched = true - } - else if (name.includes(queryLower)) { + } else if (name.includes(queryLower)) { score = 8000 + (100 - Math.min(name.length, 100)) matched = true - } - else if (keywords.length > 0) { + } else if (keywords.length > 0) { for (const keyword of keywords) { if (keyword === queryLower) { score = 6000 @@ -73,29 +68,30 @@ Singleton { if (!matched && genericName.includes(queryLower)) { score = 4000 matched = true - } - else if (!matched && comment.includes(queryLower)) { + } else if (!matched && comment.includes(queryLower)) { score = 3000 matched = true - } - else if (!matched) { + } else if (!matched) { const nameFinder = new Fzf.Finder([app], { - "selector": a => a.name || "", - "casing": "case-insensitive", - "fuzzy": "v2" - }) + "selector": a => a.name || "", + "casing": "case-insensitive", + "fuzzy": "v2" + }) const fuzzyResults = nameFinder.find(query) if (fuzzyResults.length > 0 && fuzzyResults[0].score > 0) { score = Math.min(fuzzyResults[0].score, 2000) matched = true } } - + if (matched) { - scoredApps.push({ app, score }) + scoredApps.push({ + "app": app, + "score": score + }) } } - + scoredApps.sort((a, b) => b.score - a.score) return scoredApps.slice(0, 50).map(item => item.app) } diff --git a/qmlformat-all.sh b/qmlformat-all.sh index 66806e7b..d1f9b41a 100755 --- a/qmlformat-all.sh +++ b/qmlformat-all.sh @@ -1,4 +1,7 @@ #!/usr/bin/env bash -# https://github.com/jesperhh/qmlfmt -find . -name "*.qml" -exec qmlfmt -t 4 -i 4 -b 250 -w {} \; +# Find and format all QML files, then fix pragma ComponentBehavior +find . -name "*.qml" -exec sh -c ' + qmlfmt -t 4 -i 4 -b 250 -w "$1" + sed -i "s/pragma ComponentBehavior$/pragma ComponentBehavior: Bound/g" "$1" +' _ {} \; \ No newline at end of file