Standardize bar icon geometry

This commit is contained in:
David Heinemeier Hansson
2026-07-17 15:20:55 -07:00
parent fe48e83222
commit 6e3b69b8da
17 changed files with 272 additions and 124 deletions
+60
View File
@@ -0,0 +1,60 @@
import QtQuick
import Quickshell
import qs.Commons
WidgetButton {
id: root
property Component iconComponent: null
property real opticalSize: Style.bar.iconCanvas
property bool debugOpticalBounds: Quickshell.env("OMARCHY_DEBUG_BAR_ICONS") === "1"
readonly property real opticalCenterErrorX: glyph.visible ? glyph.paintedCenterX - opticalCanvas.width / 2 : 0
readonly property real opticalCenterErrorY: glyph.visible ? glyph.paintedCenterY - opticalCanvas.height / 2 : 0
labelVisible: false
hasVisualContent: text !== "" || iconComponent !== null
fontSize: Style.font.body
fixedWidth: vertical ? -1 : Style.bar.iconSlot
fixedHeight: vertical ? Style.bar.iconSlot : -1
Item {
id: opticalCanvas
anchors.centerIn: parent
width: root.opticalSize
height: root.opticalSize
OpticalGlyph {
id: glyph
anchors.fill: parent
visible: root.iconComponent === null
text: root.text
fontFamily: root.fontFamily
fontSize: root.fontSize
color: root.active && root.useActiveColor ? root.activeColor : root.foreground
rotation: root.textRotation
debugBounds: root.debugOpticalBounds
}
Loader {
anchors.fill: parent
visible: root.iconComponent !== null
sourceComponent: root.iconComponent
}
Rectangle {
visible: root.debugOpticalBounds && root.iconComponent !== null
anchors.fill: parent
color: "transparent"
border.width: 1
border.color: "#4488ff"
}
}
Rectangle {
visible: root.debugOpticalBounds
anchors.fill: parent
color: "transparent"
border.width: 1
border.color: "#ff4455"
}
}
+58
View File
@@ -0,0 +1,58 @@
import QtQuick
import qs.Commons
Item {
id: root
property string text: ""
property string fontFamily: Style.font.family
property real fontSize: Style.font.body
property color color: Color.foreground
property real targetExtent: Math.min(width, height) * 0.82
property bool debugBounds: false
readonly property real baseTightWidth: Math.max(1, baseMetrics.tightBoundingRect.width)
readonly property real baseTightHeight: Math.max(1, baseMetrics.tightBoundingRect.height)
readonly property real normalizedScale: Math.min(1.5, targetExtent / Math.max(baseTightWidth, baseTightHeight))
readonly property int normalizedFontSize: Math.max(1, Math.round(fontSize * normalizedScale))
readonly property real tightWidth: Math.max(1, glyphMetrics.tightBoundingRect.width)
readonly property real tightHeight: Math.max(1, glyphMetrics.tightBoundingRect.height)
readonly property real horizontalCorrection: glyph.implicitWidth / 2 - (glyphMetrics.tightBoundingRect.x + tightWidth / 2)
readonly property real verticalCorrection: glyph.implicitHeight / 2 - (glyph.baselineOffset + glyphMetrics.tightBoundingRect.y + tightHeight / 2)
readonly property real paintedCenterX: glyph.x + glyphMetrics.tightBoundingRect.x + tightWidth / 2
readonly property real paintedCenterY: glyph.y + glyph.baselineOffset + glyphMetrics.tightBoundingRect.y + tightHeight / 2
TextMetrics {
id: baseMetrics
font.family: root.fontFamily
font.pixelSize: root.fontSize
text: root.text
}
TextMetrics {
id: glyphMetrics
font.family: root.fontFamily
font.pixelSize: root.normalizedFontSize
text: root.text
}
Text {
id: glyph
anchors.centerIn: parent
anchors.horizontalCenterOffset: root.horizontalCorrection
anchors.verticalCenterOffset: root.verticalCorrection
text: root.text
color: root.color
font.family: root.fontFamily
font.pixelSize: root.normalizedFontSize
renderType: Text.NativeRendering
}
Rectangle {
visible: root.debugBounds
anchors.fill: parent
color: "transparent"
border.width: 1
border.color: "#4488ff"
}
}
+6 -6
View File
@@ -12,7 +12,6 @@ Item {
property color activeColor: bar ? bar.urgent : Color.urgent
property bool active: false
property real horizontalMargin: 8.5
property real rightExtraMargin: 0
property real verticalPadding: 6
property real fixedWidth: -1
property real fixedHeight: -1
@@ -24,6 +23,8 @@ Item {
property bool pressable: true
property bool useActiveColor: true
property bool maintainIndicatorReveal: false
property bool labelVisible: true
property bool hasVisualContent: text !== ""
property var revealHost: bar
property string tooltipText: ""
property var registeredBar: null
@@ -56,13 +57,12 @@ Item {
readonly property bool vertical: bar ? bar.vertical : false
readonly property int barSize: bar ? bar.barSize : Style.bar.sizeHorizontal
readonly property real scaledHorizontalMargin: Style.spaceReal(horizontalMargin)
readonly property real scaledRightExtraMargin: Style.spaceReal(rightExtraMargin)
readonly property real scaledVerticalPadding: Style.spaceReal(verticalPadding)
readonly property bool tooltipHovered: visible && interactive && !concealed && mouseArea.containsMouse
visible: text !== "" || keepSpace
opacity: text === "" || concealed ? 0 : (dimmed ? 0.45 : 1)
implicitWidth: fixedWidth > 0 ? fixedWidth : (vertical ? barSize : Math.max(12, label.implicitWidth + scaledHorizontalMargin * 2 + scaledRightExtraMargin))
visible: hasVisualContent || keepSpace
opacity: !hasVisualContent || concealed ? 0 : (dimmed ? 0.45 : 1)
implicitWidth: fixedWidth > 0 ? fixedWidth : (vertical ? barSize : Math.max(12, label.implicitWidth + scaledHorizontalMargin * 2))
implicitHeight: fixedHeight > 0 ? fixedHeight : (vertical ? Math.max(12, label.implicitHeight + scaledVerticalPadding * 2) : barSize)
Behavior on opacity {
@@ -71,8 +71,8 @@ Item {
Text {
id: label
visible: root.labelVisible
anchors.centerIn: parent
anchors.horizontalCenterOffset: root.vertical ? 0 : -root.scaledRightExtraMargin / 2
text: root.text
color: root.active && root.useActiveColor ? root.activeColor : root.foreground
font.family: root.fontFamily
+2
View File
@@ -1,6 +1,7 @@
module qs.Ui
BarIndicator 1.0 BarIndicator.qml
BarIconButton 1.0 BarIconButton.qml
BarWidget 1.0 BarWidget.qml
BorderOverlay 1.0 BorderOverlay.qml
BorderSurface 1.0 BorderSurface.qml
@@ -12,6 +13,7 @@ Dropdown 1.0 Dropdown.qml
KeyboardPanel 1.0 KeyboardPanel.qml
MultiSelect 1.0 MultiSelect.qml
NumberField 1.0 NumberField.qml
OpticalGlyph 1.0 OpticalGlyph.qml
Panel 1.0 Panel.qml
PanelActionButton 1.0 PanelActionButton.qml
PanelController 1.0 PanelController.qml