Typoraを起動するたびに
古いファイルが開く
(Saved Application Stateの不整合)

  • Typoraの「起動時に新規ファイルを開く」設定が有効なのに、古いファイルが毎回復元される現象が起きていた。
  • 原因はmacOSのSaved Application Stateという仕組みで、~/Library/Saved Application State/abnerworks.Typora.savedState/に保存されたwindows.plistが古い状態のまま固定化されていた。
  • savedStateディレクトリをまるごと削除することで解決でき、Typoraのテーマや編集設定には影響しない。

関連記事

1. 最初に疑ったこと

Typoraの設定で「起動時:新規ファイルを開く」にしているのに、以前開いていたファイルが毎回復元されていました。

最初に疑ったこと 設定:新規ファイルを開く → 古いファイルが復元される macOS Resume機能 ウインドウ状態を自動復元する仕組み 「アプリ終了時にウインドウを閉じる」 すでにオンだった → 原因ではない Typora設定 「起動時:新規ファイル」✓ macOS Resume 設定より優先されることがある 別のレイヤーを疑う → Saved Application State

この現象、まず疑ったのは macOS の Resume機能です。
Resumeとは、アプリ終了時のウインドウ状態を記録しておき、次回起動時に自動復元する仕組みで、アプリ側の設定より優先されることがあります1

ただし、システム設定の「デスクトップとDock」にある「アプリを終了するときにウインドウを閉じる」はすでにオンになっていました。

これはプロセスを維持するかどうかに関係する設定で、「起動時に古いファイルが開く」現象を説明するには不十分です2

Typora の設定は正しく、Resume の基本的な設定もオフになっていない。
それでも古いファイルが出てくるなら、別のレイヤーを疑う必要があります。

1.1. macOS Saved Application State という仕組み

macOS には、Resume の実装として Saved Application State という保存領域があります。

Saved Application State の仕組み ~/Library/Saved Application State/abnerworks.Typora.savedState/ windows.plist ウインドウ構造情報 NSRepresentedURL ← ファイルパスを記録 ★ 問題の核心 window_N.data バイナリ状態データ スクロール位置など NSWindowIDと1対1 data.data セッション補助データ 起動時:windows.plist の NSRepresentedURL を参照 → 記録されたファイルパスを開く

保存先は次のパスです3

~/Library/Saved Application State/abnerworks.Typora.savedState/Code language: JavaScript (javascript)

このディレクトリの中身は主に3種類のファイルで構成されています。

ファイル役割
windows.plistどのウインドウで何を開いていたかの構造情報
window_N.data各ウインドウのバイナリ状態(スクロール位置など)
data.dataセッション全体の補助データ

windows.plist の中に NSRepresentedURL というキーがあり、ここに「復元すべきファイルのパス」が記録されています。
Typora はこれを参照して起動時にファイルを開きます4

1.2. 対処と結果

savedState ディレクトリをまるごと削除しました。

rm -rf ~/Library/Saved\ Application\ State/abnerworks.Typora.savedStateCode language: Bash (bash)

削除後に Typora でファイルを開いて通常終了すると、windows.plistrestorecount.plist が正しく生成・更新されるようになりました。
その後の起動では古いファイルは開かなくなり、挙動が正常化しています。

削除前後の変化は次の通りです。

削除前削除後
windows.plist の内容古いファイルパスが固定終了のたびに更新される
window_19.data孤立して残存存在しない
起動時の挙動古いファイルが開く新規ファイルが開く

2. 実際にplistを読んで分かったこと

問題が発生している状態の windows.plist を確認すると、次のようなファイルパスが明示的に記録されていました。

実際に plist を読んで分かったこと windows.plist の NSRepresentedURL /Users/user/Documents/ markdown/01.mkd /Users/user/Documents/ markdown/02.mkd ← 直前ではなく、かなり前のファイル windows.plist が固定化 Typora終了時に正しく上書きできていない Orphan Data の問題 windows.plist window_N.data NSWindowID: 1 window_1.data NSWindowID: 3 window_3.data window_19.data ? 対応するIDなし = 孤立データ orphan data 不整合が蓄積した状態
/Users/user/Documents/markdown/01.mkd
/Users/user/Documents/markdown/02.mkd

