feat: Add Auto-Scroll feature (middle-click scrolling)#913
Open
RomFatal wants to merge 21 commits into
Open
Conversation
Introduces a new auto-scroll feature activated by middle mouse button, including core logic, custom cursor, and utility classes. Updates the preferences window and storyboard to add an auto-scroll settings tab with controls for sensitivity, dead zone, drag threshold, max speed, and activation button. Updates Options and Constants to persist auto-scroll settings. ButtonCore is updated to handle auto-scroll events and integrate with the new feature.
Replaces the custom cursor with a fixed overlay icon at the activation point for auto-scroll. Introduces AutoScrollOverlay to display the icon, updates coordinate conversions for correct placement, and improves the visual design of the overlay and cursor. Also adds a dark mode option for auto-scroll icons in Constants.
Introduces a 'dark mode' toggle for the auto-scroll overlay icon, allowing users to enable a white background for better visibility in dark environments. Updates the overlay rendering logic, user preferences, and preferences UI to support this new option.
Adjusted the auto-scroll acceleration formula for a smoother, more natural speed curve based on distance. Improved Preferences UI layout with tighter spacing, shorter info text, and removed usage instructions. The reset button now explicitly resets each auto-scroll option to its default value instead of using a default struct.
AutoScrollCore now marks generated scroll events with the maskAlternate flag. ScrollCore detects this flag and bypasses further processing for these events, ensuring auto scroll events are not smoothed or altered.
Introduces logic to detect whether the middle button click occurs within a scrollable area and not in browser UI regions. Auto-scroll is now only activated if the click is outside browser UI (such as toolbars or tab bars) and on content that supports scrolling, improving user experience and preventing unintended activation.
Refactors and hardens auto-scroll logic to more reliably detect browser UI areas and block/allow events accordingly, preventing Chrome's native auto-scroll from triggering in blocked regions. Adds extensive debug logging, improves coordinate conversions, and ensures overlay positioning is accurate. Updates localization files with new auto-scroll settings strings and UI labels. Also changes event tap placement to head for more reliable event interception.
Refines logic to allow middle mouse button events to pass through in browser tab and bookmark areas, preventing interference with browser UI interactions. Updates event consumption behavior in AutoScrollCore and ButtonCore, and expands the preferences window and related UI elements in Main.storyboard for better layout. Also updates project settings to require macOS 11.0 and Xcode 14.3 or later.
Reduced the top UI block height from 250px to 130px in browser windows to more accurately reflect the actual UI area and avoid unnecessarily blocking scroll events outside the UI.
Replaced usage of NSScreen.main with NSScreen.screens.first to ensure coordinate conversions use the primary screen rather than the currently focused screen. Updated related log messages and comments for clarity.
AutoScrollCore now allows link clicks to pass through in browsers by not consuming events for AXLink roles, especially in strict mode. Removed AXLink from the general non-scrollable UI element list and improved logging. In Options, increased the default dragThreshold for auto-scroll from 10.0 to 20.0. Also removed a debug log from ButtonCore.
Replaces accessibility-based link detection with system cursor analysis to reliably detect clickable elements (like links) in browsers, especially Chromium-based ones where accessibility APIs are limited. Adds low-level cursor inspection in ButtonCore to block auto-scroll when the pointing hand cursor is active, ensuring correct behavior over links and buttons. Refactors and removes obsolete accessibility link detection logic from AutoScrollCore, and enhances event handling to use the new cursor-based approach.
# Conflicts: # .gitignore # Mos.xcodeproj/project.pbxproj # Mos.xcodeproj/xcshareddata/xcschemes/Debug.xcscheme # Mos.xcodeproj/xcshareddata/xcschemes/Profile.xcscheme # Mos/Base.lproj/Main.storyboard # Mos/ButtonCore/ButtonCore.swift # Mos/Localizable.xcstrings # Mos/ScrollCore/ScrollCore.swift # Mos/Utils/Constants.swift
Remove trailing spaces and tidy up blank lines/indentation across AutoScrollCore.swift and ButtonCore.swift. Purely cosmetic formatting changes to improve readability (whitespace, blank-line normalization, minor comment spacing) with no functional or behavioral changes.
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.
Summary
Adds an auto-scroll feature triggered by middle mouse button click, similar to the auto-scroll behavior found in Windows browsers. When the user middle-clicks in a scrollable area, the cursor changes to a scroll indicator and moving the mouse scrolls the content proportionally to distance from the origin point.
Behavior
Changes
New files
Mos/AutoScrollCore/AutoScrollCore.swift— core engine: activation, scroll loop, speed curve, drag thresholdMos/AutoScrollCore/AutoScrollCursor.swift— cursor overlay managementMos/AutoScrollCore/AutoScrollOverlay.swift— visual indicator overlay windowMos/AutoScrollCore/AutoScrollUtils.swift— utility helpersMos/Windows/PreferencesWindow/AutoScrollView/PreferencesAutoScrollViewController.swift— preferences UIModified files
Mos/ButtonCore/ButtonCore.swift— handles middle mouse down/up/move events, routes to AutoScrollCoreMos/ScrollCore/ScrollCore.swift— passthrough check for auto-scroll generated events (flagged with.maskAlternate)Mos/Options/Options.swift— addsautoScrolloptions struct (enabled, sensitivity, dead zone, drag threshold, max speed, activation button, app exceptions, dark mode)Mos/Utils/Constants.swift— addsOPTIONS_AUTOSCROLL_DEFAULTandPANEL_IDENTIFIER.autoScrollMos/Base.lproj/Main.storyboard— adds Auto-Scroll tab to Preferences windowMos/Localizable.xcstrings— adds 13 new UI strings for auto-scroll preferencesMos/mul.lproj/Main.xcstrings— adds Auto-Scroll tab title stringPreferences
All auto-scroll behavior is configurable in Preferences → Auto-Scroll:
Notes
@_silgen_nameto call private CGS APIs for cursor shape detection (CGSGetGlobalCursorData) — this is used solely to detect whether the cursor is a pointing hand, to avoid hijacking link clicks.maskAlternateflag soScrollCorecan identify and pass them through without re-processing