コンテンツにスキップ

macOS アプリのメニューバーアイコンに状態を持たせる:実装ガイド

メニューバーアプリを開発していると、アプリが今何をしているのかをユーザーにどう伝えるか、という問題に突き当たります。ただアイコンが表示されているだけでは、処理が進行中なのか、それとも待機中なのかが分かりにくいものです。かといって、派手すぎるアニメーションはユーザーの集中を妨げてしまいます。

適切なフィードバックを、さりげなく、かつ明確に伝えるためのベストプラクティスを見ていきましょう。

実装を始める前に、以下の環境が整っていることを確認してください。

  • macOS アプリのソースコード (apps/macos)
  • AppState および AppStateStore へのアクセス権限

アイコンの状態を制御するための 4 つのステップを紹介します。

1. 音声トリガー(Big Ears)の実装

Section titled “1. 音声トリガー(Big Ears)の実装”

ユーザーのウェイクワードを検知した際、アイコンの「耳」を大きくして反応を示します。インアプリの音声パイプラインから呼び出します。

// ウェイクワード検知時
AppState.triggerVoiceEars(ttl: nil)
// 1秒間の無音検知後、またはキャプチャ終了時
stopVoiceEars()

この設定により、earScale が 1.9 になり、可読性を高めるための earHoles が有効になります。

2. 実行中(Working)のアニメーション

Section titled “2. 実行中(Working)のアニメーション”

エージェントがタスクを実行している間は、アイコンに「足の動き(scurry)」を加えます。

// ワークスパンの開始と終了を制御
AppStateStore.shared.setWorking(true)
defer {
AppStateStore.shared.setWorking(false)
}

足の動き(leg wiggle)が最大 1.0 まで速くなり、わずかな水平方向の揺れが加わります。

3. アイコンのレンダリング設定

Section titled “3. アイコンのレンダリング設定”

アイコンの描画は CritterIconRenderer.makeIcon で行われます。各パラメータを調整することで、状態を表現します。

  • Idle: 通常のアニメーション(瞬きや、たまに揺れる動作)。
  • Paused: Status item に appearsDisabled を使用し、動きを停止。
  • Voice Boost: earScale=1.9 かつ earHoles=true。

アニメーションが「動きっぱなし」になるのを防ぐため、TTL は短く(10秒未満)設定することを推奨します。これにより、万が一ジョブがハングしても、アイコンはすぐに基本の状態に戻ります。

よくある問題と解決策です。

  • アニメーションが止まらない: setWorking(false) が呼ばれていない可能性があります。タスクを実行する際は、必ず defer ブロック内でリセットを行ってください。
  • アイコンのサイズが崩れる: レンダリングは 18×18 pt のテンプレート画像を使い、36×36 px の Retina バッキングストアに描画されます。フレームサイズを変更せずに、内部のスケールパラメータのみを調整してください。

さらに詳しい設定や、特定のユースケースに合わせた調整が必要な場合は、AI Setup Assistant を活用してください。

  • CritterIconRenderer の詳細な描画ロジックを確認する
  • WebChat エージェントでの setWorking 実装例を見る
OpenClaw

OpenClaw Expert

まだ解決しませんか?

このページで解決しない場合は、OpenClaw Expertに直接質問してください。