### Install MiddleClick via Homebrew Source: https://context7.com/artginzburg/middleclick/llms.txt Use Homebrew Cask to install and launch the application. ```bash # Install MiddleClick using Homebrew Cask brew install --cask middleclick # Launch MiddleClick open -a MiddleClick ``` -------------------------------- ### Install MiddleClick via Homebrew Source: https://github.com/artginzburg/middleclick/blob/main/README.md Use this command to install MiddleClick using the Homebrew package manager. This is the recommended installation method. ```ps1 brew install --cask middleclick ``` -------------------------------- ### Prepare a test build for execution Source: https://github.com/artginzburg/middleclick/blob/main/CONTRIBUTING.md Removes the macOS quarantine attribute from an unsigned build to allow execution, followed by opening the application. ```sh # Remove the quarantine attribute, then run xattr -cr MiddleClick.app open MiddleClick.app ``` -------------------------------- ### Build MiddleClick from Source Source: https://context7.com/artginzburg/middleclick/llms.txt Clone the repository and build the application using the provided Makefile. ```bash # Clone the repository git clone https://github.com/artginzburg/MiddleClick.git cd MiddleClick # Build using Makefile (requires Command Line Tools) make all # The built app will be at ./build/MiddleClick.app open ./build/MiddleClick.app ``` -------------------------------- ### Manage Accessibility Permissions Source: https://context7.com/artginzburg/middleclick/llms.txt Open system settings or reset permissions for the application. ```bash # Open Privacy & Security settings directly to Accessibility pane open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility" # Reset MiddleClick's accessibility permission (useful after updates) tccutil reset Accessibility art.ginzburg.MiddleClick ``` -------------------------------- ### Package a test build for pull requests Source: https://github.com/artginzburg/middleclick/blob/main/CONTRIBUTING.md Builds the application in Debug mode, locates the resulting bundle, and compresses it into a zip file for distribution. ```sh # 1. Build make build-debug # 2. Ask Xcode where it put the .app APP="$(xcodebuild -project MiddleClick.xcodeproj -scheme MiddleClick -configuration Debug -showBuildSettings 2>/dev/null | awk -F ' = ' '/ BUILT_PRODUCTS_DIR =/ {print $2}')/MiddleClick.app" # 3. Zip it into the repo's build/ dir mkdir -p build && ditto -c -k --keepParent "$APP" build/MiddleClick-test.zip ``` -------------------------------- ### Build and run in Debug mode Source: https://github.com/artginzburg/middleclick/blob/main/docs/dev.md Executes the project build and run process without requiring Xcode. ```sh make run ``` -------------------------------- ### Test System Wake Handling Source: https://context7.com/artginzburg/middleclick/llms.txt Command to put the system to sleep immediately, allowing testing of MiddleClick's listener restart behavior upon system wake. ```bash # Put system to sleep immediately (MiddleClick will restart listeners on wake) pmset sleepnow # After waking, MiddleClick automatically restarts its touch and mouse listeners # with a 10-second delay (2-second delay in fast-restart debug mode) ``` -------------------------------- ### Check Trackpad Settings in Swift Source: https://context7.com/artginzburg/middleclick/llms.txt Query macOS system preferences to detect trackpad configuration like 'Tap to Click' and 'Three Finger Drag'. Useful for identifying potential conflicts. ```swift import CoreFoundation // Check if "Tap to Click" is enabled in System Settings func getIsSystemTapToClickEnabled() -> Bool { return CFPreferencesGetAppBooleanValue( "Clicking" as CFString, "com.apple.driver.AppleBluetoothMultitouch.trackpad" as CFString, nil ) } // Check if "Three Finger Drag" is enabled (may conflict with MiddleClick) func getIsSystemThreeFingerDragEnabled() -> Bool { return CFPreferencesGetAppBooleanValue( "TrackpadThreeFingerDrag" as CFString, "com.apple.driver.AppleBluetoothMultitouch.trackpad" as CFString, nil ) } // Example usage if getIsSystemThreeFingerDragEnabled() { print("Warning: Three Finger Drag conflicts with default 3-finger middle click") print("Consider using: defaults write art.ginzburg.MiddleClick fingers 4") } ``` -------------------------------- ### Configure Finger Tolerance Source: https://context7.com/artginzburg/middleclick/llms.txt Enable or disable tolerance for additional fingers touching the trackpad. ```bash # Allow middle click with 3 or more fingers (useful when second hand touches trackpad) defaults write art.ginzburg.MiddleClick allowMoreFingers true # Require exact finger count (default) defaults write art.ginzburg.MiddleClick allowMoreFingers false ``` -------------------------------- ### Control Menu Bar Icon Visibility Source: https://context7.com/artginzburg/middleclick/llms.txt Instructions on how to hide and restore the MiddleClick status bar icon using drag-and-drop and relaunching the application. ```bash # To hide the status bar icon: # 1. Hold Command (⌘) key # 2. Drag the MiddleClick icon away from menu bar until × appears # 3. Release to hide # To restore the icon: # Simply open MiddleClick again while it's already running open -a MiddleClick ``` -------------------------------- ### Monitor application logs Source: https://github.com/artginzburg/middleclick/blob/main/docs/dev.md Streams logs for the MiddleClick subsystem with debug level visibility. ```sh log stream --predicate 'subsystem == "art.ginzburg.MiddleClick"' --style compact --level debug ``` -------------------------------- ### Configure Gesture Finger Count Source: https://context7.com/artginzburg/middleclick/llms.txt Set the number of fingers required to trigger a middle click using defaults. ```bash # Use 4 fingers for middle click (useful to avoid conflicts with Three Finger Drag) defaults write art.ginzburg.MiddleClick fingers 4 # Use 2 fingers (warning: conflicts with right-click) defaults write art.ginzburg.MiddleClick fingers 2 # Reset to default (3 fingers) defaults delete art.ginzburg.MiddleClick fingers ``` -------------------------------- ### Check Accessibility Permissions Programmatically Source: https://context7.com/artginzburg/middleclick/llms.txt Use the AXIsProcessTrustedWithOptions API to verify or request accessibility access. ```swift import ApplicationServices // Check if accessibility is granted, optionally prompting the user func detectAccessibilityIsGranted(forcePrompt: Bool) -> Bool { return AXIsProcessTrustedWithOptions([ kAXTrustedCheckOptionPrompt.takeUnretainedValue(): forcePrompt ] as CFDictionary) } // Example: Check without prompting let hasAccess = detectAccessibilityIsGranted(forcePrompt: false) if !hasAccess { print("Accessibility permission required") // Prompt user _ = detectAccessibilityIsGranted(forcePrompt: true) } ``` -------------------------------- ### Manage Ignored Applications in Swift Source: https://context7.com/artginzburg/middleclick/llms.txt Provides functionality to configure and check a list of applications for which MiddleClick should be disabled. Uses UserDefault for persistence. ```swift // Configuration storage for ignored apps final class Config { @UserDefault var ignoredAppBundles = Set() } // Check if the currently focused app should be ignored func isIgnoredAppBundle(_ focusedApp: NSRunningApplication? = nil) -> Bool { let app = focusedApp ?? NSWorkspace.shared.frontmostApplication guard let bundleId = app?.bundleIdentifier else { return false } return Config.shared.ignoredAppBundles.contains(bundleId) } // Toggle ignore status for an app func toggleIgnoreApp(bundleId: String) { Config.shared.ignoredAppBundles.formSymmetricDifference([bundleId]) } // Example: Ignore Finder to allow Three Finger Drag in Finder // From the tray menu, select "Ignore Finder" while Finder is focused ``` -------------------------------- ### Enable Clicking with More Than Defined Fingers Source: https://github.com/artginzburg/middleclick/blob/main/README.md Allow MiddleClick to register clicks even if more than the specified number of fingers are used. This can be helpful for accidental touches but is not a full palm rejection solution. ```ps1 defaults write art.ginzburg.MiddleClick allowMoreFingers true ``` -------------------------------- ### Set Max Time Delta for Tapping Source: https://github.com/artginzburg/middleclick/blob/main/README.md Set the maximum time in milliseconds allowed between touch and release for a tap to be considered valid. ```ps1 defaults write art.ginzburg.MiddleClick maxTimeDelta 150 ``` -------------------------------- ### Register Multitouch Callbacks in Swift Source: https://context7.com/artginzburg/middleclick/llms.txt Manages multitouch device callbacks using the MultitouchSupport framework. Registers a touch callback to detect three-finger touches and track finger positions. ```swift import MultitouchSupport // Touch callback function type typealias MTFrameCallbackFunction = @convention(c) ( MTDevice?, UnsafePointer?, Int32, // nFingers Double, Int32 ) -> Void // Register touch callback on all multitouch devices class TouchHandler { private var currentDeviceList: [MTDevice] = [] private let touchCallback: MTFrameCallbackFunction = { _, data, nFingers, _, _ in // Check if app should be ignored guard !AppUtils.isIgnoredAppBundle() else { return } // Detect three-finger touch let threeDown = nFingers == 3 // or >= 3 with allowMoreFingers GlobalState.shared.threeDown = threeDown // Process touch positions for tap detection if let data = data { for touch in UnsafeBufferPointer(start: data, count: Int(nFingers)) { let pos = SIMD2(touch.normalizedVector.position.x, touch.normalizedVector.position.y) // Track finger positions for movement delta calculation } } } func registerTouchCallback() { currentDeviceList = MTDevice.createList() currentDeviceList.forEach { $0.registerAndStart(touchCallback) } } func unregisterTouchCallback() { currentDeviceList.forEach { $0.unregisterAndStop(touchCallback) } currentDeviceList.removeAll() } } ``` -------------------------------- ### Emulate Middle Click Events in Swift Source: https://context7.com/artginzburg/middleclick/llms.txt Posts synthetic middle mouse down and up events. Useful for tap-to-click mode. Includes a debounced version to prevent rapid re-triggering. ```swift import CoreGraphics // Post a middle click at the current cursor position func emulateMiddleClick() { // Get current cursor location let location = CGEvent(source: nil)?.location ?? .zero let buttonType: CGMouseButton = .center // Post mouse down event if let downEvent = CGEvent( mouseEventSource: nil, mouseType: .otherMouseDown, mouseCursorPosition: location, mouseButton: buttonType ) { downEvent.post(tap: .cghidEventTap) } // Post mouse up event if let upEvent = CGEvent( mouseEventSource: nil, mouseType: .otherMouseUp, mouseCursorPosition: location, mouseButton: buttonType ) { upEvent.post(tap: .cghidEventTap) } } // Example: Middle click with debouncing var lastEmulatedMiddleClickTime: Date? let maxTimeDelta: TimeInterval = 0.3 func emulateMiddleClickWithDebounce() { if let lastTime = lastEmulatedMiddleClickTime, -lastTime.timeIntervalSinceNow < maxTimeDelta * 0.3 { return // Debounce rapid clicks } lastEmulatedMiddleClickTime = Date() emulateMiddleClick() } ``` -------------------------------- ### Reset Accessibility Permissions Source: https://context7.com/artginzburg/middleclick/llms.txt Steps to fix MiddleClick not working after an update by quitting the app, resetting its accessibility permissions using tccutil, and relaunching. ```bash # Step 1: Quit MiddleClick osascript -e 'quit app "MiddleClick"' # Step 2: Reset accessibility permission tccutil reset Accessibility art.ginzburg.MiddleClick # Step 3: Relaunch MiddleClick (will prompt for permission) open -a MiddleClick # Step 4: Grant permission in System Settings when prompted open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility" ``` -------------------------------- ### Configure Number of Fingers for MiddleClick Source: https://github.com/artginzburg/middleclick/blob/main/README.md Adjust the number of fingers required for a middle-click action. Be aware that setting this to 2 may conflict with standard two-finger gestures. ```ps1 defaults write art.ginzburg.MiddleClick fingers 4 ``` -------------------------------- ### Set Max Distance Delta for Tapping Source: https://github.com/artginzburg/middleclick/blob/main/README.md Configure the maximum allowable cursor movement between touch and release for a tap to be recognized. Values are normalized between 0 and 1. ```ps1 defaults write art.ginzburg.MiddleClick maxDistanceDelta 0.03 ``` -------------------------------- ### Filter logs by category Source: https://github.com/artginzburg/middleclick/blob/main/docs/dev.md Filters the log stream to show events associated with a specific application category. ```sh log stream --predicate 'subsystem == "art.ginzburg.MiddleClick" && category == "schedule"' --style compact --level debug ``` -------------------------------- ### Adjust Tap Sensitivity Source: https://context7.com/artginzburg/middleclick/llms.txt Modify the distance and time thresholds for detecting taps. ```bash # Set maximum cursor distance delta for tap detection (normalized 0-1, default: 0.05) defaults write art.ginzburg.MiddleClick maxDistanceDelta 0.03 # Set maximum time delta in milliseconds for tap detection (default: 300) defaults write art.ginzburg.MiddleClick maxTimeDelta 150 # Reset tap settings to defaults defaults delete art.ginzburg.MiddleClick maxDistanceDelta defaults delete art.ginzburg.MiddleClick maxTimeDelta ``` -------------------------------- ### CGEvent Tap for Click Conversion in Swift Source: https://context7.com/artginzburg/middleclick/llms.txt Intercepts mouse events using CoreGraphics to convert left/right clicks to middle clicks when three fingers are detected. Requires specific event masks for monitoring mouse down and up events. ```swift import CoreGraphics // Create event tap to intercept mouse events let eventMask: CGEventMask = (1 << CGEventType.leftMouseDown.rawValue) | (1 << CGEventType.leftMouseUp.rawValue) | (1 << CGEventType.rightMouseDown.rawValue) | (1 << CGEventType.rightMouseUp.rawValue) let callback: CGEventTapCallBack = { _, type, event, _ in let state = GlobalState.shared let kCGMouseButtonCenter = Int64(CGMouseButton.center.rawValue) // Convert left/right mouse down to middle mouse down when 3 fingers detected if state.threeDown && (type == .leftMouseDown || type == .rightMouseDown) { state.wasThreeDown = true state.threeDown = false event.type = .otherMouseDown event.setIntegerValueField(.mouseEventButtonNumber, value: kCGMouseButtonCenter) } // Convert corresponding mouse up to middle mouse up if state.wasThreeDown && (type == .leftMouseUp || type == .rightMouseUp) { state.wasThreeDown = false event.type = .otherMouseUp event.setIntegerValueField(.mouseEventButtonNumber, value: kCGMouseButtonCenter) } return Unmanaged.passUnretained(event) } // Create and enable the event tap if let tap = CGEvent.tapCreate( tap: .cgSessionEventTap, place: .headInsertEventTap, options: .defaultTap, eventsOfInterest: eventMask, callback: callback, userInfo: nil ) { let runLoopSource = CFMachPortCreateRunLoopSource(nil, tap, 0) CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes) CGEvent.tapEnable(tap: tap, enable: true) } ``` -------------------------------- ### Update Homebrew Cask Version Source: https://github.com/artginzburg/middleclick/blob/main/docs/maintain.md Use this command to manually trigger a pull request for the Homebrew cask if the automatic update fails. ```sh brew bump-cask-pr middleclick --version set_MARKETING_VERSION_here ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.