← 一覧に戻る

kindle-reader

GitHub ↗ Swift 最終push: 2026/7/12 20:03

WIP(現在進行中)

Work In Progress

このプロジェクトで現在進行中の作業と、過去のスナップショットを記録する。

現在の状況

  • 「保存はできるがページ送りされない」バグを修正済み。真因は turnPage() の Kindle 検索が名前部分一致で自分自身に誤マッチしていたこと(runningApplications の並び順は無保証。Kindle 7.62 自動更新後の再起動で顕在化)。
  • 修正: kindleApp() を新設し bundle ID com.amazon.Lassen 完全一致を最優先、名前フォールバックでは自分と非通常アプリを除外。再ビルド・再インストール済み(安定署名で許可は引き継がれた)。
  • 検証: AX API 経由でメニューの「今のページを保存」を2回実行し、保存+Kindle前面化+ページ送り復活を実機確認済み。

次にやること:

  • 物理 F6 での最終動作確認(ユーザー実施待ち)。合成イベントでは Carbon ホットキーが発火せず自動検証不可だった。
  • README に自動ページ送り機能(送り方向の左右切替・アクセシビリティ権限の案内)を追記(継続)。

詰まっている点・未決事項:

  • 「鉄の本」では左矢印が表紙方向(戻る)だった。設定「左へ(縦書き・和書)」でも本によって逆走する可能性 → 症状が出たらメニューの送り方向で切替、で運用可か様子見。

過去のWIPアーカイブ

(新しい「現在の状況」を書く前に、古いものをここに追記でアーカイブする。新しいものが上)

2026-07-12 20:01 時点のスナップショット

  • メニューバー常駐アプリ「Kindle ページ保存」は実用レベルで安定。F6 単独で Kindle ウィンドウをPNG保存+(ON時)自動ページ送り。
  • 解決済みの主要ポイント:
    • 自動ページ送りの重複保存バグ(真因: ⌘⇧押しっぱなしK連打での修飾解放待ち見送り → modsClear待ち撤去・front確認のみで素矢印送出)。
    • リビルド毎に許可が外れる問題(安定した自己署名証明書「KindlePageSaver Dev」で署名。無いマシンは ./setup-signing.sh./build.sh)。
    • ファイル名連番を固定長2桁化(kindle_yyyyMMdd_HHmmssNN.png)。
    • ホットキーを F6 単独に変更。
  • すべてコミット済み(最新の F6 変更分も本セッションでコミット)。
  • 次: README に自動ページ送り機能の説明を追記。

2026-06-27 14:46 時点のスナップショット

  • メニューバー常駐アプリ「Kindle ページ保存」は一通り動作する状態。⇧⌘K で Kindle ウィンドウをPNG保存+(ON時)自動ページ送り。
  • 自動ページ送りの重複保存バグは解決済み(modsClear待ち撤去・front確認のみで素矢印送出、連続重複0)。
  • 署名問題も解決(自己署名証明書「KindlePageSaver Dev」で署名、許可が外れなくなった)。
  • 次: README に自動ページ送り機能の説明を追記。

2026-06-27 14:19 時点のスナップショット

(初期テンプレートのまま。記録なし。実体はこのセッションのDEVLOG 2026-06-27 を参照)

ROADMAP(計画)

ロードマップ

今週

  • README に自動ページ送り機能の説明を追記(送り方向の左右切替・アクセシビリティ権限の案内。現状はキャプチャ機能しか書かれていない)

今月

(今月中にやりたいこと)

今四半期

(今四半期の目標)

いつか

(いつかやりたいこと・アイデアストック)

DECISIONS(意思決定)

意思決定記録

このプロジェクトで下した重要な意思決定を記録する。 最新が上に来る。


2026-07-12: ページ送り対象のKindle検索を名前一致から bundle ID 優先へ

背景: turnPage() が「名前に kindle を含む最初の実行中アプリ」を対象にしており、自分自身(「Kindle ページ保存」)やヘルパー(「自動入力(Kindle)」)にもマッチしうる。runningApplications の並び順はOS保証がなく、Kindle 本体の自動更新後に自分自身が先頭に来て、ページ送りが無言で死んだ。

決定: bundle ID(com.amazon.Lassen)完全一致を最優先で検索し、フォールバックの名前部分一致でも自分自身と activationPolicy が .regular でないアプリを除外する。

