Repository navigation
fix: 한→영 전환·ABC 입력 소스, 웹 편집기 목록 분리, 입력 소스 중복 수정 - #2
Open
calvinjkim wants to merge 13 commits into
Open
calvinjkim wants to merge 13 commits into
calvinjkim wants to merge 13 commits into
Conversation
Stop treating empty cursor context as a sentence start after a Korean-to-English switch, and stop requesting a disabled ABC layout on every focus change. Co-authored-by: Cursor <cursoragent@cursor.com>
Web hosts were ending composition on the first choseong, and TIS minted extra PriType rows when the Korean mode id matched the bundle id and Hang+Latn were both advertised. Co-authored-by: Cursor <cursoragent@cursor.com>
…ive minted Korean.
A new ad-hoc id never appears in Settings, migrating …v2.v2.korean can steal Hangul from 2-Set, and first-mark {caret,0} plus activateServer adapter rebuilds split web compositions.
Co-authored-by: Cursor <cursoragent@cursor.com>
The marked-text path ends a composition on every Hangul syllable. In a ProseMirror editor (Confluence) an empty block reconciles that composition end into two blocks, so the first syllable of a line was orphaned and the rest restarted in a new block: 라이브 arrived as 랑 + newline + 라이브. On-device logs showed the host caret drifting +2 at that commit, and the same input was clean in Chromium and under Apple's own Korean IME. Exempt WebKit browsers from the direct-insertion denial. That denial's evidence was gathered on Electron/Chromium, which report selection asynchronously; WebKit does not. Direct insertion never ends a composition, so ProseMirror has nothing to reconcile. Safari stays a web-content host, Blink and Gecko stay denied, and the adapter's caret guard still degrades to marked text when the host reports an unusable selection. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Raw U+1100 jamo exists to keep a MARKED composition open in web editors past the first choseong. A host composing by direct insertion has no composition: the jamo is written into the document as real text and survives the rewrite. Typing 사파이어메모 inside existing text in Safari left a bare ᄉ (U+1109) at the caret. Gate it on the delivery mode rather than on being a web host. Chromium, Electron and Atlassian wrappers still compose via marked text and keep it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…write.
The adapter read only selectedRange().location and discarded the length.
Safari reports a whole-field range such as {0, 42} during composition, which
read as "caret at 0", so the in-place rewrite landed at the start of the
field: typing 글자밀어넣기 mid-text duplicated 기 at position 0.
A composition's selection is always collapsed, so a non-zero length means the
host handed us a range and not a caret. Bail to marked text there, the same
degradation the adapter already uses for an unreadable selection.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…cond relaunch. ditto merges: a file the build no longer produces stays in the installed bundle forever. PriType_PriTypeCore.bundle moved to a Contents/ layout and the old flat copy survived, so codesign reported "a sealed resource is missing or invalid". A broken seal voids the TCC match against the signing identity, which is what makes an Accessibility grant survive a rebuild. Stage beside the destination and rename, so it holds exactly the new bundle and is missing only for the rename rather than for the whole copy. Drop the IME from the second killall. It was already killed above; killing it again makes macOS relaunch it twice, and each launch without a grant opens its own Settings pane, so installing asked for Accessibility two times. Add --debug, which builds and installs the debug configuration. DebugLogger is compiled out of release builds, so a release install records nothing when an input bug needs tracing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…teals one. modifierMask maps the left and right key of a modifier to the same CGEventFlags bit, so releasing the bound key while the other side is held never cleared toggleModifierIsDown: hold Left Command, tap Right Command, release both, and every later key event lost its Command — Cmd+C inserted a literal "c" until the toggle key was pressed again. Read press and release from the device-dependent NX_DEVICE*KEYMASK bits, which name one physical key, and strip both bits when passing a key through. The hanja binding had the same defect. The recorder also accepted a bare printable key. Since the tap consumes the bound key system-wide, binding Space stopped the space bar everywhere including in the settings window, so nothing short of `defaults write` could undo it. Reject those at capture time with a visible reason, and repair an already-saved one on read: a user who bound Space cannot type a space to fix it. A modifier key alone, a regular key with a modifier, and a bare function key all still work. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… type. DirectInsertionAdapter can degrade to marked text mid-session and stays the same object, so three decisions keyed off its type or its host's id were wrong after that happened. finalize skipped re-inserting the syllable because direct insertion writes it as real text. After a fallback it had not: the syllable was only in the host's marked range, the host dropped that on focus loss, and the typed character was gone. Bailing also forgot the real text it had already written and drew the same syllable again as marked text, so the host kept both; remove it first, using our own record of where the write landed rather than the selection that just proved unusable. Raw conjoining jamo is a marked-text device — under direct insertion it is left in the document as real text. It was gated on the bundle id, which gets both sides wrong: a host configured for direct insertion still composes with marked text when the activation probe failed or the adapter degraded, and needs the jamo then. Take the mode from the adapter in use. Also make a combo binding match its modifiers exactly. The subset test meant Control+Space swallowed Control+Command+Space, so the Emoji picker never opened. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…t rects. Launch and the Settings accessibility check each wired the toggle handlers separately, and only launch registered onTapFailed — a tap armed from Settings therefore ran with no IOKit fallback and died silently when the system disabled it. Move the wiring into KeyMonitoring and call it from both. Arming is idempotent, so activateServer can re-arm: granting Accessibility more than two minutes after launch used to leave the toggle key dead for the whole session while Settings showed it as granted, because the startup poll had already given up and nothing else started the tap. capsLockInputSourceSwitchEnabled hit cfprefsd on every event-tap and HID callback while the key bindings beside it were memoized for exactly that reason. Hold the answer for a second: a slow lookup there pushes the tap past its deadline, and three of those disable it for good. The caret-rect filter required positive coordinates, so a display arranged left of or below the primary — where screen coordinates are negative — had its valid rects thrown away and the Hanja window opened on the wrong monitor. Compare magnitude instead; the filter is for denormals like 1.6e-314, and the sign only says which display. Drop the recorder branch in the event tap. Nothing ever set isRecordingKey: the settings recorder uses an NSEvent local monitor, which sits behind the tap. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Typing into the middle of existing text lost the character right after the caret, the moment the syllable completed — reproducibly in Slack, Claude and Chrome, and never in Notes or in Safari. The one thing those three share is the conjoining U+1100 preedit: Notes never used it, and Safari stopped when it moved to direct insertion. A space after the caret survived, because a space cannot combine with a jamo. That is what conjoining jamo are defined to do. They were introduced so a web editor would not read the lone first consonant as a finished letter and commit it into its own ProseMirror block, splitting a list item. That split is real, but it needs an empty block and one editor; this loses a character during ordinary mid-text typing in every Blink host. Route every preedit through CompositionHelpers.preeditString, which hands the host the standalone compatibility letter that combines with nothing. The block split may return in Blink hosts as a result. Safari, where Confluence is actually used here, composes by direct insertion and is unaffected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…character." This reverts commit ed91325.
…t does not carry. main's toggle-key rework overlaps this branch. Where it is the better change it wins outright: ToggleKeyMonitor replaces the KeyMonitoring helper added here — it solves the same missing-onTapFailed defect and additionally stops the tap before handing over to IOKit, which this branch did not — and removing the TISRomanSwitchState gate entirely supersedes the one-second cache added here, since the callers on the keystroke path are gone. Two defects survived that refactor and are re-applied on top of it: - KeyBinding.modifierFlagMask still maps the left and right key of a modifier to one CGEventFlags bit, so the classifier could not tell the bound key's release from the other side still being held. Added deviceModifierFlagMask (NX_DEVICE*KEYMASK) and detect presses through it; strip both bits, since leaving the device bit behind still reads as right Command. The upstream classifier tests represented a press with the shared bit alone — real events carry both, so the fixtures now do too. - hasRequiredModifiers was a subset test, so Control+Space also matched Control+Command+Space and swallowed the Emoji picker. Compare the bindable modifier bits exactly. Also kept from this branch: the two-minute cap on the launch permission poll, which main's version dropped; the bare-key binding guard; and the removal of the dead isRecordingKey branch, which the rewrite reintroduced. Co-Authored-By: Claude Opus 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.
한→영 전환 직후 영어 입력이 깨지던 문제, 웹 편집기에서 한글 조합이 목록을 쪼개던 문제, 설정에 입력 소스가 중복으로 뜨던 문제를 고쳤습니다.
배경과 목적
전환 직후 첫 로마자가 대문자로 들어가고, 꺼 둔 ABC 입력 소스가 되살아나고, Confluence 같은 웹 편집기에서 한 글자가 목록 항목을 갈라놓는 문제가 있었습니다. 공식 PriType 배포와 섞이지 않게 개인 포크의 로컬 overlay 설치 방식으로 이어갑니다.
변경 요약
검증 상태
릴리즈 빌드 성공, 테스트 195개(28개 스위트) 전부 통과했습니다. 실제 IME 동작 확인은
미확인— 설치 후 한/영 전환과 웹 편집기 입력을 직접 확인해야 합니다.설치 주의: 서명 인증서가 없어 ad-hoc 서명으로 떨어지므로, 설치할 때마다
시스템 설정 > 개인정보 보호 및 보안 > 손쉬운 사용에서 권한을 껐다 켜야 우측 Command 전환키가 동작합니다.참고 링크
🤖 Generated with Claude Code