Skip to content

feat(indicator): add option to always display the indicator near the mouse cursor - #132

Merged
runjuu merged 2 commits into
runjuu:mainfrom
gum798:feature/follow-mouse-indicator
Sep 8, 2026
Merged

feat(indicator): add option to always display the indicator near the mouse cursor#132
runjuu merged 2 commits into
runjuu:mainfrom
gum798:feature/follow-mouse-indicator

Conversation

@gum798

@gum798 gum798 commented Sep 3, 2026

Copy link
Copy Markdown

Purpose

Add an opt-in way to keep the input source indicator always visible and glued to the mouse pointer, the way Windows' IME badge follows the cursor. Today the indicator either pops up briefly on app / input-source changes, or (with Enhanced Mode) stays near the text caret. Users who want to glance at the current input source at any time, without Accessibility permission, had no option.

Loosely related to #61, which asks about positioning the always-on dot, though that one is about the text caret.

follow-mouse demo

What changes

  • New setting "Always Display Indicator Near the Mouse Cursor" under Position, shown only while Follow Mouse is selected (it is a sub-option of that mode). Default off.
  • While on:
    • the indicator stays visible and tracks the pointer in real time (global + local NSEvent mouse monitors, throttled to ~60 Hz); it appears immediately when the toggle is switched on and disappears immediately when switched off;
    • it needs no Accessibility / Enhanced Mode;
    • it shows the current input source, and the function-key badge for one second after a toggle, like the transient indicator does;
    • it re-renders when indicator style, size or per-keyboard colours change in Settings;
    • it hides for apps / sites with a "Hide Indicator" rule;
    • it is re-ordered front on Space changes so it follows across Spaces;
    • the text-caret options under Advanced are greyed out since they do not apply.
  • The activate-event pipeline stays idle while the mode is on, so nothing else moves or hides the indicator.
  • IndicatorPosition.pointNearMouse extracts the near-mouse geometry (offset + screen clamping) that the existing one-shot Follow Mouse placement used, so both paths share it. Covered by new unit tests.
  • NSEvent.watch no longer force-unwraps the monitor on teardown.
  • Preference is wired through settings backup / restore; strings added for en, ja, ko, zh-Hans, zh-Hant.

position settings

Testing

  • xcodebuild -scheme "Input Source Pro" -configuration Debug test: 55 tests pass (4 new in IndicatorNearMousePointTests).
  • Manually on macOS 26.5 (Xcode 26.6), with an ad-hoc signed build that has no Accessibility permission:
    • indicator tracks the pointer at the 12 pt offset on every move; clamps at screen edges and on a secondary display;
    • toggle on shows it immediately, toggle off hides it immediately;
    • switching ABC ↔ 2-Set Korean updates the content in place (verified with screenshots after each switch);
    • with the option off, the transient indicator behaves exactly as before (appears on switch, gone after ~1 s);
    • CPU stays under ~8 % while sweeping the pointer at 100 Hz, 0 % when idle.

Notes for review

  • Turning the option off re-subscribes the shared activate-event stream, which replays the current app once, so the normal indicator shows for one second, the same thing that happens at launch and after unlock. Left as is; suppressing it would change that existing behaviour or leave in-flight timers fighting the pinned indicator.
  • The two Advanced toggles keep their stored values; they are only disabled while this mode is effective.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PYfrZ8oYRfkLjVXUBF5BHA

서정화 and others added 2 commits September 3, 2026 17:52
…mouse cursor

Add an opt-in "Always Display Indicator Near the Mouse Cursor" setting under
the "Follow Mouse" position mode. While it is on, the indicator stays visible
and tracks the pointer in real time instead of appearing only on app or input
source changes. It needs no Accessibility permission: pointer movement comes
from global and local NSEvent monitors throttled to ~60 Hz, and the panel is
re-ordered front on Space changes so it follows across Spaces.

The mode owns the indicator through a dedicated pipeline that renders the
current input source (and the function-key badge for a second), hides it for
apps with a "hide indicator" rule, and re-renders when indicator style or
per-keyboard colours change. The activate-event pipeline stays idle while the
mode is on, and the text-caret options under Advanced are disabled since they
do not apply.

Extracts the near-mouse geometry into IndicatorPosition.pointNearMouse so the
one-shot "Follow Mouse" placement and the new mode share it, and covers it
with unit tests. Also guards NSEvent.watch against a nil monitor on teardown,
wires the preference through settings backup/restore, and adds localization
for en, ja, ko, zh-Hans and zh-Hant.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PYfrZ8oYRfkLjVXUBF5BHA
@runjuu
runjuu merged commit 80c8fe2 into runjuu:main Sep 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants