openlogi_core/app.rs
1//! The foreground application, in the form per-app profiles match against.
2//!
3//! Lives in the platform-free core crate because three layers need the same
4//! shape and none of them can see the others: `openlogi-hook` reads it from the
5//! window server, `openlogi-agent-core` holds it, and `openlogi-ipc` puts it on
6//! the wire. That last one makes this a wire type — see
7//! `crates/openlogi-ipc/AGENTS.md`.
8
9use serde::{Deserialize, Serialize};
10
11/// One application, named the way a per-app profile names it.
12///
13/// [`Self::id`] is the whole of the matching contract; [`Self::display_name`]
14/// exists only so a UI never has to show a reverse-DNS string to a human.
15#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
16pub struct ForegroundApp {
17 /// The exact string a per-app profile key is compared against: a macOS
18 /// bundle identifier, an X11 `WM_CLASS` class or a Wayland xdg `app_id` on
19 /// Linux, or the lower-cased executable path on Windows.
20 ///
21 /// Those namespaces do not map onto one another by any simple string rule,
22 /// which is why a profile authored under one of them will not match under
23 /// another. See
24 /// [`Config::effective_bindings`](crate::config::Config::effective_bindings)
25 /// for the matcher this feeds.
26 pub id: String,
27 /// Human-readable name for the UI. Equal to [`Self::id`] on the platforms
28 /// that report no name of their own.
29 pub display_name: String,
30}
31
32impl ForegroundApp {
33 /// An application the platform identified but did not name — the display
34 /// name falls back to the identifier, which on those platforms (X11's
35 /// `WM_CLASS`, a Wayland `app_id`) is already close to readable.
36 #[must_use]
37 pub fn unnamed(id: String) -> Self {
38 Self {
39 display_name: id.clone(),
40 id,
41 }
42 }
43}