其中鼠标光标移动加速度和滚轮加速度在MacOSX中实现

问题描述:

MacOSX中鼠标光标移动加速度和滚轮加速度在哪里?其中鼠标光标移动加速度和滚轮加速度在MacOSX中实现

在API级别上,Core Graphics/Quartz Event Services提供CGEvent类型。

在应用程序方面,也有在this Chrome change review很多相关的和有趣的评论,并从那里this comment提取:

// Of Mice and Men 
// --------------- 
// 
// There are three types of scroll data available on a scroll wheel CGEvent. 
// Apple's documentation ([1]) is rather vague in their differences, and not 
// terribly helpful in deciding which to use. This is what's really going on. 
// 
// First, these events behave very differently depending on whether a standard 
// wheel mouse is used (one that scrolls in discrete units) or a 
// trackpad/Mighty Mouse is used (which both provide continuous scrolling). 
// You must check to see which was used for the event by testing the 
// kCGScrollWheelEventIsContinuous field. 
// 
// Second, these events refer to "axes". Axis 1 is the y-axis, and axis 2 is 
// the x-axis. 
// 
// Third, there is a concept of mouse acceleration. Scrolling the same amount 
// of physical distance will give you different results logically depending on 
// whether you scrolled a little at a time or in one continuous motion. Some 
// fields account for this while others do not. 
// 
// Fourth, for trackpads there is a concept of chunkiness. When scrolling 
// continuously, events can be delivered in chunks. That is to say, lots of 
// scroll events with delta 0 will be delivered, and every so often an event 
// with a non-zero delta will be delivered, containing the accumulated deltas 
// from all the intermediate moves. [2] 
// 
// For notchy wheel mice (kCGScrollWheelEventIsContinuous == 0) 
// ------------------------------------------------------------ 
// 
// kCGScrollWheelEventDeltaAxis* 
// This is the rawest of raw events. For each mouse notch you get a value of 
// +1/-1. This does not take acceleration into account and thus is less 
// useful for building UIs. 
// 
// kCGScrollWheelEventPointDeltaAxis* 
// This is smarter. In general, for each mouse notch you get a value of 
// +1/-1, but this _does_ take acceleration into account, so you will get 
// larger values on longer scrolls. This field would be ideal for building 
// UIs except for one nasty bug: when the shift key is pressed, this set of 
// fields fails to move the value into the axis2 field (the other two types 
// of data do). This wouldn't be so bad except for the fact that while the 
// number of axes is used in the creation of a CGScrollWheelEvent, there is 
// no way to get that information out of the event once created. 
// 
// kCGScrollWheelEventFixedPtDeltaAxis* 
// This is a fixed value, and for each mouse notch you get a value of 
// +0.1/-0.1 (but, like above, scaled appropriately for acceleration). This 
// value takes acceleration into account, and in fact is identical to the 
// results you get from -[NSEvent delta*]. (That is, if you linked on Tiger 
// or greater; see [2] for details.) 
// 
// A note about continuous devices 
// ------------------------------- 
// 
// There are two devices that provide continuous scrolling events (trackpads 
// and Mighty Mouses) and they behave rather differently. The Mighty Mouse 
// behaves a lot like a regular mouse. There is no chunking, and the 
// FixedPtDelta values are the PointDelta values multiplied by 0.1. With the 
// trackpad, though, there is chunking. While the FixedPtDelta values are 
// reasonable (they occur about every fifth event but have values five times 
// larger than usual) the Delta values are unreasonable. They don't appear to 
// accumulate properly. 
// 
// For continuous devices (kCGScrollWheelEventIsContinuous != 0) 
// ------------------------------------------------------------- 
// 
// kCGScrollWheelEventDeltaAxis* 
// This provides values with no acceleration. With a trackpad, these values 
// are chunked but each non-zero value does not appear to be cumulative. 
// This seems to be a bug. 
// 
// kCGScrollWheelEventPointDeltaAxis* 
// This provides values with acceleration. With a trackpad, these values are 
// not chunked and are highly accurate. 
// 
// kCGScrollWheelEventFixedPtDeltaAxis* 
// This provides values with acceleration. With a trackpad, these values are 
// chunked but unlike Delta events are properly cumulative. 
// 
// Summary 
// ------- 
// 
// In general the best approach to take is: determine if the event is 
// continuous. If it is not, then use the FixedPtDelta events (or just stick 
// with Cocoa events). They provide both acceleration and proper horizontal 
// scrolling. If the event is continuous, then doing pixel scrolling with the 
// PointDelta is the way to go. In general, avoid the Delta events. They're 
// the oldest (dating back to 10.4, before CGEvents were public) but they lack 
// acceleration and precision, making them useful only in specific edge cases. 
// 
// References 
// ---------- 
// 
// [1] <http://developer.apple.com/documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html> 
// [2] <http://developer.apple.com/releasenotes/Cocoa/AppKitOlderNotes.html> 
//  Scroll to the section headed "NSScrollWheel events". 
// 
// P.S. The "smooth scrolling" option in the system preferences is utterly 
// unrelated to any of this. 

