1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-12 00:32:17 -04: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

@@ -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