理由: bundle ID は表示名や並び順に依存せず一意で、誤マッチの余地がない。Amazon が将来 bundle ID を変える場合に備えて名前フォールバックは残すが、既知の誤マッチ源(自分・ヘルパー)を明示的に排除する方が、名前一致の順序運任せより頑健。


2026-06-27: ホットキーを ⇧⌘K から F6 単独へ

背景: 3キー同時押し(⇧⌘K)が読書中の片手操作で面倒というユーザー要望。1キー化したいが、グローバルホットキーは普通の英字・数字キー単独にすると全アプリでその文字が打てなくなるため使えない。

決定: ファンクションキー F6 単独(修飾なし)に変更。

理由: 安全に1キー化できる現実的な候補がファンクションキーのみ。F6 は明るさ/音量/メディアの主要ハード機能と被りにくい中庸なキー。Mac ノートで素の F6 がハード機能に取られる場合は Fn+F6 か「標準ファンクションキー」設定で対応可能、外付けキーボードなら単独でそのまま効く、と割り切った。横取りはアプリ常駐中のみで終了すれば元に戻るため副作用も限定的。


2026-06-27: アプリ署名を ad-hoc から固定の自己署名証明書へ

背景: codesign --sign -(ad-hoc)だと swiftc でビルドし直すたびにバイナリのcdhashが変わり、macOSのTCCが別アプリ扱いして画面収録/アクセシビリティの許可をリセットする。結果、リビルドのたびに「トグルはONなのに許可ダイアログが出る」状態になり、開発体験が悪い。

決定: ローカルに固定の自己署名コード署名証明書「KindlePageSaver Dev」を作り、build.sh はそれで署名する(証明書が無ければ ad-hoc にフォールバック)。証明書作成は setup-signing.sh に切り出し、一回だけ実行すればよい。

理由: 同じ証明書+同じバンドルIDなら designated requirement(identifier ... and certificate leaf = H"...")が一定になり、リビルドしてもTCCの許可が引き継がれる。Apple Developer 証明書は不要で、個人開発・ローカル配布の用途には自己署名で十分。証明書の秘密鍵は keychain に置きリポジトリには含めない。


DEVLOG(作業ログ)

開発日誌

このプロジェクトでの作業を時系列で記録する。 最新のエントリが上に来る。


2026-07-12

20:01 - ページ送り不能(Kindle検索の自己マッチ)を修正

やったこと:

  • 久しぶりの使用で「保存はできるがページ送りされない」との報告。7/10 の保存分に同一サイズPNGが3連続あり、その時点で既に発生していたことを確認。
  • 診断CLIで切り分け: turnPage() の Kindle 検索(localizedName に "kindle" を含む最初の実行中アプリ)が、runningApplications の並び順次第で自分自身(「Kindle ページ保存」)にマッチしていた。現環境では自分が先頭にヒットし、自分を activate → 矢印キーがどこにも届かない状態。並び順はOS保証がなく、6月に動いていたのは偶然。7/7 の Kindle 本体自動更新(v7.62、com.amazon.Lassen)に伴う再起動で並びが変わり顕在化したと推定。
  • 修正: kindleApp() を新設。bundle ID com.amazon.Lassen 完全一致を最優先で検索し、フォールバックの名前一致でも自分自身と非通常アプリ(activationPolicy が .regular でない「自動入力(Kindle)」等のヘルパー)を除外。
  • ./install.sh で再ビルド&再インストール。安定署名のおかげで画面収録・アクセシビリティの許可は再許可なしで引き継がれた(6/27 の署名方式刷新が狙い通り機能)。
  • 検証: AX API でステータスメニューの「今のページを保存」を2回実行 → ①保存成功 ②保存後に Kindle が前面化 ③2枚のPNG内容が相違=ページ送り復活を確認。テスト用PNGは削除し、読書位置は巻頭付近に復帰させた。

気づき:

  • 合成 CGEvent の F6 では Carbon の RegisterEventHotKey が発火しなかった(物理キーでは発火する)。ホットキー経由の自動テストは不可で、AX API でメニュー項目を AXPress する方が確実。
  • 「鉄の本」では左矢印が表紙方向=戻る動きだった。設定「左へ(縦書き・和書)」でも本のメタデータ次第で逆走する可能性がある(必要ならメニューの送り方向で切替)。

