【问题标题】:OSX - disabling system-wide touch gesturesOSX - 禁用系统范围的触摸手势
【发布时间】:2012-11-28 14:51:33
【问题描述】:

我需要在 Mac OS 上以编程方式禁用/抑制系统范围的触摸手势。我指的是手势,例如在空格之间滑动的四指滑动等。

我查看了 EventTap,但这似乎不是一个选项(尽管此处有以前的报告 - 也许它在 10.8 下已更改)

我还尝试了多种以编程方式更改系统首选项的方法。例如,我尝试在使用 IORegistryEntryCreateCFProperties 定位的服务上使用 IOConnectSetCFProperties。

我还深入研究了触控板首选项窗格,看看他们是如何做到的,并尝试重现它(忽略任何创建/发布的不一致,这只是测试代码):

    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,但我不知道可能是哪个框架才能链接到它。也许这就是问题的关键……

更新:实际上我现在已经找到它并将其链接到。添加该调用没有任何区别,尽管它返回 1 可能表示错误。我已将调用添加到上面的代码中。

最后我从终端尝试了这个:

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

这也不会立即产生影响。

我不相信这是不可能的,一定有办法……

不需要 MAS 兼容性。

【问题讨论】:

  • 对于“默认写入”位,您所说的“没有立即生效”是什么意思 重启后是否有效?很多时候你必须'killall dock'和'killall finder'才能让一些默认值生效。
  • 嗨杰里米。确实,但我需要它立即生效,就像您在首选项窗格中更改触控板选项时一样。
  • 如果您不想退出,可以尝试重新启动 finder。
  • 对不起,这可能不是很清楚。我希望能够将触控板用于我自己的应用程序。目前这是不可能的,因为系统接管了太多手势。因此,我想在我的应用程序正在使用时禁用手势,然后再次启用它们,我不想用重新启动的东西来打扰用户,它应该都是不可见的和即时的。
  • 你为什么要这样做?如果用户配置了这些手势,您为什么要尝试覆盖用户的设置?

标签: macos cocoa osx-lion osx-mountain-lion iokit


【解决方案1】:

我也在尝试这样做。

事件点击不起作用,作为第一响应者的视图也不起作用。

来自 Apple 文档:

但是,有某些系统范围的手势,例如四指滑动。系统实现优先于应用程序执行的任何手势处理。

我能够停止系统范围手势的唯一方法是使用CGDisplayCapture。这使我的应用程序可以独占访问所有事件...而且还提供全屏绘图上下文。

也许在进入这个模式时可以看到石英事件服务的调用情况

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

【讨论】:

    【解决方案2】:

    我认为您正在寻找禁用触摸事件的错误位置。 OSX(和许多其他系统)的方式是视图链中处理事件的第一个响应者将阻止事件传播。您需要在视图中为要处理的每个触摸事件编写事件处理程序,如果它们存在,操作系统将停止发送事件,一直到 finder 或下一个处理触摸的任何其他应用程序事件。

    见:http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/EventOverview/HandlingTouchEvents/HandlingTouchEvents.html

    具体来说:处理多点触控事件(调用setAcceptsTouchEvents,然后实现touches...WithEvent...)

    希望有帮助!

    【讨论】:

    • 嗨。我不知道这是否适用于全球手势是否仍然会发生的标准应用程序。在任何情况下我都不能这样做,因为我正在尝试将手势添加到另一个应用程序(通过辅助 API 控制它)。所以,我必须做我想做的事……
    • 在热键上,你可以加载一个透明的全屏视图到可以捕获事件的屏幕吗?
    • 很遗憾没有,因为用户仍然需要能够与其他应用交互。
    • 我认为如果你不处理它们会通过,可能值得一试。你看过 [NSEvent addGlobalMonitorForEventsMatchingMask] 吗?
    猜你喜欢
    • 2015-10-21
    • 2015-05-31
    • 1970-01-01
    • 2018-03-31
    • 2013-10-28
    • 1970-01-01
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多