Последние пару дней я пытался написать приложение, которое сбрасывало бы запись IORegistry
> IOHIDSystem
> HIDIdleTime
.Конечной целью было бы запретить другим приложениям, считывающим это значение, помечать пользователя как бездействующего (речь идет не только об управлении питанием или предотвращении спящего режима).Предположим, что песочница отключена и приложение имеет все необходимые разрешения (такие как доступ с расширенными возможностями).
Вот мои попытки сделать это (пока безуспешно):
Попытка 1 -переместите курсор мыши для имитации активности:
вариант 1:
let mouseCursorPosition = CGPoint(x: Int.random(in: 0...500), y: Int.random(in: 0...500))
CGWarpMouseCursorPosition(mouseCursorPosition)
вариант 2:
CGDisplayMoveCursorToPoint(CGMainDisplayID(), mouseCursorPosition)
Вариант 3 (использование CGEvent
само по себе или вместе с одним из 2 вариантов выше):
let moveEvent = CGEvent(mouseEventSource: nil, mouseType:
CGEventType.mouseMoved, mouseCursorPosition: mouseCursorPosition,
mouseButton: CGMouseButton.left)
moveEvent?.post(tap: CGEventTapLocation.cghidEventTap)
Вариант 4 (с использованием IOHIDSetMouseLocation
/ IOHIDPostEvent
):
func moveCursor() {
let service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"))
if (service == 0) { return }
var connect:io_connect_t = 0
let result = IOServiceOpen(service, mach_task_self_, UInt32(kIOHIDParamConnectType), &connect)
IOObjectRelease(service)
if (result == kIOReturnSuccess) {
let cursorX = Int16.random(in: 0...100)
let cursorY = Int16.random(in: 0...100)
IOHIDSetMouseLocation(connect, Int32(cursorX), Int32(cursorY))
let cursorLocation:IOGPoint = IOGPoint(x: cursorX, y: cursorY)
var event:NXEventData = NXEventData()
IOHIDPostEvent(connect, UInt32(NX_MOUSEMOVED), cursorLocation, &event, 0, 0, 0)
}
}
ПРИМЕЧАНИЕ: I 'Позже мы узнали, что, начиная с macOS 10.12, IOHIDPostEvent
не сбрасывается HIDIdleTime
(источник: https://github.com/tekezo/Karabiner-Elements/issues/385). Также пытались симулировать нажатия клавиш без успеха.
Попытка 2 - перезаписать значениенепосредственно в IORegistry
func overwriteValue() -> Bool {
var iterator: io_iterator_t = 0
defer { IOObjectRelease(iterator) }
guard IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"), &iterator) == kIOReturnSuccess else { return false }
let entry: io_registry_entry_t = IOIteratorNext(iterator)
defer { IOObjectRelease(entry) }
guard entry != 0 else { return false }
var value:NSInteger = 0;
var convertedValue:CFNumber = CFNumberCreate(kCFAllocatorDefault, CFNumberType.nsIntegerType, &value);
let result = IORegistryEntrySetCFProperty(entry, "HIDIdleTime" as CFString, convertedValue)
if (result != kIOReturnSuccess) { return false }
return true
}
Хотя это, кажется, работает (функция выше возвращает true
), значение затем перезаписывается системой, которая отслеживает фактический холостой ходвремя в памяти.Получил некоторое представление об этом из выпуска исходного кода Apple для IOHIDSystem
здесь .В настоящее время используется этот скрипт для простого мониторинга времени простоя системы и тестирования решений.
Будем благодарны за любые предложения.Если это вообще возможно, я стараюсь не писать свой собственный виртуальный драйвер (хотя я готов подключиться к существующему и симулировать события, если это возможно).