次回やること:

  • 物理 F6 での最終動作確認(ユーザー実施待ち。合成イベントでは検証不可のため)。
  • README に自動ページ送り機能の説明を追記(継続)。

2026-06-27

15:22 - ファイル名連番を固定長化&ホットキーをF6単独に

やったこと:

  • 保存ファイル名の連番を固定長2桁に変更。同一秒衝突時に長さが変わる _1 形式を廃止し、1枚目から HHmmss の後ろに 01,02.. を必ず付与(例: kindle_20260627_14444401.png)。nextFileURL を修正。コミット bfce16e。
  • ホットキーを ⇧⌘K(3キー)から F6 単独(1キー)に変更。3キー押すのが面倒というユーザー要望。registerHotKey を修飾なし kVK_F6 登録に変更し、メニューのヒント表記・冒頭コメント・README のショートカット記述も F6 に更新。

気づき / 案内したこと:

  • グローバルホットキーなので普通の英字キー単独にすると全アプリでその文字が打てなくなる→不可。安全な1キー候補はファンクションキー。
  • Mac ノートだと素の F6 はハード機能(バックライト等)に割り当たっており、F6 単独で効かない場合は Fn+F6、または システム設定「F1, F2 などのキーを標準のファンクションキーとして使用」をオンにする必要がある(その場合ハード機能は Fn 側へ)。外付けフルキーボードなら F6 単独でそのまま効く。
  • ホットキーの横取りはアプリ常駐中のみ。終了すれば F6 は元の動作に戻る。

次回やること:

  • README に自動ページ送り機能(送り方向の左右切替・アクセシビリティ権限)の説明を追記(継続)。

14:46 - 重複の真因(修飾キー押しっぱなし)を特定して解消

やったこと:

  • 14:19の修正後も重複が残るとの報告。アプリにデバッグログ(保存ファイル名・送出/見送り・front/mods/待ち時間を ~/Library/Logs/KindlePageSaver.log に記録)を仕込んで実機再現。
  • ユーザーが操作パターンから真因を発見: ⌘⇧を押しっぱなしでKだけ連打すると失敗する。ログでも裏付け: TURN skip(待ち切れ): front=true mods=false =修飾キーが解放されないまま1.6秒経過して見送り→次の押下で同じページを撮り重複。
  • 原因: sendArrowWhenReadymodsClear(⌘⇧が全部離れるまで待つ)ガード。⌘⇧K hotkeyを「⌘⇧握ったままKタップ」で連打する自然な操作だと修飾が永遠に解放されず、毎回見送られていた。waited=1200ms等の「ちょっと待ってから送られる」現象も同根。
  • 修正: modsClear待ちを撤去し、front確認だけで flags=[] の矢印を送る。実機検証で、⌘⇧を物理的に握ったままでも flags=[] の矢印は素のページ送りとして正しく届き、⌘⇧→への化け(merge)は起きないことを確認(modsHeld=あり(1179648=⌘+⇧)でも全ターン送出成功・連続重複0)。
  • 検証ツール(scratchpad/turntest2)で「CGEventで合成した修飾キー押下は NSEvent.modifierFlags に反映されない=物理ホールドはスクリプトで再現不可」も判明。最終確認は実機(人の指)で実施。
  • デバッグログ一式は撤去してクリーンな本実装に。

気づき:

  • 原作者が入れていた「修飾解放待ち」は、merge懸念への過剰防御で、むしろ握りタップ操作を殺していた。flags=[] だけで物理修飾は混ざらない。

14:19 - 自動ページ送りの重複保存バグ修正+署名方式の刷新