これらは直前のセッションのファイルではなく、かなり前に開いていたものです。
windows.plist の内容が古いまま固定化されており、Typora が終了するたびに正しく上書きできていない状態でした。

さらに気になったのが window_19.data の存在です。
通常、windows.plist に記載された NSWindowIDwindow_N.data は1対1で対応します。
しかし今回は window_19.data が残存しており、現在のウインドウ構成と対応しない孤立データ、いわゆる orphan data になっていた可能性があります5

2.1. なぜ「だいぶ前」のファイルが開くのか

Saved Application State は、差分更新ではなくある時点の状態をそのまま保持する設計です。

windows.plist への書き込みを行うのは Typora ではなく、macOS の AppKit フレームワークと talagent というバックグラウンドエージェントです6
Typora は終了時に AppKit へ正しい終了シグナルを渡す役割を持ち、AppKit がそれを受けて savedState を更新します。

Typora がクラッシュや強制終了した場合、このシグナルが伝わりません。
AppKit は古い状態を保持したまま終了し、次回起動時にそれを復元します。
「だいぶ前のファイルが開く」のは、その古い状態が固定化されていたためだと考えられます。

不整合を生んだきっかけは Typora の異常終了であり、古いデータを保持し続けたのは macOS の仕組みという、両方が絡んでいます。
Typora の公式トラブルシューティングでも savedState の手動削除が推奨されており、開発者側もこの挙動を認識しています7

3. まとめ

今回の現象は、Typora の異常終了をきっかけに macOS の Saved Application State が古い状態のまま固定化されたことで起きていました。
書き込みの主体は macOS 側ですが、正しい終了シグナルを渡せなかった Typora も無関係ではありません。
設定は正しかったのに症状が出ていた理由は、そういう構造にあります。

同様の症状が出た場合は、~/Library/Saved Application State/abnerworks.Typora.savedState の中身を確認し、内容が古ければディレクトリごと削除してください。
削除しても Typora の設定には影響しません。
テーマや編集設定は ~/Library/Application Support/Typora に別途保存されています。

  1. Resume機能は Mac OS X 10.7(Lion)で導入されました。内部的には TAL(Transparent App Lifecycle)という名称で、「ユーザーがアプリの起動・終了を意識しなくて済む」というコンセプトに由来します。 – Archaeology | Saved Application State
  2. Typora 公式の Auto Save ドキュメントでは「ウインドウを復元したい場合はこの設定をオフにする」と説明されています。つまりこの設定はウインドウ復元の有効化に使うものであり、すでにオンの状態では savedState の内容に関係しません。 – Auto Save – Typora Support
  3. macOS 15(Sequoia)以降、savedState の管理は talagentd という新しいデーモンに移行し、保存先も ~/Library/Daemon Containers 配下に変わっています。Sequoia 環境では Terminal にフルディスクアクセスを付与しないとアクセスできない場合があります。 – Archaeology | Saved Application State
  4. windows.plist への書き込みは AppKit.framework と talagent が行います。アプリ側が直接このファイルを操作するわけではなく、AppKit の API を通じて状態を渡す設計になっています。 – Archaeology | Saved Application State
  5. data.data は差分追記される設計のため、古いレコードが上書きされず残存することがあります。talagent がある時点でファイルを書き直すことはありますが、タイミングは保証されていません。 – Archaeology | Saved Application State
  6. talagent は TAL(Transparent App Lifecycle)の略で、macOS のウインドウ状態の保存・復元を担うシステムエージェントです。man page にも記載されており、アプリとは独立して動作します。 – talagent(8) man page
  7. Typora 公式サポートでは「クラッシュ後に前のファイルが再度開かれるのを防ぐために、savedState ディレクトリを手動で削除してほしい」と明記されています。 – Trouble Shooting – Typora Support