pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import Quickshell import Quickshell.Widgets import ZShell.Config import ZShell.Services import qs.Components import qs.Services CustomListView { id: root required property ProcessesHeader columnHeader required property int rowHeight property real rowSpacing: Tokens.spacing.small model: Processes.list spacing: root.rowSpacing clip: true CustomScrollBar.vertical: CustomScrollBar { flickable: root } delegate: CustomRect { id: processRow required property var modelData required property int index implicitWidth: ListView.view.width implicitHeight: rowLayout.implicitHeight radius: Tokens.rounding.full StateLayer { id: rowHover } RowLayout { id: rowLayout anchors.left: parent.left anchors.top: parent.top anchors.bottom: parent.bottom spacing: Tokens.spacing.extraSmall / 2 ClipRect { id: iconClip Layout.fillHeight: true Layout.margins: Tokens.padding.medium implicitWidth: height radius: Tokens.rounding.full IconImage { id: appIcon anchors.fill: parent implicitSize: height source: Quickshell.iconPath(processRow.modelData.iconName, "application-x-executable") } } Repeater { id: cellRepeater model: root.columnHeader.columnsModel Item { id: rowCell required property var modelData required property int index implicitWidth: root.columnHeader.widthForColumn(modelData.id, modelData.width) - (index === 0 ? iconClip.implicitWidth + iconClip.Layout.margins * 2 + rowLayout.spacing : 0) implicitHeight: layout.implicitHeight + layout.anchors.margins * 2 Layout.preferredWidth: implicitWidth Layout.fillHeight: true CustomRect { anchors.top: parent.top anchors.bottom: parent.bottom anchors.left: parent.left anchors.margins: Tokens.padding.small anchors.leftMargin: -(rowLayout.spacing) implicitWidth: 2 color: Colors.palette.m3outlineVariant visible: rowCell.index !== 0 } Item { id: layout anchors.fill: parent anchors.margins: Tokens.padding.small anchors.leftMargin: rowCell.index !== 0 ? Tokens.padding.medium : 0 anchors.rightMargin: Tokens.padding.medium implicitHeight: mainText.implicitHeight + subText.implicitHeight + mainText.anchors.margins * 2 + subText.anchors.topMargin CustomText { id: mainText anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right elide: CustomText.ElideRight text: { const value = processRow.modelData[rowCell.modelData.id]; return value === undefined ? "" : ProcessesColumns.formatCell(rowCell.modelData.id, value); } states: State { name: "centerAnchored" when: !subText.visible AnchorChanges { target: mainText anchors.top: undefined anchors.verticalCenter: layout.verticalCenter } } } CustomText { id: subText anchors.top: mainText.bottom anchors.left: parent.left anchors.right: parent.right visible: rowCell.modelData.id === "command" elide: CustomText.ElideRight text: rowCell.modelData.id === "command" ? processRow.modelData["commandLine"] : "" font: Tokens.font.label.small color: Colors.palette.m3outline } } } } } } }