frontmost

Crates.iofrontmost
lib.rsfrontmost
version0.1.0
created_at2026-01-01 21:35:41.569473+00
updated_at2026-01-01 21:35:41.569473+00
descriptionA Rust crate for detecting the currently focused application on macOS using NSWorkspace notifications.
homepage
repositoryhttps://github.com/kllarena07/frontmost
max_upload_size
id2017553
size13,718
Kieran Llarena (kllarena07)

documentation

README

Frontmost

✍ About

A crate that dynamically captures the currently focused application on macOS, powered by objc2, objc2_foundation, and objc2_app_kit Rust bindings.

🤔 Why Frontmost

One might assume that you could simply use the applications crate by placing ctx.get_frontmost_application().unwrap() inside a loop and call it a day. However, this approach does not work as expected in practice.

Why? Because macOS uses an event-driven architecture, and a blocking loop prevents the main NSRunLoop from processing events. The NSRunLoop powers macOS's asynchronous notification system, so blocking it disrupts normal event handling.

To work with this architecture, the code instead creates an observer (such as an NSWorkspace notification observer) that triggers when the user switches focus to a different application, specifically utilizing the NSWorkspaceDidActivateApplicationNotification notification. This allows your code to respond to application changes without blocking the run loop.

📖 How to Use

Check examples for an example of frontmost put into use.

  1. Bring the frontmost module and crate into scope
mod frontmost;
use frontmost::Detector;
  1. Create the callback function that will be used when the observer detects that the user has changed apps
use objc2_app_kit::NSRunningApplication;

fn handle_app_change(ns_running_application: &NSRunningApplication) {
    unsafe {
        let frontmost_app_name = ns_running_application
            .localizedName()
            .expect("Failed to capture application localizedName");
        println!("Application activated: {}", frontmost_app_name);
    }
}
  1. Initialize a Detector singleton by calling the init function and pass your callback function into it
Detector::init(handle_app_change);
  1. Start the event loop using the start_nsrunloop!() macro

👾 Bugs or vulnerabilities

If you find any bugs or vulnerabilities, please contact me on my Twitter using the link below.

Made with ❤️ by krayondev

Commit count: 0

cargo fmt