mirror of
https://github.com/acamarata/curtain.git
synced 2026-06-30 18:54:25 +00:00
Detection: netstat lives at /usr/sbin/netstat, not /usr/bin — the hardcoded wrong path silently killed the ESTABLISHED-TCP activator (root cause of the failed live test). Fixed and live-verified. Added peered-UDP activator (5900-5902) for High-Performance sessions, per-signal transition logging, unconditional error logging for dead probe helpers, and probe v2 with full CGSession dictionary diffing. 7 new parser tests (32 total). Fixes from a full audit + adversarial review: idle source setting honored (default now Remote session activity), cover scope reduced to a coherent two-mode model with legacy migration (per-display toggle was inverted in onlyMarked and dead in all), curtain test no longer schedules a teardown over a live session, specific-display password box placement gets a real picker, refuse-to-arm enforced, activation notification posts a real banner, menu password gate bypassed when the event tap is dead, shared single-decoder aerial player with stale-task guard and async playability check, password buffer zeroed on successful unlock and Esc, XPC interruption/invalidation handlers, modern Accessibility settings URL, launchPath modernized, codesign failures now abort release.sh, monotonic CFBundleVersion, install.sh temp cleanup, dead armDisarmHotkey setting removed. Refactor: Curtain.swift and PreferencesWindow.swift split into focused files (largest now 479 lines). Wiki, README, and contributing docs updated to match. Build clean at 0 warnings, 32/32 tests pass.
26 lines
1.2 KiB
Swift
26 lines
1.2 KiB
Swift
import Foundation
|
|
|
|
/// Purpose: convert between a "#rrggbb" hex string and normalized (0...1) RGB
|
|
/// components. Pure Foundation so it can be shared between the headless
|
|
/// cover renderer and the preferences ColorPicker bridge without AppKit.
|
|
public enum HexColor {
|
|
/// Parse a "#rrggbb" (or "rrggbb") string into normalized RGB components.
|
|
/// Returns nil for malformed input.
|
|
public static func toRGB(_ hex: String) -> (r: Double, g: Double, b: Double)? {
|
|
var s = hex
|
|
if s.hasPrefix("#") { s.removeFirst() }
|
|
guard s.count == 6, let v = UInt32(s, radix: 16) else { return nil }
|
|
let r = Double((v >> 16) & 0xFF) / 255.0
|
|
let g = Double((v >> 8) & 0xFF) / 255.0
|
|
let b = Double(v & 0xFF) / 255.0
|
|
return (r, g, b)
|
|
}
|
|
|
|
/// Render normalized RGB components (clamped to 0...1) as a "#rrggbb" string.
|
|
public static func fromRGB(_ r: Double, _ g: Double, _ b: Double) -> String {
|
|
let ri = Int(round(min(max(r, 0), 1) * 255))
|
|
let gi = Int(round(min(max(g, 0), 1) * 255))
|
|
let bi = Int(round(min(max(b, 0), 1) * 255))
|
|
return String(format: "#%02x%02x%02x", ri, gi, bi)
|
|
}
|
|
}
|