How OpenLogi Identifies Applications for Per-App Profiles: A Deep Dive into Platform-Specific Detection
OpenLogi identifies applications for per-app profiles using the ForegroundApp type, which stores a platform-specific identifier (id) as the lookup key and a human-readable display_name for the UI, with observers in the openlogi-hook crate extracting bundle IDs on macOS, WM_CLASS on X11, app_id on Wayland, and executable paths on Windows.
OpenLogi's per-app profile system relies on precise identification of the currently active foreground application. The system is built around a unified abstraction—the ForegroundApp struct—that normalizes platform differences while maintaining a strict contract between running applications and user-defined configuration overrides.
The ForegroundApp Abstraction
At the heart of OpenLogi's detection logic is the ForegroundApp struct defined in crates/openlogi-core/src/app.rs. This type serves as the canonical representation of the active application across all supported platforms:
| Field | Purpose | Platform Mapping |
|---|---|---|
id |
Exact lookup key for per-app profile matching | Platform-specific identifier |
display_name |
Human-readable label shown in the UI | Falls back to id when unavailable |
The id field is the sole identifier used for configuration lookups. The UI never exposes this raw value to users; instead, it renders the display_name for readability.
Platform-Specific Extraction Mechanisms
OpenLogi implements dedicated foreground-app observers in the openlogi-hook crate, with each platform using native APIs to extract application identity:
macOS: Bundle Identifier Extraction
In crates/openlogi-hook/src/macos.rs, OpenLogi leverages the Launch Services framework to obtain the bundle identifier (e.g., com.apple.Safari) and localized application name when available.
X11 (Linux): WM_CLASS Parsing
The X11 implementation in crates/openlogi-hook/src/linux/wlr_foreign_toplevel.rs extracts the WM_CLASS class string from the X11 window properties. This string typically matches the application's .desktop file name.
Wayland (Linux): app_id Retrieval
For Wayland compositors, crates/openlogi-hook/src/linux/gnome_shell.rs reads the xdg_app_id (or simply app_id) provided by the compositor. This follows the app_id convention established by xdg-shell.
Windows: Executable Path Normalization
On Windows, crates/openlogi-hook/src/windows.rs uses the lower-cased full executable path as the identifier. This provides a stable, file-system-backed key that remains consistent across application versions.
Unified API and IPC Propagation
Each platform observer returns an Option<ForegroundApp>, handling detection failures gracefully. These implementations are consolidated through the public API in crates/openlogi-hook/src/lib.rs:
/// Returns the current foreground application, if one can be determined.
pub fn frontmost_application() -> Option<ForegroundApp> {
// internally dispatches to the appropriate platform module
}
The ForegroundApp value traverses the IPC channel defined in crates/openlogi-ipc/src/ipc.rs, connecting the GUI and agent processes. Upon foreground changes, the agent recomputes effective bindings via Config::effective_bindings in crates/openlogi-core/src/config.rs, applying any per-app overrides from the user's TOML configuration.
Working with ForegroundApp in Code
The following examples demonstrate practical usage of the detection API:
use openlogi_hook::frontmost_application;
use openlogi_core::app::ForegroundApp;
/// Get the current foreground app and print its identifier.
fn print_foreground_app() {
if let Some(app) = frontmost_application() {
println!("App ID: {}", app.id);
println!("App Name: {}", app.display_name);
} else {
println!("No foreground application detected");
}
}
For cases where platform detection fails or no friendly name exists, the unnamed constructor provides a fallback:
/// Create a dummy app entry when the platform cannot provide a name.
fn make_unnamed_app(id: &str) -> ForegroundApp {
ForegroundApp::unnamed(id.to_owned())
}
Key Source Files
| Path | Responsibility |
|---|---|
crates/openlogi-core/src/app.rs |
ForegroundApp definition and identifier semantics |
crates/openlogi-hook/src/lib.rs |
Unified frontmost_application() API |
crates/openlogi-hook/src/macos.rs |
macOS Launch Services integration |
crates/openlogi-hook/src/linux/wlr_foreign_toplevel.rs |
X11 WM_CLASS extraction |
crates/openlogi-hook/src/linux/gnome_shell.rs |
Wayland app_id retrieval |
crates/openlogi-hook/src/windows.rs |
Windows executable path handling |
crates/openlogi-ipc/src/ipc.rs |
IPC structures for cross-process communication |
crates/openlogi-core/src/config.rs |
Per-app profile resolution logic |
Summary
- OpenLogi identifies applications through the
ForegroundAppstruct, which encapsulates both a stable lookup key (id) and a human-readable label (display_name) - Platform-specific observers extract native identifiers: bundle IDs on macOS,
WM_CLASSon X11,app_idon Wayland, and executable paths on Windows - The
frontmost_application()function inopenlogi-hookprovides a unified, cross-platform API - IPC propagation carries detection results from the GUI to the agent core for configuration resolution
- Per-app profile matching occurs exclusively against the
ForegroundApp.idfield, ensuring consistent behavior across platforms
Frequently Asked Questions
How do I find the correct app ID for my per-app profile configuration?
Query the currently running application using frontmost_application() or check OpenLogi's logs. On macOS, use mdls -name kMDItemCFBundleIdentifier -r /Applications/AppName.app to verify bundle identifiers. On X11, run xprop WM_CLASS and click the target window. On Wayland, swaymsg -t get_tree or equivalent compositor commands expose app_id values.
Why does Windows use executable paths instead of more stable identifiers?
Windows lacks a universal, user-friendly application identifier comparable to macOS bundle IDs. The lower-cased executable path provides deterministic, version-agnostic identification without requiring registry parsing or heuristic name matching. This trades occasional path sensitivity for reliability and implementation simplicity.
Can ForegroundApp.id change for the same application across versions?
Platform-dependent. macOS bundle IDs and X11 WM_CLASS values rarely change. Windows executable paths remain stable unless the installation directory changes. Wayland app_id values are controlled by the application and compositor, making them generally consistent but not guaranteed.
What happens when foreground detection fails?
The frontmost_application() function returns None, and the agent falls back to global default bindings. Detection failures may occur during rapid application switching, fullscreen direct-rendering contexts, or when platform APIs are temporarily unavailable. OpenLogi's architecture treats None as a valid state, ensuring continuous operability.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →