本記事は、
ブログ
Objective-C
Objective-C を 使用して Electron アプリで MacOS の アクティブウィンドウを 追跡する
この
執筆者
Gáspár Balázsi
(ChatGPT
最終更新日
MAR 02, 2026
トピック
#dev
所要時間
7 min read
背景
Electron アプリケーション内で MacOS のネイティブコード(Objective-C)を使用して、アクティブウィンドウの追跡機能を実装し、NAPI を介して Electron アプリにバインドします。これは、ユーザーが一つのウィンドウから別のウィンドウに切り替えるたびに、ネイティブ側から常にアプリに通知することを意味します。ユーザーがウィンドウ間でどのように切り替えるか(例:CMD + Tab、一つのアプリから別のアプリにクリックで切り替えるなど)に関係なく、このチュートリアルの終わりには、Javascript の世界でアクティブウィンドウの ID を取得できるようになります。後でウィンドウ ID を使用し、スクリーンレコーディングを行うなどのことも可能ですが、それはこのチュートリアルの範囲外です。
<br />カバーする内容:
- electron-react-boilerplateを使用して Electron アプリを作成します(すでに既存の Electron アプリがある場合は、それを出発点として使用しても構いません)。執筆時点での Electron のバージョンは
v20.0.2です。 - ネイティブコードを書きます。
- 必要なファイルを作成します(
activeWindowObserver.h、activeWindowObserver.mm、nativeWindows.mm) activeWindowObserver.hを書きますactiveWindowObserver.mmを実装しますnativeWindows.mmを実装します
electron-rebuildでビルドスクリプトをセットアップします。- ネイティブコードのための Typescript ラッパーを作成します。
mainJavascript プロセスからそれを呼び出し、結果をコンソールにログします。
前提条件:
- アプリは
Accessibility権限が必要ですので、ターミナルから実行する場合は、ターミナルにAccessibility権限を付与し、後でスタンドアロンアプリとしてビルドする場合は、アプリに付与してください。
VSCode のターミナルから実行する場合は、VSCode に権限が与えられていることを確認してください。これは、ターミナルを生成するオーナープロセスとして VSCode が機能するためです。他の統合ターミナルにも同様のことが適用されます。
- ある程度、Typescript と Electron に精通していることが前提となります。
1. Electron のボイラープレートを作成する
あなたは基本的な Electron のボイラープレートを持っており、そのフォルダのルートに位置しているはずです。
2. ネイティブコードを書く
NAPI をインストール
このチュートリアルでは、ObjectiveC++コードを Node にバインドするためにnode-addon-apiを使用します。このチュートリアルではv4.3.0を使用します。すぐにビルドのための必要なファイルを作成しますが、設定について詳しく読みたい場合は、GitHub で読むことが可能です。
ネイティブモジュールのフォルダ構造を作成する
私たちのモジュールはnative-windowsと呼び、その中にmacosフォルダを作成します。これは、Windows にも拡張する可能性があるためです。
NAPI をセットアップする
src/native-modules/native-windowsに、以下の内容でbinding.gypという名前のファイルを作成します:
.gypファイルは基本的に、ObjectiveC++プログラムをコンパイルするために使用される Makefiles を生成するための JSON ファイルです。これはnode-gypによって消費され、これは私たちが使用するビルドツールです。私たちのアプリは MacOS でビルドされると想定しています。MacOS 特有の API を使用するためには Cocoa フレームワークが必要になります。Node-gyp は、モジュールのバインディングを含む.nodeファイルを私たちのObjectiveC++ソースコードからコンパイルし、それをjsファイルにインポートすることができます。
また、以下の内容でここにpackage.jsonファイルを追加します:
このファイルは基本的に、このモジュールが NodeJS にバインドするC++モジュールであることを示しています。
必要なファイルを作成する
src/native-modules/native-windows/macosフォルダに、activeWindowObserver.h、activeWindowObserver.mm、およびnativeWindows.mmファイルを作成します。
.hファイルはヘッダーファイルです。C++に慣れていない場合は、.hファイルをインターフェースと考え、この場合.mmファイルで実装されているものを定義するものと考えてください。
activeWindowObserver.mmは、.hファイルで定義されているものの実装を含んでいます。.mm拡張子はObjectiveC++ための特有なものです。
nativeWindows.mmファイルには、JS からモジュールを使用できるようにするバインディングが含まれています。
activeWindowObserver.hを書く
activeWindowObserver.mmを実装する
上記コードの説明:
windowChangedCallbackは、同じアプリケーションに属するウィンドウ間の変更を追跡するために使用されます。「なぜ 30ms の遅延が最前面のウィンドウを再度フェッチする前にあるのか」と疑問に思うかもしれません。遅延なしでは、常に前の状態の順序でウィンドウを取得するため、実際にユーザーが見ているものよりも常に 1 ステップ遅れていました。おそらくこれは、使用している API の同期の欠如によるものですが、これは単なる推測です。しかし、これがバグかもしれないため、この奇妙な動作について Apple に問題を報告しました。この問題の今後に興味がある場合は、次のリンクで追跡できます:Apple フォーラムdeallocは、オブザーバーを削除するために使用されますinitでは、アプリケーション間の変更を確認するために、共有ワークスペースの通知センターにオブザーバーを追加しますreceiveAppChangeNotificationは、init でアタッチされたハンドラー自体です。このハンドラーで、同じアプリケーションに属するウィンドウの変更を購読する別のオブザーバーを定義します(windowChangeCallback)。getActiveWindowは、最前面のウィンドウの ID を取得する責任がありますremoveWindowObserverはオブザーバーをデタッチしますcleanUpは、ウィンドウの変更オブザーバーとアプリの変更オブザーバーを削除しますinitActiveWindowObserverは、上記のクラスのインスタンスの初期化をトリガーします。これは、JS から呼び出す NAPI でラップする関数ですstopActiveWindowObserverは、私たちのインスタンスの破壊をトリガーし、すべてのリスナーを削除します
nativeWindows.mmを実装する
かなり簡単で、モジュールから公開した 2 つのメソッドをラップして JS から利用可能にします。
3. electron-rebuildでビルドスクリプトをセットアップする
Electron プロジェクトのルートにあるメインのpackage.jsonファイルに、以下の行を追加します。
ネイティブコードにエラーがない場合、ルートフォルダでnpm run native-modules:rebuildまたはnpm run native-modules:rebuild:armを実行することで、モジュールを正しくビルドできるはずです。これは、ビルドするプラットフォームに依存します。
これには、次のような出力があるはずです:
![]()
4. ネイティブコードのための Typescript ラッパーを作成する
electron-react-boilerplate から始めた場合は、以下の行を.eslintrc.jsに追加してください以下をsrc/native-modules/native-windows/index.tsに追加します
nativeWindows変数をエクスポートします。これは、コンパイルされたコードからネイティブコードをaddonとしてインポートする、正しく型付けされたインスタンス化されたクラスです。
5. main.tsからモジュールを呼び出す
main.tsに以下のインポートを追加します:
下記のコードを、アプリが準備完了した後のどこかに追加して、これまでの作業をテストします:
その後、npm startでアプリを起動します。
次のようなログが表示されるはずです:
![]()
🎉 これで完了です。これで MacOS でアクティブなウィンドウを追跡できるようになるはずです。🎉
完全なコードは、以下のリンクの Github で利用可能です: https://github.com/scriptide-tech/blog-tracking-active-window-macos-objective-c-electron
Scriptide は、 テクノロジーパー トナーであり、 複雑な カスタム B2B ソリューションの 提供を 専門と しています。 デジタルトランス フォーメーション、 Web・ モバイル開発、 AI、 ブロックチェーンなど、 幅広い サービスを 提供しています。 無料の IT 相談を 承っております。 ぜひお気軽に お問い 合わせください。
無料のIT相談をぜひご利用ください。。皆さまからのご相談を心よりお待ちしております。
こちらの 記事も おすすめです!
詳細は こちら
自動テストに おける AI (コンピュータユー ザーエージェント) モデルの 活用: より 簡単で 迅速な テスト
Scriptide
#dev
•
NOV 10, 2025
•
9 min read
詳細は こちら
Lighthouse スコア改善: Web サイトの SEO スコアを 最大化する 方 法
Google Lighthouse
#dev
•
JUL 01, 2025
•
6 min read