mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-05 21:15:38 -05:00
modules cleanup and qmlfmt everywhere
- throw in 24H clock fix and app drawer fix too
This commit is contained in:
@@ -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
|
||||
|
||||
24
CONTRIBUTING.md
Normal file
24
CONTRIBUTING.md
Normal file
@@ -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
|
||||
},
|
||||
```
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 || "")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<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
|
||||
}
|
||||
}
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,4 @@ DankOSD {
|
||||
size: Theme.iconSize
|
||||
color: SessionService.idleInhibited ? Theme.primary : Theme.outline
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,4 +24,4 @@ DankOSD {
|
||||
size: Theme.iconSize
|
||||
color: AudioService.source && AudioService.source.audio && AudioService.source.audio.muted ? Theme.error : Theme.primary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ ColumnLayout {
|
||||
ProcessListView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
contextMenu: processesTab.contextMenu || localContextMenu
|
||||
contextMenu: processesTab.contextMenu
|
||||
}
|
||||
|
||||
ProcessContextMenu {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
' _ {} \;
|
||||
Reference in New Issue
Block a user