fix: Ctrlキーの組み合わせを適切に処理できるように修正#324
Merged
Merged
Conversation
Contributor
Author
|
すみません、もう1つ直さなければならない箇所を見つけたので、一旦draftにさせていただきます。少々お待ちください! |
- InputState.composing/previewing/selecting/replaceSuggestionの`.unknown`分岐を分離 - Ctrl修飾を含むイベントは`.consume`を返してmarked textを保護する - それ以外の`.unknown`は従来通り`.fallthrough`させてホストアプリに委譲する - ControlShortcutRoutingTestsにcomposing系状態でのconsume確認とnone状態のfallthrough確認を追加
amatsus
reviewed
May 8, 2026
Contributor
Author
#310 に言及しているこのコメントですが、このPRのスコープ以外の修正も必要そうなので、別のPRで出そうと思います。後ほどよろしくお願いします。 |
Contributor
Author
|
不具合例として挙げていただいた、Discodeでの入力中に ScreenShot.2026-05-09.0.53.18.mov |
Contributor
Author
|
@ensan-hcl |
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.
概要・背景
PR #310 では未定義のCtrl系キーをIMEで処理しないようにしましたが、処理が不十分で一部のCtrlの組み合わせの入力に影響が出てしまいました。
このPRでは、既知のCtrlショートカットをlogicalKey側で処理した後、未定義のCtrl系キーをkeyCodeでの処理へ落とさず 早期に
.unknownで返すことで、ホストアプリ側へ渡すようにして、アプリのショートカットが適切に動作するように修正します。加えて、composing中(変換中の入力がある状態)に未定義のCtrl修飾付きキー(例:
Ctrl+Shift+O)が発火されると、Discordなどの一部アプリで変換中の入力が消失する問題があったため、composing系状態ではIME側で.consumeして入力を保護します。関連Issue
Related to #310
変更内容
.unknownに分類Ctrl+Deleteは既存仕様の.forgetとして維持Ctrl+数字が数字入力として扱われないよう、数字キー分岐でも.controlを明示的に除外InputStateの composing / previewing / selecting / replaceSuggestion で.unknown分岐を分離し、Ctrl修飾を含む場合は.consumeを返して入力テキストを保護.unknownのfallthrough/consumeを検証するテストを追加詳細
処理の流れ
変更前は、
UserAction.getUserActionの処理が大きく次の流れになっていました。charactersIgnoringModifiersから logicalKey を取得するcontrol修飾を含む未定義キーを.unknownにする)keyCodeブロックで Space / Delete / 矢印 / 数字などの物理キーを判定する.inputとして扱うこの構造では、
control修飾を含む未定義キーの判定が logicalKey ブロック内にありました。変更後は、処理の流れを次のように整理しています。
charactersIgnoringModifiersから logicalKey を取得するCtrl+H,Ctrl+J,Ctrl+;,Ctrl+Shift+Uなどを処理するcontrol修飾付きキーを、keyCodeブロックへ入る前に.unknownにする(ただしCtrl+Deleteは既存仕様の.forgetとして扱うため、4へ通す)control修飾を含まない通常キーをkeyCodeブロックで処理する.inputとして扱うこれにより、既存の
logicalKey -> keyCode -> fallbackという大枠は維持しつつ、未定義のcontrol系キーがkeyCode処理へ落ちないようにしています。発生していた問題と解決方法
Ctrl + Deleteが動作しなくなっていた1つ目は、
control修飾付きキーを logicalKey ブロック内でまとめて.unknownにしていたため、後続のkeyCodeブロックにあるCtrl+Deleteの処理まで到達できなくなったことです。Ctrl+Deleteは既存仕様として.forgetに対応していましたが、logicalKey ブロックで先に.unknownになってしまうと、下記の Delete 分岐へ到達できていませんでした。このPRでは、明示的に
Ctrl + Deleteを分岐で扱うことで修正しました。一部の
Ctrl +系のキーが適切に処理されていなかった2つ目は、
charactersIgnoringModifiersが取得できないキーや、logicalKey ブロックで処理されずにkeyCode側で処理されるキーでは、未定義のcontrol系キーがSpace、矢印、数字などとして処理される可能性が残っていたことです。例えば以下のようなケースです。
Ctrl+Space.spaceとして処理され、スペース入力や変換操作になるCtrl+Left.navigation(.left)として azooKey 側で消費されるCtrl+1.number(.one)として処理されるCtrl+Shift+O.inputや.unknownの扱いが処理位置に依存する今回の修正では、まず logicalKey ブロックで azooKey が明示的に対応している
control系ショートカットだけを処理します。その後、keyCodeブロックに入る前に、未定義のcontrol系キーを.unknownとして返します。これにより、
Ctrl+Space、Ctrl+Left、Ctrl+数字などがkeyCode処理へ落ちず、ホストアプリへ fallthrough されるようになります。さらに、数字キー分岐でも
.controlを明示的に除外しています。変換中にCtrl系が入力されるとテキストが破棄されてしまった
3つ目は、composing中(変換中の入力がある状態)に未定義のCtrl修飾付きキー(例:
Ctrl+Shift+O)が押されたとき、.unknownがホストアプリへ fallthrough される過程で、Discordなどの一部アプリがテキストを破棄してしまい、変換中の入力が消失する問題です。UserAction側で.unknownに分類してホストへ委譲する方針を維持しつつも、composing系状態では入力を保護したいので、InputStateのcomposing/previewing/selecting/replaceSuggestionの各状態で.unknown分岐を他のケースから分離し、.control修飾を含むイベントは.consumeを返すようにしました。これにより、
.unknownが来た場合: IME側で.consumeして変換文字列を保持.none状態でCtrl修飾付きの.unknownが来た場合: 従来通り.fallthroughしてアプリ側のショートカットを発火.unknownが来た場合: 従来通り.fallthroughという動作になります。
追加したテスト
Ctrl+`.unknownCtrl+Shift+O.unknownCtrl+0〜Ctrl+9.unknownCtrl+Space.unknown.spaceとして処理されず、ホストアプリへ渡ることを確認Ctrl+Left.unknown.navigation(.left)として消費されないことを確認Ctrl+Delete.forgetCtrl+H.backspaceCtrl+J.function(.six)Ctrl+;.function(.eight)Ctrl+Shift+U.startUnicodeInput.unknowninInputState.none.fallthroughCtrl+`/Ctrl+Shift+Oincomposing/previewing/selecting/replaceSuggestion.consume.unknownがIME側で消費されmarked textを保護することを確認Ctrl+Shift+OinInputState.none.fallthrough.unknowninInputState.composing.fallthrough.unknownは従来通りfallthroughされることを確認(既存挙動の回帰防止)テスト方法
swift test --package-path Core