1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-05 21:15:38 -05:00

dankbar: make border shape respect goth radius

part of #804
This commit is contained in:
bbedward
2025-11-23 23:55:07 -05:00
parent 3bc6461e2a
commit 5e77a10a81

View File

@@ -1,5 +1,4 @@
import QtQuick import QtQuick
import Quickshell.Hyprland
import qs.Common import qs.Common
import qs.Services import qs.Services
@@ -23,7 +22,7 @@ Item {
readonly property real dpr: CompositorService.getScreenScale(barWindow.screen) readonly property real dpr: CompositorService.getScreenScale(barWindow.screen)
function requestRepaint() { function requestRepaint() {
debounceTimer.restart() debounceTimer.restart();
} }
MouseArea { MouseArea {
@@ -31,17 +30,17 @@ Item {
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
z: -999 z: -999
onClicked: { onClicked: {
const activePopout = PopoutManager.getActivePopout(barWindow.screen) const activePopout = PopoutManager.getActivePopout(barWindow.screen);
if (activePopout) { if (activePopout) {
if (activePopout.dashVisible !== undefined) { if (activePopout.dashVisible !== undefined) {
activePopout.dashVisible = false activePopout.dashVisible = false;
} else if (activePopout.notificationHistoryVisible !== undefined) { } else if (activePopout.notificationHistoryVisible !== undefined) {
activePopout.notificationHistoryVisible = false activePopout.notificationHistoryVisible = false;
} else { } else {
activePopout.close() activePopout.close();
} }
} }
TrayMenuManager.closeAllMenus() TrayMenuManager.closeAllMenus();
} }
} }
@@ -50,9 +49,9 @@ Item {
interval: 50 interval: 50
repeat: false repeat: false
onTriggered: { onTriggered: {
barShape.requestPaint() barShape.requestPaint();
barTint.requestPaint() barTint.requestPaint();
barBorder.requestPaint() barBorder.requestPaint();
} }
} }
@@ -74,85 +73,98 @@ Item {
onRtChanged: root.requestRepaint() onRtChanged: root.requestRepaint()
onCorrectWidthChanged: root.requestRepaint() onCorrectWidthChanged: root.requestRepaint()
onCorrectHeightChanged: root.requestRepaint() onCorrectHeightChanged: root.requestRepaint()
onVisibleChanged: if (visible) root.requestRepaint() onVisibleChanged: if (visible)
root.requestRepaint()
Component.onCompleted: root.requestRepaint() Component.onCompleted: root.requestRepaint()
Connections { Connections {
target: root target: root
function onDprChanged() { root.requestRepaint() } function onDprChanged() {
root.requestRepaint();
}
} }
Connections { Connections {
target: barWindow target: barWindow
function on_BgColorChanged() { root.requestRepaint() } function on_BgColorChanged() {
function onGothCornersEnabledChanged() { root.requestRepaint() } root.requestRepaint();
function onWingtipsRadiusChanged() { root.requestRepaint() } }
function onGothCornersEnabledChanged() {
root.requestRepaint();
}
function onWingtipsRadiusChanged() {
root.requestRepaint();
}
} }
Connections { Connections {
target: Theme target: Theme
function onIsLightModeChanged() { root.requestRepaint() } function onIsLightModeChanged() {
function onSurfaceContainerChanged() { root.requestRepaint() } root.requestRepaint();
}
function onSurfaceContainerChanged() {
root.requestRepaint();
}
} }
onPaint: { onPaint: {
const ctx = getContext("2d") const ctx = getContext("2d");
const W = barWindow.isVertical ? correctHeight : correctWidth const W = barWindow.isVertical ? correctHeight : correctWidth;
const H_raw = barWindow.isVertical ? correctWidth : correctHeight const H_raw = barWindow.isVertical ? correctWidth : correctHeight;
const R = wing const R = wing;
const RT = rt const RT = rt;
const H = H_raw - (R > 0 ? R : 0) const H = H_raw - (R > 0 ? R : 0);
const barPos = barConfig?.position ?? 0 const barPos = barConfig?.position ?? 0;
const isTop = barPos === SettingsData.Position.Top const isTop = barPos === SettingsData.Position.Top;
const isBottom = barPos === SettingsData.Position.Bottom const isBottom = barPos === SettingsData.Position.Bottom;
const isLeft = barPos === SettingsData.Position.Left const isLeft = barPos === SettingsData.Position.Left;
const isRight = barPos === SettingsData.Position.Right const isRight = barPos === SettingsData.Position.Right;
function drawTopPath() { function drawTopPath() {
ctx.beginPath() ctx.beginPath();
ctx.moveTo(RT, 0) ctx.moveTo(RT, 0);
ctx.lineTo(W - RT, 0) ctx.lineTo(W - RT, 0);
ctx.arcTo(W, 0, W, RT, RT) ctx.arcTo(W, 0, W, RT, RT);
ctx.lineTo(W, H) ctx.lineTo(W, H);
if (R > 0) { if (R > 0) {
ctx.lineTo(W, H + R) ctx.lineTo(W, H + R);
ctx.arc(W - R, H + R, R, 0, -Math.PI / 2, true) ctx.arc(W - R, H + R, R, 0, -Math.PI / 2, true);
ctx.lineTo(R, H) ctx.lineTo(R, H);
ctx.arc(R, H + R, R, -Math.PI / 2, -Math.PI, true) ctx.arc(R, H + R, R, -Math.PI / 2, -Math.PI, true);
ctx.lineTo(0, H + R) ctx.lineTo(0, H + R);
} else { } else {
ctx.lineTo(W, H - RT) ctx.lineTo(W, H - RT);
ctx.arcTo(W, H, W - RT, H, RT) ctx.arcTo(W, H, W - RT, H, RT);
ctx.lineTo(RT, H) ctx.lineTo(RT, H);
ctx.arcTo(0, H, 0, H - RT, RT) ctx.arcTo(0, H, 0, H - RT, RT);
} }
ctx.lineTo(0, RT) ctx.lineTo(0, RT);
ctx.arcTo(0, 0, RT, 0, RT) ctx.arcTo(0, 0, RT, 0, RT);
ctx.closePath() ctx.closePath();
} }
ctx.reset() ctx.reset();
ctx.clearRect(0, 0, W, H_raw) ctx.clearRect(0, 0, W, H_raw);
ctx.save() ctx.save();
if (isBottom) { if (isBottom) {
ctx.translate(W, H_raw) ctx.translate(W, H_raw);
ctx.rotate(Math.PI) ctx.rotate(Math.PI);
} else if (isLeft) { } else if (isLeft) {
ctx.translate(0, W) ctx.translate(0, W);
ctx.rotate(-Math.PI / 2) ctx.rotate(-Math.PI / 2);
} else if (isRight) { } else if (isRight) {
ctx.translate(H_raw, 0) ctx.translate(H_raw, 0);
ctx.rotate(Math.PI / 2) ctx.rotate(Math.PI / 2);
} }
drawTopPath() drawTopPath();
ctx.restore() ctx.restore();
ctx.fillStyle = barWindow._bgColor ctx.fillStyle = barWindow._bgColor;
ctx.fill() ctx.fill();
} }
} }
@@ -176,85 +188,98 @@ Item {
onAlphaTintChanged: root.requestRepaint() onAlphaTintChanged: root.requestRepaint()
onCorrectWidthChanged: root.requestRepaint() onCorrectWidthChanged: root.requestRepaint()
onCorrectHeightChanged: root.requestRepaint() onCorrectHeightChanged: root.requestRepaint()
onVisibleChanged: if (visible) root.requestRepaint() onVisibleChanged: if (visible)
root.requestRepaint()
Component.onCompleted: root.requestRepaint() Component.onCompleted: root.requestRepaint()
Connections { Connections {
target: root target: root
function onDprChanged() { root.requestRepaint() } function onDprChanged() {
root.requestRepaint();
}
} }
Connections { Connections {
target: barWindow target: barWindow
function on_BgColorChanged() { root.requestRepaint() } function on_BgColorChanged() {
function onGothCornersEnabledChanged() { root.requestRepaint() } root.requestRepaint();
function onWingtipsRadiusChanged() { root.requestRepaint() } }
function onGothCornersEnabledChanged() {
root.requestRepaint();
}
function onWingtipsRadiusChanged() {
root.requestRepaint();
}
} }
Connections { Connections {
target: Theme target: Theme
function onIsLightModeChanged() { root.requestRepaint() } function onIsLightModeChanged() {
function onSurfaceChanged() { root.requestRepaint() } root.requestRepaint();
}
function onSurfaceChanged() {
root.requestRepaint();
}
} }
onPaint: { onPaint: {
const ctx = getContext("2d") const ctx = getContext("2d");
const W = barWindow.isVertical ? correctHeight : correctWidth const W = barWindow.isVertical ? correctHeight : correctWidth;
const H_raw = barWindow.isVertical ? correctWidth : correctHeight const H_raw = barWindow.isVertical ? correctWidth : correctHeight;
const R = wing const R = wing;
const RT = rt const RT = rt;
const H = H_raw - (R > 0 ? R : 0) const H = H_raw - (R > 0 ? R : 0);
const barPos = barConfig?.position ?? 0 const barPos = barConfig?.position ?? 0;
const isTop = barPos === SettingsData.Position.Top const isTop = barPos === SettingsData.Position.Top;
const isBottom = barPos === SettingsData.Position.Bottom const isBottom = barPos === SettingsData.Position.Bottom;
const isLeft = barPos === SettingsData.Position.Left const isLeft = barPos === SettingsData.Position.Left;
const isRight = barPos === SettingsData.Position.Right const isRight = barPos === SettingsData.Position.Right;
function drawTopPath() { function drawTopPath() {
ctx.beginPath() ctx.beginPath();
ctx.moveTo(RT, 0) ctx.moveTo(RT, 0);
ctx.lineTo(W - RT, 0) ctx.lineTo(W - RT, 0);
ctx.arcTo(W, 0, W, RT, RT) ctx.arcTo(W, 0, W, RT, RT);
ctx.lineTo(W, H) ctx.lineTo(W, H);
if (R > 0) { if (R > 0) {
ctx.lineTo(W, H + R) ctx.lineTo(W, H + R);
ctx.arc(W - R, H + R, R, 0, -Math.PI / 2, true) ctx.arc(W - R, H + R, R, 0, -Math.PI / 2, true);
ctx.lineTo(R, H) ctx.lineTo(R, H);
ctx.arc(R, H + R, R, -Math.PI / 2, -Math.PI, true) ctx.arc(R, H + R, R, -Math.PI / 2, -Math.PI, true);
ctx.lineTo(0, H + R) ctx.lineTo(0, H + R);
} else { } else {
ctx.lineTo(W, H - RT) ctx.lineTo(W, H - RT);
ctx.arcTo(W, H, W - RT, H, RT) ctx.arcTo(W, H, W - RT, H, RT);
ctx.lineTo(RT, H) ctx.lineTo(RT, H);
ctx.arcTo(0, H, 0, H - RT, RT) ctx.arcTo(0, H, 0, H - RT, RT);
} }
ctx.lineTo(0, RT) ctx.lineTo(0, RT);
ctx.arcTo(0, 0, RT, 0, RT) ctx.arcTo(0, 0, RT, 0, RT);
ctx.closePath() ctx.closePath();
} }
ctx.reset() ctx.reset();
ctx.clearRect(0, 0, W, H_raw) ctx.clearRect(0, 0, W, H_raw);
ctx.save() ctx.save();
if (isBottom) { if (isBottom) {
ctx.translate(W, H_raw) ctx.translate(W, H_raw);
ctx.rotate(Math.PI) ctx.rotate(Math.PI);
} else if (isLeft) { } else if (isLeft) {
ctx.translate(0, W) ctx.translate(0, W);
ctx.rotate(-Math.PI / 2) ctx.rotate(-Math.PI / 2);
} else if (isRight) { } else if (isRight) {
ctx.translate(H_raw, 0) ctx.translate(H_raw, 0);
ctx.rotate(Math.PI / 2) ctx.rotate(Math.PI / 2);
} }
drawTopPath() drawTopPath();
ctx.restore() ctx.restore();
ctx.fillStyle = Qt.rgba(Theme.surface.r, Theme.surface.g, Theme.surface.b, alphaTint) ctx.fillStyle = Qt.rgba(Theme.surface.r, Theme.surface.g, Theme.surface.b, alphaTint);
ctx.fill() ctx.fill();
} }
} }
@@ -280,141 +305,137 @@ Item {
onBorderEnabledChanged: root.requestRepaint() onBorderEnabledChanged: root.requestRepaint()
onCorrectWidthChanged: root.requestRepaint() onCorrectWidthChanged: root.requestRepaint()
onCorrectHeightChanged: root.requestRepaint() onCorrectHeightChanged: root.requestRepaint()
onVisibleChanged: if (visible) root.requestRepaint() onVisibleChanged: if (visible)
root.requestRepaint()
Component.onCompleted: root.requestRepaint() Component.onCompleted: root.requestRepaint()
Connections { Connections {
target: root target: root
function onDprChanged() { root.requestRepaint() } function onDprChanged() {
root.requestRepaint();
}
} }
Connections { Connections {
target: Theme target: Theme
function onIsLightModeChanged() { root.requestRepaint() } function onIsLightModeChanged() {
function onSurfaceTextChanged() { root.requestRepaint() } root.requestRepaint();
function onPrimaryChanged() { root.requestRepaint() } }
function onSecondaryChanged() { root.requestRepaint() } function onSurfaceTextChanged() {
function onOutlineChanged() { root.requestRepaint() } root.requestRepaint();
}
function onPrimaryChanged() {
root.requestRepaint();
}
function onSecondaryChanged() {
root.requestRepaint();
}
function onOutlineChanged() {
root.requestRepaint();
}
} }
Connections { Connections {
target: barWindow target: barWindow
function onGothCornersEnabledChanged() { root.requestRepaint() } function onGothCornersEnabledChanged() {
function onWingtipsRadiusChanged() { root.requestRepaint() } root.requestRepaint();
}
function onWingtipsRadiusChanged() {
root.requestRepaint();
}
} }
onPaint: { onPaint: {
if (!borderEnabled) return if (!borderEnabled)
return;
const ctx = getContext("2d");
const W = barWindow.isVertical ? correctHeight : correctWidth;
const H_raw = barWindow.isVertical ? correctWidth : correctHeight;
const R = wing;
const RT = rt;
const H = H_raw - (R > 0 ? R : 0);
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 ctx = getContext("2d") const spacing = barConfig?.spacing ?? 4;
const W = barWindow.isVertical ? correctHeight : correctWidth
const H_raw = barWindow.isVertical ? correctWidth : correctHeight
const R = wing
const RT = rt
const H = H_raw - (R > 0 ? R : 0)
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 = barConfig?.spacing ?? 4 ctx.reset();
const hasEdgeGap = spacing > 0 || RT > 0 ctx.clearRect(0, 0, W, H_raw);
ctx.reset() ctx.save();
ctx.clearRect(0, 0, W, H_raw)
ctx.save()
if (isBottom) { if (isBottom) {
ctx.translate(W, H_raw) ctx.translate(W, H_raw);
ctx.rotate(Math.PI) ctx.rotate(Math.PI);
} else if (isLeft) { } else if (isLeft) {
ctx.translate(0, W) ctx.translate(0, W);
ctx.rotate(-Math.PI / 2) ctx.rotate(-Math.PI / 2);
} else if (isRight) { } else if (isRight) {
ctx.translate(H_raw, 0) ctx.translate(H_raw, 0);
ctx.rotate(Math.PI / 2) ctx.rotate(Math.PI / 2);
} }
const uiThickness = Math.max(1, barConfig?.borderThickness ?? 1) const uiThickness = Math.max(1, barConfig?.borderThickness ?? 1);
const devThickness = Math.max(1, Math.round(Theme.px(uiThickness, dpr))) const devThickness = Math.max(1, Math.round(Theme.px(uiThickness, dpr)));
const key = barConfig?.borderColor || "surfaceText" const key = barConfig?.borderColor || "surfaceText";
const base = (key === "surfaceText") ? Theme.surfaceText const base = (key === "surfaceText") ? Theme.surfaceText : (key === "primary") ? Theme.primary : Theme.secondary;
: (key === "primary") ? Theme.primary const color = Theme.withAlpha(base, barConfig?.borderOpacity ?? 1.0);
: Theme.secondary
const color = Theme.withAlpha(base, barConfig?.borderOpacity ?? 1.0)
ctx.globalCompositeOperation = "source-over" ctx.strokeStyle = color;
ctx.fillStyle = color ctx.lineWidth = devThickness * 2;
ctx.lineJoin = "round";
ctx.lineCap = "butt";
function drawTopBorder() { function drawFullShape() {
if (!hasEdgeGap) { ctx.beginPath();
ctx.beginPath() ctx.moveTo(RT, 0);
ctx.rect(0, H - devThickness, W, devThickness) ctx.lineTo(W - RT, 0);
ctx.fill() ctx.arcTo(W, 0, W, RT, RT);
ctx.lineTo(W, H);
if (R > 0) {
ctx.lineTo(W, H + R);
ctx.arc(W - R, H + R, R, 0, -Math.PI / 2, true);
ctx.lineTo(R, H);
ctx.arc(R, H + R, R, -Math.PI / 2, -Math.PI, true);
ctx.lineTo(0, H + R);
} else { } else {
const thk = devThickness ctx.lineTo(W, H - RT);
const RTi = Math.max(0, RT - thk) ctx.arcTo(W, H, W - RT, H, RT);
const Ri = Math.max(0, R - thk) ctx.lineTo(RT, H);
ctx.arcTo(0, H, 0, H - RT, RT);
}
ctx.beginPath() ctx.lineTo(0, RT);
ctx.arcTo(0, 0, RT, 0, RT);
ctx.closePath();
}
if (R > 0 && Ri > 0) { drawFullShape();
ctx.moveTo(RT, 0) ctx.clip();
ctx.lineTo(W - RT, 0)
ctx.arcTo(W, 0, W, RT, RT)
ctx.lineTo(W, H)
ctx.lineTo(W, H + R)
ctx.arc(W - R, H + R, R, 0, -Math.PI / 2, true)
ctx.lineTo(R, H)
ctx.arc(R, H + R, R, -Math.PI / 2, -Math.PI, true)
ctx.lineTo(0, H + R)
ctx.lineTo(0, RT)
ctx.arcTo(0, 0, RT, 0, RT)
ctx.closePath()
ctx.moveTo(RT, thk) if (spacing > 0) {
ctx.arcTo(thk, thk, thk, RT, RTi) drawFullShape();
ctx.lineTo(thk, H + R) } else {
ctx.arc(R, H + R, Ri, -Math.PI, -Math.PI / 2, false) ctx.beginPath();
ctx.lineTo(W - R, H + thk) if (R > 0) {
ctx.arc(W - R, H + R, Ri, -Math.PI / 2, 0, false) ctx.moveTo(W, H + R);
ctx.lineTo(W - thk, H + R) ctx.arc(W - R, H + R, R, 0, -Math.PI / 2, true);
ctx.lineTo(W - thk, RT) ctx.lineTo(R, H);
ctx.arcTo(W - thk, thk, W - RT, thk, RTi) ctx.arc(R, H + R, R, -Math.PI / 2, -Math.PI, true);
ctx.lineTo(RT, thk) } else {
ctx.closePath() ctx.moveTo(W, H - RT);
} else { ctx.arcTo(W, H, W - RT, H, RT);
ctx.moveTo(RT, 0) ctx.lineTo(RT, H);
ctx.lineTo(W - RT, 0) ctx.arcTo(0, H, 0, H - RT, RT);
ctx.arcTo(W, 0, W, RT, RT)
ctx.lineTo(W, H - RT)
ctx.arcTo(W, H, W - RT, H, RT)
ctx.lineTo(RT, H)
ctx.arcTo(0, H, 0, H - RT, RT)
ctx.lineTo(0, RT)
ctx.arcTo(0, 0, RT, 0, RT)
ctx.closePath()
ctx.moveTo(RT, thk)
ctx.arcTo(thk, thk, thk, RT, RTi)
ctx.lineTo(thk, H - RT)
ctx.arcTo(thk, H - thk, RT, H - thk, RTi)
ctx.lineTo(W - RT, H - thk)
ctx.arcTo(W - thk, H - thk, W - thk, H - RT, RTi)
ctx.lineTo(W - thk, RT)
ctx.arcTo(W - thk, thk, W - RT, thk, RTi)
ctx.lineTo(RT, thk)
ctx.closePath()
}
ctx.fill("evenodd")
} }
} }
ctx.stroke();
drawTopBorder() ctx.restore();
ctx.restore()
} }
} }
} }