在内核级别,I/O Kit是基本的驱动程序接口,和我猜的鼠标HID(人机界面设备)系列(IOHIDFamily)。 XNU kernel source can be seen here但我不确定这是否完整,因为当我搜索IOHIDFamily时我没有找到一个匹配项。代码可能是here at IOHIDFamily。其实我在IOHIPointing.cpp发现注释:

/* 
* 17 July 1998 sdouglas Initial creation 
* 01 April  2002 ryepez  added support for scroll acceleration 
*/ 

而且从代码,它看起来像它的实现存在。有人可以确认吗? 另请参阅here

IOHIPointing中的逻辑如何最终进入CGEvent?这是Core Graphics/Quartz的所有部分吗?之间有什么?这是一些马赫事件吗?关于通用体系结构有什么好的概述?

请注意,我在想这个问题,因为正在进行的讨论在哪里实施mouse scroll wheel acceleration in Linux/Xorg/libinput here

好,问题 - 那是一个很大的问题。我应该注意到,我没有完整的信息 - 正如你发现的那样,很多信息都是封闭的。据我已经能够告诉,这些都是重要的几点:

  • 鼠标设置(跟踪速度,滚动速度等),你在系统偏好看到一个通用的,非苹果鼠标都在WindowServer内部处理 - 其中CGEvent是源于此。有一些HID报告在IOHIDPointing等按摩,但从我看到这主要是为了保持与古怪的设备兼容性。
  • 更新:(参见注释讨论)看起来WindowServer可能通过在其IORegistry条目上设置属性将加速参数传递给内核驱动程序。
  • 我相信苹果触控设备(触控板,魔术鼠标)的动量滚动可能实际上至少部分在其各自的闭源内核驱动程序中实现,如AppleMultitouchTrackpadHIDEventDriver
  • HID堆栈的较低级别用户空间一侧的源代码可在IOKitUser源包中找到。这包括IOHIDManager等。
  • 从装置到CGEvent旅程大致是:设备 - >IOHIDDevice - >IOHIDInterface - >IOHIDEventDriver - > [IOHIDevice] - >IOHIDSystem - >IOHIDUserClient - >由于IOKit内核 - 用户通信机制(使用马赫端口内部) - > HID部分IOKitUser - > WindowServer(核心图形)。
  • 您可以通过IOHIDLibUserClient直接连接到IOHIDDevice从用户空间进程绕过此路径。

IOKitUser源可能会更详细地回答您的一些问题。或者如果你想要做一些特定的事情,请为此提出一个新问题。

+0

非常感谢您的详细解答!我看了一下IOKitUser代码([这里](https://github.com/opensource-apple/IOKitUser/)),我刚刚发现了一些'IOHIDSetScrollAcceleration' /'IOHIDSetMouseAcceleration'和相关函数([另见] https://github.com/practicalswift/osx/search?utf8=%E2%9C%93&q=kIOHIDScrollAccelerationKey&type=)),所以我猜IOKitUser没有任何逻辑,但IOHIPointing。也许多点触控驱动程序和WindowServer也可以。 – Albert

+0

@Albert有趣的是,看起来像那些函数调用IO设置IO注册表对象的属性,所以是的,看起来像它发生在内核毕竟。 – pmdj