1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-24 21:42:51 -05:00

dankbar: support multiple bars and per-display bars

- Migrate settings to v2
  - Up to 4 bars
  - Per-bar settings instead of global
This commit is contained in:
bbedward
2025-11-22 15:28:06 -05:00
parent 4f32376f22
commit a3a27e07fa
69 changed files with 5567 additions and 3846 deletions

View File

@@ -8,15 +8,17 @@ Item {
required property var barWindow
required property var axis
required property var barConfig
anchors.fill: parent
anchors.left: parent.left
anchors.top: parent.top
anchors.leftMargin: -(SettingsData.dankBarGothCornersEnabled && axis.isVertical && axis.edge === "right" ? barWindow._wingR : 0)
anchors.rightMargin: -(SettingsData.dankBarGothCornersEnabled && axis.isVertical && axis.edge === "left" ? barWindow._wingR : 0)
anchors.topMargin: -(SettingsData.dankBarGothCornersEnabled && !axis.isVertical && axis.edge === "bottom" ? barWindow._wingR : 0)
anchors.bottomMargin: -(SettingsData.dankBarGothCornersEnabled && !axis.isVertical && axis.edge === "top" ? barWindow._wingR : 0)
readonly property bool gothEnabled: barConfig?.gothCornersEnabled ?? false
anchors.leftMargin: -(gothEnabled && axis.isVertical && axis.edge === "right" ? barWindow._wingR : 0)
anchors.rightMargin: -(gothEnabled && axis.isVertical && axis.edge === "left" ? barWindow._wingR : 0)
anchors.topMargin: -(gothEnabled && !axis.isVertical && axis.edge === "bottom" ? barWindow._wingR : 0)
anchors.bottomMargin: -(gothEnabled && !axis.isVertical && axis.edge === "top" ? barWindow._wingR : 0)
readonly property real dpr: CompositorService.getScreenScale(barWindow.screen)
@@ -65,8 +67,8 @@ Item {
readonly property real correctHeight: Theme.px(root.height, dpr)
canvasSize: Qt.size(correctWidth, correctHeight)
property real wing: SettingsData.dankBarGothCornersEnabled ? Theme.px(barWindow._wingR, dpr) : 0
property real rt: SettingsData.dankBarSquareCorners ? 0 : Theme.px(Theme.cornerRadius, dpr)
property real wing: (barConfig?.gothCornersEnabled ?? false) ? Theme.px(barWindow._wingR, dpr) : 0
property real rt: (barConfig?.squareCorners ?? false) ? 0 : Theme.px(Theme.cornerRadius, dpr)
onWingChanged: root.requestRepaint()
onRtChanged: root.requestRepaint()
@@ -83,6 +85,8 @@ Item {
Connections {
target: barWindow
function on_BgColorChanged() { root.requestRepaint() }
function onGothCornersEnabledChanged() { root.requestRepaint() }
function onWingtipsRadiusChanged() { root.requestRepaint() }
}
Connections {
@@ -91,12 +95,6 @@ Item {
function onSurfaceContainerChanged() { root.requestRepaint() }
}
Connections {
target: SettingsData
function onDankBarGothCornerRadiusOverrideChanged() { root.requestRepaint() }
function onDankBarGothCornerRadiusValueChanged() { root.requestRepaint() }
}
onPaint: {
const ctx = getContext("2d")
const W = barWindow.isVertical ? correctHeight : correctWidth
@@ -104,10 +102,11 @@ Item {
const R = wing
const RT = rt
const H = H_raw - (R > 0 ? R : 0)
const isTop = SettingsData.dankBarPosition === SettingsData.Position.Top
const isBottom = SettingsData.dankBarPosition === SettingsData.Position.Bottom
const isLeft = SettingsData.dankBarPosition === SettingsData.Position.Left
const isRight = SettingsData.dankBarPosition === SettingsData.Position.Right
const barPos = barConfig?.position ?? 0
const isTop = barPos === SettingsData.Position.Top
const isBottom = barPos === SettingsData.Position.Bottom
const isLeft = barPos === SettingsData.Position.Left
const isRight = barPos === SettingsData.Position.Right
function drawTopPath() {
ctx.beginPath()
@@ -168,8 +167,8 @@ Item {
readonly property real correctHeight: Theme.px(root.height, dpr)
canvasSize: Qt.size(correctWidth, correctHeight)
property real wing: SettingsData.dankBarGothCornersEnabled ? Theme.px(barWindow._wingR, dpr) : 0
property real rt: SettingsData.dankBarSquareCorners ? 0 : Theme.px(Theme.cornerRadius, dpr)
property real wing: (barConfig?.gothCornersEnabled ?? false) ? Theme.px(barWindow._wingR, dpr) : 0
property real rt: (barConfig?.squareCorners ?? false) ? 0 : Theme.px(Theme.cornerRadius, dpr)
property real alphaTint: (barWindow._bgColor?.a ?? 1) < 0.99 ? (Theme.stateLayerOpacity ?? 0) : 0
onWingChanged: root.requestRepaint()
@@ -188,6 +187,8 @@ Item {
Connections {
target: barWindow
function on_BgColorChanged() { root.requestRepaint() }
function onGothCornersEnabledChanged() { root.requestRepaint() }
function onWingtipsRadiusChanged() { root.requestRepaint() }
}
Connections {
@@ -196,12 +197,6 @@ Item {
function onSurfaceChanged() { root.requestRepaint() }
}
Connections {
target: SettingsData
function onDankBarGothCornerRadiusOverrideChanged() { root.requestRepaint() }
function onDankBarGothCornerRadiusValueChanged() { root.requestRepaint() }
}
onPaint: {
const ctx = getContext("2d")
const W = barWindow.isVertical ? correctHeight : correctWidth
@@ -209,10 +204,11 @@ Item {
const R = wing
const RT = rt
const H = H_raw - (R > 0 ? R : 0)
const isTop = SettingsData.dankBarPosition === SettingsData.Position.Top
const isBottom = SettingsData.dankBarPosition === SettingsData.Position.Bottom
const isLeft = SettingsData.dankBarPosition === SettingsData.Position.Left
const isRight = SettingsData.dankBarPosition === SettingsData.Position.Right
const barPos = barConfig?.position ?? 0
const isTop = barPos === SettingsData.Position.Top
const isBottom = barPos === SettingsData.Position.Bottom
const isLeft = barPos === SettingsData.Position.Left
const isRight = barPos === SettingsData.Position.Right
function drawTopPath() {
ctx.beginPath()
@@ -265,7 +261,7 @@ Item {
Canvas {
id: barBorder
anchors.fill: parent
visible: SettingsData.dankBarBorderEnabled
visible: barConfig?.borderEnabled ?? false
renderTarget: Canvas.FramebufferObject
renderStrategy: Canvas.Cooperative
@@ -273,9 +269,9 @@ Item {
readonly property real correctHeight: Theme.px(root.height, dpr)
canvasSize: Qt.size(correctWidth, correctHeight)
property real wing: SettingsData.dankBarGothCornersEnabled ? Theme.px(barWindow._wingR, dpr) : 0
property real rt: SettingsData.dankBarSquareCorners ? 0 : Theme.px(Theme.cornerRadius, dpr)
property bool borderEnabled: SettingsData.dankBarBorderEnabled
property real wing: (barConfig?.gothCornersEnabled ?? false) ? Theme.px(barWindow._wingR, dpr) : 0
property real rt: (barConfig?.squareCorners ?? false) ? 0 : Theme.px(Theme.cornerRadius, dpr)
property bool borderEnabled: barConfig?.borderEnabled ?? false
antialiasing: rt > 0 || wing > 0
@@ -302,15 +298,9 @@ Item {
}
Connections {
target: SettingsData
function onDankBarBorderColorChanged() { root.requestRepaint() }
function onDankBarBorderOpacityChanged() { root.requestRepaint() }
function onDankBarBorderThicknessChanged() { root.requestRepaint() }
function onDankBarSpacingChanged() { root.requestRepaint() }
function onDankBarSquareCornersChanged() { root.requestRepaint() }
function onDankBarTransparencyChanged() { root.requestRepaint() }
function onDankBarGothCornerRadiusOverrideChanged() { root.requestRepaint() }
function onDankBarGothCornerRadiusValueChanged() { root.requestRepaint() }
target: barWindow
function onGothCornersEnabledChanged() { root.requestRepaint() }
function onWingtipsRadiusChanged() { root.requestRepaint() }
}
onPaint: {
@@ -322,12 +312,13 @@ Item {
const R = wing
const RT = rt
const H = H_raw - (R > 0 ? R : 0)
const isTop = SettingsData.dankBarPosition === SettingsData.Position.Top
const isBottom = SettingsData.dankBarPosition === SettingsData.Position.Bottom
const isLeft = SettingsData.dankBarPosition === SettingsData.Position.Left
const isRight = SettingsData.dankBarPosition === SettingsData.Position.Right
const barPos = barConfig?.position ?? 0
const isTop = barPos === SettingsData.Position.Top
const isBottom = barPos === SettingsData.Position.Bottom
const isLeft = barPos === SettingsData.Position.Left
const isRight = barPos === SettingsData.Position.Right
const spacing = SettingsData.dankBarSpacing
const spacing = barConfig?.spacing ?? 4
const hasEdgeGap = spacing > 0 || RT > 0
ctx.reset()
@@ -345,14 +336,14 @@ Item {
ctx.rotate(Math.PI / 2)
}
const uiThickness = Math.max(1, SettingsData.dankBarBorderThickness ?? 1)
const uiThickness = Math.max(1, barConfig?.borderThickness ?? 1)
const devThickness = Math.max(1, Math.round(Theme.px(uiThickness, dpr)))
const key = SettingsData.dankBarBorderColor || "surfaceText"
const key = barConfig?.borderColor || "surfaceText"
const base = (key === "surfaceText") ? Theme.surfaceText
: (key === "primary") ? Theme.primary
: Theme.secondary
const color = Theme.withAlpha(base, SettingsData.dankBarBorderOpacity ?? 1.0)
const color = Theme.withAlpha(base, barConfig?.borderOpacity ?? 1.0)
ctx.globalCompositeOperation = "source-over"
ctx.fillStyle = color

View File

@@ -13,6 +13,8 @@ Item {
property var parentScreen: null
property real widgetThickness: 30
property real barThickness: 48
property real barSpacing: 4
property var barConfig: null
property bool overrideAxisLayout: false
property bool forceVerticalLayout: false
@@ -25,238 +27,238 @@ Item {
function updateLayout() {
if ((isVertical ? height : width) <= 0 || !visible) {
return
return;
}
centerWidgets = []
totalWidgets = 0
totalSize = 0
centerWidgets = [];
totalWidgets = 0;
totalSize = 0;
let configuredWidgets = 0
let configuredMiddleWidget = null
let configuredLeftWidget = null
let configuredRightWidget = null
let configuredWidgets = 0;
let configuredMiddleWidget = null;
let configuredLeftWidget = null;
let configuredRightWidget = null;
for (var i = 0; i < centerRepeater.count; i++) {
const item = centerRepeater.itemAt(i)
const item = centerRepeater.itemAt(i);
if (item && getWidgetVisible(item.widgetId)) {
configuredWidgets++
configuredWidgets++;
}
}
const isOddConfigured = configuredWidgets % 2 === 1
const configuredMiddlePos = Math.floor(configuredWidgets / 2)
const configuredLeftPos = isOddConfigured ? -1 : ((configuredWidgets / 2) - 1)
const configuredRightPos = isOddConfigured ? -1 : (configuredWidgets / 2)
let currentConfigIndex = 0
const isOddConfigured = configuredWidgets % 2 === 1;
const configuredMiddlePos = Math.floor(configuredWidgets / 2);
const configuredLeftPos = isOddConfigured ? -1 : ((configuredWidgets / 2) - 1);
const configuredRightPos = isOddConfigured ? -1 : (configuredWidgets / 2);
let currentConfigIndex = 0;
for (var i = 0; i < centerRepeater.count; i++) {
const item = centerRepeater.itemAt(i)
const item = centerRepeater.itemAt(i);
if (item && getWidgetVisible(item.widgetId)) {
if (isOddConfigured && currentConfigIndex === configuredMiddlePos && item.active && item.item) {
configuredMiddleWidget = item.item
configuredMiddleWidget = item.item;
}
if (!isOddConfigured && currentConfigIndex === configuredLeftPos && item.active && item.item) {
configuredLeftWidget = item.item
configuredLeftWidget = item.item;
}
if (!isOddConfigured && currentConfigIndex === configuredRightPos && item.active && item.item) {
configuredRightWidget = item.item
configuredRightWidget = item.item;
}
if (item.active && item.item) {
centerWidgets.push(item.item)
totalWidgets++
totalSize += isVertical ? item.item.height : item.item.width
centerWidgets.push(item.item);
totalWidgets++;
totalSize += isVertical ? item.item.height : item.item.width;
}
currentConfigIndex++
currentConfigIndex++;
}
}
if (totalWidgets === 0) {
return
return;
}
if (totalWidgets > 1) {
totalSize += spacing * (totalWidgets - 1)
totalSize += spacing * (totalWidgets - 1);
}
positionWidgets(configuredWidgets, configuredMiddleWidget, configuredLeftWidget, configuredRightWidget)
positionWidgets(configuredWidgets, configuredMiddleWidget, configuredLeftWidget, configuredRightWidget);
}
function positionWidgets(configuredWidgets, configuredMiddleWidget, configuredLeftWidget, configuredRightWidget) {
const parentCenter = (isVertical ? height : width) / 2
const isOddConfigured = configuredWidgets % 2 === 1
const parentCenter = (isVertical ? height : width) / 2;
const isOddConfigured = configuredWidgets % 2 === 1;
centerWidgets.forEach(widget => {
if (isVertical) {
widget.anchors.verticalCenter = undefined
widget.anchors.verticalCenter = undefined;
} else {
widget.anchors.horizontalCenter = undefined
widget.anchors.horizontalCenter = undefined;
}
})
});
if (isOddConfigured && configuredMiddleWidget) {
const middleWidget = configuredMiddleWidget
const middleIndex = centerWidgets.indexOf(middleWidget)
const middleSize = isVertical ? middleWidget.height : middleWidget.width
const middleWidget = configuredMiddleWidget;
const middleIndex = centerWidgets.indexOf(middleWidget);
const middleSize = isVertical ? middleWidget.height : middleWidget.width;
if (isVertical) {
middleWidget.y = parentCenter - (middleSize / 2)
middleWidget.y = parentCenter - (middleSize / 2);
} else {
middleWidget.x = parentCenter - (middleSize / 2)
middleWidget.x = parentCenter - (middleSize / 2);
}
let currentPos = isVertical ? middleWidget.y : middleWidget.x
let currentPos = isVertical ? middleWidget.y : middleWidget.x;
for (var i = middleIndex - 1; i >= 0; i--) {
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width
currentPos -= (spacing + size)
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width;
currentPos -= (spacing + size);
if (isVertical) {
centerWidgets[i].y = currentPos
centerWidgets[i].y = currentPos;
} else {
centerWidgets[i].x = currentPos
centerWidgets[i].x = currentPos;
}
}
currentPos = (isVertical ? middleWidget.y : middleWidget.x) + middleSize
currentPos = (isVertical ? middleWidget.y : middleWidget.x) + middleSize;
for (var i = middleIndex + 1; i < totalWidgets; i++) {
currentPos += spacing
currentPos += spacing;
if (isVertical) {
centerWidgets[i].y = currentPos
centerWidgets[i].y = currentPos;
} else {
centerWidgets[i].x = currentPos
centerWidgets[i].x = currentPos;
}
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width;
}
} else {
if (totalWidgets === 1) {
const widget = centerWidgets[0]
const size = isVertical ? widget.height : widget.width
const widget = centerWidgets[0];
const size = isVertical ? widget.height : widget.width;
if (isVertical) {
widget.y = parentCenter - (size / 2)
widget.y = parentCenter - (size / 2);
} else {
widget.x = parentCenter - (size / 2)
widget.x = parentCenter - (size / 2);
}
return
return;
}
if (!configuredLeftWidget || !configuredRightWidget) {
if (totalWidgets % 2 === 1) {
const middleIndex = Math.floor(totalWidgets / 2)
const middleWidget = centerWidgets[middleIndex]
const middleIndex = Math.floor(totalWidgets / 2);
const middleWidget = centerWidgets[middleIndex];
if (!middleWidget) {
return
return;
}
const middleSize = isVertical ? middleWidget.height : middleWidget.width
const middleSize = isVertical ? middleWidget.height : middleWidget.width;
if (isVertical) {
middleWidget.y = parentCenter - (middleSize / 2)
middleWidget.y = parentCenter - (middleSize / 2);
} else {
middleWidget.x = parentCenter - (middleSize / 2)
middleWidget.x = parentCenter - (middleSize / 2);
}
let currentPos = isVertical ? middleWidget.y : middleWidget.x
let currentPos = isVertical ? middleWidget.y : middleWidget.x;
for (var i = middleIndex - 1; i >= 0; i--) {
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width
currentPos -= (spacing + size)
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width;
currentPos -= (spacing + size);
if (isVertical) {
centerWidgets[i].y = currentPos
centerWidgets[i].y = currentPos;
} else {
centerWidgets[i].x = currentPos
centerWidgets[i].x = currentPos;
}
}
currentPos = (isVertical ? middleWidget.y : middleWidget.x) + middleSize
currentPos = (isVertical ? middleWidget.y : middleWidget.x) + middleSize;
for (var i = middleIndex + 1; i < totalWidgets; i++) {
currentPos += spacing
currentPos += spacing;
if (isVertical) {
centerWidgets[i].y = currentPos
centerWidgets[i].y = currentPos;
} else {
centerWidgets[i].x = currentPos
centerWidgets[i].x = currentPos;
}
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width;
}
} else {
const leftIndex = (totalWidgets / 2) - 1
const rightIndex = totalWidgets / 2
const fallbackLeft = centerWidgets[leftIndex]
const fallbackRight = centerWidgets[rightIndex]
const leftIndex = (totalWidgets / 2) - 1;
const rightIndex = totalWidgets / 2;
const fallbackLeft = centerWidgets[leftIndex];
const fallbackRight = centerWidgets[rightIndex];
if (!fallbackLeft || !fallbackRight) {
return
return;
}
const halfSpacing = spacing / 2
const leftSize = isVertical ? fallbackLeft.height : fallbackLeft.width
const halfSpacing = spacing / 2;
const leftSize = isVertical ? fallbackLeft.height : fallbackLeft.width;
if (isVertical) {
fallbackLeft.y = parentCenter - halfSpacing - leftSize
fallbackRight.y = parentCenter + halfSpacing
fallbackLeft.y = parentCenter - halfSpacing - leftSize;
fallbackRight.y = parentCenter + halfSpacing;
} else {
fallbackLeft.x = parentCenter - halfSpacing - leftSize
fallbackRight.x = parentCenter + halfSpacing
fallbackLeft.x = parentCenter - halfSpacing - leftSize;
fallbackRight.x = parentCenter + halfSpacing;
}
let currentPos = isVertical ? fallbackLeft.y : fallbackLeft.x
let currentPos = isVertical ? fallbackLeft.y : fallbackLeft.x;
for (var i = leftIndex - 1; i >= 0; i--) {
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width
currentPos -= (spacing + size)
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width;
currentPos -= (spacing + size);
if (isVertical) {
centerWidgets[i].y = currentPos
centerWidgets[i].y = currentPos;
} else {
centerWidgets[i].x = currentPos
centerWidgets[i].x = currentPos;
}
}
currentPos = (isVertical ? fallbackRight.y + fallbackRight.height : fallbackRight.x + fallbackRight.width)
currentPos = (isVertical ? fallbackRight.y + fallbackRight.height : fallbackRight.x + fallbackRight.width);
for (var i = rightIndex + 1; i < totalWidgets; i++) {
currentPos += spacing
currentPos += spacing;
if (isVertical) {
centerWidgets[i].y = currentPos
centerWidgets[i].y = currentPos;
} else {
centerWidgets[i].x = currentPos
centerWidgets[i].x = currentPos;
}
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width;
}
}
return
return;
}
const leftWidget = configuredLeftWidget
const rightWidget = configuredRightWidget
const leftIndex = centerWidgets.indexOf(leftWidget)
const rightIndex = centerWidgets.indexOf(rightWidget)
const halfSpacing = spacing / 2
const leftSize = isVertical ? leftWidget.height : leftWidget.width
const leftWidget = configuredLeftWidget;
const rightWidget = configuredRightWidget;
const leftIndex = centerWidgets.indexOf(leftWidget);
const rightIndex = centerWidgets.indexOf(rightWidget);
const halfSpacing = spacing / 2;
const leftSize = isVertical ? leftWidget.height : leftWidget.width;
if (isVertical) {
leftWidget.y = parentCenter - halfSpacing - leftSize
rightWidget.y = parentCenter + halfSpacing
leftWidget.y = parentCenter - halfSpacing - leftSize;
rightWidget.y = parentCenter + halfSpacing;
} else {
leftWidget.x = parentCenter - halfSpacing - leftSize
rightWidget.x = parentCenter + halfSpacing
leftWidget.x = parentCenter - halfSpacing - leftSize;
rightWidget.x = parentCenter + halfSpacing;
}
let currentPos = isVertical ? leftWidget.y : leftWidget.x
let currentPos = isVertical ? leftWidget.y : leftWidget.x;
for (var i = leftIndex - 1; i >= 0; i--) {
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width
currentPos -= (spacing + size)
const size = isVertical ? centerWidgets[i].height : centerWidgets[i].width;
currentPos -= (spacing + size);
if (isVertical) {
centerWidgets[i].y = currentPos
centerWidgets[i].y = currentPos;
} else {
centerWidgets[i].x = currentPos
centerWidgets[i].x = currentPos;
}
}
currentPos = (isVertical ? rightWidget.y + rightWidget.height : rightWidget.x + rightWidget.width)
currentPos = (isVertical ? rightWidget.y + rightWidget.height : rightWidget.x + rightWidget.width);
for (var i = rightIndex + 1; i < totalWidgets; i++) {
currentPos += spacing
currentPos += spacing;
if (isVertical) {
centerWidgets[i].y = currentPos
centerWidgets[i].y = currentPos;
} else {
centerWidgets[i].x = currentPos
centerWidgets[i].x = currentPos;
}
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width
currentPos += isVertical ? centerWidgets[i].height : centerWidgets[i].width;
}
}
}
@@ -268,8 +270,8 @@ Item {
"cpuTemp": DgopService.dgopAvailable,
"gpuTemp": DgopService.dgopAvailable,
"network_speed_monitor": DgopService.dgopAvailable
}
return widgetVisibility[widgetId] ?? true
};
return widgetVisibility[widgetId] ?? true;
}
function getWidgetComponent(widgetId) {
@@ -302,19 +304,19 @@ Item {
"notepadButton": "notepadButtonComponent",
"colorPicker": "colorPickerComponent",
"systemUpdate": "systemUpdateComponent"
}
};
// For built-in components, get from components property
const componentKey = baseMap[widgetId]
const componentKey = baseMap[widgetId];
if (componentKey && root.components[componentKey]) {
return root.components[componentKey]
return root.components[componentKey];
}
// For plugin components, get from PluginService
var parts = widgetId.split(":")
var pluginId = parts[0]
let pluginComponents = PluginService.getWidgetComponents()
return pluginComponents[pluginId] || null
var parts = widgetId.split(":");
var pluginId = parts[0];
let pluginComponents = PluginService.getWidgetComponents();
return pluginComponents[pluginId] || null;
}
height: parent.height
@@ -329,24 +331,24 @@ Item {
}
Component.onCompleted: {
layoutTimer.restart()
layoutTimer.restart();
}
onWidthChanged: {
if (width > 0) {
layoutTimer.restart()
layoutTimer.restart();
}
}
onHeightChanged: {
if (height > 0) {
layoutTimer.restart()
layoutTimer.restart();
}
}
onVisibleChanged: {
if (visible && (isVertical ? height : width) > 0) {
layoutTimer.restart()
layoutTimer.restart();
}
}
@@ -354,146 +356,149 @@ Item {
id: centerRepeater
model: root.widgetsModel
Loader {
property string widgetId: model.widgetId
property var widgetData: model
property int spacerSize: model.size || 20
property var itemData: modelData
property string widgetId: itemData.widgetId
property var widgetData: itemData
property int spacerSize: itemData.size || 20
anchors.verticalCenter: !root.isVertical ? parent.verticalCenter : undefined
anchors.horizontalCenter: root.isVertical ? parent.horizontalCenter : undefined
active: root.getWidgetVisible(model.widgetId) && (model.widgetId !== "music" || MprisController.activePlayer !== null)
sourceComponent: root.getWidgetComponent(model.widgetId)
opacity: (model.enabled !== false) ? 1 : 0
active: root.getWidgetVisible(itemData.widgetId) && (itemData.widgetId !== "music" || MprisController.activePlayer !== null)
sourceComponent: root.getWidgetComponent(itemData.widgetId)
opacity: (itemData.enabled !== false) ? 1 : 0
asynchronous: false
onLoaded: {
if (!item) {
return
return;
}
item.widthChanged.connect(() => layoutTimer.restart())
item.heightChanged.connect(() => layoutTimer.restart())
item.widthChanged.connect(() => {
if (layoutTimer)
layoutTimer.restart();
});
item.heightChanged.connect(() => {
if (layoutTimer)
layoutTimer.restart();
});
if (root.axis && "axis" in item) {
item.axis = Qt.binding(() => root.axis)
item.axis = Qt.binding(() => root.axis);
}
if (root.axis && "isVertical" in item) {
try {
item.isVertical = Qt.binding(() => root.axis.isVertical)
} catch (e) {
}
item.isVertical = Qt.binding(() => root.axis.isVertical);
} catch (e) {}
}
// Inject properties for plugin widgets
if ("section" in item) {
item.section = root.section
item.section = root.section;
}
if ("parentScreen" in item) {
item.parentScreen = Qt.binding(() => root.parentScreen)
item.parentScreen = Qt.binding(() => root.parentScreen);
}
if ("widgetThickness" in item) {
item.widgetThickness = Qt.binding(() => root.widgetThickness)
item.widgetThickness = Qt.binding(() => root.widgetThickness);
}
if ("barThickness" in item) {
item.barThickness = Qt.binding(() => root.barThickness)
item.barThickness = Qt.binding(() => root.barThickness);
}
if ("barSpacing" in item) {
item.barSpacing = Qt.binding(() => root.barSpacing);
}
if ("barConfig" in item) {
item.barConfig = Qt.binding(() => root.barConfig);
}
if ("sectionSpacing" in item) {
item.sectionSpacing = Qt.binding(() => root.spacing)
item.sectionSpacing = Qt.binding(() => root.spacing);
}
if ("isFirst" in item) {
item.isFirst = Qt.binding(() => {
for (var i = 0; i < centerRepeater.count; i++) {
const checkItem = centerRepeater.itemAt(i)
const checkItem = centerRepeater.itemAt(i);
if (checkItem && checkItem.active && checkItem.item) {
return checkItem.item === item
return checkItem.item === item;
}
}
return false
})
return false;
});
}
if ("isLast" in item) {
item.isLast = Qt.binding(() => {
for (var i = centerRepeater.count - 1; i >= 0; i--) {
const checkItem = centerRepeater.itemAt(i)
const checkItem = centerRepeater.itemAt(i);
if (checkItem && checkItem.active && checkItem.item) {
return checkItem.item === item
return checkItem.item === item;
}
}
return false
})
return false;
});
}
if ("isLeftBarEdge" in item) {
item.isLeftBarEdge = false
item.isLeftBarEdge = false;
}
if ("isRightBarEdge" in item) {
item.isRightBarEdge = false
item.isRightBarEdge = false;
}
if ("isTopBarEdge" in item) {
item.isTopBarEdge = false
item.isTopBarEdge = false;
}
if ("isBottomBarEdge" in item) {
item.isBottomBarEdge = false
item.isBottomBarEdge = false;
}
if (item.pluginService !== undefined) {
var parts = model.widgetId.split(":")
var pluginId = parts[0]
var variantId = parts.length > 1 ? parts[1] : null
var parts = model.widgetId.split(":");
var pluginId = parts[0];
var variantId = parts.length > 1 ? parts[1] : null;
if (item.pluginId !== undefined) {
item.pluginId = pluginId
item.pluginId = pluginId;
}
if (item.variantId !== undefined) {
item.variantId = variantId
item.variantId = variantId;
}
if (item.variantData !== undefined && variantId) {
item.variantData = PluginService.getPluginVariantData(pluginId, variantId)
item.variantData = PluginService.getPluginVariantData(pluginId, variantId);
}
item.pluginService = PluginService
item.pluginService = PluginService;
}
if (item.popoutService !== undefined) {
item.popoutService = PopoutService
item.popoutService = PopoutService;
}
layoutTimer.restart()
layoutTimer.restart();
}
onActiveChanged: {
layoutTimer.restart()
layoutTimer.restart();
}
}
}
Connections {
target: widgetsModel
function onCountChanged() {
layoutTimer.restart()
}
}
// Listen for plugin changes and refresh components
Connections {
target: PluginService
function onPluginLoaded(pluginId) {
// Force refresh of component lookups
for (var i = 0; i < centerRepeater.count; i++) {
var item = centerRepeater.itemAt(i)
var item = centerRepeater.itemAt(i);
if (item && item.widgetId.startsWith(pluginId)) {
item.sourceComponent = root.getWidgetComponent(item.widgetId)
item.sourceComponent = root.getWidgetComponent(item.widgetId);
}
}
}
function onPluginUnloaded(pluginId) {
// Force refresh of component lookups
for (var i = 0; i < centerRepeater.count; i++) {
var item = centerRepeater.itemAt(i)
var item = centerRepeater.itemAt(i);
if (item && item.widgetId.startsWith(pluginId)) {
item.sourceComponent = root.getWidgetComponent(item.widgetId)
item.sourceComponent = root.getWidgetComponent(item.widgetId);
}
}
}
}
}
}

View File

@@ -1,92 +1,169 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Effects
import QtQuick.Shapes
import Quickshell
import Quickshell.Hyprland
import Quickshell.I3
import Quickshell.Io
import Quickshell.Services.Mpris
import Quickshell.Services.Notifications
import Quickshell.Services.SystemTray
import Quickshell.Wayland
import Quickshell.Widgets
import qs.Common
import qs.Modules
import qs.Modules.DankBar.Widgets
import qs.Modules.DankBar.Popouts
import qs.Services
import qs.Widgets
Item {
id: root
required property var barConfig
signal colorPickerRequested
signal barReady(var barConfig)
property alias barVariants: barVariants
property var hyprlandOverviewLoader: null
property bool systemTrayMenuOpen: false
property alias leftWidgetsModel: leftWidgetsModel
property alias centerWidgetsModel: centerWidgetsModel
property alias rightWidgetsModel: rightWidgetsModel
ScriptModel {
id: leftWidgetsModel
values: {
root.barConfig;
const leftWidgets = root.barConfig?.leftWidgets || [];
return leftWidgets.map((w, index) => {
if (typeof w === "string") {
return {
widgetId: w,
id: w + "_" + index,
enabled: true
};
} else {
const obj = Object.assign({}, w);
obj.widgetId = w.id || w.widgetId;
obj.id = (w.id || w.widgetId) + "_" + index;
obj.enabled = w.enabled !== false;
return obj;
}
});
}
}
ScriptModel {
id: centerWidgetsModel
values: {
root.barConfig;
const centerWidgets = root.barConfig?.centerWidgets || [];
return centerWidgets.map((w, index) => {
if (typeof w === "string") {
return {
widgetId: w,
id: w + "_" + index,
enabled: true
};
} else {
const obj = Object.assign({}, w);
obj.widgetId = w.id || w.widgetId;
obj.id = (w.id || w.widgetId) + "_" + index;
obj.enabled = w.enabled !== false;
return obj;
}
});
}
}
ScriptModel {
id: rightWidgetsModel
values: {
root.barConfig;
const rightWidgets = root.barConfig?.rightWidgets || [];
return rightWidgets.map((w, index) => {
if (typeof w === "string") {
return {
widgetId: w,
id: w + "_" + index,
enabled: true
};
} else {
const obj = Object.assign({}, w);
obj.widgetId = w.id || w.widgetId;
obj.id = (w.id || w.widgetId) + "_" + index;
obj.enabled = w.enabled !== false;
return obj;
}
});
}
}
function triggerControlCenterOnFocusedScreen() {
let focusedScreenName = ""
let focusedScreenName = "";
if (CompositorService.isHyprland && Hyprland.focusedWorkspace && Hyprland.focusedWorkspace.monitor) {
focusedScreenName = Hyprland.focusedWorkspace.monitor.name
focusedScreenName = Hyprland.focusedWorkspace.monitor.name;
} else if (CompositorService.isNiri && NiriService.currentOutput) {
focusedScreenName = NiriService.currentOutput
focusedScreenName = NiriService.currentOutput;
} else if (CompositorService.isSway) {
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true)
focusedScreenName = focusedWs?.monitor?.name || ""
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
focusedScreenName = focusedWs?.monitor?.name || "";
}
if (!focusedScreenName && barVariants.instances.length > 0) {
const firstBar = barVariants.instances[0]
firstBar.triggerControlCenter()
return true
const firstBar = barVariants.instances[0];
firstBar.triggerControlCenter();
return true;
}
for (var i = 0; i < barVariants.instances.length; i++) {
const barInstance = barVariants.instances[i]
const barInstance = barVariants.instances[i];
if (barInstance.modelData && barInstance.modelData.name === focusedScreenName) {
barInstance.triggerControlCenter()
return true
barInstance.triggerControlCenter();
return true;
}
}
return false
return false;
}
function triggerWallpaperBrowserOnFocusedScreen() {
let focusedScreenName = ""
let focusedScreenName = "";
if (CompositorService.isHyprland && Hyprland.focusedWorkspace && Hyprland.focusedWorkspace.monitor) {
focusedScreenName = Hyprland.focusedWorkspace.monitor.name
focusedScreenName = Hyprland.focusedWorkspace.monitor.name;
} else if (CompositorService.isNiri && NiriService.currentOutput) {
focusedScreenName = NiriService.currentOutput
focusedScreenName = NiriService.currentOutput;
} else if (CompositorService.isSway) {
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true)
focusedScreenName = focusedWs?.monitor?.name || ""
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
focusedScreenName = focusedWs?.monitor?.name || "";
}
if (!focusedScreenName && barVariants.instances.length > 0) {
const firstBar = barVariants.instances[0]
firstBar.triggerWallpaperBrowser()
return true
const firstBar = barVariants.instances[0];
firstBar.triggerWallpaperBrowser();
return true;
}
for (var i = 0; i < barVariants.instances.length; i++) {
const barInstance = barVariants.instances[i]
const barInstance = barVariants.instances[i];
if (barInstance.modelData && barInstance.modelData.name === focusedScreenName) {
barInstance.triggerWallpaperBrowser()
return true
barInstance.triggerWallpaperBrowser();
return true;
}
}
return false
return false;
}
Variants {
id: barVariants
model: SettingsData.getFilteredScreens("dankBar")
model: {
const prefs = root.barConfig?.screenPreferences || ["all"];
if (prefs.includes("all") || (typeof prefs[0] === "string" && prefs[0] === "all")) {
return Quickshell.screens;
}
const filtered = Quickshell.screens.filter(screen => SettingsData.isScreenInPreferences(screen, prefs));
if (filtered.length === 0 && root.barConfig?.showOnLastDisplay && Quickshell.screens.length === 1) {
return Quickshell.screens;
}
return filtered;
}
delegate: DankBarWindow {
rootWindow: root
barConfig: root.barConfig
leftWidgetsModel: root.leftWidgetsModel
centerWidgetsModel: root.centerWidgetsModel
rightWidgetsModel: root.rightWidgetsModel
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,86 +1,113 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Effects
import QtQuick.Shapes
import Quickshell
import Quickshell.Hyprland
import Quickshell.I3
import Quickshell.Io
import Quickshell.Services.Mpris
import Quickshell.Services.Notifications
import Quickshell.Services.SystemTray
import Quickshell.Wayland
import Quickshell.Widgets
import qs.Common
import qs.Modules
import qs.Modules.DankBar.Widgets
import qs.Modules.DankBar.Popouts
import qs.Services
import qs.Widgets
PanelWindow {
id: barWindow
required property var rootWindow
required property var barConfig
property var modelData: item
property var hyprlandOverviewLoader: rootWindow ? rootWindow.hyprlandOverviewLoader : null
property var leftWidgetsModel
property var centerWidgetsModel
property var rightWidgetsModel
property var controlCenterButtonRef: null
property var clockButtonRef: null
function triggerControlCenter() {
controlCenterLoader.active = true
controlCenterLoader.active = true;
if (!controlCenterLoader.item) {
return
return;
}
if (controlCenterButtonRef && controlCenterLoader.item.setTriggerPosition) {
const globalPos = controlCenterButtonRef.mapToGlobal(0, 0)
const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, controlCenterButtonRef.width)
const section = controlCenterButtonRef.section || "right"
controlCenterLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen)
const globalPos = controlCenterButtonRef.mapToGlobal(0, 0);
// Calculate barPosition from axis.edge
const barPosition = axis?.edge === "left" ? 2 : (axis?.edge === "right" ? 3 : (axis?.edge === "top" ? 0 : 1));
const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, controlCenterButtonRef.width, barConfig?.spacing ?? 4, barPosition, barConfig);
const section = controlCenterButtonRef.section || "right";
controlCenterLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen, barPosition, barWindow.effectiveBarThickness, barConfig?.spacing ?? 4, barConfig);
} else {
controlCenterLoader.item.triggerScreen = barWindow.screen
controlCenterLoader.item.triggerScreen = barWindow.screen;
}
controlCenterLoader.item.toggle()
controlCenterLoader.item.toggle();
if (controlCenterLoader.item.shouldBeVisible && NetworkService.wifiEnabled) {
NetworkService.scanWifi()
NetworkService.scanWifi();
}
}
function triggerWallpaperBrowser() {
dankDashPopoutLoader.active = true
dankDashPopoutLoader.active = true;
if (!dankDashPopoutLoader.item) {
return
return;
}
if (clockButtonRef && clockButtonRef.visualContent && dankDashPopoutLoader.item.setTriggerPosition) {
const globalPos = clockButtonRef.visualContent.mapToGlobal(0, 0)
const pos = SettingsData.getPopupTriggerPosition(globalPos, barWindow.screen, barWindow.effectiveBarThickness, clockButtonRef.visualWidth)
const section = clockButtonRef.section || "center"
dankDashPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen)
// Calculate barPosition from axis.edge
const barPosition = axis?.edge === "left" ? 2 : (axis?.edge === "right" ? 3 : (axis?.edge === "top" ? 0 : 1));
const section = clockButtonRef.section || "center";
// For center section widgets, use center section bounds for DankDash centering
let triggerPos, triggerWidth;
if (section === "center") {
const centerSection = barWindow.isVertical ? (barWindow.axis?.edge === "left" ? topBarContent.vCenterSection : topBarContent.vCenterSection) : topBarContent.hCenterSection;
if (centerSection) {
// For vertical bars, use center Y of section; for horizontal, use left edge
if (barWindow.isVertical) {
const centerY = centerSection.height / 2;
const centerGlobalPos = centerSection.mapToGlobal(0, centerY);
triggerPos = centerGlobalPos;
triggerWidth = centerSection.height;
} else {
// For horizontal bars, use left edge (DankPopout will center it)
const centerGlobalPos = centerSection.mapToGlobal(0, 0);
triggerPos = centerGlobalPos;
triggerWidth = centerSection.width;
}
} else {
triggerPos = clockButtonRef.visualContent.mapToGlobal(0, 0);
triggerWidth = clockButtonRef.visualWidth;
}
} else {
triggerPos = clockButtonRef.visualContent.mapToGlobal(0, 0);
triggerWidth = clockButtonRef.visualWidth;
}
const pos = SettingsData.getPopupTriggerPosition(triggerPos, barWindow.screen, barWindow.effectiveBarThickness, triggerWidth, barConfig?.spacing ?? 4, barPosition, barConfig);
dankDashPopoutLoader.item.setTriggerPosition(pos.x, pos.y, pos.width, section, barWindow.screen, barPosition, barWindow.effectiveBarThickness, barConfig?.spacing ?? 4, barConfig);
} else {
dankDashPopoutLoader.item.triggerScreen = barWindow.screen
dankDashPopoutLoader.item.triggerScreen = barWindow.screen;
}
PopoutManager.requestPopout(dankDashPopoutLoader.item, 2)
PopoutManager.requestPopout(dankDashPopoutLoader.item, 2, (barConfig?.id ?? "default") + "-2");
}
readonly property var dBarLayer: {
switch (Quickshell.env("DMS_DANKBAR_LAYER")) {
case "bottom":
return WlrLayer.Bottom
return WlrLayer.Bottom;
case "overlay":
return WlrLayer.Overlay
return WlrLayer.Overlay;
case "background":
return WlrLayer.background
return WlrLayer.background;
default:
return WlrLayer.Top
return WlrLayer.Top;
}
}
WlrLayershell.layer: dBarLayer
WlrLayershell.layer: {
if ((barConfig?.autoHide ?? false) && topBarCore.reveal) {
return WlrLayer.Overlay;
}
return dBarLayer;
}
WlrLayershell.namespace: "dms:bar"
signal colorPickerRequested
@@ -92,39 +119,134 @@ PanelWindow {
AxisContext {
id: axis
edge: {
switch (SettingsData.dankBarPosition) {
switch (barConfig?.position ?? 0) {
case SettingsData.Position.Top:
return "top"
return "top";
case SettingsData.Position.Bottom:
return "bottom"
return "bottom";
case SettingsData.Position.Left:
return "left"
return "left";
case SettingsData.Position.Right:
return "right"
return "right";
default:
return "top"
return "top";
}
}
}
readonly property bool isVertical: axis.isVertical
property bool gothCornersEnabled: SettingsData.dankBarGothCornersEnabled
property real wingtipsRadius: SettingsData.dankBarGothCornerRadiusOverride ? SettingsData.dankBarGothCornerRadiusValue : Theme.cornerRadius
property bool gothCornersEnabled: barConfig?.gothCornersEnabled ?? false
property real wingtipsRadius: barConfig?.gothCornerRadiusOverride ? (barConfig?.gothCornerRadiusValue ?? 12) : Theme.cornerRadius
readonly property real _wingR: Math.max(0, wingtipsRadius)
readonly property color _surfaceContainer: Theme.surfaceContainer
readonly property real _backgroundAlpha: topBarCore?.backgroundTransparency ?? SettingsData.dankBarTransparency
readonly property real _backgroundAlpha: topBarCore?.backgroundTransparency ?? (barConfig?.transparency ?? 1.0)
readonly property color _bgColor: Theme.withAlpha(_surfaceContainer, _backgroundAlpha)
readonly property real _dpr: CompositorService.getScreenScale(barWindow.screen)
property string screenName: modelData.name
readonly property int notificationCount: NotificationService.notifications.length
readonly property real effectiveBarThickness: Math.max(barWindow.widgetThickness + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding))
readonly property real widgetThickness: Math.max(20, 26 + SettingsData.dankBarInnerPadding * 0.6)
readonly property real effectiveBarThickness: Math.max(barWindow.widgetThickness + (barConfig?.innerPadding ?? 4) + 4, Theme.barHeight - 4 - (8 - (barConfig?.innerPadding ?? 4)))
readonly property real widgetThickness: Math.max(20, 26 + (barConfig?.innerPadding ?? 4) * 0.6)
readonly property bool hasAdjacentTopBar: {
if (barConfig?.autoHide ?? false)
return false;
if (!isVertical)
return false;
return SettingsData.barConfigs.some(bc => {
if (!bc.enabled || bc.id === barConfig?.id)
return false;
if (bc.autoHide)
return false;
if (!(bc.visible ?? true))
return false;
if (bc.position !== SettingsData.Position.Top && bc.position !== 0)
return false;
const onThisScreen = bc.screenPreferences.includes(screenName) || bc.screenPreferences.length === 0 || bc.screenPreferences.includes("all");
if (!onThisScreen)
return false;
if (bc.showOnLastDisplay && screenName !== barWindow.screen.name)
return false;
return true;
});
}
readonly property bool hasAdjacentBottomBar: {
if (barConfig?.autoHide ?? false)
return false;
if (!isVertical)
return false;
const result = SettingsData.barConfigs.some(bc => {
if (!bc.enabled || bc.id === barConfig?.id)
return false;
if (bc.autoHide)
return false;
if (!(bc.visible ?? true))
return false;
if (bc.position !== SettingsData.Position.Bottom && bc.position !== 1)
return false;
const onThisScreen = bc.screenPreferences.includes(screenName) || bc.screenPreferences.length === 0 || bc.screenPreferences.includes("all");
if (!onThisScreen)
return false;
if (bc.showOnLastDisplay && screenName !== barWindow.screen.name)
return false;
return true;
});
return result;
}
readonly property bool hasAdjacentLeftBar: {
if (barConfig?.autoHide ?? false)
return false;
if (isVertical)
return false;
const result = SettingsData.barConfigs.some(bc => {
if (!bc.enabled || bc.id === barConfig?.id)
return false;
if (bc.autoHide)
return false;
if (!(bc.visible ?? true))
return false;
if (bc.position !== SettingsData.Position.Left && bc.position !== 2)
return false;
const onThisScreen = bc.screenPreferences.includes(screenName) || bc.screenPreferences.length === 0 || bc.screenPreferences.includes("all");
if (!onThisScreen)
return false;
if (bc.showOnLastDisplay && screenName !== barWindow.screen.name)
return false;
return true;
});
return result;
}
readonly property bool hasAdjacentRightBar: {
if (barConfig?.autoHide ?? false)
return false;
if (isVertical)
return false;
const result = SettingsData.barConfigs.some(bc => {
if (!bc.enabled || bc.id === barConfig?.id)
return false;
if (bc.autoHide)
return false;
if (!(bc.visible ?? true))
return false;
if (bc.position !== SettingsData.Position.Right && bc.position !== 3)
return false;
const onThisScreen = bc.screenPreferences.includes(screenName) || bc.screenPreferences.length === 0 || bc.screenPreferences.includes("all");
if (!onThisScreen)
return false;
if (bc.showOnLastDisplay && screenName !== barWindow.screen.name)
return false;
return true;
});
return result;
}
screen: modelData
implicitHeight: !isVertical ? Theme.px(effectiveBarThickness + SettingsData.dankBarSpacing + (SettingsData.dankBarGothCornersEnabled ? _wingR : 0), _dpr) : 0
implicitWidth: isVertical ? Theme.px(effectiveBarThickness + SettingsData.dankBarSpacing + (SettingsData.dankBarGothCornersEnabled ? _wingR : 0), _dpr) : 0
implicitHeight: !isVertical ? Theme.px(effectiveBarThickness + (barConfig?.spacing ?? 4) + ((barConfig?.gothCornersEnabled ?? false) ? _wingR : 0), _dpr) : 0
implicitWidth: isVertical ? Theme.px(effectiveBarThickness + (barConfig?.spacing ?? 4) + ((barConfig?.gothCornersEnabled ?? false) ? _wingR : 0), _dpr) : 0
color: "transparent"
property var nativeInhibitor: null
@@ -132,18 +254,18 @@ PanelWindow {
Component.onCompleted: {
if (SettingsData.forceStatusBarLayoutRefresh) {
SettingsData.forceStatusBarLayoutRefresh.connect(() => {
Qt.callLater(() => {
stackContainer.visible = false
Qt.callLater(() => {
stackContainer.visible = true
})
})
})
Qt.callLater(() => {
stackContainer.visible = false;
Qt.callLater(() => {
stackContainer.visible = true;
});
});
});
}
updateGpuTempConfig()
updateGpuTempConfig();
inhibitorInitTimer.start()
inhibitorInitTimer.start();
}
Timer {
@@ -152,7 +274,7 @@ PanelWindow {
repeat: false
onTriggered: {
if (SessionService.nativeInhibitorAvailable) {
createNativeInhibitor()
createNativeInhibitor();
}
}
}
@@ -160,32 +282,35 @@ PanelWindow {
Connections {
target: PluginService
function onPluginLoaded(pluginId) {
console.info("DankBar: Plugin loaded:", pluginId)
SettingsData.widgetDataChanged()
console.info("DankBar: Plugin loaded:", pluginId);
SettingsData.widgetDataChanged();
}
function onPluginUnloaded(pluginId) {
console.info("DankBar: Plugin unloaded:", pluginId)
SettingsData.widgetDataChanged()
console.info("DankBar: Plugin unloaded:", pluginId);
SettingsData.widgetDataChanged();
}
}
function updateGpuTempConfig() {
const allWidgets = [...(SettingsData.dankBarLeftWidgets || []), ...(SettingsData.dankBarCenterWidgets || []), ...(SettingsData.dankBarRightWidgets || [])]
const leftWidgets = barConfig?.leftWidgets || [];
const centerWidgets = barConfig?.centerWidgets || [];
const rightWidgets = barConfig?.rightWidgets || [];
const allWidgets = [...leftWidgets, ...centerWidgets, ...rightWidgets];
const hasGpuTempWidget = allWidgets.some(widget => {
const widgetId = typeof widget === "string" ? widget : widget.id
const widgetEnabled = typeof widget === "string" ? true : (widget.enabled !== false)
return widgetId === "gpuTemp" && widgetEnabled
})
const widgetId = typeof widget === "string" ? widget : widget.id;
const widgetEnabled = typeof widget === "string" ? true : (widget.enabled !== false);
return widgetId === "gpuTemp" && widgetEnabled;
});
DgopService.gpuTempEnabled = hasGpuTempWidget || SessionData.nvidiaGpuTempEnabled || SessionData.nonNvidiaGpuTempEnabled
DgopService.nvidiaGpuTempEnabled = hasGpuTempWidget || SessionData.nvidiaGpuTempEnabled
DgopService.nonNvidiaGpuTempEnabled = hasGpuTempWidget || SessionData.nonNvidiaGpuTempEnabled
DgopService.gpuTempEnabled = hasGpuTempWidget || SessionData.nvidiaGpuTempEnabled || SessionData.nonNvidiaGpuTempEnabled;
DgopService.nvidiaGpuTempEnabled = hasGpuTempWidget || SessionData.nvidiaGpuTempEnabled;
DgopService.nonNvidiaGpuTempEnabled = hasGpuTempWidget || SessionData.nonNvidiaGpuTempEnabled;
}
function createNativeInhibitor() {
if (!SessionService.nativeInhibitorAvailable) {
return
return;
}
try {
@@ -196,121 +321,88 @@ PanelWindow {
IdleInhibitor {
enabled: false
}
`
`;
nativeInhibitor = Qt.createQmlObject(qmlString, barWindow, "DankBar.NativeInhibitor")
nativeInhibitor.window = barWindow
nativeInhibitor.enabled = Qt.binding(() => SessionService.idleInhibited)
nativeInhibitor = Qt.createQmlObject(qmlString, barWindow, "DankBar.NativeInhibitor");
nativeInhibitor.window = barWindow;
nativeInhibitor.enabled = Qt.binding(() => SessionService.idleInhibited);
nativeInhibitor.enabledChanged.connect(function () {
console.log("DankBar: Native inhibitor enabled changed to:", nativeInhibitor.enabled)
if (SessionService.idleInhibited !== nativeInhibitor.enabled) {
SessionService.idleInhibited = nativeInhibitor.enabled
SessionService.inhibitorChanged()
SessionService.idleInhibited = nativeInhibitor.enabled;
SessionService.inhibitorChanged();
}
})
console.log("DankBar: Created native Wayland IdleInhibitor for", barWindow.screenName)
});
} catch (e) {
console.warn("DankBar: Failed to create native IdleInhibitor:", e)
nativeInhibitor = null
nativeInhibitor = null;
}
}
Connections {
function onDankBarLeftWidgetsChanged() {
barWindow.updateGpuTempConfig()
function onBarConfigChanged() {
barWindow.updateGpuTempConfig();
}
function onDankBarCenterWidgetsChanged() {
barWindow.updateGpuTempConfig()
}
function onDankBarRightWidgetsChanged() {
barWindow.updateGpuTempConfig()
}
target: SettingsData
target: rootWindow
}
Connections {
function onNvidiaGpuTempEnabledChanged() {
barWindow.updateGpuTempConfig()
barWindow.updateGpuTempConfig();
}
function onNonNvidiaGpuTempEnabledChanged() {
barWindow.updateGpuTempConfig()
barWindow.updateGpuTempConfig();
}
target: SessionData
}
Connections {
target: barWindow.screen
function onGeometryChanged() {
Qt.callLater(forceWidgetRefresh)
}
}
Timer {
id: refreshTimer
interval: 0
running: false
repeat: false
onTriggered: {
forceWidgetRefresh()
}
}
readonly property int barPos: barConfig?.position ?? 0
Connections {
target: axis
function onChanged() {
Qt.application.active
refreshTimer.restart()
}
}
anchors.top: !isVertical ? (barPos === SettingsData.Position.Top) : true
anchors.bottom: !isVertical ? (barPos === SettingsData.Position.Bottom) : true
anchors.left: !isVertical ? true : (barPos === SettingsData.Position.Left)
anchors.right: !isVertical ? true : (barPos === SettingsData.Position.Right)
anchors.top: !isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Top) : true
anchors.bottom: !isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Bottom) : true
anchors.left: !isVertical ? true : (SettingsData.dankBarPosition === SettingsData.Position.Left)
anchors.right: !isVertical ? true : (SettingsData.dankBarPosition === SettingsData.Position.Right)
exclusiveZone: (!SettingsData.dankBarVisible || topBarCore.autoHide) ? -1 : (barWindow.effectiveBarThickness + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap)
exclusiveZone: (!(barConfig?.visible ?? true) || topBarCore.autoHide) ? -1 : (barWindow.effectiveBarThickness + (barConfig?.spacing ?? 4) + (barConfig?.bottomGap ?? 0))
Item {
id: inputMask
readonly property int barThickness: Theme.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing, barWindow._dpr)
readonly property int barThickness: Theme.px(barWindow.effectiveBarThickness + (barConfig?.spacing ?? 4), barWindow._dpr)
readonly property bool inOverviewWithShow: CompositorService.isNiri && NiriService.inOverview && SettingsData.dankBarOpenOnOverview
readonly property bool effectiveVisible: SettingsData.dankBarVisible || inOverviewWithShow
readonly property bool inOverviewWithShow: CompositorService.isNiri && NiriService.inOverview && (barConfig?.openOnOverview ?? false)
readonly property bool effectiveVisible: (barConfig?.visible ?? true) || inOverviewWithShow
readonly property bool showing: effectiveVisible && (topBarCore.reveal || inOverviewWithShow || !topBarCore.autoHide)
readonly property int maskThickness: showing ? barThickness : 1
x: {
if (!axis.isVertical) {
return 0
return 0;
} else {
switch (SettingsData.dankBarPosition) {
switch (barPos) {
case SettingsData.Position.Left:
return 0
return 0;
case SettingsData.Position.Right:
return parent.width - maskThickness
return parent.width - maskThickness;
default:
return 0
return 0;
}
}
}
y: {
if (axis.isVertical) {
return 0
return 0;
} else {
switch (SettingsData.dankBarPosition) {
switch (barPos) {
case SettingsData.Position.Top:
return 0
return 0;
case SettingsData.Position.Bottom:
return parent.height - maskThickness
return parent.height - maskThickness;
default:
return 0
return 0;
}
}
}
@@ -327,112 +419,97 @@ PanelWindow {
anchors.fill: parent
layer.enabled: true
property real backgroundTransparency: SettingsData.dankBarTransparency
property bool autoHide: SettingsData.dankBarAutoHide
property real backgroundTransparency: barConfig?.transparency ?? 1.0
property bool autoHide: barConfig?.autoHide ?? false
property bool revealSticky: false
Timer {
id: revealHold
interval: SettingsData.dankBarAutoHideDelay
interval: barConfig?.autoHideDelay ?? 250
repeat: false
onTriggered: topBarCore.revealSticky = false
onTriggered: {
if (!topBarMouseArea.containsMouse && !topBarCore.hasActivePopout) {
topBarCore.revealSticky = false;
}
}
}
property bool reveal: {
if (CompositorService.isNiri && NiriService.inOverview) {
return SettingsData.dankBarOpenOnOverview || topBarMouseArea.containsMouse || hasActivePopout || revealSticky
return (barConfig?.openOnOverview ?? false) || topBarMouseArea.containsMouse || hasActivePopout || revealSticky;
}
return SettingsData.dankBarVisible && (!autoHide || topBarMouseArea.containsMouse || hasActivePopout || revealSticky)
return (barConfig?.visible ?? true) && (!autoHide || topBarMouseArea.containsMouse || hasActivePopout || revealSticky);
}
readonly property bool hasActivePopout: {
const loaders = [{
"loader": appDrawerLoader,
"prop": "shouldBeVisible"
}, {
"loader": dankDashPopoutLoader,
"prop": "shouldBeVisible"
}, {
"loader": processListPopoutLoader,
"prop": "shouldBeVisible"
}, {
"loader": notificationCenterLoader,
"prop": "shouldBeVisible"
}, {
"loader": batteryPopoutLoader,
"prop": "shouldBeVisible"
}, {
"loader": layoutPopoutLoader,
"prop": "shouldBeVisible"
}, {
"loader": vpnPopoutLoader,
"prop": "shouldBeVisible"
}, {
"loader": controlCenterLoader,
"prop": "shouldBeVisible"
}, {
"loader": clipboardHistoryModalPopup,
"prop": "visible"
}, {
"loader": systemUpdateLoader,
"prop": "shouldBeVisible"
}]
return loaders.some(item => {
if (item.loader && item.loader.item) {
return item.loader.item[item.prop]
}
return false
}) || rootWindow.systemTrayMenuOpen
property bool hasActivePopout: false
onHasActivePopoutChanged: evaluateReveal()
Connections {
target: PopoutManager
function onPopoutChanged() {
const screenName = barWindow.screen.name;
const activePopout = PopoutManager.currentPopoutsByScreen[screenName];
const activeTrayMenu = TrayMenuManager.activeTrayMenus[screenName];
const trayOpen = rootWindow.systemTrayMenuOpen;
topBarCore.hasActivePopout = !!(activePopout || activeTrayMenu || trayOpen);
}
}
Connections {
function onDankBarTransparencyChanged() {
topBarCore.backgroundTransparency = SettingsData.dankBarTransparency
function onBarConfigChanged() {
topBarCore.backgroundTransparency = barConfig?.transparency ?? 1.0;
topBarCore.autoHide = barConfig?.autoHide ?? false;
revealHold.interval = barConfig?.autoHideDelay ?? 250;
}
target: SettingsData
target: rootWindow
}
function evaluateReveal() {
if (!autoHide)
return;
if (topBarMouseArea.containsMouse || hasActivePopout) {
revealSticky = true;
revealHold.stop();
return;
}
revealHold.restart();
}
Connections {
target: topBarMouseArea
function onContainsMouseChanged() {
if (topBarMouseArea.containsMouse) {
topBarCore.revealSticky = true
revealHold.stop()
} else {
if (topBarCore.autoHide && !topBarCore.hasActivePopout) {
revealHold.restart()
}
}
topBarCore.evaluateReveal();
}
}
onHasActivePopoutChanged: {
if (hasActivePopout) {
revealSticky = true
revealHold.stop()
} else if (autoHide && !topBarMouseArea.containsMouse) {
revealSticky = true
revealHold.restart()
Connections {
target: PopoutManager
function onPopoutOpening() {
topBarCore.evaluateReveal();
}
}
MouseArea {
id: topBarMouseArea
y: !barWindow.isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Bottom ? parent.height - height : 0) : 0
x: barWindow.isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Right ? parent.width - width : 0) : 0
height: !barWindow.isVertical ? Theme.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing, barWindow._dpr) : undefined
width: barWindow.isVertical ? Theme.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing, barWindow._dpr) : undefined
y: !barWindow.isVertical ? (barPos === SettingsData.Position.Bottom ? parent.height - height : 0) : 0
x: barWindow.isVertical ? (barPos === SettingsData.Position.Right ? parent.width - width : 0) : 0
height: !barWindow.isVertical ? Theme.px(barWindow.effectiveBarThickness + (barConfig?.spacing ?? 4), barWindow._dpr) : undefined
width: barWindow.isVertical ? Theme.px(barWindow.effectiveBarThickness + (barConfig?.spacing ?? 4), barWindow._dpr) : undefined
anchors {
left: !barWindow.isVertical ? parent.left : (SettingsData.dankBarPosition === SettingsData.Position.Left ? parent.left : undefined)
right: !barWindow.isVertical ? parent.right : (SettingsData.dankBarPosition === SettingsData.Position.Right ? parent.right : undefined)
left: !barWindow.isVertical ? parent.left : (barPos === SettingsData.Position.Left ? parent.left : undefined)
right: !barWindow.isVertical ? parent.right : (barPos === SettingsData.Position.Right ? parent.right : undefined)
top: barWindow.isVertical ? parent.top : undefined
bottom: barWindow.isVertical ? parent.bottom : undefined
}
readonly property bool inOverview: CompositorService.isNiri && NiriService.inOverview && SettingsData.dankBarOpenOnOverview
hoverEnabled: SettingsData.dankBarAutoHide && !inOverview
readonly property bool inOverview: CompositorService.isNiri && NiriService.inOverview && (barConfig?.openOnOverview ?? false)
hoverEnabled: (barConfig?.autoHide ?? false) && !inOverview && !topBarCore.hasActivePopout
acceptedButtons: Qt.NoButton
enabled: SettingsData.dankBarAutoHide && !inOverview
enabled: (barConfig?.autoHide ?? false) && !inOverview
Item {
id: topBarContainer
@@ -440,8 +517,8 @@ PanelWindow {
transform: Translate {
id: topBarSlide
x: barWindow.isVertical ? Theme.snap(topBarCore.reveal ? 0 : (SettingsData.dankBarPosition === SettingsData.Position.Right ? barWindow.implicitWidth : -barWindow.implicitWidth), barWindow._dpr) : 0
y: !barWindow.isVertical ? Theme.snap(topBarCore.reveal ? 0 : (SettingsData.dankBarPosition === SettingsData.Position.Bottom ? barWindow.implicitHeight : -barWindow.implicitHeight), barWindow._dpr) : 0
x: barWindow.isVertical ? Theme.snap(topBarCore.reveal ? 0 : (barPos === SettingsData.Position.Right ? barWindow.implicitWidth : -barWindow.implicitWidth), barWindow._dpr) : 0
y: !barWindow.isVertical ? Theme.snap(topBarCore.reveal ? 0 : (barPos === SettingsData.Position.Bottom ? barWindow.implicitHeight : -barWindow.implicitHeight), barWindow._dpr) : 0
Behavior on x {
NumberAnimation {
@@ -460,16 +537,18 @@ PanelWindow {
Item {
id: barUnitInset
property int spacingPx: Theme.px(barConfig?.spacing ?? 4, barWindow._dpr)
anchors.fill: parent
anchors.leftMargin: !barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.edge === "left" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0)
anchors.rightMargin: !barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.edge === "right" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0)
anchors.topMargin: barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.outerVisualEdge() === "bottom" ? 0 : Theme.px(SettingsData.dankBarSpacing, barWindow._dpr))
anchors.bottomMargin: barWindow.isVertical ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : (axis.outerVisualEdge() === "bottom" ? Theme.px(SettingsData.dankBarSpacing, barWindow._dpr) : 0)
anchors.leftMargin: !barWindow.isVertical ? spacingPx : (axis.edge === "left" ? spacingPx : 0)
anchors.rightMargin: !barWindow.isVertical ? spacingPx : (axis.edge === "right" ? spacingPx : 0)
anchors.topMargin: barWindow.isVertical ? (barWindow.hasAdjacentTopBar ? 0 : spacingPx) : (axis.outerVisualEdge() === "bottom" ? 0 : spacingPx)
anchors.bottomMargin: barWindow.isVertical ? (barWindow.hasAdjacentBottomBar ? 0 : spacingPx) : (axis.outerVisualEdge() === "bottom" ? spacingPx : 0)
BarCanvas {
id: barBackground
barWindow: barWindow
axis: axis
barConfig: barWindow.barConfig
}
MouseArea {
@@ -491,39 +570,39 @@ PanelWindow {
onWheel: wheel => {
if (actionInProgress) {
wheel.accepted = false
return
wheel.accepted = false;
return;
}
const deltaY = wheel.angleDelta.y
const deltaX = wheel.angleDelta.x
const deltaY = wheel.angleDelta.y;
const deltaX = wheel.angleDelta.x;
if (CompositorService.isNiri && Math.abs(deltaX) > Math.abs(deltaY)) {
topBarContent.switchApp(deltaX)
wheel.accepted = false
return
topBarContent.switchApp(deltaX);
wheel.accepted = false;
return;
}
const isMouseWheel = Math.abs(deltaY) >= 120 && (Math.abs(deltaY) % 120) === 0
const direction = deltaY < 0 ? 1 : -1
const isMouseWheel = Math.abs(deltaY) >= 120 && (Math.abs(deltaY) % 120) === 0;
const direction = deltaY < 0 ? 1 : -1;
if (isMouseWheel) {
topBarContent.switchWorkspace(direction)
actionInProgress = true
cooldownTimer.restart()
topBarContent.switchWorkspace(direction);
actionInProgress = true;
cooldownTimer.restart();
} else {
scrollAccumulator += deltaY
scrollAccumulator += deltaY;
if (Math.abs(scrollAccumulator) >= touchpadThreshold) {
const touchDirection = scrollAccumulator < 0 ? 1 : -1
topBarContent.switchWorkspace(touchDirection)
scrollAccumulator = 0
actionInProgress = true
cooldownTimer.restart()
const touchDirection = scrollAccumulator < 0 ? 1 : -1;
topBarContent.switchWorkspace(touchDirection);
scrollAccumulator = 0;
actionInProgress = true;
cooldownTimer.restart();
}
}
wheel.accepted = false
wheel.accepted = false;
}
}
@@ -531,6 +610,10 @@ PanelWindow {
id: topBarContent
barWindow: barWindow
rootWindow: rootWindow
barConfig: barWindow.barConfig
leftWidgetsModel: barWindow.leftWidgetsModel
centerWidgetsModel: barWindow.centerWidgetsModel
rightWidgetsModel: barWindow.rightWidgetsModel
}
}
}

View File

@@ -11,13 +11,15 @@ Item {
property var parentScreen: null
property real widgetThickness: 30
property real barThickness: 48
property real barSpacing: 4
property var barConfig: null
property bool overrideAxisLayout: false
property bool forceVerticalLayout: false
readonly property bool isVertical: overrideAxisLayout ? forceVerticalLayout : (axis?.isVertical ?? false)
implicitHeight: layoutLoader.item ? (layoutLoader.item.implicitHeight || layoutLoader.item.height) : 0
implicitWidth: layoutLoader.item ? (layoutLoader.item.implicitWidth || layoutLoader.item.width) : 0
implicitHeight: layoutLoader.item ? layoutLoader.item.implicitHeight : 0
implicitWidth: layoutLoader.item ? layoutLoader.item.implicitWidth : 0
Loader {
id: layoutLoader
@@ -35,14 +37,15 @@ Item {
model: root.widgetsModel
Item {
readonly property real rowSpacing: parent.widgetSpacing
property var itemData: modelData
width: widgetLoader.item ? widgetLoader.item.width : 0
height: widgetLoader.item ? widgetLoader.item.height : 0
WidgetHost {
id: widgetLoader
anchors.verticalCenter: parent.verticalCenter
widgetId: model.widgetId
widgetData: model
spacerSize: model.size || 20
widgetId: itemData.widgetId
widgetData: itemData
spacerSize: itemData.size || 20
components: root.components
isInColumn: false
axis: root.axis
@@ -50,8 +53,10 @@ Item {
parentScreen: root.parentScreen
widgetThickness: root.widgetThickness
barThickness: root.barThickness
isFirst: model.index === 0
isLast: model.index === rowRepeater.count - 1
barSpacing: root.barSpacing
barConfig: root.barConfig
isFirst: index === 0
isLast: index === rowRepeater.count - 1
sectionSpacing: parent.rowSpacing
isLeftBarEdge: true
isRightBarEdge: false
@@ -64,22 +69,23 @@ Item {
Component {
id: columnComp
Column {
width: Math.max(parent.width, 200)
width: parent.width
readonly property real widgetSpacing: noBackground ? 2 : Theme.spacingXS
spacing: widgetSpacing
Repeater {
id: columnRepeater
model: root.widgetsModel
Item {
readonly property real columnSpacing: parent.widgetSpacing
width: parent.width
readonly property real columnSpacing: parent.widgetSpacing
property var itemData: modelData
height: widgetLoader.item ? widgetLoader.item.height : 0
WidgetHost {
id: widgetLoader
anchors.horizontalCenter: parent.horizontalCenter
widgetId: model.widgetId
widgetData: model
spacerSize: model.size || 20
widgetId: itemData.widgetId
widgetData: itemData
spacerSize: itemData.size || 20
components: root.components
isInColumn: true
axis: root.axis
@@ -87,8 +93,10 @@ Item {
parentScreen: root.parentScreen
widgetThickness: root.widgetThickness
barThickness: root.barThickness
isFirst: model.index === 0
isLast: model.index === columnRepeater.count - 1
barSpacing: root.barSpacing
barConfig: root.barConfig
isFirst: index === 0
isLast: index === columnRepeater.count - 1
sectionSpacing: parent.columnSpacing
isTopBarEdge: true
isBottomBarEdge: false

View File

@@ -15,14 +15,6 @@ DankPopout {
property var triggerScreen: null
function setTriggerPosition(x, y, width, section, screen) {
triggerX = x;
triggerY = y;
triggerWidth = width;
triggerSection = section;
triggerScreen = screen;
}
function isActiveProfile(profile) {
if (typeof PowerProfiles === "undefined") {
return false;
@@ -45,8 +37,6 @@ DankPopout {
popupWidth: 400
popupHeight: contentLoader.item ? contentLoader.item.implicitHeight : 400
triggerX: Screen.width - 380 - Theme.spacingL
triggerY: Theme.barHeight - 4 + SettingsData.dankBarSpacing
triggerWidth: 70
positioning: ""
screen: triggerScreen

View File

@@ -14,18 +14,30 @@ DankPopout {
property var triggerScreen: null
function setTriggerPosition(x, y, width, section, screen) {
function setTriggerPosition(x, y, width, section, screen, barPosition, barThickness, barSpacing, barConfig) {
triggerX = x
triggerY = y
triggerWidth = width
triggerSection = section
triggerScreen = screen
root.screen = screen
storedBarThickness = barThickness !== undefined ? barThickness : (Theme.barHeight - 4)
storedBarSpacing = barSpacing !== undefined ? barSpacing : 4
storedBarConfig = barConfig
const pos = barPosition !== undefined ? barPosition : 0
const bottomGap = barConfig ? (barConfig.bottomGap !== undefined ? barConfig.bottomGap : 0) : 0
setBarContext(pos, bottomGap)
updateOutputState()
}
onScreenChanged: updateOutputState()
function updateOutputState() {
if (triggerScreen && DwlService.dwlAvailable) {
outputState = DwlService.getOutputState(triggerScreen.name)
if (screen && DwlService.dwlAvailable) {
outputState = DwlService.getOutputState(screen.name)
} else {
outputState = null
}
@@ -89,8 +101,6 @@ DankPopout {
popupWidth: 300
popupHeight: contentLoader.item ? contentLoader.item.implicitHeight : 550
triggerX: Screen.width - 380 - Theme.spacingL
triggerY: Theme.barHeight - 4 + SettingsData.dankBarSpacing
triggerWidth: 70
positioning: ""
screen: triggerScreen
@@ -271,19 +281,13 @@ DankPopout {
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onPressed: {
console.log("DWLLayoutPopout: Pressed layout", modelData, "at index", index)
console.log("DWLLayoutPopout: triggerScreen:", root.triggerScreen, "dwlAvailable:", DwlService.dwlAvailable)
if (!root.triggerScreen) {
console.error("DWLLayoutPopout: triggerScreen is null!")
return
}
if (!DwlService.dwlAvailable) {
console.error("DWLLayoutPopout: DwlService not available!")
return
}
console.log("DWLLayoutPopout: CALLING setLayout with output:", root.triggerScreen.name, "index:", index)
DwlService.setLayout(root.triggerScreen.name, index)
root.close()
}

View File

@@ -30,20 +30,9 @@ DankPopout {
property var triggerScreen: null
function setTriggerPosition(x, y, width, section, screen) {
triggerX = x;
triggerY = y;
triggerWidth = width;
triggerSection = section;
triggerScreen = screen;
}
popupWidth: 360
popupHeight: Math.min(Screen.height - 100, contentLoader.item ? contentLoader.item.implicitHeight : 260)
triggerX: Screen.width - 380 - Theme.spacingL
triggerY: Theme.barHeight - 4 + SettingsData.dankBarSpacing
triggerWidth: 70
positioning: ""
screen: triggerScreen
shouldBeVisible: false

View File

@@ -11,6 +11,8 @@ Item {
property var parentScreen: null
property real widgetThickness: 30
property real barThickness: 48
property real barSpacing: 4
property var barConfig: null
property bool overrideAxisLayout: false
property bool forceVerticalLayout: false
@@ -37,14 +39,15 @@ Item {
model: root.widgetsModel
Item {
readonly property real rowSpacing: parent.widgetSpacing
property var itemData: modelData
width: widgetLoader.item ? widgetLoader.item.width : 0
height: widgetLoader.item ? widgetLoader.item.height : 0
WidgetHost {
id: widgetLoader
anchors.verticalCenter: parent.verticalCenter
widgetId: model.widgetId
widgetData: model
spacerSize: model.size || 20
widgetId: itemData.widgetId
widgetData: itemData
spacerSize: itemData.size || 20
components: root.components
isInColumn: false
axis: root.axis
@@ -52,8 +55,10 @@ Item {
parentScreen: root.parentScreen
widgetThickness: root.widgetThickness
barThickness: root.barThickness
isFirst: model.index === 0
isLast: model.index === rowRepeater.count - 1
barSpacing: root.barSpacing
barConfig: root.barConfig
isFirst: index === 0
isLast: index === rowRepeater.count - 1
sectionSpacing: parent.rowSpacing
isLeftBarEdge: false
isRightBarEdge: true
@@ -66,22 +71,23 @@ Item {
Component {
id: columnComp
Column {
width: parent ? parent.width : 0
width: parent.width
readonly property real widgetSpacing: noBackground ? 2 : Theme.spacingXS
spacing: widgetSpacing
Repeater {
id: columnRepeater
model: root.widgetsModel
Item {
readonly property real columnSpacing: parent.widgetSpacing
width: parent.width
readonly property real columnSpacing: parent.widgetSpacing
property var itemData: modelData
height: widgetLoader.item ? widgetLoader.item.height : 0
WidgetHost {
id: widgetLoader
anchors.horizontalCenter: parent.horizontalCenter
widgetId: model.widgetId
widgetData: model
spacerSize: model.size || 20
widgetId: itemData.widgetId
widgetData: itemData
spacerSize: itemData.size || 20
components: root.components
isInColumn: true
axis: root.axis
@@ -89,8 +95,10 @@ Item {
parentScreen: root.parentScreen
widgetThickness: root.widgetThickness
barThickness: root.barThickness
isFirst: model.index === 0
isLast: model.index === columnRepeater.count - 1
barSpacing: root.barSpacing
barConfig: root.barConfig
isFirst: index === 0
isLast: index === columnRepeater.count - 1
sectionSpacing: parent.columnSpacing
isTopBarEdge: false
isBottomBarEdge: true

View File

@@ -1,5 +1,4 @@
import QtQuick
import Quickshell.Services.Mpris
import qs.Services
Loader {
@@ -15,6 +14,8 @@ Loader {
property var parentScreen: null
property real widgetThickness: 30
property real barThickness: 48
property real barSpacing: 4
property var barConfig: null
property bool isFirst: false
property bool isLast: false
property real sectionSpacing: 0
@@ -27,9 +28,7 @@ Loader {
readonly property bool orientationMatches: (axis?.isVertical ?? false) === isInColumn
active: orientationMatches &&
getWidgetVisible(widgetId, DgopService.dgopAvailable) &&
(widgetId !== "music" || MprisController.activePlayer !== null)
active: orientationMatches && getWidgetVisible(widgetId, DgopService.dgopAvailable) && (widgetId !== "music" || MprisController.activePlayer !== null)
sourceComponent: getWidgetComponent(widgetId, components)
opacity: getWidgetEnabled(widgetData?.enabled) ? 1 : 0
@@ -67,6 +66,22 @@ Loader {
restoreMode: Binding.RestoreNone
}
Binding {
target: root.item
when: root.item && "barSpacing" in root.item
property: "barSpacing"
value: root.barSpacing
restoreMode: Binding.RestoreNone
}
Binding {
target: root.item
when: root.item && "barConfig" in root.item
property: "barConfig"
value: root.barConfig
restoreMode: Binding.RestoreNone
}
Binding {
target: root.item
when: root.item && "axis" in root.item
@@ -141,33 +156,32 @@ Loader {
onLoaded: {
if (item) {
contentItemReady(item)
contentItemReady(item);
if (axis && "isVertical" in item) {
try {
item.isVertical = axis.isVertical
} catch (e) {
}
item.isVertical = axis.isVertical;
} catch (e) {}
}
if (item.pluginService !== undefined) {
var parts = widgetId.split(":")
var pluginId = parts[0]
var variantId = parts.length > 1 ? parts[1] : null
var parts = widgetId.split(":");
var pluginId = parts[0];
var variantId = parts.length > 1 ? parts[1] : null;
if (item.pluginId !== undefined) {
item.pluginId = pluginId
item.pluginId = pluginId;
}
if (item.variantId !== undefined) {
item.variantId = variantId
item.variantId = variantId;
}
if (item.variantData !== undefined && variantId) {
item.variantData = PluginService.getPluginVariantData(pluginId, variantId)
item.variantData = PluginService.getPluginVariantData(pluginId, variantId);
}
item.pluginService = PluginService
item.pluginService = PluginService;
}
if (item.popoutService !== undefined) {
item.popoutService = PopoutService
item.popoutService = PopoutService;
}
}
}
@@ -203,17 +217,17 @@ Loader {
"colorPicker": components.colorPickerComponent,
"systemUpdate": components.systemUpdateComponent,
"layout": components.layoutComponent
}
};
if (componentMap[widgetId]) {
return componentMap[widgetId]
return componentMap[widgetId];
}
var parts = widgetId.split(":")
var pluginId = parts[0]
var parts = widgetId.split(":");
var pluginId = parts[0];
let pluginMap = PluginService.getWidgetComponents()
return pluginMap[pluginId] || null
let pluginMap = PluginService.getWidgetComponents();
return pluginMap[pluginId] || null;
}
function getWidgetVisible(widgetId, dgopAvailable) {
@@ -224,12 +238,12 @@ Loader {
"gpuTemp": dgopAvailable,
"network_speed_monitor": dgopAvailable,
"layout": CompositorService.isDwl && DwlService.dwlAvailable
}
};
return widgetVisibility[widgetId] ?? true
return widgetVisibility[widgetId] ?? true;
}
function getWidgetEnabled(enabled) {
return enabled !== false
return enabled !== false;
}
}

View File

@@ -1,5 +1,4 @@
import QtQuick
import Quickshell.Services.UPower
import qs.Common
import qs.Modules.Plugins
import qs.Services
@@ -11,7 +10,22 @@ BasePill {
property bool batteryPopupVisible: false
property var popoutTarget: null
signal toggleBatteryPopup()
readonly property int barPosition: {
switch (axis?.edge) {
case "top":
return 0;
case "bottom":
return 1;
case "left":
return 2;
case "right":
return 3;
default:
return 0;
}
}
signal toggleBatteryPopup
visible: true
@@ -31,25 +45,25 @@ BasePill {
size: Theme.barIconSize(battery.barThickness)
color: {
if (!BatteryService.batteryAvailable) {
return Theme.widgetIconColor
return Theme.widgetIconColor;
}
if (BatteryService.isLowBattery && !BatteryService.isCharging) {
return Theme.error
return Theme.error;
}
if (BatteryService.isCharging || BatteryService.isPluggedIn) {
return Theme.primary
return Theme.primary;
}
return Theme.widgetIconColor
return Theme.widgetIconColor;
}
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: BatteryService.batteryLevel.toString()
font.pixelSize: Theme.barTextSize(battery.barThickness)
font.pixelSize: Theme.barTextSize(battery.barThickness, battery.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
visible: BatteryService.batteryAvailable
@@ -60,7 +74,7 @@ BasePill {
id: batteryContent
visible: !battery.isVerticalOrientation
anchors.centerIn: parent
spacing: SettingsData.dankBarNoBackground ? 1 : 2
spacing: (barConfig?.noBackground ?? false) ? 1 : 2
DankIcon {
name: BatteryService.getBatteryIcon()
@@ -85,7 +99,7 @@ BasePill {
StyledText {
text: `${BatteryService.batteryLevel}%`
font.pixelSize: Theme.barTextSize(battery.barThickness)
font.pixelSize: Theme.barTextSize(battery.barThickness, battery.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
visible: BatteryService.batteryAvailable
@@ -102,13 +116,7 @@ BasePill {
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton
onPressed: {
if (popoutTarget && popoutTarget.setTriggerPosition) {
const globalPos = battery.visualContent.mapToGlobal(0, 0)
const currentScreen = parentScreen || Screen
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, battery.visualWidth)
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
}
toggleBatteryPopup()
toggleBatteryPopup();
}
}
}
}

View File

@@ -35,7 +35,7 @@ BasePill {
return String(display).padStart(2, '0').charAt(0)
}
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
@@ -51,7 +51,7 @@ BasePill {
return String(display).padStart(2, '0').charAt(1)
}
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
@@ -64,7 +64,7 @@ BasePill {
StyledText {
text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(0)
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
@@ -72,7 +72,7 @@ BasePill {
StyledText {
text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(1)
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
@@ -86,7 +86,7 @@ BasePill {
StyledText {
text: String(systemClock?.date?.getSeconds()).padStart(2, '0').charAt(0)
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
@@ -94,7 +94,7 @@ BasePill {
StyledText {
text: String(systemClock?.date?.getSeconds()).padStart(2, '0').charAt(1)
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
@@ -126,7 +126,7 @@ BasePill {
const value = dayFirst ? String(systemClock?.date?.getDate()).padStart(2, '0') : String(systemClock?.date?.getMonth() + 1).padStart(2, '0')
return value.charAt(0)
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.primary
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
@@ -140,7 +140,7 @@ BasePill {
const value = dayFirst ? String(systemClock?.date?.getDate()).padStart(2, '0') : String(systemClock?.date?.getMonth() + 1).padStart(2, '0')
return value.charAt(1)
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.primary
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
@@ -159,7 +159,7 @@ BasePill {
const value = dayFirst ? String(systemClock?.date?.getMonth() + 1).padStart(2, '0') : String(systemClock?.date?.getDate()).padStart(2, '0')
return value.charAt(0)
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.primary
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
@@ -173,7 +173,7 @@ BasePill {
const value = dayFirst ? String(systemClock?.date?.getMonth() + 1).padStart(2, '0') : String(systemClock?.date?.getDate()).padStart(2, '0')
return value.charAt(1)
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.primary
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom
@@ -192,7 +192,7 @@ BasePill {
text: {
return systemClock?.date?.toLocaleTimeString(Qt.locale(), SettingsData.getEffectiveTimeFormat())
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.baseline: dateText.baseline
}
@@ -214,7 +214,7 @@ BasePill {
}
return systemClock?.date?.toLocaleDateString(Qt.locale(), "ddd d")
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
visible: !SettingsData.clockCompactMode
@@ -235,12 +235,6 @@ BasePill {
height: root.height + root.topMargin + root.bottomMargin
cursorShape: Qt.PointingHandCursor
onPressed: {
if (root.popoutTarget && root.popoutTarget.setTriggerPosition) {
const globalPos = root.visualContent.mapToGlobal(0, 0)
const currentScreen = root.parentScreen || Screen
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, root.barThickness, root.visualWidth)
root.popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, root.section, currentScreen)
}
root.clockClicked()
}
}

View File

@@ -236,22 +236,4 @@ BasePill {
}
}
}
MouseArea {
x: -root.leftMargin
y: -root.topMargin
width: root.width + root.leftMargin + root.rightMargin
height: root.height + root.topMargin + root.bottomMargin
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton
onPressed: {
if (popoutTarget && popoutTarget.setTriggerPosition) {
const globalPos = root.visualContent.mapToGlobal(0, 0)
const currentScreen = parentScreen || Screen
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.visualWidth)
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
}
root.clicked()
}
}
}

View File

@@ -15,6 +15,8 @@ BasePill {
property var widgetData: null
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
signal cpuClicked()
Component.onCompleted: {
DgopService.addRef(["cpu"]);
}
@@ -58,7 +60,7 @@ BasePill {
return DgopService.cpuUsage.toFixed(0);
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -95,7 +97,7 @@ BasePill {
return DgopService.cpuUsage.toFixed(0) + "%";
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
@@ -103,7 +105,7 @@ BasePill {
StyledTextMetrics {
id: cpuBaseline
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
text: "100%"
}
@@ -125,16 +127,8 @@ BasePill {
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton
onPressed: {
if (popoutTarget && popoutTarget.setTriggerPosition) {
const globalPos = root.visualContent.mapToGlobal(0, 0)
const currentScreen = parentScreen || Screen
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.visualWidth)
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
}
DgopService.setSortBy("cpu");
if (popoutTarget) {
PopoutManager.requestPopout(popoutTarget, undefined, "cpu");
}
DgopService.setSortBy("cpu")
cpuClicked()
}
}
}

View File

@@ -15,6 +15,8 @@ BasePill {
property var widgetData: null
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
signal cpuTempClicked()
Component.onCompleted: {
DgopService.addRef(["cpu"]);
}
@@ -58,7 +60,7 @@ BasePill {
return Math.round(DgopService.cpuTemperature).toString();
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -95,7 +97,7 @@ BasePill {
return Math.round(DgopService.cpuTemperature) + "°";
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
@@ -103,7 +105,7 @@ BasePill {
StyledTextMetrics {
id: tempBaseline
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
text: "100°"
}
@@ -125,16 +127,8 @@ BasePill {
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton
onPressed: {
if (popoutTarget && popoutTarget.setTriggerPosition) {
const globalPos = root.visualContent.mapToGlobal(0, 0)
const currentScreen = parentScreen || Screen
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.visualWidth)
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
}
DgopService.setSortBy("cpu");
if (popoutTarget) {
PopoutManager.requestPopout(popoutTarget, undefined, "cpu_temp");
}
DgopService.setSortBy("cpu")
cpuTempClicked()
}
}
}

View File

@@ -64,7 +64,7 @@ BasePill {
StyledText {
text: layout.currentLayoutSymbol
font.pixelSize: Theme.barTextSize(layout.barThickness)
font.pixelSize: Theme.barTextSize(layout.barThickness, layout.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -74,7 +74,7 @@ BasePill {
id: layoutContent
visible: !layout.isVerticalOrientation
anchors.centerIn: parent
spacing: SettingsData.dankBarNoBackground ? 1 : 2
spacing: (barConfig?.noBackground ?? false) ? 1 : 2
DankIcon {
name: layout.getLayoutIcon(layout.currentLayoutSymbol)
@@ -85,7 +85,7 @@ BasePill {
StyledText {
text: layout.currentLayoutSymbol
font.pixelSize: Theme.barTextSize(layout.barThickness)
font.pixelSize: Theme.barTextSize(layout.barThickness, layout.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
}
@@ -94,12 +94,6 @@ BasePill {
}
onClicked: {
if (popoutTarget && popoutTarget.setTriggerPosition) {
const globalPos = layout.visualContent.mapToGlobal(0, 0)
const currentScreen = parentScreen || Screen
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, layout.visualWidth)
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
}
toggleLayoutPopup()
}

View File

@@ -1,5 +1,4 @@
import QtQuick
import QtQuick.Controls
import qs.Common
import qs.Modules.Plugins
import qs.Services
@@ -11,71 +10,90 @@ BasePill {
property var widgetData: null
property string mountPath: (widgetData && widgetData.mountPath !== undefined) ? widgetData.mountPath : "/"
property bool isHovered: mouseArea.containsMouse
property bool isAutoHideBar: false
property var selectedMount: {
if (!DgopService.diskMounts || DgopService.diskMounts.length === 0) {
return null
return null;
}
const currentMountPath = root.mountPath || "/"
const currentMountPath = root.mountPath || "/";
for (let i = 0; i < DgopService.diskMounts.length; i++) {
if (DgopService.diskMounts[i].mount === currentMountPath) {
return DgopService.diskMounts[i]
return DgopService.diskMounts[i];
}
}
for (let i = 0; i < DgopService.diskMounts.length; i++) {
if (DgopService.diskMounts[i].mount === "/") {
return DgopService.diskMounts[i]
return DgopService.diskMounts[i];
}
}
return DgopService.diskMounts[0] || null
return DgopService.diskMounts[0] || null;
}
property real diskUsagePercent: {
if (!selectedMount || !selectedMount.percent) {
return 0
return 0;
}
const percentStr = selectedMount.percent.replace("%", "")
return parseFloat(percentStr) || 0
const percentStr = selectedMount.percent.replace("%", "");
return parseFloat(percentStr) || 0;
}
Component.onCompleted: {
DgopService.addRef(["diskmounts"])
DgopService.addRef(["diskmounts"]);
}
Component.onDestruction: {
DgopService.removeRef(["diskmounts"])
DgopService.removeRef(["diskmounts"]);
}
readonly property real minTooltipY: {
if (!parentScreen || !isVerticalOrientation) {
return 0;
}
if (isAutoHideBar) {
return 0;
}
if (parentScreen.y > 0) {
const spacing = barConfig?.spacing ?? 4;
const offset = barThickness + spacing;
return offset;
}
return 0;
}
Connections {
function onWidgetDataChanged() {
root.mountPath = Qt.binding(() => {
return (root.widgetData && root.widgetData.mountPath !== undefined) ? root.widgetData.mountPath : "/"
})
return (root.widgetData && root.widgetData.mountPath !== undefined) ? root.widgetData.mountPath : "/";
});
root.selectedMount = Qt.binding(() => {
if (!DgopService.diskMounts || DgopService.diskMounts.length === 0) {
return null
return null;
}
const currentMountPath = root.mountPath || "/"
const currentMountPath = root.mountPath || "/";
for (let i = 0; i < DgopService.diskMounts.length; i++) {
if (DgopService.diskMounts[i].mount === currentMountPath) {
return DgopService.diskMounts[i]
return DgopService.diskMounts[i];
}
}
for (let i = 0; i < DgopService.diskMounts.length; i++) {
if (DgopService.diskMounts[i].mount === "/") {
return DgopService.diskMounts[i]
return DgopService.diskMounts[i];
}
}
return DgopService.diskMounts[0] || null
})
return DgopService.diskMounts[0] || null;
});
}
target: SettingsData
@@ -97,12 +115,12 @@ BasePill {
size: Theme.barIconSize(root.barThickness)
color: {
if (root.diskUsagePercent > 90) {
return Theme.tempDanger
return Theme.tempDanger;
}
if (root.diskUsagePercent > 75) {
return Theme.tempWarning
return Theme.tempWarning;
}
return Theme.surfaceText
return Theme.surfaceText;
}
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -110,11 +128,11 @@ BasePill {
StyledText {
text: {
if (root.diskUsagePercent === undefined || root.diskUsagePercent === null || root.diskUsagePercent === 0) {
return "--"
return "--";
}
return root.diskUsagePercent.toFixed(0)
return root.diskUsagePercent.toFixed(0);
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -131,12 +149,12 @@ BasePill {
size: Theme.barIconSize(root.barThickness)
color: {
if (root.diskUsagePercent > 90) {
return Theme.tempDanger
return Theme.tempDanger;
}
if (root.diskUsagePercent > 75) {
return Theme.tempWarning
return Theme.tempWarning;
}
return Theme.surfaceText
return Theme.surfaceText;
}
anchors.verticalCenter: parent.verticalCenter
}
@@ -144,11 +162,11 @@ BasePill {
StyledText {
text: {
if (!root.selectedMount) {
return "--"
return "--";
}
return root.selectedMount.mount
return root.selectedMount.mount;
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
@@ -158,11 +176,11 @@ BasePill {
StyledText {
text: {
if (root.diskUsagePercent === undefined || root.diskUsagePercent === null || root.diskUsagePercent === 0) {
return "--%"
return "--%";
}
return root.diskUsagePercent.toFixed(0) + "%"
return root.diskUsagePercent.toFixed(0) + "%";
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
@@ -170,7 +188,7 @@ BasePill {
StyledTextMetrics {
id: diskBaseline
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
text: "100%"
}
@@ -200,24 +218,25 @@ BasePill {
hoverEnabled: root.isVerticalOrientation
onEntered: {
if (root.isVerticalOrientation && root.selectedMount) {
tooltipLoader.active = true
tooltipLoader.active = true;
if (tooltipLoader.item) {
const globalPos = mapToGlobal(width / 2, height / 2)
const currentScreen = root.parentScreen || Screen
const screenX = currentScreen ? currentScreen.x : 0
const screenY = currentScreen ? currentScreen.y : 0
const relativeY = globalPos.y - screenY
const tooltipX = root.axis?.edge === "left" ? (Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS) : (currentScreen.width - Theme.barHeight - SettingsData.dankBarSpacing - Theme.spacingXS)
const isLeft = root.axis?.edge === "left"
tooltipLoader.item.show(root.selectedMount.mount, screenX + tooltipX, relativeY, currentScreen, isLeft, !isLeft)
const globalPos = mapToGlobal(width / 2, height / 2);
const currentScreen = root.parentScreen || Screen;
const screenX = currentScreen ? currentScreen.x : 0;
const screenY = currentScreen ? currentScreen.y : 0;
const relativeY = globalPos.y - screenY;
const adjustedY = relativeY + root.minTooltipY;
const tooltipX = root.axis?.edge === "left" ? (root.barThickness + root.barSpacing + Theme.spacingXS) : (currentScreen.width - root.barThickness - root.barSpacing - Theme.spacingXS);
const isLeft = root.axis?.edge === "left";
tooltipLoader.item.show(root.selectedMount.mount, screenX + tooltipX, adjustedY, currentScreen, isLeft, !isLeft);
}
}
}
onExited: {
if (tooltipLoader.item) {
tooltipLoader.item.hide()
tooltipLoader.item.hide();
}
tooltipLoader.active = false
tooltipLoader.active = false;
}
}
}

View File

@@ -18,6 +18,23 @@ BasePill {
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
property var activeDesktopEntry: null
property bool isHovered: mouseArea.containsMouse
property bool isAutoHideBar: false
readonly property real minTooltipY: {
if (!parentScreen || !isVerticalOrientation) {
return 0
}
if (isAutoHideBar) {
return 0
}
if (parentScreen.y > 0) {
return barThickness + (barSpacing || 4)
}
return 0
}
Component.onCompleted: {
updateDesktopEntry()
@@ -80,7 +97,6 @@ BasePill {
return activeHyprToplevel.workspace.id === Hyprland.focusedWorkspace.id
} catch (e) {
console.error("FocusedApp: hasWindowsOnCurrentWorkspace error:", e)
return false
}
}
@@ -167,7 +183,7 @@ BasePill {
const desktopEntry = DesktopEntries.heuristicLookup(activeWindow.appId);
return desktopEntry && desktopEntry.name ? desktopEntry.name : activeWindow.appId;
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
@@ -178,7 +194,7 @@ BasePill {
StyledText {
text: "•"
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.outlineButton
anchors.verticalCenter: parent.verticalCenter
visible: !compactMode && appText.text && titleText.text
@@ -203,7 +219,7 @@ BasePill {
return title;
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
@@ -229,14 +245,16 @@ BasePill {
const screenX = currentScreen ? currentScreen.x : 0
const screenY = currentScreen ? currentScreen.y : 0
const relativeY = globalPos.y - screenY
const tooltipX = root.axis?.edge === "left" ? (Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS) : (currentScreen.width - Theme.barHeight - SettingsData.dankBarSpacing - Theme.spacingXS)
// Add minTooltipY offset to account for top bar
const adjustedY = relativeY + root.minTooltipY
const tooltipX = root.axis?.edge === "left" ? (Theme.barHeight + (barConfig?.spacing ?? 4) + Theme.spacingXS) : (currentScreen.width - Theme.barHeight - (barConfig?.spacing ?? 4) - Theme.spacingXS)
const appName = activeDesktopEntry && activeDesktopEntry.name ? activeDesktopEntry.name : activeWindow.appId
const title = activeWindow.title || ""
const tooltipText = appName + (title ? " • " + title : "")
const isLeft = root.axis?.edge === "left"
tooltipLoader.item.show(tooltipText, screenX + tooltipX, relativeY, currentScreen, isLeft, !isLeft)
tooltipLoader.item.show(tooltipText, screenX + tooltipX, adjustedY, currentScreen, isLeft, !isLeft)
}
}
}

View File

@@ -15,6 +15,9 @@ BasePill {
property var widgetData: null
property int selectedGpuIndex: (widgetData && widgetData.selectedGpuIndex !== undefined) ? widgetData.selectedGpuIndex : 0
property bool minimumWidth: (widgetData && widgetData.minimumWidth !== undefined) ? widgetData.minimumWidth : true
signal gpuTempClicked()
property real displayTemp: {
if (!DgopService.availableGpus || DgopService.availableGpus.length === 0) {
return 0;
@@ -29,15 +32,18 @@ BasePill {
function updateWidgetPciId(pciId) {
const sections = ["left", "center", "right"];
const defaultBar = SettingsData.barConfigs[0] || SettingsData.getBarConfig("default")
if (!defaultBar) return
for (let s = 0; s < sections.length; s++) {
const sectionId = sections[s];
let widgets = [];
if (sectionId === "left") {
widgets = SettingsData.dankBarLeftWidgets.slice();
widgets = (defaultBar.leftWidgets || []).slice();
} else if (sectionId === "center") {
widgets = SettingsData.dankBarCenterWidgets.slice();
widgets = (defaultBar.centerWidgets || []).slice();
} else if (sectionId === "right") {
widgets = SettingsData.dankBarRightWidgets.slice();
widgets = (defaultBar.rightWidgets || []).slice();
}
for (let i = 0; i < widgets.length; i++) {
const widget = widgets[i];
@@ -122,7 +128,7 @@ BasePill {
return Math.round(root.displayTemp).toString();
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -159,7 +165,7 @@ BasePill {
return Math.round(root.displayTemp) + "°";
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
@@ -167,7 +173,7 @@ BasePill {
StyledTextMetrics {
id: gpuTempBaseline
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
text: "100°"
}
@@ -189,16 +195,8 @@ BasePill {
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton
onPressed: {
if (popoutTarget && popoutTarget.setTriggerPosition) {
const globalPos = root.visualContent.mapToGlobal(0, 0)
const currentScreen = parentScreen || Screen
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.visualWidth)
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
}
DgopService.setSortBy("cpu");
if (popoutTarget) {
PopoutManager.requestPopout(popoutTarget, undefined, "gpu_temp");
}
DgopService.setSortBy("cpu")
gpuTempClicked()
}
}

View File

@@ -50,7 +50,7 @@ BasePill {
}
return root.currentLayout.substring(0, 2).toUpperCase()
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -64,7 +64,7 @@ BasePill {
StyledText {
text: root.currentLayout
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
}

View File

@@ -174,7 +174,7 @@ BasePill {
anchors.verticalCenter: parent.verticalCenter
text: textContainer.displayText
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
wrapMode: Text.NoWrap
x: needsScrolling ? -scrollOffset : 0

View File

@@ -53,7 +53,7 @@ BasePill {
if (rate < 1024 * 1024) return (rate / 1024).toFixed(0) + "K"
return (rate / (1024 * 1024)).toFixed(0) + "M"
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.info
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -65,7 +65,7 @@ BasePill {
if (rate < 1024 * 1024) return (rate / 1024).toFixed(0) + "K"
return (rate / (1024 * 1024)).toFixed(0) + "M"
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.error
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -90,13 +90,13 @@ BasePill {
StyledText {
text: "↓"
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.info
}
StyledText {
text: DgopService.networkRxRate > 0 ? root.formatNetworkSpeed(DgopService.networkRxRate) : "0 B/s"
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
@@ -105,7 +105,7 @@ BasePill {
StyledTextMetrics {
id: rxBaseline
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
text: "88.8 MB/s"
}
@@ -126,13 +126,13 @@ BasePill {
StyledText {
text: "↑"
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.error
}
StyledText {
text: DgopService.networkTxRate > 0 ? root.formatNetworkSpeed(DgopService.networkTxRate) : "0 B/s"
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
@@ -141,7 +141,7 @@ BasePill {
StyledTextMetrics {
id: txBaseline
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
text: "88.8 MB/s"
}

View File

@@ -1,5 +1,4 @@
import QtQuick
import QtQuick.Controls
import qs.Common
import qs.Services
import qs.Widgets
@@ -14,14 +13,15 @@ Item {
property var parentScreen: null
property real widgetThickness: 30
property real barThickness: 48
property var barConfig: null
property bool showMicIcon: SettingsData.privacyShowMicIcon
property bool showCameraIcon: SettingsData.privacyShowCameraIcon
property bool showScreenSharingIcon: SettingsData.privacyShowScreenShareIcon
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 2 : Theme.spacingS
readonly property real horizontalPadding: (barConfig?.noBackground ?? false) ? 2 : Theme.spacingS
readonly property bool hasActivePrivacy: showMicIcon || showCameraIcon || showScreenSharingIcon || PrivacyService.anyPrivacyActive
readonly property int activeCount: ( showMicIcon ? 1 : PrivacyService.microphoneActive) + (showCameraIcon ? 1 : PrivacyService.cameraActive) + (showScreenSharingIcon ? 1 : PrivacyService.screensharingActive)
readonly property int activeCount: (showMicIcon ? 1 : PrivacyService.microphoneActive) + (showCameraIcon ? 1 : PrivacyService.cameraActive) + (showScreenSharingIcon ? 1 : PrivacyService.screensharingActive)
readonly property real contentWidth: hasActivePrivacy ? (activeCount * 18 + (activeCount - 1) * Theme.spacingXS) : 0
readonly property real contentHeight: hasActivePrivacy ? (activeCount * 18 + (activeCount - 1) * Theme.spacingXS) : 0
readonly property real visualWidth: isVertical ? widgetThickness : (hasActivePrivacy ? (contentWidth + horizontalPadding * 2) : 0)
@@ -38,14 +38,15 @@ Item {
width: root.visualWidth
height: root.visualHeight
anchors.centerIn: parent
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
radius: (barConfig?.noBackground ?? false) ? 0 : Theme.cornerRadius
color: {
if (SettingsData.dankBarNoBackground) {
return "transparent"
if (barConfig?.noBackground ?? false) {
return "transparent";
}
const baseColor = Theme.widgetBaseBackgroundColor
return Qt.rgba(privacyArea.containsMouse ? Theme.errorPressed.r : baseColor.r, privacyArea.containsMouse ? Theme.errorPressed.g : baseColor.g, privacyArea.containsMouse ? Theme.errorPressed.b : baseColor.b, (privacyArea.containsMouse ? Theme.errorPressed.a : baseColor.a) * Theme.widgetTransparency)
const baseColor = privacyArea.containsMouse ? Theme.errorPressed : Theme.errorHover;
const transparency = (root.barConfig && root.barConfig.widgetTransparency !== undefined) ? root.barConfig.widgetTransparency : 1.0;
return Theme.withAlpha(baseColor, transparency);
}
Column {
@@ -61,10 +62,11 @@ Item {
DankIcon {
name: {
const sourceAudio = AudioService.source?.audio
const muted = !sourceAudio || sourceAudio.muted || sourceAudio.volume === 0.0
if (muted) return "mic_off"
return "mic"
const sourceAudio = AudioService.source?.audio;
const muted = !sourceAudio || sourceAudio.muted || sourceAudio.volume === 0.0;
if (muted)
return "mic_off";
return "mic";
}
size: Theme.iconSizeSmall
color: Theme.error
@@ -128,10 +130,11 @@ Item {
DankIcon {
name: {
const sourceAudio = AudioService.source?.audio
const muted = !sourceAudio || sourceAudio.muted || sourceAudio.volume === 0.0
if (muted) return "mic_off"
return "mic"
const sourceAudio = AudioService.source?.audio;
const muted = !sourceAudio || sourceAudio.muted || sourceAudio.volume === 0.0;
if (muted)
return "mic_off";
return "mic";
}
size: Theme.iconSizeSmall
color: PrivacyService.microphoneActive ? Theme.error : Theme.surfaceText
@@ -191,8 +194,7 @@ Item {
hoverEnabled: hasActivePrivacy
enabled: hasActivePrivacy
cursorShape: Qt.PointingHandCursor
onClicked: {
}
onClicked: {}
}
Rectangle {
@@ -213,7 +215,7 @@ Item {
id: tooltipText
anchors.centerIn: parent
text: PrivacyService.getPrivacySummary()
font.pixelSize: Theme.barTextSize(barThickness)
font.pixelSize: Theme.barTextSize(barThickness, barConfig?.fontScale)
color: Theme.widgetTextColor
}

View File

@@ -17,6 +17,8 @@ BasePill {
property bool showSwap: (widgetData && widgetData.showSwap !== undefined) ? widgetData.showSwap : false
readonly property real swapUsage: DgopService.totalSwapKB > 0 ? (DgopService.usedSwapKB / DgopService.totalSwapKB) * 100 : 0
signal ramClicked()
Component.onCompleted: {
DgopService.addRef(["memory"]);
}
@@ -60,7 +62,7 @@ BasePill {
return DgopService.memoryUsage.toFixed(0);
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -68,7 +70,7 @@ BasePill {
StyledText {
visible: root.showSwap && DgopService.totalSwapKB > 0
text: root.swapUsage.toFixed(0)
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -109,7 +111,7 @@ BasePill {
}
return ramText;
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignLeft
@@ -118,7 +120,7 @@ BasePill {
StyledTextMetrics {
id: ramBaseline
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
text: {
if (!root.showSwap) {
return "100%";
@@ -148,16 +150,8 @@ BasePill {
cursorShape: Qt.PointingHandCursor
acceptedButtons: Qt.LeftButton
onPressed: {
if (popoutTarget && popoutTarget.setTriggerPosition) {
const globalPos = root.visualContent.mapToGlobal(0, 0)
const currentScreen = parentScreen || Screen
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.visualWidth)
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
}
DgopService.setSortBy("memory");
if (popoutTarget) {
PopoutManager.requestPopout(popoutTarget, undefined, "memory");
}
DgopService.setSortBy("memory")
ramClicked()
}
}
}

View File

@@ -11,6 +11,7 @@ import qs.Widgets
Item {
id: root
property var barConfig: null
property bool isVertical: axis?.isVertical ?? false
property var axis: null
property string section: "left"
@@ -19,8 +20,46 @@ Item {
property var topBar: null
property real widgetThickness: 30
property real barThickness: 48
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 2 : Theme.spacingS
property real barSpacing: 4
property bool isAutoHideBar: false
readonly property real horizontalPadding: (barConfig?.noBackground ?? false) ? 2 : Theme.spacingS
property Item windowRoot: (Window.window ? Window.window.contentItem : null)
readonly property real effectiveBarThickness: {
if (barThickness > 0 && barSpacing > 0) {
return barThickness + barSpacing
}
const innerPadding = barConfig?.innerPadding ?? 4
const spacing = barConfig?.spacing ?? 4
return Math.max(26 + innerPadding * 0.6, Theme.barHeight - 4 - (8 - innerPadding)) + spacing
}
readonly property var barBounds: {
if (!parentScreen || !barConfig) {
return { "x": 0, "y": 0, "width": 0, "height": 0, "wingSize": 0 }
}
const barPosition = axis.edge === "left" ? 2 : (axis.edge === "right" ? 3 : (axis.edge === "top" ? 0 : 1))
return SettingsData.getBarBounds(parentScreen, effectiveBarThickness, barPosition, barConfig)
}
readonly property real barY: barBounds.y
readonly property real minTooltipY: {
if (!parentScreen || !isVertical) {
return 0
}
if (isAutoHideBar) {
return 0
}
if (parentScreen.y > 0) {
return effectiveBarThickness
}
return 0
}
property int _desktopEntriesUpdateTrigger: 0
property int _toplevelsUpdateTrigger: 0
@@ -75,7 +114,6 @@ Item {
})
return Array.from(appGroups.values())
} catch (e) {
console.error("RunningApps: groupedWindows error:", e)
return []
}
}
@@ -101,19 +139,20 @@ Item {
width: root.isVertical ? root.widgetThickness : root.calculatedSize
height: root.isVertical ? root.calculatedSize : root.widgetThickness
anchors.centerIn: parent
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
radius: (barConfig?.noBackground ?? false) ? 0 : Theme.cornerRadius
clip: false
color: {
if (windowCount === 0) {
return "transparent"
}
if (SettingsData.dankBarNoBackground) {
if ((barConfig?.noBackground ?? false)) {
return "transparent"
}
const baseColor = Theme.widgetBaseBackgroundColor
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency)
const transparency = (root.barConfig && root.barConfig.widgetTransparency !== undefined) ? root.barConfig.widgetTransparency : 1.0
return Theme.withAlpha(baseColor, transparency)
}
}
@@ -353,7 +392,7 @@ Item {
anchors.verticalCenter: parent.verticalCenter
visible: !SettingsData.runningAppsCompactMode
text: windowTitle
font.pixelSize: Theme.barTextSize(barThickness)
font.pixelSize: Theme.barTextSize(barThickness, barConfig?.fontScale)
color: Theme.widgetTextColor
elide: Text.ElideRight
maximumLineCount: 1
@@ -390,18 +429,25 @@ Item {
windowContextMenuLoader.active = true
if (windowContextMenuLoader.item) {
windowContextMenuLoader.item.currentWindow = toplevelObject
// Pass bar context
windowContextMenuLoader.item.triggerBarConfig = root.barConfig
windowContextMenuLoader.item.triggerBarPosition = root.axis.edge === "left" ? 2 : (root.axis.edge === "right" ? 3 : (root.axis.edge === "top" ? 0 : 1))
windowContextMenuLoader.item.triggerBarThickness = root.barThickness
windowContextMenuLoader.item.triggerBarSpacing = root.barSpacing
if (root.isVertical) {
const globalPos = delegateItem.mapToGlobal(delegateItem.width / 2, delegateItem.height / 2)
const screenX = root.parentScreen ? root.parentScreen.x : 0
const screenY = root.parentScreen ? root.parentScreen.y : 0
const relativeY = globalPos.y - screenY
const xPos = root.axis?.edge === "left" ? (Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS) : (root.parentScreen.width - Theme.barHeight - SettingsData.dankBarSpacing - Theme.spacingXS)
windowContextMenuLoader.item.showAt(xPos, relativeY, true, root.axis?.edge)
// Add minTooltipY offset to account for top bar
const adjustedY = relativeY + root.minTooltipY
const xPos = root.axis?.edge === "left" ? (root.barThickness + root.barSpacing + Theme.spacingXS) : (root.parentScreen.width - root.barThickness - root.barSpacing - Theme.spacingXS)
windowContextMenuLoader.item.showAt(xPos, adjustedY, true, root.axis?.edge)
} else {
const globalPos = delegateItem.mapToGlobal(delegateItem.width / 2, 0)
const screenX = root.parentScreen ? root.parentScreen.x : 0
const relativeX = globalPos.x - screenX
const yPos = Theme.barHeight + SettingsData.dankBarSpacing - 7
const yPos = root.barThickness + root.barSpacing - 7
windowContextMenuLoader.item.showAt(relativeX, yPos, false, "top")
}
}
@@ -416,16 +462,18 @@ Item {
const screenX = root.parentScreen ? root.parentScreen.x : 0
const screenY = root.parentScreen ? root.parentScreen.y : 0
const relativeY = globalPos.y - screenY
const tooltipX = root.axis?.edge === "left" ? (Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS) : (root.parentScreen.width - Theme.barHeight - SettingsData.dankBarSpacing - Theme.spacingXS)
const tooltipX = root.axis?.edge === "left" ? (Theme.barHeight + (barConfig?.spacing ?? 4) + Theme.spacingXS) : (root.parentScreen.width - Theme.barHeight - (barConfig?.spacing ?? 4) - Theme.spacingXS)
const isLeft = root.axis?.edge === "left"
tooltipLoader.item.show(delegateItem.tooltipText, screenX + tooltipX, relativeY, root.parentScreen, isLeft, !isLeft)
const adjustedY = relativeY + root.minTooltipY
const finalX = screenX + tooltipX
tooltipLoader.item.show(delegateItem.tooltipText, finalX, adjustedY, root.parentScreen, isLeft, !isLeft)
} else {
const globalPos = delegateItem.mapToGlobal(delegateItem.width / 2, delegateItem.height)
const screenHeight = root.parentScreen ? root.parentScreen.height : Screen.height
const isBottom = root.axis?.edge === "bottom"
const tooltipY = isBottom
? (screenHeight - Theme.barHeight - SettingsData.dankBarSpacing - Theme.spacingXS - 35)
: (Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS)
? (screenHeight - Theme.barHeight - (barConfig?.spacing ?? 4) - Theme.spacingXS - 35)
: (Theme.barHeight + (barConfig?.spacing ?? 4) + Theme.spacingXS)
tooltipLoader.item.show(delegateItem.tooltipText, globalPos.x, tooltipY, root.parentScreen, false, false)
}
}
@@ -586,7 +634,7 @@ Item {
anchors.verticalCenter: parent.verticalCenter
visible: !SettingsData.runningAppsCompactMode
text: windowTitle
font.pixelSize: Theme.barTextSize(barThickness)
font.pixelSize: Theme.barTextSize(barThickness, barConfig?.fontScale)
color: Theme.widgetTextColor
elide: Text.ElideRight
maximumLineCount: 1
@@ -623,18 +671,25 @@ Item {
windowContextMenuLoader.active = true
if (windowContextMenuLoader.item) {
windowContextMenuLoader.item.currentWindow = toplevelObject
// Pass bar context
windowContextMenuLoader.item.triggerBarConfig = root.barConfig
windowContextMenuLoader.item.triggerBarPosition = root.axis.edge === "left" ? 2 : (root.axis.edge === "right" ? 3 : (root.axis.edge === "top" ? 0 : 1))
windowContextMenuLoader.item.triggerBarThickness = root.barThickness
windowContextMenuLoader.item.triggerBarSpacing = root.barSpacing
if (root.isVertical) {
const globalPos = delegateItem.mapToGlobal(delegateItem.width / 2, delegateItem.height / 2)
const screenX = root.parentScreen ? root.parentScreen.x : 0
const screenY = root.parentScreen ? root.parentScreen.y : 0
const relativeY = globalPos.y - screenY
const xPos = root.axis?.edge === "left" ? (Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS) : (root.parentScreen.width - Theme.barHeight - SettingsData.dankBarSpacing - Theme.spacingXS)
windowContextMenuLoader.item.showAt(xPos, relativeY, true, root.axis?.edge)
// Add minTooltipY offset to account for top bar
const adjustedY = relativeY + root.minTooltipY
const xPos = root.axis?.edge === "left" ? (root.barThickness + root.barSpacing + Theme.spacingXS) : (root.parentScreen.width - root.barThickness - root.barSpacing - Theme.spacingXS)
windowContextMenuLoader.item.showAt(xPos, adjustedY, true, root.axis?.edge)
} else {
const globalPos = delegateItem.mapToGlobal(delegateItem.width / 2, 0)
const screenX = root.parentScreen ? root.parentScreen.x : 0
const relativeX = globalPos.x - screenX
const yPos = Theme.barHeight + SettingsData.dankBarSpacing - 7
const yPos = root.barThickness + root.barSpacing - 7
windowContextMenuLoader.item.showAt(relativeX, yPos, false, "top")
}
}
@@ -649,16 +704,18 @@ Item {
const screenX = root.parentScreen ? root.parentScreen.x : 0
const screenY = root.parentScreen ? root.parentScreen.y : 0
const relativeY = globalPos.y - screenY
const tooltipX = root.axis?.edge === "left" ? (Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS) : (root.parentScreen.width - Theme.barHeight - SettingsData.dankBarSpacing - Theme.spacingXS)
const tooltipX = root.axis?.edge === "left" ? (root.barThickness + root.barSpacing + Theme.spacingXS) : (root.parentScreen.width - root.barThickness - root.barSpacing - Theme.spacingXS)
const isLeft = root.axis?.edge === "left"
tooltipLoader.item.show(delegateItem.tooltipText, screenX + tooltipX, relativeY, root.parentScreen, isLeft, !isLeft)
const adjustedY = relativeY + root.minTooltipY
const finalX = screenX + tooltipX
tooltipLoader.item.show(delegateItem.tooltipText, finalX, adjustedY, root.parentScreen, isLeft, !isLeft)
} else {
const globalPos = delegateItem.mapToGlobal(delegateItem.width / 2, delegateItem.height)
const screenHeight = root.parentScreen ? root.parentScreen.height : Screen.height
const isBottom = root.axis?.edge === "bottom"
const tooltipY = isBottom
? (screenHeight - Theme.barHeight - SettingsData.dankBarSpacing - Theme.spacingXS - 35)
: (Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS)
? (screenHeight - root.barThickness - root.barSpacing - Theme.spacingXS - 35)
: (root.barThickness + root.barSpacing + Theme.spacingXS)
tooltipLoader.item.show(delegateItem.tooltipText, globalPos.x, tooltipY, root.parentScreen, false, false)
}
}
@@ -699,6 +756,28 @@ Item {
property bool isVertical: false
property string edge: "top"
// New properties for bar context
property int triggerBarPosition: (SettingsData.barConfigs[0]?.position ?? SettingsData.Position.Top)
property real triggerBarThickness: 0
property real triggerBarSpacing: 0
property var triggerBarConfig: null
readonly property real effectiveBarThickness: {
if (triggerBarThickness > 0 && triggerBarSpacing > 0) {
return triggerBarThickness + triggerBarSpacing
}
return Math.max(26 + (barConfig?.innerPadding ?? 4) * 0.6, Theme.barHeight - 4 - (8 - (barConfig?.innerPadding ?? 4))) + (barConfig?.spacing ?? 4)
}
property var barBounds: {
if (!contextMenuWindow.screen || !triggerBarConfig) {
return { "x": 0, "y": 0, "width": 0, "height": 0, "wingSize": 0 }
}
return SettingsData.getBarBounds(contextMenuWindow.screen, effectiveBarThickness, triggerBarPosition, triggerBarConfig)
}
property real barY: barBounds.y
function showAt(x, y, vertical, barEdge) {
screen = root.parentScreen
anchorPos = Qt.point(x, y)
@@ -752,7 +831,7 @@ Item {
}
y: {
if (contextMenuWindow.isVertical) {
const top = 10
const top = Math.max(barY, 10)
const bottom = contextMenuWindow.height - height - 10
const want = contextMenuWindow.anchorPos.y - height / 2
return Math.max(top, Math.min(bottom, want))

File diff suppressed because it is too large Load Diff

View File

@@ -62,8 +62,8 @@ BasePill {
color: Theme.error
anchors.right: parent.right
anchors.top: parent.top
anchors.rightMargin: SettingsData.dankBarNoBackground ? 0 : 6
anchors.topMargin: SettingsData.dankBarNoBackground ? 0 : 6
anchors.rightMargin: (barConfig?.noBackground ?? false) ? 0 : 6
anchors.topMargin: (barConfig?.noBackground ?? false) ? 0 : 6
visible: root.isVerticalOrientation && root.hasUpdates && !root.isChecking
}
@@ -111,7 +111,7 @@ BasePill {
id: countText
anchors.verticalCenter: parent.verticalCenter
text: SystemUpdateService.updateCount.toString()
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
visible: root.hasUpdates && !root.isChecking
}

View File

@@ -13,7 +13,26 @@ BasePill {
}
property var popoutTarget: null
property var barConfig: null
property bool isHovered: clickArea.containsMouse
property real barSpacing: 4
property bool isAutoHideBar: false
readonly property real minTooltipY: {
if (!parentScreen || !isVerticalOrientation) {
return 0
}
if (isAutoHideBar) {
return 0
}
if (parentScreen.y > 0) {
return barThickness + barSpacing
}
return 0
}
signal toggleVpnPopup()
@@ -56,51 +75,47 @@ BasePill {
acceptedButtons: Qt.LeftButton
enabled: !DMSNetworkService.isBusy
onPressed: {
if (popoutTarget && popoutTarget.setTriggerPosition) {
const globalPos = root.visualContent.mapToGlobal(0, 0)
const currentScreen = parentScreen || Screen
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, root.visualWidth)
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
}
root.toggleVpnPopup();
root.toggleVpnPopup()
}
onEntered: {
if (root.parentScreen && !(popoutTarget && popoutTarget.shouldBeVisible)) {
tooltipLoader.active = true
if (tooltipLoader.item) {
let tooltipText = ""
if (!DMSNetworkService.connected) {
tooltipText = "VPN Disconnected"
} else {
const names = DMSNetworkService.activeNames || []
if (names.length <= 1) {
const name = names[0] || ""
const maxLength = 25
const displayName = name.length > maxLength ? name.substring(0, maxLength) + "..." : name
tooltipText = "VPN Connected • " + displayName
} else {
const name = names[0]
const maxLength = 20
const displayName = name.length > maxLength ? name.substring(0, maxLength) + "..." : name
tooltipText = "VPN Connected • " + displayName + " +" + (names.length - 1)
}
}
if (!root.parentScreen || (popoutTarget?.shouldBeVisible)) return
if (root.isVerticalOrientation) {
const globalPos = mapToGlobal(width / 2, height / 2)
const screenX = root.parentScreen ? root.parentScreen.x : 0
const screenY = root.parentScreen ? root.parentScreen.y : 0
const relativeY = globalPos.y - screenY
const tooltipX = root.axis?.edge === "left" ? (Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS) : (root.parentScreen.width - Theme.barHeight - SettingsData.dankBarSpacing - Theme.spacingXS)
const isLeft = root.axis?.edge === "left"
tooltipLoader.item.show(tooltipText, screenX + tooltipX, relativeY, root.parentScreen, isLeft, !isLeft)
} else {
const globalPos = mapToGlobal(width / 2, height)
const tooltipY = Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS
tooltipLoader.item.show(tooltipText, globalPos.x, tooltipY, root.parentScreen, false, false)
}
tooltipLoader.active = true
if (!tooltipLoader.item) return
let tooltipText = ""
if (!DMSNetworkService.connected) {
tooltipText = "VPN Disconnected"
} else {
const names = DMSNetworkService.activeNames || []
if (names.length <= 1) {
const name = names[0] || ""
const maxLength = 25
const displayName = name.length > maxLength ? name.substring(0, maxLength) + "..." : name
tooltipText = "VPN Connected • " + displayName
} else {
const name = names[0]
const maxLength = 20
const displayName = name.length > maxLength ? name.substring(0, maxLength) + "..." : name
tooltipText = "VPN Connected • " + displayName + " +" + (names.length - 1)
}
}
if (root.isVerticalOrientation) {
const globalPos = mapToGlobal(width / 2, height / 2)
const currentScreen = root.parentScreen || Screen
const screenX = currentScreen ? currentScreen.x : 0
const screenY = currentScreen ? currentScreen.y : 0
const relativeY = globalPos.y - screenY
const adjustedY = relativeY + root.minTooltipY
const tooltipX = root.axis?.edge === "left" ? (root.barThickness + root.barSpacing + Theme.spacingXS) : (currentScreen.width - root.barThickness - root.barSpacing - Theme.spacingXS)
const isLeft = root.axis?.edge === "left"
tooltipLoader.item.show(tooltipText, screenX + tooltipX, adjustedY, currentScreen, isLeft, !isLeft)
} else {
const globalPos = mapToGlobal(width / 2, height)
const tooltipY = root.barThickness + root.barSpacing + Theme.spacingXS
tooltipLoader.item.show(tooltipText, globalPos.x, tooltipY, root.parentScreen, false, false)
}
}
onExited: {
if (tooltipLoader.item) {

View File

@@ -43,7 +43,7 @@ BasePill {
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
return temp;
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -70,7 +70,7 @@ BasePill {
const temp = SettingsData.useFahrenheit ? WeatherService.weather.tempF : WeatherService.weather.temp;
return temp + "°" + (SettingsData.useFahrenheit ? "F" : "C");
}
font.pixelSize: Theme.barTextSize(root.barThickness)
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
color: Theme.widgetTextColor
anchors.verticalCenter: parent.verticalCenter
}

File diff suppressed because it is too large Load Diff