Baseline: omarchy.indicators as shipped
Indicators.qml and the six indicator files exactly as they ship in omarchy-dev 4.0.0.r1744.gf002044, alongside the manifest `omarchy plugin clone` generates. Kept on its own branch so `git diff stock..master` shows precisely what this fork changes.
This commit is contained in:
+471
@@ -0,0 +1,471 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import qs.Commons
|
||||||
|
import qs.Ui
|
||||||
|
|
||||||
|
BarWidget {
|
||||||
|
id: root
|
||||||
|
moduleName: "omarchy.indicators"
|
||||||
|
|
||||||
|
readonly property var defaultIndicatorEntries: [ "Dictation", "ScreenRecording", "Reminder", "NightLight", "Dnd", "StayAwake" ]
|
||||||
|
readonly property var indicatorEntries: indicatorEntriesFromSettings(settings)
|
||||||
|
property var activeIndicatorIds: []
|
||||||
|
property var indicatorActiveStates: ({})
|
||||||
|
property bool indicatorAreaHovered: false
|
||||||
|
property bool indicatorItemHovered: false
|
||||||
|
readonly property bool alwaysShowIndicators: setting("alwaysShow", false) === true
|
||||||
|
readonly property bool revealInactiveIndicators: alwaysShowIndicators || indicatorAreaHovered || indicatorItemHovered || (bar && bar.centerSectionRevealHeld === true && bar.centerHoverRevealSuppressed !== true)
|
||||||
|
|
||||||
|
signal refreshRequested()
|
||||||
|
|
||||||
|
ListModel { id: activeIndicatorModel }
|
||||||
|
|
||||||
|
function entryId(entry) {
|
||||||
|
if (typeof entry === "string") return entry
|
||||||
|
if (Util.isPlainObject(entry)) {
|
||||||
|
var id = entry["id"]
|
||||||
|
if (id !== undefined && id !== null && String(id) !== "") return String(id)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
function entrySettings(entry) {
|
||||||
|
if (!Util.isPlainObject(entry)) return {}
|
||||||
|
var copy = {}
|
||||||
|
for (var key in entry) {
|
||||||
|
if (key === "id") continue
|
||||||
|
copy[key] = entry[key]
|
||||||
|
}
|
||||||
|
return copy
|
||||||
|
}
|
||||||
|
|
||||||
|
function indicatorEntriesFromSettings(settings) {
|
||||||
|
var source = defaultIndicatorEntries
|
||||||
|
if (settings.items && typeof settings.items.length === "number" && settings.items.length > 0) source = settings.items
|
||||||
|
else if (settings.indicators && typeof settings.indicators.length === "number" && settings.indicators.length > 0) source = settings.indicators
|
||||||
|
|
||||||
|
var result = []
|
||||||
|
for (var i = 0; i < source.length; i++) {
|
||||||
|
var item = source[i]
|
||||||
|
if (typeof item !== "string" && item !== null && typeof item === "object") {
|
||||||
|
try {
|
||||||
|
item = JSON.parse(JSON.stringify(item))
|
||||||
|
} catch (error) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var id = entryId(item)
|
||||||
|
if (id !== "") result.push(item)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
function setIndicatorAreaHovered(hovered) {
|
||||||
|
indicatorAreaHovered = hovered
|
||||||
|
if (hovered) indicatorHideTimer.stop()
|
||||||
|
else indicatorHideTimer.restart()
|
||||||
|
}
|
||||||
|
|
||||||
|
function setIndicatorItemHovered(hovered) {
|
||||||
|
if (hovered) {
|
||||||
|
indicatorItemHovered = true
|
||||||
|
indicatorHideTimer.stop()
|
||||||
|
} else {
|
||||||
|
indicatorHideTimer.restart()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasIndicatorId(id) {
|
||||||
|
for (var i = 0; i < indicatorEntries.length; i++) {
|
||||||
|
if (entryId(indicatorEntries[i]) === id) return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function entryForId(id) {
|
||||||
|
for (var i = 0; i < indicatorEntries.length; i++) {
|
||||||
|
var entry = indicatorEntries[i]
|
||||||
|
if (entryId(entry) === id) return entry
|
||||||
|
}
|
||||||
|
|
||||||
|
return { id: id }
|
||||||
|
}
|
||||||
|
|
||||||
|
function activeModelIndex(id) {
|
||||||
|
for (var i = 0; i < activeIndicatorModel.count; i++) {
|
||||||
|
if (activeIndicatorModel.get(i).activeId === id) return i
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyActiveStates() {
|
||||||
|
var states = {}
|
||||||
|
for (var id in indicatorActiveStates) {
|
||||||
|
if (indicatorActiveStates[id] === true) states[id] = true
|
||||||
|
}
|
||||||
|
return states
|
||||||
|
}
|
||||||
|
|
||||||
|
function orderedActiveIds(states, preferredOrder) {
|
||||||
|
var ids = []
|
||||||
|
|
||||||
|
for (var i = 0; i < preferredOrder.length; i++) {
|
||||||
|
var id = preferredOrder[i]
|
||||||
|
if (ids.indexOf(id) === -1 && hasIndicatorId(id) && states[id] === true) ids.push(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ids
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncActiveIndicatorModel() {
|
||||||
|
for (var i = activeIndicatorModel.count - 1; i >= 0; i--) {
|
||||||
|
if (activeIndicatorIds.indexOf(activeIndicatorModel.get(i).activeId) === -1)
|
||||||
|
activeIndicatorModel.remove(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var j = 0; j < activeIndicatorIds.length; j++) {
|
||||||
|
var id = activeIndicatorIds[j]
|
||||||
|
var index = activeModelIndex(id)
|
||||||
|
if (index === -1) activeIndicatorModel.insert(j, { activeId: id })
|
||||||
|
else if (index !== j) activeIndicatorModel.move(index, j, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setIndicatorActive(entry, active) {
|
||||||
|
var id = entryId(entry)
|
||||||
|
if (id === "") return
|
||||||
|
|
||||||
|
var states = copyActiveStates()
|
||||||
|
if (active) states[id] = true
|
||||||
|
else delete states[id]
|
||||||
|
|
||||||
|
indicatorActiveStates = states
|
||||||
|
|
||||||
|
var ids = orderedActiveIds(states, activeIndicatorIds)
|
||||||
|
// The active block sits closest to the clock, so newcomers go on the far
|
||||||
|
// side of it. Appending would shove everything already showing sideways.
|
||||||
|
if (active && ids.indexOf(id) === -1 && hasIndicatorId(id)) ids.unshift(id)
|
||||||
|
activeIndicatorIds = ids
|
||||||
|
syncActiveIndicatorModel()
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncActiveIndicatorOrder() {
|
||||||
|
activeIndicatorIds = orderedActiveIds(indicatorActiveStates, activeIndicatorIds)
|
||||||
|
syncActiveIndicatorModel()
|
||||||
|
}
|
||||||
|
|
||||||
|
function refresh() { root.refreshRequested() }
|
||||||
|
|
||||||
|
onIndicatorEntriesChanged: syncActiveIndicatorOrder()
|
||||||
|
|
||||||
|
implicitWidth: root.vertical
|
||||||
|
? Math.max(activeVerticalBlock.implicitWidth, inactiveVerticalArea.implicitWidth)
|
||||||
|
: activeHorizontalBlock.implicitWidth + inactiveHorizontalArea.implicitWidth
|
||||||
|
implicitHeight: root.vertical
|
||||||
|
? activeVerticalBlock.implicitHeight + inactiveVerticalArea.implicitHeight
|
||||||
|
: Math.max(activeHorizontalBlock.implicitHeight, inactiveHorizontalArea.implicitHeight)
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
target: "omarchy.indicators"
|
||||||
|
|
||||||
|
function refresh(): void {
|
||||||
|
root.broadcast("refresh")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: indicatorHideTimer
|
||||||
|
interval: 120
|
||||||
|
onTriggered: {
|
||||||
|
if (!root.indicatorAreaHovered)
|
||||||
|
root.indicatorItemHovered = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: root.refreshRequested()
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: horizontalIndicators
|
||||||
|
|
||||||
|
visible: !root.vertical
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
HoverHandler {
|
||||||
|
onHoveredChanged: root.setIndicatorAreaHovered(hovered)
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: inactiveHorizontalArea
|
||||||
|
|
||||||
|
implicitWidth: root.revealInactiveIndicators ? inactiveHorizontalBlock.implicitWidth : 0
|
||||||
|
implicitHeight: Math.max(inactiveHorizontalBlock.implicitHeight, root.barSize)
|
||||||
|
width: implicitWidth
|
||||||
|
height: implicitHeight
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
IndicatorBlock {
|
||||||
|
id: inactiveHorizontalBlock
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
indicatorsModule: root
|
||||||
|
indicatorEntries: root.indicatorEntries
|
||||||
|
indicatorBlock: "inactive"
|
||||||
|
horizontal: true
|
||||||
|
reportActiveState: !root.vertical
|
||||||
|
}
|
||||||
|
|
||||||
|
HoverHandler {
|
||||||
|
onHoveredChanged: root.setIndicatorAreaHovered(hovered)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ActiveIndicatorBlock {
|
||||||
|
id: activeHorizontalBlock
|
||||||
|
indicatorsModule: root
|
||||||
|
indicatorModel: activeIndicatorModel
|
||||||
|
horizontal: true
|
||||||
|
reportActiveState: !root.vertical
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: verticalIndicators
|
||||||
|
|
||||||
|
visible: root.vertical
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
HoverHandler {
|
||||||
|
onHoveredChanged: root.setIndicatorAreaHovered(hovered)
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: inactiveVerticalArea
|
||||||
|
|
||||||
|
implicitWidth: Math.max(inactiveVerticalBlock.implicitWidth, root.barSize)
|
||||||
|
implicitHeight: root.revealInactiveIndicators ? inactiveVerticalBlock.implicitHeight : 0
|
||||||
|
width: implicitWidth
|
||||||
|
height: implicitHeight
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
IndicatorBlock {
|
||||||
|
id: inactiveVerticalBlock
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
indicatorsModule: root
|
||||||
|
indicatorEntries: root.indicatorEntries
|
||||||
|
indicatorBlock: "inactive"
|
||||||
|
horizontal: false
|
||||||
|
reportActiveState: root.vertical
|
||||||
|
}
|
||||||
|
|
||||||
|
HoverHandler {
|
||||||
|
onHoveredChanged: root.setIndicatorAreaHovered(hovered)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ActiveIndicatorBlock {
|
||||||
|
id: activeVerticalBlock
|
||||||
|
indicatorsModule: root
|
||||||
|
indicatorModel: activeIndicatorModel
|
||||||
|
horizontal: false
|
||||||
|
reportActiveState: root.vertical
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HoverHandler {
|
||||||
|
onHoveredChanged: root.setIndicatorAreaHovered(hovered)
|
||||||
|
}
|
||||||
|
|
||||||
|
component ActiveIndicatorBlock: Item {
|
||||||
|
id: activeIndicatorBlockRoot
|
||||||
|
|
||||||
|
property var indicatorModel: null
|
||||||
|
property var indicatorsModule: null
|
||||||
|
property bool horizontal: true
|
||||||
|
property bool reportActiveState: false
|
||||||
|
|
||||||
|
implicitWidth: blockLoader.item ? blockLoader.item.implicitWidth : 0
|
||||||
|
implicitHeight: blockLoader.item ? blockLoader.item.implicitHeight : 0
|
||||||
|
width: implicitWidth
|
||||||
|
height: implicitHeight
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: blockLoader
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
sourceComponent: activeIndicatorBlockRoot.horizontal ? horizontalActiveIndicatorBlock : verticalActiveIndicatorBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: horizontalActiveIndicatorBlock
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: activeIndicatorBlockRoot.indicatorModel
|
||||||
|
|
||||||
|
IndicatorLoader {
|
||||||
|
required property string activeId
|
||||||
|
indicatorsModule: activeIndicatorBlockRoot.indicatorsModule
|
||||||
|
entry: activeIndicatorBlockRoot.indicatorsModule.entryForId(activeId)
|
||||||
|
indicatorBlock: "active"
|
||||||
|
reportActiveState: activeIndicatorBlockRoot.reportActiveState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: verticalActiveIndicatorBlock
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: activeIndicatorBlockRoot.indicatorModel
|
||||||
|
|
||||||
|
IndicatorLoader {
|
||||||
|
required property string activeId
|
||||||
|
indicatorsModule: activeIndicatorBlockRoot.indicatorsModule
|
||||||
|
entry: activeIndicatorBlockRoot.indicatorsModule.entryForId(activeId)
|
||||||
|
indicatorBlock: "active"
|
||||||
|
reportActiveState: activeIndicatorBlockRoot.reportActiveState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component IndicatorBlock: Item {
|
||||||
|
id: indicatorBlockRoot
|
||||||
|
|
||||||
|
property var indicatorEntries: []
|
||||||
|
property var indicatorsModule: null
|
||||||
|
property string indicatorBlock: "active"
|
||||||
|
property bool horizontal: true
|
||||||
|
property bool reportActiveState: false
|
||||||
|
|
||||||
|
implicitWidth: blockLoader.item ? blockLoader.item.implicitWidth : 0
|
||||||
|
implicitHeight: blockLoader.item ? blockLoader.item.implicitHeight : 0
|
||||||
|
width: implicitWidth
|
||||||
|
height: implicitHeight
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: blockLoader
|
||||||
|
|
||||||
|
anchors.centerIn: parent
|
||||||
|
sourceComponent: indicatorBlockRoot.horizontal ? horizontalIndicatorBlock : verticalIndicatorBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: horizontalIndicatorBlock
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: indicatorBlockRoot.indicatorEntries
|
||||||
|
|
||||||
|
IndicatorLoader {
|
||||||
|
required property var modelData
|
||||||
|
indicatorsModule: indicatorBlockRoot.indicatorsModule
|
||||||
|
entry: modelData
|
||||||
|
indicatorBlock: indicatorBlockRoot.indicatorBlock
|
||||||
|
reportActiveState: indicatorBlockRoot.reportActiveState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: verticalIndicatorBlock
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: indicatorBlockRoot.indicatorEntries
|
||||||
|
|
||||||
|
IndicatorLoader {
|
||||||
|
required property var modelData
|
||||||
|
indicatorsModule: indicatorBlockRoot.indicatorsModule
|
||||||
|
entry: modelData
|
||||||
|
indicatorBlock: indicatorBlockRoot.indicatorBlock
|
||||||
|
reportActiveState: indicatorBlockRoot.reportActiveState
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
component IndicatorLoader: Item {
|
||||||
|
id: indicatorSlot
|
||||||
|
|
||||||
|
required property var entry
|
||||||
|
property var indicatorsModule: null
|
||||||
|
required property string indicatorBlock
|
||||||
|
property bool reportActiveState: false
|
||||||
|
property bool activeStateObserved: false
|
||||||
|
readonly property string indicatorId: root.entryId(entry)
|
||||||
|
readonly property var indicatorSettings: root.entrySettings(entry)
|
||||||
|
readonly property var barRef: root.bar
|
||||||
|
|
||||||
|
implicitWidth: indicatorSource.item && indicatorSource.item.visible ? indicatorSource.item.implicitWidth : 0
|
||||||
|
implicitHeight: indicatorSource.item && indicatorSource.item.visible ? indicatorSource.item.implicitHeight : 0
|
||||||
|
width: implicitWidth
|
||||||
|
height: implicitHeight
|
||||||
|
onEntryChanged: {
|
||||||
|
activeStateObserved = false
|
||||||
|
injectProps()
|
||||||
|
syncActiveState()
|
||||||
|
}
|
||||||
|
onIndicatorBlockChanged: injectProps()
|
||||||
|
onIndicatorSettingsChanged: injectProps()
|
||||||
|
onIndicatorsModuleChanged: {
|
||||||
|
injectProps()
|
||||||
|
syncActiveState()
|
||||||
|
}
|
||||||
|
onReportActiveStateChanged: syncActiveState()
|
||||||
|
onBarRefChanged: injectProps()
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: indicatorSource
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
source: indicatorSlot.indicatorId ? Qt.resolvedUrl("indicators/" + indicatorSlot.indicatorId + ".qml") : ""
|
||||||
|
onLoaded: {
|
||||||
|
indicatorSlot.injectProps()
|
||||||
|
indicatorSlot.syncActiveState()
|
||||||
|
}
|
||||||
|
onStatusChanged: if (status === Loader.Error) console.warn("Indicator loader error", indicatorSlot.indicatorId, source)
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: indicatorSource.item
|
||||||
|
ignoreUnknownSignals: true
|
||||||
|
function onActiveChanged() { indicatorSlot.syncActiveState() }
|
||||||
|
}
|
||||||
|
|
||||||
|
function injectProps() {
|
||||||
|
var target = indicatorSource.item
|
||||||
|
if (!target) return
|
||||||
|
if ("bar" in target) target.bar = root.bar
|
||||||
|
if ("moduleName" in target) target.moduleName = indicatorId
|
||||||
|
if ("settings" in target) target.settings = indicatorSettings
|
||||||
|
if ("indicatorBlock" in target) target.indicatorBlock = indicatorBlock
|
||||||
|
if ("indicatorHost" in target) target.indicatorHost = root
|
||||||
|
if ("activeOverride" in target) target.activeOverride = indicatorBlock === "active" ? true : null
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncActiveState() {
|
||||||
|
if (!reportActiveState || !indicatorsModule || !indicatorsModule.setIndicatorActive) return
|
||||||
|
|
||||||
|
var active = !!indicatorSource.item && indicatorSource.item.active === true
|
||||||
|
if (indicatorBlock === "active") {
|
||||||
|
if (active) activeStateObserved = true
|
||||||
|
else if (!activeStateObserved) return
|
||||||
|
}
|
||||||
|
|
||||||
|
indicatorsModule.setIndicatorActive(entry, active)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell.Io
|
||||||
|
import qs.Ui
|
||||||
|
|
||||||
|
BarIndicator {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string state: "idle"
|
||||||
|
property string icon: ""
|
||||||
|
|
||||||
|
active: state === "recording"
|
||||||
|
activeText: icon
|
||||||
|
inactiveText: ""
|
||||||
|
activeTooltipText: state
|
||||||
|
inactiveTooltipText: "Dictate"
|
||||||
|
|
||||||
|
function update(raw) {
|
||||||
|
var data = extractData(raw)
|
||||||
|
|
||||||
|
state = String(data.alt || data.class || "idle")
|
||||||
|
if (state === "recording") icon = ""
|
||||||
|
else if (state === "transcribing") icon = ""
|
||||||
|
else icon = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
command: ["bash", "-c", "omarchy-voxtype-status"]
|
||||||
|
running: true
|
||||||
|
stdout: SplitParser {
|
||||||
|
onRead: function(data) { root.update(data) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressed: function() {
|
||||||
|
if (!root.bar) return
|
||||||
|
root.bar.run("omarchy-voxtype-config")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import QtQuick
|
||||||
|
import qs.Commons
|
||||||
|
import qs.Ui
|
||||||
|
|
||||||
|
BarIndicator {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property var notificationService: bar?.shell?.firstPartyServiceFor("omarchy.notifications")
|
||||||
|
readonly property bool dnd: notificationService ? notificationService.doNotDisturb : false
|
||||||
|
|
||||||
|
active: dnd
|
||||||
|
activeText: ""
|
||||||
|
inactiveText: ""
|
||||||
|
activeTooltipText: "Allow Notifications"
|
||||||
|
inactiveTooltipText: "Silence Notifications"
|
||||||
|
|
||||||
|
onPressed: function() {
|
||||||
|
if (root.notificationService) {
|
||||||
|
root.notificationService.setDoNotDisturb(!root.notificationService.doNotDisturb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import QtQuick
|
||||||
|
import qs.Ui
|
||||||
|
|
||||||
|
BarIndicator {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property var nightlightService: bar?.shell?.firstPartyServiceFor("omarchy.nightlight")
|
||||||
|
|
||||||
|
active: nightlightService ? nightlightService.enabled : false
|
||||||
|
activeText: ""
|
||||||
|
inactiveText: ""
|
||||||
|
activeTooltipText: "Day Light"
|
||||||
|
inactiveTooltipText: "Night Light"
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
if (root.nightlightService) root.nightlightService.setNightlight(!root.active)
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressed: function() { root.toggle() }
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import qs.Ui
|
||||||
|
|
||||||
|
BarIndicator {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property int reminderCount: 0
|
||||||
|
property string tooltip: ""
|
||||||
|
|
||||||
|
active: reminderCount > 0
|
||||||
|
activeText: ""
|
||||||
|
inactiveText: ""
|
||||||
|
activeTooltipText: tooltip
|
||||||
|
inactiveTooltipText: tooltip
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
if (!jsonProc.running) jsonProc.running = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function openReminderFlow() {
|
||||||
|
Quickshell.execDetached(["omarchy-reminder", "-i"])
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(raw) {
|
||||||
|
var data = extractData(raw)
|
||||||
|
reminderCount = Number(data.count || 0)
|
||||||
|
tooltip = String(data.tooltip || "")
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: refresh()
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root.indicatorHost
|
||||||
|
ignoreUnknownSignals: true
|
||||||
|
function onRefreshRequested() { root.refresh() }
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: jsonProc
|
||||||
|
command: ["omarchy-reminder", "show", "--json"]
|
||||||
|
stdout: StdioCollector {
|
||||||
|
waitForEnd: true
|
||||||
|
onStreamFinished: root.update(text)
|
||||||
|
}
|
||||||
|
onExited: function(exitCode) {
|
||||||
|
if (exitCode !== 0) {
|
||||||
|
root.reminderCount = 0
|
||||||
|
root.tooltip = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressed: function() {
|
||||||
|
if (root.reminderCount > 0) Quickshell.execDetached(["omarchy-reminder", "show"])
|
||||||
|
else root.openReminderFlow()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell.Io
|
||||||
|
import qs.Ui
|
||||||
|
|
||||||
|
BarIndicator {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool recording: false
|
||||||
|
|
||||||
|
active: recording
|
||||||
|
activeText: ""
|
||||||
|
inactiveText: ""
|
||||||
|
activeTooltipText: "Stop recording"
|
||||||
|
inactiveTooltipText: "Screen Recording"
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
if (!root.bar || statusProc.running) return
|
||||||
|
statusProc.command = ["pgrep", "--quiet", "-f", "^gpu-screen-recorder"]
|
||||||
|
statusProc.running = true
|
||||||
|
}
|
||||||
|
|
||||||
|
onBarChanged: refresh()
|
||||||
|
Component.onCompleted: refresh()
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root.indicatorHost
|
||||||
|
ignoreUnknownSignals: true
|
||||||
|
function onRefreshRequested() { root.refresh() }
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: statusProc
|
||||||
|
onExited: function(exitCode) {
|
||||||
|
root.recording = exitCode === 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressed: function() {
|
||||||
|
if (root.bar) {
|
||||||
|
root.bar.run(root.recording ? "omarchy-capture-screenrecording --stop-recording" : "omarchy-menu toggle trigger.capture.screenrecord")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import QtQuick
|
||||||
|
import qs.Ui
|
||||||
|
|
||||||
|
BarIndicator {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property var idleService: bar?.shell?.firstPartyServiceFor("omarchy.idle")
|
||||||
|
|
||||||
|
active: idleService ? idleService.stayAwake : false
|
||||||
|
activeText: ""
|
||||||
|
inactiveText: ""
|
||||||
|
activeTooltipText: "Allow Idle Lock & Screensaver"
|
||||||
|
inactiveTooltipText: "Stay Awake"
|
||||||
|
|
||||||
|
function toggle() {
|
||||||
|
if (root.idleService) root.idleService.setIdleEnabled(root.active)
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressed: function() { root.toggle() }
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"schemaVersion": 1,
|
||||||
|
"id": "pastilhas.indicators",
|
||||||
|
"name": "Indicators",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"author": "pastilhas",
|
||||||
|
"description": "Manual state indicators",
|
||||||
|
"kinds": [
|
||||||
|
"bar-widget"
|
||||||
|
],
|
||||||
|
"entryPoints": {
|
||||||
|
"barWidget": "Indicators.qml"
|
||||||
|
},
|
||||||
|
"barWidget": {
|
||||||
|
"displayName": "Indicators",
|
||||||
|
"description": "Manual state indicators",
|
||||||
|
"category": "Status",
|
||||||
|
"allowMultiple": true,
|
||||||
|
"schema": [
|
||||||
|
{
|
||||||
|
"key": "items",
|
||||||
|
"type": "multiselect",
|
||||||
|
"label": "Indicators",
|
||||||
|
"description": "Choose which indicators this widget instance should show. Leave empty to show all indicators.",
|
||||||
|
"noSelectionText": "All indicators",
|
||||||
|
"placeholderText": "Search indicators...",
|
||||||
|
"emptyText": "No indicators",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"value": "Dictation",
|
||||||
|
"label": "Dictation",
|
||||||
|
"description": "Voice typing status"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "ScreenRecording",
|
||||||
|
"label": "Screen recording",
|
||||||
|
"description": "GPU screen recorder status"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "Reminder",
|
||||||
|
"label": "Reminder",
|
||||||
|
"description": "Queued reminder status"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "NightLight",
|
||||||
|
"label": "Night light",
|
||||||
|
"description": "Blue-light filter"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "Dnd",
|
||||||
|
"label": "Do not disturb",
|
||||||
|
"description": "Notification silencing"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "StayAwake",
|
||||||
|
"label": "Stay awake",
|
||||||
|
"description": "Idle lock and screensaver override"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "alwaysShow",
|
||||||
|
"type": "boolean",
|
||||||
|
"label": "Always Show",
|
||||||
|
"description": "Show inactive indicators without waiting for hover.",
|
||||||
|
"defaultValue": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"omarchy": {
|
||||||
|
"clonedFrom": "omarchy.indicators"
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user