pinnacle/api/lua/window_rules.lua
2023-09-05 23:18:44 -05:00

122 lines
4 KiB
Lua

---Rules that apply to spawned windows when conditions are met.
---@class WindowRules
local window_rules = {}
---Convert all tag constructors in `cond` to actual tags
---@param cond WindowRuleCondition
---@return _WindowRuleCondition
local function convert_tag_params(cond)
if cond.tag then
---@type TagId|Tag|nil
local tag = require("tag").create_tag_from_params(cond.tag)
if tag then
---@diagnostic disable-next-line
tag = tag:id()
end
cond.tag = tag
end
if cond.cond_any then
local conds = {}
for _, c in pairs(cond.cond_any) do
table.insert(conds, convert_tag_params(c))
end
cond.cond_any = conds
end
if cond.cond_all then
local conds = {}
for _, c in pairs(cond.cond_all) do
table.insert(conds, convert_tag_params(c))
end
cond.cond_all = conds
end
return cond --[[@as _WindowRuleCondition]]
end
---Add one or more window rules.
---
---A window rule defines what a window will spawn with given certain conditions.
---For example, if Firefox is spawned, you can set it to open on the second tag.
---
---This function takes in a table with two keys:
--- - `cond`: The condition for `rule` to apply to a new window.
--- - `rule`: What gets applied to the new window if `cond` is true.
---
---`cond` can be a bit confusing and *very* table heavy. Examples are shown below for guidance.
---An attempt at simplifying this API will happen in the future, but is a low priority.
---
---### Examples
---```lua
----- A simple window rule. This one will cause Firefox to open on tag "Browser".
---window.rules.add({
--- cond = { class = "firefox" },
--- rule = { tags = { "Browser" } },
---})
---
----- To apply rules when *all* provided conditions are true, use `cond_all`.
----- `cond_all` takes an array of conditions and checks if all are true.
----- Note that `cond_any` is not a keyed table; rather, it's a table of tables.
---
----- The following will open Steam fullscreen only if it opens on tag "5".
---window.rules.add({
--- cond = {
--- cond_any = {
--- { class = "steam" }, -- Note that each table must only have one key.
--- { tag = tag.get_by_name("5")[1] },
--- }
--- },
--- rule = { fullscreen_or_maximized = "Fullscreen" },
---})
---
----- You can arbitrarily nest `cond_any` and `cond_all` to achieve desired logic.
----- The following will open Discord, Thunderbird, or Alacritty floating if they
----- open on either *all* of tags "A", "B", and "C" or both tags "1" and "2".
---window.rules.add({
--- cond = { cond_all = {
--- { cond_any = { { class = "discord" }, { class = "firefox" }, { class = "thunderbird" } } },
--- { cond_any = {
--- { cond_all = { { tag = "A" }, { tag = "B" }, { tag = "C" } } },
--- { cond_all = { { tag = "1" }, { tag = "2" } } },
--- } }
--- } },
--- rule = { floating_or_tiled = "Floating" },
---})
---```
---@param ... { cond: WindowRuleCondition, rule: WindowRule }
function window_rules.add(...)
local rules = { ... }
for _, rule in pairs(rules) do
---@diagnostic disable-next-line a lil cheating
rule.cond = convert_tag_params(rule.cond)
if rule.rule.tags then
local tags = {}
for _, tag in pairs(rule.rule.tags) do
---@type TagId|Tag|nil
local t = require("tag").create_tag_from_params(tag)
if t then
---@diagnostic disable-next-line
t = t:id()
end
table.insert(tags, t)
end
rule.rule.tags = tags
end
RPrint(rule)
SendMsg({
AddWindowRule = {
-- stylua: ignore start
cond = rule.cond --[[@as _WindowRuleCondition]],
rule = rule.rule --[[@as _WindowRule]],
-- stylua: ignore end
},
})
end
end
return window_rules