使用细分隔线样式时,NSSplitView 如何跟踪光标?

How does NSSplitView track the cursor when using the thin divider style?

NSSplitView 有一个名为 NSSplitViewDividerStyleThin 的分隔线样式,它已成为 OS X 最新版本的规范。它只是绘制一条 1 像素宽的实线来表示分隔线.然而,分隔线的实际跟踪区域约为 3-5 像素宽,允许用户在分隔线的任一侧点击一点以启动拖动。

由于拆分视图的子视图的布局使得它们实际上彼此仅相距 1 个像素,拆分视图如何跟踪光标和鼠标按下事件,以便它能够拦截稍稍超出外部的任何事件分隔符的 "frame"。通常这些事件会落入底层视图(就像滚动条与分隔线齐平)。

第一个想法:

那个 NSSplitView 只是有一个 3-5 像素宽的透明子视图,用于放置在其两个(或更多)内容视图之上的分隔线。但是如果我查询 splitview 的子视图数量,它只有 returns 2. 同样,如果我使用 F-Script 之类的东西进行检查。

在此 Stack Overflow 问题中也讨论了 AppKit 并不真正支持重叠的兄弟视图:

Is there a proper way to handle overlapping NSView siblings?

第二个想法:

也许 NSSplitView 只是使用 NSTrackingArea 作为分隔线,但如果我向拆分视图询问其跟踪区域,则会返回 none。即使它使用了跟踪区域,父视图上的跟踪区域是否可以覆盖子视图上的跟踪区域? (例如,我假设子视图的滚动条优先 - 但它不会在拆分视图中。)

第三个想法:

可能 NSSplitView 使用了某种覆盖在顶部的透明 window,但除非我找错了地方,否则我看不到任何额外的 windows 正在创建。

第四个想法:

NSSplitView 使用本地事件监视器来跟踪所有发往应用程序的鼠标移动和鼠标按下事件,并拦截拆分视图跟踪区域内的任何事件,即使这些事件在技术上也是如此在子视图上。

那么 NSSplitView 如何能够拦截在为细边框绘制的视觉 1 像素宽 space 之外,而是发生在其子视图之一上的鼠标事件?

首先,NSSplitView 似乎覆盖了 -resetCursorRects,并且在该方法中,使用 -addCursorRect:cursor: 添加了游标矩形。这就是它如何安排光标在其分隔线附近发生变化。

其次,它覆盖了 -hitTest:。鼠标事件通过 -[NSWindow sendEvent:] 路由到视图。这使用 -hitTest: 来询问它的视图(例如 contentView 和主题框架的东西)哪个后代视图被击中了。当它找到哪个视图被击中时,它会在该视图上调用 -mouseDown:(或类似的,取决于确切的事件)。因此,一个视图可以防止鼠标事件被路由到它的子视图。它可以 return 自己从其对 -hitTest: 的覆盖中进行,即使该点实际上位于其子视图之一内并且鼠标事件将传递给它而不是子视图。