From 8843bfc830c1ea2f2e4371d99542a5522ff00030 Mon Sep 17 00:00:00 2001 From: rope Date: Wed, 27 May 2026 15:58:46 +0100 Subject: [PATCH] quickshell: fix border timing, add rounded corner outlines Co-Authored-By: Claude Opus 4.6 --- settings/hyprland.nix | 67 ++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/settings/hyprland.nix b/settings/hyprland.nix index 8870207..4d63933 100644 --- a/settings/hyprland.nix +++ b/settings/hyprland.nix @@ -656,7 +656,7 @@ in id: barBorderLeft x: 0; y: 30 width: { - if (!activeDropdown || !activeDropdown.visible) return bar.width; + if (!activeDropdown || activeDropdown.dropdownHeight <= 0) return bar.width; if (activeDropdown.alignRight) return activeDropdown.x + activeDropdown.width - activeDropdown.fullWidth - 8; return activeDropdown.x + 8; @@ -668,7 +668,7 @@ in // Bar bottom border — right segment (after dropdown gap) Rectangle { id: barBorderRight - visible: activeDropdown && activeDropdown.visible && !activeDropdown.alignRight + visible: activeDropdown && activeDropdown.dropdownHeight > 0 && !activeDropdown.alignRight x: activeDropdown ? activeDropdown.x + 8 + activeDropdown.fullWidth : 0 y: 30 width: activeDropdown ? bar.width - x : 0 @@ -1217,6 +1217,7 @@ in property real fullHeight: 200 property int autoCloseMs: 1500 property bool alignRight: false + property real dropdownHeight: _dropdownRect.height default property alias content: dropdownContent.data function animateClose() { @@ -1343,36 +1344,38 @@ in bottomRightRadius: dropdown.alignRight ? 0 : 8 clip: true - // Left border - Rectangle { - anchors.left: parent.left - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.bottomMargin: 8 - width: 1 - color: Theme.base03 - } - - // Right border (only for centered dropdowns) - Rectangle { - visible: !dropdown.alignRight - anchors.right: parent.right - anchors.top: parent.top - anchors.bottom: parent.bottom - anchors.bottomMargin: 8 - width: 1 - color: Theme.base03 - } - - // Bottom border - Rectangle { - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.leftMargin: 8 - anchors.rightMargin: dropdown.alignRight ? 0 : 8 - height: 1 - color: Theme.base03 + // Border outline (sides + bottom with rounded corners) + Canvas { + id: _dropdownBorder + anchors.fill: parent + onPaint: { + var ctx = getContext("2d"); + var w = width, h = height, r = 8; + ctx.clearRect(0, 0, w, h); + if (h < 1) return; + ctx.strokeStyle = Theme.base03; + ctx.lineWidth = 1; + ctx.beginPath(); + // Start below the top ear, go down left side + ctx.moveTo(0.5, r); + ctx.lineTo(0.5, h - r); + // Bottom-left curve + ctx.arc(r + 0.5, h - r - 0.5, r, Math.PI, Math.PI / 2, true); + // Bottom edge + if (dropdown.alignRight) { + ctx.lineTo(w, h - 0.5); + } else { + ctx.lineTo(w - r - 0.5, h - 0.5); + // Bottom-right curve + ctx.arc(w - r - 0.5, h - r - 0.5, r, Math.PI / 2, 0, true); + // Right side up (stop at ear height) + ctx.lineTo(w - 0.5, r); + } + ctx.stroke(); + } + // Repaint when size changes + onWidthChanged: requestPaint() + onHeightChanged: requestPaint() } Behavior on height {