やったこと:

  • 「⇧⌘K で保存後の自動ページ送りが効かず、同じページが繰り返し保存される」不具合を調査。 実機キャプチャ33枚中ユニークは14枚(重複率58%)と確認。
  • アプリと独立した診断ツール(scratchpad/turntest)で切り分け。「矢印送出→前後でウィンドウを撮ってmd5比較」を反復し、機械的にADVANCED/NO CHANGEを判定。
    • 結論: アクセシビリティ権限はOK・矢印は届いている。Kindleが前面なら左右矢印は確実にページを進める。失敗は「Kindleが前面になりきる前に矢印を送り、別アプリにキーが吸われる」コールド時のみ。
  • 真因: sendArrowWhenReadyguard (frontIsKindle && modsClear) || retries <= 0 が、待ち時間切れに「未前面のまま矢印を空振り送出」していた。
  • 修正(Sources/main.swift):
    • 空振り送出を廃止(前面確認できた時だけ送る/確認できなければ安全に見送る)
    • 待機中にときどき activate() を押し直す
    • frontmostApplication が activate 直後に過小報告するため isActive も併用して前面判定を堅牢化
  • 検証: 修正後、読書中の連続7枚(141810→141821)はすべて別ページでユニーク。
  • 派生問題: ad-hoc署名(codesign --sign -)だとリビルド毎にcdhashが変わり、TCC(画面収録/アクセシビリティ)が別アプリ扱いで許可をリセット→毎回許可ダイアログが出る。
    • 対策: 安定した自己署名コード署名証明書「KindlePageSaver Dev」を作成し、それで署名する方式へ変更。designated requirement が identifier ... and certificate leaf = H"273659f7..." で一定になり、リビルドしても許可が引き継がれる。
    • build.sh を証明書署名(無ければad-hocフォールバック)に変更、setup-signing.sh を新規追加(証明書をlogin keychainに作る一回限りのセットアップ。OpenSSL3対策で -legacy -macalg sha1)。
    • tccutil reset で溜まっていた stale 登録を一掃。

詰まったこと / 気づき:

  • バックグラウンド(.accessory)アプリからの kindle.activate() はコールド時に macOS のフォーカス制限で即座に通らない。待ち窓を3.2秒に伸ばしても回1は前面化せず。→ コールドの強制前面化は「不可能かつ邪魔」なので追わず、安全に見送る設計が正解。
  • 重複率58%はテスト由来のアーティファクト(IDE/ターミナルを前面にしてビルドしながらホットキーを叩いていた)で、実読書ではKindleが前面なので起きにくい。
  • p12のmacへの取り込みは OpenSSL3 の MAC 非互換でハマる → -legacy -macalg sha1 +実パスワードで解決。

次回やること:

  • READMEに自動ページ送り機能(送り方向の左右切替・アクセシビリティ権限)の説明を追記(現状未記載)。

最近のコミット

README

Kindle ページ保存

Mac の Kindle アプリを読みながら、今開いているページをホットキーひと押しで画像保存するメニューバー常駐アプリ。

  • グローバルホットキー F6 で、現在の Kindle ウィンドウだけを PNG キャプチャ
  • 保存先: ~/Pictures/KindleCaptures/kindle_日時.png
  • Dock には出ず、メニューバーに本アイコンで常駐
  • 読みながら自分のペースで一枚ずつ溜めていける

ビルド

./build.sh

build/KindlePageSaver.app ができる(Xcode GUI 不要、swiftc のみ)。

起動

open build/KindlePageSaver.app

メニューバーに本アイコンが出れば常駐成功。

/Applications にインストール

./install.sh

ビルドして /Applications/KindlePageSaver.app に配置し、起動する。 以降は Launchpad / Finder からも起動できる。安定した自己署名証明書で署名しているため、 再インストールしても画面収録/アクセシビリティの許可は引き継がれる。

初回だけ: 画面収録の許可

キャプチャには macOS の「画面収録」権限が必要。 初回キャプチャ時に許可ダイアログが出る。出ない/撮れない場合は手動で:

  1. システム設定 → プライバシーとセキュリティ → 画面収録
  2. KindlePageSaver を ON
  3. アプリを一度終了して再起動

使い方

  1. Kindle で読みたいページを開く
  2. F6 を押す(メニューバーアイコン → 「今のページを保存」でも可)
  3. 「カチッ」と鳴れば保存成功。メニューに最後の保存ファイル名と累計枚数が出る

メニューの「保存先フォルダを開く」で Finder からまとめて確認できる。

仕組み

screencapture -l<windowID> で Kindle ウィンドウ単位をキャプチャしている。 ホットキーは Carbon の RegisterEventHotKey(アクセシビリティ権限不要)。

注意

保存した画像は個人利用の範囲で。著作物の再配布はしないこと。