Health: clean degraded message; PTT hotkey monitors

This commit is contained in:
Peter Steinberger
2025-12-09 03:46:52 +01:00
parent 514b90ac69
commit 7aefcab8b0
3 changed files with 33 additions and 8 deletions

View File

@@ -164,7 +164,7 @@ final class HealthStore: ObservableObject {
return nil return nil
} }
private func describeFailure(from snap: HealthSnapshot, fallback: String?) -> String { func describeFailure(from snap: HealthSnapshot, fallback: String?) -> String {
if !snap.web.linked { if !snap.web.linked {
return "Not linked — run clawdis login" return "Not linked — run clawdis login"
} }
@@ -185,6 +185,16 @@ final class HealthStore: ObservableObject {
} }
return "health probe failed" return "health probe failed"
} }
var degradedSummary: String? {
guard case let .degraded(reason) = self.state else { return nil }
if reason == "[object Object]" || reason.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty,
let snap = self.snapshot
{
return self.describeFailure(from: snap, fallback: reason)
}
return reason
}
} }
func msToAge(_ ms: Double) -> String { func msToAge(_ ms: Double) -> String {

View File

@@ -98,8 +98,9 @@ struct MenuContent: View {
label = "Health: login required" label = "Health: login required"
color = .red color = .red
case let .degraded(reason): case let .degraded(reason):
let detail = HealthStore.shared.degradedSummary ?? reason
let ageText = lastAge.map { " · checked \($0)" } ?? "" let ageText = lastAge.map { " · checked \($0)" } ?? ""
label = "Health degraded: \(reason)\(ageText)" label = "Health degraded: \(detail)\(ageText)"
color = .orange color = .orange
case .unknown: case .unknown:
label = "Health pending" label = "Health pending"

View File

@@ -8,7 +8,8 @@ import Speech
final class VoicePushToTalkHotkey { final class VoicePushToTalkHotkey {
static let shared = VoicePushToTalkHotkey() static let shared = VoicePushToTalkHotkey()
private var monitor: Any? private var globalMonitor: Any?
private var localMonitor: Any?
private var optionDown = false // right option only private var optionDown = false // right option only
private var active = false private var active = false
@@ -21,18 +22,27 @@ final class VoicePushToTalkHotkey {
} }
private func startMonitoring() { private func startMonitoring() {
guard self.monitor == nil else { return } guard self.globalMonitor == nil, self.localMonitor == nil else { return }
// Listen-only global monitor; we rely on Input Monitoring permission to receive events. // Listen-only global monitor; we rely on Input Monitoring permission to receive events.
self.monitor = NSEvent.addGlobalMonitorForEvents(matching: .flagsChanged) { [weak self] event in self.globalMonitor = NSEvent.addGlobalMonitorForEvents(matching: .flagsChanged) { [weak self] event in
guard let self else { return } guard let self else { return }
self.updateModifierState(from: event) self.updateModifierState(from: event)
} }
// Also listen locally so we still catch events when the app is active/focused.
self.localMonitor = NSEvent.addLocalMonitorForEvents(matching: .flagsChanged) { [weak self] event in
self?.updateModifierState(from: event)
return event
}
} }
private func stopMonitoring() { private func stopMonitoring() {
if let monitor { if let globalMonitor {
NSEvent.removeMonitor(monitor) NSEvent.removeMonitor(globalMonitor)
self.monitor = nil self.globalMonitor = nil
}
if let localMonitor {
NSEvent.removeMonitor(localMonitor)
self.localMonitor = nil
} }
self.optionDown = false self.optionDown = false
self.active = false self.active = false
@@ -48,11 +58,15 @@ final class VoicePushToTalkHotkey {
if chordActive && !self.active { if chordActive && !self.active {
self.active = true self.active = true
Task { Task {
Logger(subsystem: "com.steipete.clawdis", category: "voicewake.ptt")
.info("ptt hotkey down")
await VoicePushToTalk.shared.begin() await VoicePushToTalk.shared.begin()
} }
} else if !chordActive && self.active { } else if !chordActive && self.active {
self.active = false self.active = false
Task { Task {
Logger(subsystem: "com.steipete.clawdis", category: "voicewake.ptt")
.info("ptt hotkey up")
await VoicePushToTalk.shared.end() await VoicePushToTalk.shared.end()
} }
} }