|
// |
|
// DebugOverridesView.swift |
|
// FreeSpace |
|
|
|
import SwiftUI |
|
|
|
struct DebugOverridesView: View { |
|
@State private var smartInvert: Bool? = nil |
|
@State private var grayscale: Bool? = nil |
|
@State private var buttonShapes: Bool? = nil |
|
@State private var reduceTransparency: Bool? = nil |
|
@State private var interfaceStyle: DBGInterfaceStyleOverride = .none |
|
@State private var reduceMotion: Bool? = nil |
|
@State private var boldText: Bool? = nil |
|
|
|
|
|
|
|
var body: some View { |
|
NavigationView { |
|
Form { |
|
// Smart Invert |
|
Section(header: Text("Accessibility Settings")) { |
|
Toggle("Smart Invert", isOn: Binding( |
|
get: { smartInvert ?? false }, |
|
set: { newValue in |
|
smartInvert = newValue |
|
DebugOverridesWrapper.setSmartInvert(newValue) |
|
} |
|
)) |
|
|
|
Toggle("Grayscale", isOn: Binding( |
|
get: { grayscale ?? false }, |
|
set: { newValue in |
|
grayscale = newValue |
|
DebugOverridesWrapper.setGrayscale(newValue) |
|
} |
|
)) |
|
|
|
Toggle("Button Shapes", isOn: Binding( |
|
get: { buttonShapes ?? false }, |
|
set: { newValue in |
|
buttonShapes = newValue |
|
DebugOverridesWrapper.setButtonShapes(newValue) |
|
} |
|
)) |
|
|
|
Toggle("Reduce Transparency", isOn: Binding( |
|
get: { reduceTransparency ?? false }, |
|
set: { newValue in |
|
reduceTransparency = newValue |
|
DebugOverridesWrapper.setReduceTransparency(newValue) |
|
} |
|
)) |
|
|
|
Toggle("Reduce Motion", isOn: Binding( |
|
get: { reduceMotion ?? false }, |
|
set: { newValue in |
|
reduceMotion = newValue |
|
DebugOverridesWrapper.setReduceMotion(newValue) |
|
} |
|
)) |
|
|
|
Toggle("Bold Text", isOn: Binding( |
|
get: { boldText ?? false }, |
|
set: { newValue in |
|
boldText = newValue |
|
DebugOverridesWrapper.setBoldText(newValue) |
|
} |
|
)) |
|
} |
|
|
|
// Interface Style |
|
Section(header: Text("Interface Style")) { |
|
Picker("Interface Style", selection: $interfaceStyle) { |
|
Text("None").tag(DBGInterfaceStyleOverride.none) |
|
Text("Light").tag(DBGInterfaceStyleOverride.light) |
|
Text("Dark").tag(DBGInterfaceStyleOverride.dark) |
|
} |
|
.pickerStyle(SegmentedPickerStyle()) |
|
.onChange(of: interfaceStyle) { _, newValue in |
|
DebugOverridesWrapper.setInterfaceStyle(newValue.rawValue) |
|
} |
|
} |
|
|
|
Section { |
|
Button("AXPreferences") { |
|
AccessibilityWrapper.axPreferences() |
|
} |
|
Button("ToggleSmartInvertColors") { |
|
AccessibilityWrapper.toggleSmartInvertColors() |
|
} |
|
} |
|
} |
|
.navigationTitle("Debug Overrides") |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
class DebugOverridesWrapper: NSObject { |
|
static func setSmartInvert(_ enabled: Bool?) { |
|
let value = enabled.map { NSNumber(value: $0) } |
|
DBGSetSmartInvert(value) |
|
} |
|
|
|
static func setGrayscale(_ enabled: Bool?) { |
|
let value = enabled.map { NSNumber(value: $0) } |
|
DBGSetGrayscale(value) |
|
} |
|
|
|
static func setButtonShapes(_ enabled: Bool?) { |
|
let value = enabled.map { NSNumber(value: $0) } |
|
DBGSetButtonShapes(value) |
|
} |
|
|
|
static func setOnOffLabels(_ enabled: Bool?) { |
|
let value = enabled.map { NSNumber(value: $0) } |
|
DBGSetOnOffLabels(value) |
|
} |
|
|
|
static func setReduceTransparency(_ enabled: Bool?) { |
|
let value = enabled.map { NSNumber(value: $0) } |
|
DBGSetReduceTransparency(value) |
|
} |
|
|
|
static func setInterfaceStyle(_ style: Int) { |
|
DBGSetInterfaceStyle(DBGInterfaceStyleOverride(rawValue: style) ?? .none) |
|
} |
|
|
|
static func setDifferentiateWithoutColor(_ enabled: Bool?) { |
|
let value = enabled.map { NSNumber(value: $0) } |
|
DBGSetDifferentiateWithoutColor(value) |
|
} |
|
|
|
static func setReduceMotion(_ enabled: Bool?) { |
|
let value = enabled.map { NSNumber(value: $0) } |
|
DBGSetReduceMotion(value) |
|
} |
|
|
|
static func setDynamicType(_ size: UIContentSizeCategory) { |
|
DBGSetDynamicType(size) |
|
} |
|
|
|
static func setIncreaseContrast(_ enabled: Bool?) { |
|
let value = enabled.map { NSNumber(value: $0) } |
|
DBGSetIncreaseContrast(value) |
|
} |
|
|
|
static func setBoldText(_ enabled: Bool?) { |
|
let value = enabled.map { NSNumber(value: $0) } |
|
DBGSetBoldText(value) |
|
} |
|
} |
|
|
|
class AccessibilityWrapper { |
|
static func setVoiceOver(_ enabled: Bool) { |
|
let path = "/System/Library/PrivateFrameworks/AccessibilityUtilities.framework/AccessibilityUtilities" |
|
let handle = dlopen(path, RTLD_NOW) |
|
defer { dlclose(handle) } |
|
|
|
guard let voiceOverFunction = dlsym(handle, "_AXSVoiceOverTouchSetEnabled") |
|
else { return print("Couldn't find voiceOver function") } |
|
|
|
typealias VoiceOverFunctionType = @convention(c) (Bool) -> Void |
|
let _AXSVoiceOverTouchSetEnabled = unsafeBitCast(voiceOverFunction, to: VoiceOverFunctionType.self) |
|
_AXSVoiceOverTouchSetEnabled(enabled) |
|
|
|
print("VoiceOver Toggled.") |
|
} |
|
|
|
static func axPreferences() { |
|
let path = "/System/Library/PrivateFrameworks/AccessibilityUtilities.framework/AccessibilityUtilities" |
|
let handle = dlopen(path, RTLD_NOW) |
|
defer { dlclose(handle) } |
|
|
|
let classObject = objc_getClass("AXPreferences") as! NSObject.Type |
|
let shared = classObject.value(forKey: "shared") as! NSObject |
|
let liveSpeech = shared.value(forKey: "liveSpeech") |
|
|
|
print(liveSpeech as Any) |
|
} |
|
|
|
static func toggleSmartInvertColors() { |
|
let path = "/System/Library/PrivateFrameworks/AccessibilityUtilities.framework/AccessibilityUtilities" |
|
let handle = dlopen(path, RTLD_NOW) |
|
defer { dlclose(handle) } |
|
|
|
|
|
let classObject = objc_getClass("AXTripleClickHelpers") as! NSObject.Type |
|
classObject.perform(Selector(("toggleGuidedAccess"))) |
|
} |
|
} |