Standardize bar icon geometry
This commit is contained in:
@@ -341,6 +341,8 @@ QtObject {
|
||||
readonly property QtObject bar: QtObject {
|
||||
readonly property int sizeHorizontal: root.barToken("size-horizontal", 26)
|
||||
readonly property int sizeVertical: root.barToken("size-vertical", 28)
|
||||
readonly property int iconSlot: root.barToken("icon-slot", 27)
|
||||
readonly property int iconCanvas: root.barToken("icon-canvas", 16)
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1297,13 +1297,6 @@ Item {
|
||||
readonly property bool hovered: moduleHover.hovered
|
||||
readonly property bool dragSource: root.barDragSource === slot
|
||||
readonly property bool panelOpen: root.activePopout === slot.activeItem
|
||||
readonly property real openIndicatorInlineOffset: {
|
||||
var item = slot.activeItem
|
||||
if (!item || !("openIndicatorInlineOffset" in item)) return 0
|
||||
var offset = Number(item.openIndicatorInlineOffset)
|
||||
return isFinite(offset) ? offset : 0
|
||||
}
|
||||
|
||||
implicitWidth: activeItem && activeItem.visible ? (root.vertical ? root.barSize : activeItem.implicitWidth) : 0
|
||||
implicitHeight: activeItem && activeItem.visible ? activeItem.implicitHeight : 0
|
||||
width: implicitWidth
|
||||
@@ -1377,9 +1370,9 @@ Item {
|
||||
height: root.vertical ? Math.max(Style.space(10), Math.round(parent.height * 0.55)) : Style.space(2)
|
||||
x: root.vertical
|
||||
? (root.position === "left" ? parent.width - width - inset : inset)
|
||||
: (slot.openIndicatorInlineOffset === 0 ? Math.round((parent.width - width) / 2) : (parent.width - width) / 2 + slot.openIndicatorInlineOffset)
|
||||
: Math.round((parent.width - width) / 2)
|
||||
y: root.vertical
|
||||
? (slot.openIndicatorInlineOffset === 0 ? Math.round((parent.height - height) / 2) : (parent.height - height) / 2 + slot.openIndicatorInlineOffset)
|
||||
? Math.round((parent.height - height) / 2)
|
||||
: (root.position === "top" ? parent.height - height - inset : inset)
|
||||
z: 50
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ BarWidget {
|
||||
|
||||
PwObjectTracker { objects: root.source ? [root.source] : [] }
|
||||
|
||||
WidgetButton {
|
||||
BarIconButton {
|
||||
id: button
|
||||
anchors.fill: parent
|
||||
bar: root.bar
|
||||
|
||||
@@ -52,12 +52,11 @@ BarWidget {
|
||||
onTriggered: root.refresh()
|
||||
}
|
||||
|
||||
WidgetButton {
|
||||
BarIconButton {
|
||||
id: button
|
||||
anchors.fill: parent
|
||||
bar: root.bar
|
||||
text: "\uf021"
|
||||
fontSize: Style.font.caption
|
||||
tooltipText: ""
|
||||
onPressed: root.runUpdate()
|
||||
}
|
||||
|
||||
@@ -24,9 +24,9 @@ BarWidget {
|
||||
readonly property var drawerItems: bucket("drawer")
|
||||
readonly property var allItems: bucket("all")
|
||||
readonly property int drawerCount: drawerItems.length
|
||||
readonly property int trayItemExtent: Style.space(16)
|
||||
readonly property int trayItemGap: Style.space(9)
|
||||
readonly property int trayJoinGap: Style.space(4)
|
||||
readonly property int trayItemExtent: Style.bar.iconSlot
|
||||
readonly property int trayItemGap: 0
|
||||
readonly property int trayJoinGap: 0
|
||||
readonly property int drawerExtent: drawerCount > 0 ? drawerCount * trayItemExtent + (drawerCount - 1) * trayItemGap : 0
|
||||
// Match Waybar's group/tray-expander drawer transition-duration.
|
||||
readonly property int animationDuration: 600
|
||||
@@ -182,15 +182,13 @@ BarWidget {
|
||||
onHoveredChanged: root.expanded = hovered
|
||||
}
|
||||
|
||||
WidgetButton {
|
||||
BarIconButton {
|
||||
id: expandIcon
|
||||
bar: root.bar
|
||||
width: implicitWidth
|
||||
height: implicitHeight
|
||||
x: root.drawerExtent - root.revealExtent
|
||||
text: "\uf053"
|
||||
horizontalMargin: 9
|
||||
verticalPadding: 6
|
||||
onPressed: function(button) {
|
||||
if (button === Qt.RightButton) root.managePopupOpen = !root.managePopupOpen
|
||||
}
|
||||
@@ -266,7 +264,7 @@ BarWidget {
|
||||
onHoveredChanged: root.expanded = hovered
|
||||
}
|
||||
|
||||
WidgetButton {
|
||||
BarIconButton {
|
||||
id: expandIcon
|
||||
bar: root.bar
|
||||
width: implicitWidth
|
||||
@@ -274,8 +272,6 @@ BarWidget {
|
||||
y: root.drawerExtent - root.revealExtent
|
||||
text: "\uf053"
|
||||
textRotation: 90
|
||||
horizontalMargin: 9
|
||||
verticalPadding: 6
|
||||
onPressed: function(button) {
|
||||
if (button === Qt.RightButton) root.managePopupOpen = !root.managePopupOpen
|
||||
}
|
||||
|
||||
@@ -522,14 +522,11 @@ Panel {
|
||||
onTriggered: root.refreshDisplayAudioModels()
|
||||
}
|
||||
|
||||
WidgetButton {
|
||||
BarIconButton {
|
||||
id: button
|
||||
anchors.fill: parent
|
||||
bar: root.bar
|
||||
text: root.outputIcon()
|
||||
fontSize: Style.font.body
|
||||
fixedWidth: root.bar && root.bar.vertical ? -1 : Style.space(27)
|
||||
fixedHeight: root.bar && root.bar.vertical ? Style.space(26) : -1
|
||||
onPressed: function(b) {
|
||||
if (b === Qt.RightButton) root.toggleOutputMute()
|
||||
else root.toggle()
|
||||
|
||||
@@ -469,13 +469,11 @@ Panel {
|
||||
})
|
||||
}
|
||||
|
||||
WidgetButton {
|
||||
BarIconButton {
|
||||
id: button
|
||||
anchors.fill: parent
|
||||
bar: root.bar
|
||||
text: root.icon
|
||||
fixedWidth: root.bar && root.bar.vertical ? -1 : Style.space(27)
|
||||
fixedHeight: root.bar && root.bar.vertical ? Style.space(26) : -1
|
||||
onPressed: function(b) {
|
||||
if (b === Qt.RightButton) root.toggleBluetooth()
|
||||
else if (b === Qt.MiddleButton) root.bar.run("omarchy-launch-bluetooth")
|
||||
|
||||
@@ -139,48 +139,25 @@ Panel {
|
||||
function status(): string { return dropbox.statusText }
|
||||
}
|
||||
|
||||
Item {
|
||||
BarIconButton {
|
||||
id: button
|
||||
anchors.fill: parent
|
||||
implicitWidth: root.bar && root.bar.vertical ? root.bar.barSize : Style.space(27)
|
||||
implicitHeight: root.bar && root.bar.vertical ? Style.space(26) : (root.bar ? root.bar.barSize : Style.space(26))
|
||||
|
||||
property var registeredBar: null
|
||||
|
||||
function triggerPress(buttonCode) {
|
||||
bar: root.bar
|
||||
iconComponent: Component {
|
||||
Item {
|
||||
DropboxIcon {
|
||||
anchors.centerIn: parent
|
||||
iconSize: Style.space(12)
|
||||
color: root.barIconColor
|
||||
opacity: dropbox.authenticated ? 1.0 : 0.6
|
||||
}
|
||||
}
|
||||
}
|
||||
onPressed: function(buttonCode) {
|
||||
if (buttonCode === Qt.RightButton) dropbox.refresh()
|
||||
else if (buttonCode === Qt.MiddleButton) dropbox.login()
|
||||
else root.toggle()
|
||||
}
|
||||
|
||||
function syncClickRegistration() {
|
||||
if (registeredBar && registeredBar.unregisterClickTarget) registeredBar.unregisterClickTarget(button)
|
||||
registeredBar = root.bar
|
||||
if (registeredBar && registeredBar.registerClickTarget) registeredBar.registerClickTarget(button)
|
||||
}
|
||||
|
||||
Component.onCompleted: syncClickRegistration()
|
||||
Component.onDestruction: if (registeredBar && registeredBar.unregisterClickTarget) registeredBar.unregisterClickTarget(button)
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
function onBarChanged() { button.syncClickRegistration() }
|
||||
}
|
||||
|
||||
DropboxIcon {
|
||||
anchors.centerIn: parent
|
||||
iconSize: Style.space(12)
|
||||
color: root.barIconColor
|
||||
opacity: dropbox.authenticated ? 1.0 : 0.6
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: function(mouse) { button.triggerPress(mouse.button) }
|
||||
}
|
||||
}
|
||||
|
||||
KeyboardPanel {
|
||||
|
||||
@@ -337,15 +337,11 @@ Panel {
|
||||
onRunningChanged: if (!running) root.refresh()
|
||||
}
|
||||
|
||||
WidgetButton {
|
||||
BarIconButton {
|
||||
id: button
|
||||
anchors.fill: parent
|
||||
bar: root.bar
|
||||
text: root.displays.length > 1 ? "" : ""
|
||||
fontSize: Style.font.subtitle
|
||||
fixedWidth: root.bar && root.bar.vertical ? -1 : Style.space(27)
|
||||
fixedHeight: root.bar && root.bar.vertical ? Style.space(26) : -1
|
||||
rightExtraMargin: 4
|
||||
onPressed: function(b) { root.toggle() }
|
||||
onWheelMoved: function(delta) {
|
||||
if (root.brightnessAvailable) root.setBrightness(root.brightnessPercent + (delta > 0 ? 5 : -5))
|
||||
|
||||
@@ -707,14 +707,11 @@ Panel {
|
||||
}
|
||||
}
|
||||
|
||||
WidgetButton {
|
||||
BarIconButton {
|
||||
id: button
|
||||
anchors.fill: parent
|
||||
bar: root.bar
|
||||
text: root.icon
|
||||
fixedWidth: root.bar && root.bar.vertical ? -1 : Style.space(27)
|
||||
fixedHeight: root.bar && root.bar.vertical ? Style.space(26) : -1
|
||||
rightExtraMargin: 5.5
|
||||
|
||||
onPressed: function(b) {
|
||||
if (root.opened) root.close()
|
||||
|
||||
@@ -249,13 +249,11 @@ Panel {
|
||||
}
|
||||
}
|
||||
|
||||
WidgetButton {
|
||||
BarIconButton {
|
||||
id: button
|
||||
anchors.fill: parent
|
||||
bar: root.bar
|
||||
text: root.batteryIcon()
|
||||
fixedWidth: root.bar && root.bar.vertical ? -1 : Style.space(27)
|
||||
fixedHeight: root.bar && root.bar.vertical ? Style.space(26) : -1
|
||||
tooltipText: ""
|
||||
onPressed: function(b) { if (root.batteryPresent) root.toggle() }
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ Panel {
|
||||
ipcTarget: "omarchy.tailscale"
|
||||
manageIpc: false
|
||||
|
||||
readonly property real openIndicatorInlineOffset: bar && bar.vertical ? 0 : Style.spaceReal(1.5)
|
||||
property string focusSection: "header"
|
||||
property int headerIndex: 0
|
||||
property int accountIndex: 0
|
||||
@@ -360,53 +359,27 @@ Panel {
|
||||
function status(): string { return tailscale.statusText }
|
||||
}
|
||||
|
||||
Item {
|
||||
BarIconButton {
|
||||
id: button
|
||||
anchors.fill: parent
|
||||
implicitWidth: root.bar && root.bar.vertical ? root.bar.barSize : Style.space(27)
|
||||
implicitHeight: root.bar && root.bar.vertical ? Style.space(26) : (root.bar ? root.bar.barSize : Style.space(26))
|
||||
|
||||
property var registeredBar: null
|
||||
|
||||
function triggerPress(buttonCode) {
|
||||
bar: root.bar
|
||||
iconComponent: Component {
|
||||
Item {
|
||||
TailscaleIcon {
|
||||
anchors.centerIn: parent
|
||||
iconSize: Style.space(11)
|
||||
color: root.barIconColor
|
||||
badgeColor: root.urgent
|
||||
crossed: !tailscale.running && !tailscale.needsLogin
|
||||
warning: tailscale.needsLogin
|
||||
}
|
||||
}
|
||||
}
|
||||
onPressed: function(buttonCode) {
|
||||
if (buttonCode === Qt.RightButton) tailscale.toggleTailscale()
|
||||
else if (buttonCode === Qt.MiddleButton) tailscale.refresh()
|
||||
else root.toggle()
|
||||
}
|
||||
|
||||
function syncClickRegistration() {
|
||||
if (registeredBar && registeredBar.unregisterClickTarget) registeredBar.unregisterClickTarget(button)
|
||||
registeredBar = root.bar
|
||||
if (registeredBar && registeredBar.registerClickTarget) registeredBar.registerClickTarget(button)
|
||||
}
|
||||
|
||||
Component.onCompleted: syncClickRegistration()
|
||||
Component.onDestruction: if (registeredBar && registeredBar.unregisterClickTarget) registeredBar.unregisterClickTarget(button)
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
function onBarChanged() { button.syncClickRegistration() }
|
||||
}
|
||||
|
||||
TailscaleIcon {
|
||||
anchors.centerIn: parent
|
||||
anchors.horizontalCenterOffset: root.openIndicatorInlineOffset
|
||||
anchors.verticalCenterOffset: -Style.space(1)
|
||||
iconSize: Style.space(12) * 0.85
|
||||
color: root.barIconColor
|
||||
badgeColor: root.urgent
|
||||
crossed: !tailscale.running && !tailscale.needsLogin
|
||||
warning: tailscale.needsLogin
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: function(mouse) { button.triggerPress(mouse.button) }
|
||||
}
|
||||
}
|
||||
|
||||
KeyboardPanel {
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
|
||||
|
||||
if ! command -v quickshell >/dev/null 2>&1; then
|
||||
pass "quickshell not installed; skipping bar icon geometry test"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
test_tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$test_tmp"' EXIT
|
||||
|
||||
ln -s "$ROOT/shell/Ui" "$test_tmp/Ui"
|
||||
ln -s "$ROOT/shell/Commons" "$test_tmp/Commons"
|
||||
|
||||
cat >"$test_tmp/shell.qml" <<'QML'
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.Commons
|
||||
import qs.Ui
|
||||
|
||||
ShellRoot {
|
||||
id: root
|
||||
|
||||
function fail(message) {
|
||||
console.log("RESULT fail " + message)
|
||||
Qt.quit()
|
||||
}
|
||||
|
||||
function checkIcon(icon, name) {
|
||||
if (icon.implicitWidth !== Style.bar.iconSlot) {
|
||||
fail(name + " slot width is " + icon.implicitWidth)
|
||||
return false
|
||||
}
|
||||
if (icon.opticalSize !== Style.bar.iconCanvas) {
|
||||
fail(name + " optical canvas is " + icon.opticalSize)
|
||||
return false
|
||||
}
|
||||
if (Math.abs(icon.opticalCenterErrorX) > 0.5 || Math.abs(icon.opticalCenterErrorY) > 0.5) {
|
||||
fail(name + " painted bounds are over half a pixel off center by " + icon.opticalCenterErrorX + "," + icon.opticalCenterErrorY)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
Component.onCompleted: Qt.callLater(function() {
|
||||
if (!checkIcon(bluetooth, "bluetooth")) return
|
||||
if (!checkIcon(network, "network")) return
|
||||
if (!checkIcon(audio, "audio")) return
|
||||
if (!checkIcon(monitor, "monitor")) return
|
||||
if (!checkIcon(power, "power")) return
|
||||
if (vector.implicitWidth !== Style.bar.iconSlot || vector.opticalSize !== Style.bar.iconCanvas) {
|
||||
fail("vector icon does not share glyph geometry")
|
||||
return
|
||||
}
|
||||
console.log("RESULT pass")
|
||||
Qt.quit()
|
||||
})
|
||||
|
||||
QtObject {
|
||||
id: testBar
|
||||
property bool vertical: false
|
||||
property int barSize: Style.bar.sizeHorizontal
|
||||
property string fontFamily: Style.font.family
|
||||
property color barForeground: "white"
|
||||
property color urgent: "red"
|
||||
property bool foregroundAnimationEnabled: false
|
||||
function registerClickTarget(target) {}
|
||||
function unregisterClickTarget(target) {}
|
||||
function hideTooltip(target) {}
|
||||
function showTooltip(target, text) {}
|
||||
}
|
||||
|
||||
BarIconButton { id: bluetooth; bar: testBar; text: "" }
|
||||
BarIconButton { id: network; bar: testBar; text: "" }
|
||||
BarIconButton { id: audio; bar: testBar; text: "" }
|
||||
BarIconButton { id: monitor; bar: testBar; text: "" }
|
||||
BarIconButton { id: power; bar: testBar; text: "" }
|
||||
BarIconButton {
|
||||
id: vector
|
||||
bar: testBar
|
||||
iconComponent: Component { Rectangle { width: 12; height: 12 } }
|
||||
}
|
||||
}
|
||||
QML
|
||||
|
||||
output=$(timeout 15 env \
|
||||
QML2_IMPORT_PATH="$ROOT/shell${QML2_IMPORT_PATH:+:$QML2_IMPORT_PATH}" \
|
||||
QML_IMPORT_PATH="$ROOT/shell${QML_IMPORT_PATH:+:$QML_IMPORT_PATH}" \
|
||||
quickshell -p "$test_tmp" --no-color 2>&1) || {
|
||||
printf '%s\n' "$output" >&2
|
||||
fail "bar icon geometry fixture exits cleanly"
|
||||
}
|
||||
|
||||
if ! grep -q 'RESULT pass' <<<"$output"; then
|
||||
printf '%s\n' "$output" >&2
|
||||
fail "bar icons share centered optical geometry"
|
||||
fi
|
||||
|
||||
pass "bar icons share centered optical geometry"
|
||||
Reference in New Issue
Block a user