mirror of
https://github.com/outbackdingo/hyprcosmic-comp.git
synced 2026-08-25 14:53:22 +00:00
Hyprland's `windowrule = workspace 4, class:^(vivaldi)$` has no COSMIC
counterpart, and the missing piece is small: map_window already accepts a
workspace other than the active one, because activation tokens use that
path. This adds a second source for the same decision.
`window_rules` is a new CosmicCompConfig key rather than an addition to
com.system76.CosmicSettings.WindowRules. That component belongs to
cosmic-settings-daemon and holds one kind of rule -- tiling exceptions,
`{ appid, title }` with no action, because the action is implied. There is
nowhere in it to say *which workspace*, and putting one there would mean
forking a second upstream crate to add a field cosmic-settings' own UI
could not show. `preserve_split` set the precedent for keys the fork adds.
The matching half is deliberately the same shape as the exceptions: two
RegexSets, app ids and titles, a rule matching when the same index matches
in both. A regex that works in a tiling exception works here. The third
vector is what an exception list does not need -- exceptions answer yes or
no, a rule has to say where -- and it is index-aligned with the two sets,
which is why an invalid expression is skipped from all three together.
Precedence
An activation token wins. It is an application saying where it wants this
window right now -- a file manager reopening a document where you launched
it from -- and that outranks a rule written months ago. So the rules are
consulted only when nothing else claimed a workspace.
`was_activated` stays keyed to the token rather than to the resulting
handle. It raises the urgency hint on the target workspace, and a window
that went exactly where the config said is not worth flagging; one that
turned up somewhere unexpected is. Without splitting the two apart, every
rule-placed window would have made its workspace blink.
That also means a rule never switches you to the workspace it used, which
is Hyprland's `silent` and is now unconditional.
Missing targets miss
Workspaces are resolved per output, because a WorkspaceSet is, so
"workspace 4" is the fourth workspace of the screen the window would have
opened on. A rule naming a workspace that does not exist returns None and
the window opens where it would have anyway: `workspace 4` with three
workspaces must not conjure a fourth, and a name only exists because a
`workspace` line created it.
Live
The key has an arm in the config watcher, so an edit applies to the next
window that opens. Nothing moves -- windows already open stay put, since
the rules are only read at map time. That is the opposite of
pinned_workspaces, which is read once at startup and lands at next login.
Not verified: nothing was compiled here. This half is built by
packages.yml; the cosmic-conf job covers the parser that writes the key.