import QtQuick import "." as M M.BarSection { id: root spacing: Math.max(1, M.Theme.moduleSpacing - 2) tooltip: "" property int percent: M.SystemStats.memPercent property real usedGb: M.SystemStats.memUsedGb property real totalGb: M.SystemStats.memTotalGb property real availGb: M.SystemStats.memAvailGb property real cachedGb: M.SystemStats.memCachedGb property real buffersGb: M.SystemStats.memBuffersGb function _fmt(gb) { return gb >= 10 ? gb.toFixed(1) + "G" : gb.toFixed(2) + "G"; } property bool _pinned: false readonly property bool _anyHover: root._hovered || hoverPanel.panelHovered readonly property bool _showPanel: _anyHover || _pinned property M.ProcessList _procs: M.ProcessList { sortBy: "mem" active: root._showPanel } on_AnyHoverChanged: { if (_anyHover) _unpinTimer.stop(); else if (_pinned) _unpinTimer.start(); } Timer { id: _unpinTimer interval: 500 onTriggered: root._pinned = false } M.BarIcon { icon: "\uEFC5" anchors.verticalCenter: parent.verticalCenter TapHandler { cursorShape: Qt.PointingHandCursor onTapped: root._pinned = !root._pinned } } M.BarLabel { label: root.percent + "%" minText: "100%" anchors.verticalCenter: parent.verticalCenter TapHandler { cursorShape: Qt.PointingHandCursor onTapped: root._pinned = !root._pinned } } M.HoverPanel { id: hoverPanel showPanel: root._showPanel screen: QsWindow.window?.screen ?? null anchorItem: root accentColor: root.accentColor panelNamespace: "nova-memory" contentWidth: 240 // Header Item { width: parent.width height: 28 Text { anchors.left: parent.left anchors.leftMargin: 12 anchors.verticalCenter: parent.verticalCenter text: "Memory" color: M.Theme.base04 font.pixelSize: M.Theme.fontSize - 1 font.family: M.Theme.fontFamily } Text { anchors.right: parent.right anchors.rightMargin: 12 anchors.verticalCenter: parent.verticalCenter text: root._fmt(root.usedGb) + " / " + root._fmt(root.totalGb) color: root.accentColor font.pixelSize: M.Theme.fontSize font.family: M.Theme.fontFamily font.bold: true } } // Usage bar Item { width: parent.width height: 14 Item { id: memBar anchors.left: parent.left anchors.leftMargin: 12 anchors.right: parent.right anchors.rightMargin: 12 anchors.verticalCenter: parent.verticalCenter height: 6 Rectangle { anchors.fill: parent color: M.Theme.base02 radius: 3 } // Cached (base0D, behind used) Rectangle { width: parent.width * Math.min(1, (root.usedGb + root.cachedGb) / Math.max(root.totalGb, 0.001)) height: parent.height color: M.Theme.base0D opacity: 0.4 radius: 3 Behavior on width { NumberAnimation { duration: 200 } } } // Used (accentColor, on top) Rectangle { width: parent.width * Math.min(1, root.usedGb / Math.max(root.totalGb, 0.001)) height: parent.height color: root.accentColor radius: 3 Behavior on width { NumberAnimation { duration: 200 } } } } } // Breakdown rows Item { width: parent.width height: 18 Text { anchors.left: parent.left anchors.leftMargin: 12 anchors.verticalCenter: parent.verticalCenter text: "Used" color: M.Theme.base04 font.pixelSize: M.Theme.fontSize - 2 font.family: M.Theme.fontFamily } Text { anchors.right: parent.right anchors.rightMargin: 12 anchors.verticalCenter: parent.verticalCenter text: root._fmt(root.usedGb) color: M.Theme.base05 font.pixelSize: M.Theme.fontSize - 2 font.family: M.Theme.fontFamily } } Item { width: parent.width height: 18 Text { anchors.left: parent.left anchors.leftMargin: 12 anchors.verticalCenter: parent.verticalCenter text: "Cached" color: M.Theme.base04 font.pixelSize: M.Theme.fontSize - 2 font.family: M.Theme.fontFamily } Text { anchors.right: parent.right anchors.rightMargin: 12 anchors.verticalCenter: parent.verticalCenter text: root._fmt(root.cachedGb) color: M.Theme.base05 font.pixelSize: M.Theme.fontSize - 2 font.family: M.Theme.fontFamily } } Item { width: parent.width height: 18 Text { anchors.left: parent.left anchors.leftMargin: 12 anchors.verticalCenter: parent.verticalCenter text: "Available" color: M.Theme.base04 font.pixelSize: M.Theme.fontSize - 2 font.family: M.Theme.fontFamily } Text { anchors.right: parent.right anchors.rightMargin: 12 anchors.verticalCenter: parent.verticalCenter text: root._fmt(root.availGb) color: M.Theme.base05 font.pixelSize: M.Theme.fontSize - 2 font.family: M.Theme.fontFamily } } // Process list separator Rectangle { width: parent.width - 16 height: 1 anchors.horizontalCenter: parent.horizontalCenter color: M.Theme.base03 } // Top processes by memory Repeater { model: root._procs.processes delegate: Item { required property var modelData width: hoverPanel.contentWidth height: 20 Text { id: procCmd anchors.left: parent.left anchors.leftMargin: 12 anchors.verticalCenter: parent.verticalCenter text: modelData.cmd color: M.Theme.base05 font.pixelSize: M.Theme.fontSize - 2 font.family: M.Theme.fontFamily elide: Text.ElideRight width: parent.width - 80 } Text { anchors.right: parent.right anchors.rightMargin: 12 anchors.verticalCenter: parent.verticalCenter text: modelData.mem.toFixed(1) + "%" color: M.Theme.base04 font.pixelSize: M.Theme.fontSize - 2 font.family: M.Theme.fontFamily width: 36 horizontalAlignment: Text.AlignRight } } } Item { width: 1 height: 4 } } }