// SPDX-License-Identifier: GPL-3.0-only //! Rules that decide where a window opens, from its app id and title. //! //! COSMIC already has a `com.system76.CosmicSettings.WindowRules` component, //! but it belongs to cosmic-settings-daemon and holds exactly one kind of rule: //! `tiling_exception_defaults` / `tiling_exception_custom`, both lists of //! `{ appid, title }` with no action attached, because the action is implied. //! There is nowhere in it to say *which workspace*, and extending it would mean //! forking a second upstream crate to add a field cosmic-settings' own UI would //! not know how to show. //! //! So this lives on `CosmicCompConfig` instead, next to the other keys the fork //! adds. The matching half is deliberately identical to the exceptions: `appid` //! and `title` are regular expressions, matched with the same `RegexSet` the //! tiling exceptions use, so one mental model covers both. use serde::{Deserialize, Serialize}; /// Which workspace a rule sends its window to. /// /// A name is not a nicety here. Workspace numbers shift the moment an empty /// workspace is collected, so a rule written against a number is a rule that /// can quietly start pointing somewhere else; a name pins it to the workspace /// the user actually meant. Both are accepted because Hyprland's own /// `windowrule = workspace 4` is written with a number. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum WorkspaceTarget { /// 1-based, as the user counts them. Index(u32), /// Matched against `Workspace::name`, which is what `pinned_workspaces` /// sets and what waybar shows. Name(String), } /// One rule: match a window, then place it. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct WindowRule { /// Regular expression matched against the window's app id. pub app_id: String, /// Regular expression matched against the window's title. An empty /// expression matches everything, which is what "no title condition" means. pub title: String, /// Where a matching window opens. pub workspace: WorkspaceTarget, }