// One tile of the camera/microphone/screen strip: whether the thing is being // used right this second, and by what. // // PrivacyLiveTile { // glyph: "\u{F0100}" // label: "Camera" // measured: PrivacyState.initialized // active: PrivacyState.cameraActive // app: PrivacyState.cameraApp // } // // Three states, not two. `active` is false both when nothing is using the // camera and when nobody has looked -- PrivacyState's probe is pw-dump, which // is absent on a machine without PipeWire's tools and leaves every flag at its // default false -- so `measured` says which of the two "Idle" would have meant. // // Deliberately still. An indicator that pulses or fades is reporting the same // fact over and over at sixty frames a second, and this one sits on a settings // page that may be open for a long time -- the border and the warn-toned line // carry the whole of the difference, and they carry it without repainting. import QtQuick import qs.config Rectangle { id: root property string glyph: "" property string label: "" property bool active: false // Whether anything has actually been read. False until the first probe // lands, and false forever if the probe cannot run at all. property bool measured: false // The application name PipeWire reported, which is often empty even while // a stream is plainly running. property string app: "" // Not `state`: Item already owns that name. readonly property string useLine: { if (root.active) return "In use by " + (root.app !== "" ? root.app : "an application"); return root.measured ? "Idle" : "Not measured"; } // The neutral third state is neutral in the colour too: warn means in use, // dim means idle, and "not measured" must not read as either. readonly property color toneColor: root.active ? Theme.warn : (root.measured ? Theme.fgDim : Theme.fgMuted) implicitHeight: 56 radius: Theme.cardRadius color: Theme.alpha(Theme.bgDark, 0.55) border.width: 1 border.color: root.active ? Theme.alpha(Theme.warn, 0.45) : Theme.alpha(Theme.fg, 0.08) Text { id: icon anchors.left: parent.left anchors.leftMargin: 12 anchors.verticalCenter: parent.verticalCenter text: root.glyph color: root.toneColor font.family: Theme.fontMono font.pixelSize: 17 } Column { anchors.left: icon.right anchors.leftMargin: 10 anchors.right: parent.right anchors.rightMargin: 12 anchors.verticalCenter: parent.verticalCenter spacing: 2 Text { width: parent.width text: root.label color: Theme.fg font.family: Theme.fontFamily font.pixelSize: Theme.fontSizeSmall font.weight: Font.DemiBold elide: Text.ElideRight } Text { width: parent.width text: root.useLine color: root.toneColor font.family: Theme.fontFamily font.pixelSize: Math.max(9, Theme.fontSizeSmall - 1) elide: Text.ElideRight } } }