Repository navigation
Fix stuck buttons, display detection, double-click, capture safety and calibration - #4
Merged
Merged
Conversation
… gesture tests Synthesized events now go through an EventSink (SystemEventSink in production) and TouchGestureEngine takes an injectable clock and onSwipe closure, so the state machines can be tested without Accessibility permission or osascript. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
EventEmitter.reset() posts leftMouseUp / side-button ups / proximity-exit at the last in-range point. Proximity exit now uses it (it previously dropped the tip without a mouse-up), and the app calls it on profile change (unplug) and before calibration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Matching on the current mode's 3840x2160 pixel size picked any 4K monitor and missed the Cintiq in scaled modes. DisplayLocator matches the profile's EDID vendor/model (DTH2420: 0x5c23/0x1056), then the native mode's pixel size. Both pen mapping and the calibration overlay use it, removing the overlay's hard-coded 3840x2160. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The window server doesn't derive .mouseEventClickState for posted events, so every pen or tap click arrived as a single click. ClickCounter tracks multi-clicks using the system double-click interval and a small distance threshold; pen tip, side buttons and tap-to-click all set it (on downs, drags and ups). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The vendor-wide hotplug watcher registered an input-report callback on every Wacom device and copied each pen report into a Swift array only to discard it. HIDTransport's onReport is now optional; with none, the C shim registers no report callback. Each matched device also gets its own buffer (sized from kIOHIDMaxInputReportSizeKey) instead of all devices sharing one 64-byte array, writes fall back to another matched device on removal, and allocation failures are handled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
EventEmitter hard-coded Wacom's vendor ID and the DTH2420's 8191 pressure max, so a model with a different pressure resolution would be scaled wrongly. setProfile() adopts them from the DeviceProfile whenever mappings are rebuilt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Capture used to send the DTH2420's vendor feature/output reports to every interface of every Wacom device, where they may mean something else. It now only listens unless --send-enable is given; ADDING-A-DEVICE.md describes running passive first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The CLI calibrate command and the in-app overlay each had a copy of the hold-detection state machine and solved without checks, so tapping the same spot twice gave xMin == xMax and a divide-by-zero in the mapping. CalibrationSolver now holds the state machine and rejects pairs that are too close (<10% of the logical range) or reversed, restarting at point 1. DisplayMapping also maps a degenerate range to 0 instead of NaN. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…roadmap - PressureCurve keeps its points sorted once instead of sorting on every pen sample; the encoded format (just "points") is unchanged. - NibConfig.effectiveNaturalScrolling() replaces identical copies in the menu and the preferences window; remove the leftover var/_ = def in NibConfig.init(from:). - ROADMAP: Developer ID signing + notarization is done. Co-Authored-By: Claude Opus 5.5 <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.
Fixes the issues from a codebase evaluation. One commit per item.
User-facing fixes
EventEmitter.reset()releases the tip and side buttons and ends proximity at the pen's last position. It runs on proximity exit (which previously dropped the tip without a mouse-up), on unplug, and before calibration.0x5c23/0x1056for the DTH2420), then by native panel size, instead of the current mode's 3840×2160. This fixes another 4K monitor winning and scaled modes failing to match. The calibration overlay uses the same lookup..mouseEventClickState(ClickCounter, using the system double-click interval).Before accepting a second device profile
DeviceProfile.nib captureis passive by default: DTH2420 vendor reports are only sent with--send-enable.docs/ADDING-A-DEVICE.mdis updated to match.Calibration
CalibrationSolver(NibCore) replaces the duplicated state machines in the CLI and the overlay. It rejects point pairs that are too close or reversed and restarts at point 1.DisplayMappingno longer divides by zero.Cleanups
EventSink; gestures take an injectable clock and swipe action.ROADMAP.mdmarks signing and notarization as done.Testing
swift test: 42 tests pass (up from 17). New suites: emitter, touch gestures, click counter, display locator, calibration solver, pressure-curve Codable, config.swift build -c releasewith no warnings.--send-enablecapture.🤖 Generated with Claude Code