Filter pen logical collections from composite digitizer HID trees - #17
Open
testors wants to merge 2 commits into
Open
Filter pen logical collections from composite digitizer HID trees#17testors wants to merge 2 commits into
testors wants to merge 2 commits into
Conversation
Composite digitizers (e.g. Wacom-based touchscreens with integrated active pen) can expose pen and touch data within the same HID application collection. Without filtering, pen-specific logical collections (containing pressure, tilt, barrel elements) end up being treated as touch contacts, producing incorrect coordinates. Add IsPenCollection() to detect logical collections that contain pen-only HID usages (TipPressure, BarrelPressure, XTilt, YTilt, BarrelSwitch, Eraser) and skip them during element identification so only finger-touch collections feed into the mouse mapping logic. Tested with Lenovo ThinkVision M14t Gen2 (Wacom VID 0x2D1F PID 0x53D1).
When multiple HID devices match (e.g. composite digitizers exposing several interfaces), Handle_RemovalCallback is called once per device. After the first call releases and NULLs gQueue, subsequent calls would pass NULL to IOHIDQueueStop and CFRelease, causing a crash. Add a NULL check to return early on repeated removal calls.
ajmcclary
added a commit
to ajmcclary/Touch-Up
that referenced
this pull request
Jun 17, 2026
Composite digitizers (e.g. Wacom-based touchscreens with integrated active pen) can expose pen and touch data within the same HID application collection. Without filtering, pen-specific logical collections — containing pressure, tilt, and barrel elements — end up being treated as touch contacts, producing incorrect coordinates. Add IsPenCollection(), which inspects the direct children of a logical collection for pen-only Digitizer-page usages (TipPressure, BarrelPressure, XTilt, YTilt, BarrelSwitch, Eraser), and call it in IdentifyElements() to skip pen collections before they are appended to the device's touchCollectionElements. Adapted from shueber/Touch-Up#17 by KiHyun Kang. The PR's gQueue NULL-guard hunk is omitted: the multiscreen refactor replaced the global gQueue with per-device state and Handle_RemovalCallback already guards against an unmatched device. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Thank you for this useful tool — it has been great for adding touch support to external monitors.
Summary
Composite digitizers (e.g. Wacom-based touchscreens with integrated active pen) can expose pen and touch data within the same HID application collection. Without filtering, pen-specific logical collections — containing pressure, tilt, and barrel elements — end up being treated as touch contacts, producing incorrect coordinates.
This PR adds a small pen-collection filter in
IdentifyElements()so that only finger-touch logical collections feed into the mouse-mapping logic.Changes
IsPenCollection()— inspects direct children of a logical collection for pen-only Digitizer-page usages (TipPressure,BarrelPressure,XTilt,YTilt,BarrelSwitch,Eraser)IsPenCollection()inIdentifyElements()to skip pen collections before they are appended togTouchCollectionElementsHandle_RemovalCallbackagainst NULLgQueue— composite digitizers trigger multiple removal callbacks per disconnect; without the guard, the second call passes NULL toIOHIDQueueStop/CFRelease, causing a crashNotes
IdentifyElements()itselfInRange(0x32) is intentionally excluded because it appears in both pen and touch collectionsTested with
0x2D1F/ PID0x53D1)Test plan