動かざることバグの如し

近づきたいよ 君の理想に

azooKeyでシフトキー押下時の英字モード継続機能を実装した

環境

  • azooKey on macOS v0.1.3

やりたいこと

azooKey on macOSが大変良い。というかMacOS標準日本語入力とGoogle日本語入力がゴミだというのがある。 特にGoogle日本語入力は年を重ねるごとに変換精度がドンドン劣化していってる気がする。自分は学習履歴を残さないタイプなので変に学習されているとかでもない。

その点azooKey on macOSは変換の候補が他アプリに比べて極めて良好だしATOKとかと違って無料。

ただしそんな神アプリのazooKey on macOSでも不満点は1つだけある。「シフトキー押下時の英字モード継続機能」である。

具体的には「Apple」と入力したい場合、

  • シフトキーを押しながら「a」を入力、シフトキーを離して「p」「p」「l」「e」「エンター」と入力する→「Apple」となる

と入力している。しかしazooKeyでは最初の押している間しか有効にならないので「Aっpぇ」となってしまう。

これはすでに要望で出されているが受け入れられていない。

github.com

スレッドにもある通り、MacOS標準やGoogle日本語入力ATOKでもデフォルトで入力可能な方式にもかかわらず、「シフト入力がシフトから手を離した後も持続的に影響を与える振る舞いは非直感的である」という哲学と「機能としてあまり知られておらず、実装コストに見合わない」という理由で一蹴されている。

まあエンジニア思考的には入力後も状態を持ち続けているのは例外かもしれないけど、他入力アプリでできるんだったらそれは標準なんじゃないのかと正直思ってる。がしかし実装される見込みはないだろう。

幸いにもazooKeyはオープンソースソースコードが公開されている。であれば自分で実装してしまえ、ということで実装した。

実装

Swiftのコードは1行も書いたことがないのでAIにやらせるしかない。指示するプロンプトは以下にした。

Macosで動作する日本語入力システムアプリです。
macOS標準の日本語入力やGoogle日本語入力のように、シフトキーを押した際に、「英字モードに入る」を実装してください。変換中のように下線が表示され、エンターキーを押すと確定されてモードが終了します。
フォークして自分用にビルドするのでデフォルトの挙動で設定やフラグの切り替えは不要です。こういう仕様で良いです。日本語のコメントをコード内に書いてください。
ビルド、テストは実行しなくていいです。

### 現在

- 「a」「p」「p」「l」「e」と入力する→「あっpぇ」となる
- シフトキーをずっと押しながら「a」「p」「p」「l」「e」と入力する→「APPLE」となる
- シフトキーを押しながら「a」を入力、シフトキーを離して「p」「p」「l」「e」と入力する→「Aっpぇ」となる

### 要望

- 「a」「p」「p」「l」「e」と入力する→「あっpぇ」となる
- シフトキーをずっと押しながら「a」「p」「p」「l」「e」と入力する→「APPLE」となる
- シフトキーを押しながら「a」を入力、シフトキーを離して「p」「p」「l」「e」「エンター」と入力する→「Apple」となる(AppleのAは半角大文字、ppleは全て半角小文字)
- シフトキーを押しながら「a」を入力、シフトキーを離して「p」「p」「l」「e」「スペースキー」「シフトキー押しながらl」「o」「v」「e」「エンター」と入力する→「Apple Love」となる

実装結果

結論、以下の実装でできるようになった。実装したのはcodexでモデルは「gpt-5.1-codex-max」のExtra highである。1発成功

github.com

ガチャだったのかもしれないが「gpt-5.2-codex xhigh」とopencodeの「Opus 4.6」では実装はしたがビルドエラーになってしまった。(多分実装も失敗しているだろう)

ビルド

git cloneするときに--recursive 必要なので注意

git clone git@github.com:thr3a/azooKey-Desktop.git azooKey-Desktop-forked --recursive
git submodule update --init

またハマった点がREADMEにも書いてあるようにgit LFSが必須である。git LFS未対応だとファイルは存在するが明らかにファイルサイズが小さい。 ビルドには成功してしまうので確かに気づきにくかった。

❯ ls -lh azooKeyMac/Resources/zenz-v3.1-small-gguf/ggml-model-Q5_K_M.gguf
-rw-r--r--@ 1 thr3a  staff   133B Feb 14 14:46 azooKeyMac/Resources/zenz-v3.1-small-gguf/ggml-model-Q5_K_M.gguf

既存のazooKeyのアンインストールコマンドは以下

sudo rm -rf /Library/Input\ Methods/azooKeyMac.app
pkill azooKeyMac

手元の環境で毎回ビルドしていると環境が壊れた時辛いのでGitHub Actionsでパッケージを作るようにした。

name: Build DMG

on:
  push:
  pull_request:

jobs:
  build-dmg:
    name: Build and Upload DMG
    runs-on: macos-15
    steps:
      - name: Select Xcode 16.3
        run: |
          XCODE_PATH=$(ls -d /Applications/Xcode_16.3*.app | head -n 1)
          echo "Using Xcode at $XCODE_PATH"
          sudo xcode-select -s "$XCODE_PATH/Contents/Developer"
          xcodebuild -version

      - uses: actions/checkout@v4
        with:
          submodules: true

      - name: Archive
        run: |
          set -euo pipefail
          xcodebuild \
            archive \
            -project azooKeyMac.xcodeproj \
            -scheme azooKeyMac \
            -configuration Release \
            -archivePath build/archive.xcarchive \
            -destination 'generic/platform=macOS' \
            CODE_SIGNING_ALLOWED=NO \
            CODE_SIGNING_REQUIRED=NO \
            CODE_SIGN_IDENTITY=""
          ls -la build/archive.xcarchive/Products/Applications

      - name: Extract .app from archive
        run: |
          mkdir -p build/app
          ditto build/archive.xcarchive/Products/Applications/azooKeyMac.app build/app/azooKeyMac.app

      - name: Create DMG
        run: |
          APP_NAME="azooKeyMac"
          DMG_NAME="${APP_NAME}.dmg"
          TEMP_DMG="temp.dmg"
          
          # Create temporary DMG
          hdiutil create -srcfolder build/app -volname "${APP_NAME}" -fs HFS+ -format UDRW -size 100m "${TEMP_DMG}"
          
          # Attach and configure
          DEVICE=$(hdiutil attach -readwrite -noverify "${TEMP_DMG}" | grep "Apple_HFS" | awk '{print $1}')
          
          # Optional: Set window properties
          osascript -e "tell application \"Finder\" to set bounds of window \"${APP_NAME}\" to {100, 100, 600, 400}" || true
          osascript -e "tell application \"Finder\" to set icon size of icon view options of window \"${APP_NAME}\" to 128" || true
          
          # Detach
          hdiutil detach "${DEVICE}"
          
          # Convert to compressed read-only DMG
          hdiutil convert "${TEMP_DMG}" -format UDZO -o "${DMG_NAME}"
          
          # Clean up
          rm "${TEMP_DMG}"
          
          echo "Created ${DMG_NAME}"
          ls -lh "${DMG_NAME}"

      - name: Upload DMG Artifact
        uses: actions/upload-artifact@v4
        with:
          name: azooKeyMac-dmg
          path: azooKeyMac.dmg
          if-no-files-found: error

CIに成功したらArtifactsにpkgファイルが作成されているはず。

https://github.com/thr3a/azooKey-Desktop/actions/runs/22014997596

最後に、azooKeyという素晴らしい日本語入力システムをオープンソースという形で開発・公開してくださっている作者には感謝しかない。