OSX - отключение системных жестов в системе

Мне нужно программно отключить/подавить жесты сенсорного экрана в системе в Mac OS. Я имею в виду жесты, такие как пробел между четырьмя пальцами между пробелами и т.д.

Я посмотрел EventTap, но это не похоже на вариант (несмотря на предыдущие отчеты здесь - возможно, он изменился в 10.8)

Я также пробовал множество способов изменения системных предпочтений программным образом. Например, я попытался использовать IOConnectSetCFProperties в сервисе, разместив его с помощью IORegistryEntryCreateCFProperties.

Я также углубился в панель предпочтений трекпада, чтобы посмотреть, как они это делают, и я попытался воспроизвести его (игнорируйте любые несоответствия создания/выпуска, это всего лишь тестовый код):

    NSInteger zero = 0;
    CFNumberRef numberWith0 = CFNumberCreate(kCFAllocatorDefault, kCFNumberNSIntegerType, &zero);

    CFMutableDictionaryRef propertyDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                                                    &kCFTypeDictionaryKeyCallBacks,
                                                                    &kCFTypeDictionaryValueCallBacks);

    CFDictionarySetValue(propertyDict, @"TrackpadFourFingerHorizSwipeGesture", numberWith0);

    io_connect_t connect = getEVSHandle(); // Found in the MachineSettings framework

    if (!connect)
    {
        NSLog(@"Unable to get EVS handle");
    }

    kern_return_t status = IOConnectSetCFProperties(connect, propertyDict);

    if (status != KERN_SUCCESS)
    {
        NSLog(@"Unable to get set IO properties");
    }

    CFRelease(propertyDict);
    CFPreferencesSetValue(CFSTR("com.apple.trackpad.fourFingerHorizSwipeGesture"), _numberWith0, kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);

    CFPreferencesSetValue(CFSTR("TrackpadFourFingerHorizSwipeGesture"), _numberWith0, CFSTR("com.apple.driver.AppleBluetoothMultitouch.trackpad"), kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);

    CFPreferencesSynchronize(kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);

    status = BSKernelPreferenceChanged(CFSTR("com.apple.driver.AppleBluetoothMultitouch.trackpad"));

В этом случае он работает, ошибок нет, и опция отключается в панели предпочтений системы, однако жест четырех пальцев продолжает работать. Я подозреваю, что выход из системы тогда будет иметь эффект, но я не пробовал, потому что это не очень хорошо в любом случае.

Стоит отметить, что сама Pref Pane также вызывает BSKernelPreferenceChanged, но я не знаю, какую инфраструктуру можно было бы связать с ней. Возможно, это ключ к проблеме...

UPDATE: На самом деле я нашел его и связал. Добавление этого вызова не имело никакого значения, хотя оно возвращает 1, что может указывать на ошибку. Я добавил вызов вышеприведенного кода.

Наконец, я попробовал это с терминала:

defaults write -globalDomain com.apple.trackpad.fourFingerHorizSwipeGesture 0
defaults write  com.apple.driver.AppleBluetoothMultitouch.trackpad TrackpadFourFingerHorizSwipeGesture 0

Это также не имеет немедленного эффекта.

Я не верю, что это невозможно, должен быть способ...

Совместимость с MAS не требуется.

Ответ 1

Я также пытаюсь это сделать.

Метки событий не работают, и не имеет представления, которое является первым ответчиком.

Из документов Apple:

Тем не менее, существуют определенные общесистемные жесты, например, проведите пальцем по четыре пальца. для которых реализация системы имеет приоритет над любой обработкой жестов, выполняемой приложением.

Единственный способ, которым я смог остановить жесты системы, - это использовать CGDisplayCapture. Это дает моему приложению исключительный доступ ко всем событиям... но также и контекст полноэкранного рисования.

Возможно, возможно увидеть, какие вызовы выполняются службам кварцевого события при входе в этот режим

https://developer.apple.com/library/mac/#documentation/graphicsimaging/Conceptual/QuartzDisplayServicesConceptual/Articles/DisplayCapture.html

Ответ 2

Я думаю, что вы ищете неправильное место для отключения сенсорных событий. Способ OSX (и многих других систем) заключается в том, что первый ответчик в цепочке представлений для обработки события остановит событие от распространения. Вам нужно будет написать обработчики событий в своих представлениях для каждого из событий касания, которые вы хотите обработать, и если они существуют, ОС перестанет отправлять события полностью на поисковик или другое другое приложение в очереди, чтобы справиться с прикосновением события.

Смотрите: http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/EventOverview/HandlingTouchEvents/HandlingTouchEvents.html

В частности: обработка событий Multi-Touch (вызов setAcceptsTouchEvents, затем реализация штрихов... WithEvent...)

Надеюсь, что это поможет!