(Init): Added shit

This commit is contained in:
2026-05-29 00:41:12 +00:00
commit 72005fd71d
52 changed files with 12875 additions and 0 deletions

299
nirimod/window_effects.py Normal file
View File

@@ -0,0 +1,299 @@
"""Helpers for Niri global window effect rules."""
from __future__ import annotations
from nirimod.kdl_parser import KdlNode, remove_child, set_child_arg, set_node_flag
_RULE_CHILD_ORDER = [
"match",
"exclude",
"geometry-corner-radius",
"clip-to-geometry",
"draw-border-with-background",
"opacity",
"background-effect",
]
_EFFECT_CHILD_ORDER = ["blur", "xray"]
_BLUR_CONFIG_CHILD_ORDER = ["off", "passes", "offset", "noise", "saturation"]
def _is_global_window_rule(node: KdlNode) -> bool:
return (
node.name == "window-rule"
and not node.get_children("match")
and not node.get_children("exclude")
)
def _is_focused_window_rule(node: KdlNode) -> bool:
if node.name != "window-rule" or node.get_children("exclude"):
return False
matches = node.get_children("match")
if len(matches) != 1:
return False
match = matches[0]
return match.args == [] and match.props == {"is-focused": True}
def _global_window_rule(nodes: list[KdlNode]) -> KdlNode | None:
return next((n for n in reversed(nodes) if _is_global_window_rule(n)), None)
def _focused_window_rule(nodes: list[KdlNode]) -> KdlNode | None:
return next((n for n in reversed(nodes) if _is_focused_window_rule(n)), None)
def _blur_config_node(nodes: list[KdlNode]) -> KdlNode | None:
return next((n for n in reversed(nodes) if n.name == "blur"), None)
def _ensure_blur_config_node(nodes: list[KdlNode]) -> KdlNode:
blur = _blur_config_node(nodes)
if blur is None:
blur = KdlNode("blur")
blur.leading_trivia = "\n"
nodes.append(blur)
return blur
def _ensure_global_window_rule(nodes: list[KdlNode]) -> KdlNode:
rule = _global_window_rule(nodes)
if rule is None:
rule = KdlNode("window-rule")
rule.leading_trivia = "\n"
nodes.append(rule)
return rule
def _ensure_focused_window_rule(nodes: list[KdlNode]) -> KdlNode:
rule = _focused_window_rule(nodes)
if rule is None:
rule = KdlNode("window-rule")
rule.leading_trivia = "\n"
rule.children.append(KdlNode("match", props={"is-focused": True}))
nodes.append(rule)
return rule
def _background_effect(rule: KdlNode) -> KdlNode | None:
return rule.get_child("background-effect")
def _ensure_background_effect(rule: KdlNode) -> KdlNode:
effect = _background_effect(rule)
if effect is None:
effect = KdlNode("background-effect")
effect.leading_trivia = "\n"
rule.children.append(effect)
return effect
def _remove_rule_if_empty(nodes: list[KdlNode], rule: KdlNode) -> None:
if not rule.args and not rule.props and not rule.children and rule in nodes:
nodes.remove(rule)
def _remove_background_effect_if_empty(rule: KdlNode) -> None:
effect = _background_effect(rule)
if effect and not effect.args and not effect.props and not effect.children:
remove_child(rule, "background-effect")
def _compact_generated_spacing(node: KdlNode) -> None:
if not node.trailing_trivia or node.trailing_trivia.isspace():
node.trailing_trivia = "\n"
for child in node.children:
if not child.leading_trivia or child.leading_trivia.isspace():
child.leading_trivia = ""
if not child.trailing_trivia or child.trailing_trivia.isspace():
child.trailing_trivia = ""
if child.name == "background-effect":
_compact_generated_spacing(child)
def _sort_children_by_name(node: KdlNode, order: list[str]) -> None:
order_index = {name: index for index, name in enumerate(order)}
indexed_children = list(enumerate(node.children))
indexed_children.sort(
key=lambda item: (order_index.get(item[1].name, len(order)), item[0])
)
node.children = [child for _, child in indexed_children]
def _finalize_window_rule(rule: KdlNode) -> None:
effect = _background_effect(rule)
if effect is not None:
_sort_children_by_name(effect, _EFFECT_CHILD_ORDER)
_sort_children_by_name(rule, _RULE_CHILD_ORDER)
_compact_generated_spacing(rule)
def _finalize_blur_config(blur: KdlNode) -> None:
_sort_children_by_name(blur, _BLUR_CONFIG_CHILD_ORDER)
_compact_generated_spacing(blur)
def _rule_opacity(rule: KdlNode | None) -> float:
if rule is None:
return 1.0
value = rule.child_arg("opacity", 1.0)
try:
return float(value)
except (TypeError, ValueError):
return 1.0
def get_global_draw_border_with_background(nodes: list[KdlNode]) -> bool:
rule = _global_window_rule(nodes)
if rule is None:
return True
return rule.child_arg("draw-border-with-background", True) is not False
def set_global_draw_border_with_background(nodes: list[KdlNode], enabled: bool) -> None:
rule = _ensure_global_window_rule(nodes)
if enabled:
remove_child(rule, "draw-border-with-background")
else:
set_child_arg(rule, "draw-border-with-background", False)
_finalize_window_rule(rule)
_remove_rule_if_empty(nodes, rule)
def blur_effects_enabled(nodes: list[KdlNode]) -> bool:
blur = _blur_config_node(nodes)
return blur is None or blur.get_child("off") is None
def set_blur_effects_enabled(nodes: list[KdlNode], enabled: bool) -> None:
blur = _ensure_blur_config_node(nodes)
set_node_flag(blur, "off", not enabled)
_finalize_blur_config(blur)
_remove_rule_if_empty(nodes, blur)
if enabled:
rule = _ensure_global_window_rule(nodes)
if _rule_opacity(rule) >= 1.0:
set_child_arg(rule, "opacity", 0.9)
_finalize_window_rule(rule)
else:
set_global_window_blur(nodes, False)
set_focused_window_blur(nodes, False)
def global_window_blur_enabled(nodes: list[KdlNode]) -> bool:
rule = _global_window_rule(nodes)
return _rule_blur_enabled(rule)
def focused_window_blur_enabled(nodes: list[KdlNode]) -> bool:
rule = _focused_window_rule(nodes)
return _rule_blur_enabled(rule)
def _rule_blur_enabled(rule: KdlNode | None) -> bool:
if rule is None:
return False
effect = _background_effect(rule)
if effect is None:
return False
blur = effect.get_child("blur")
return blur is not None and (not blur.args or blur.args[0] is True)
def set_global_window_blur(nodes: list[KdlNode], enabled: bool) -> None:
if enabled:
rule = _ensure_global_window_rule(nodes)
if _rule_opacity(rule) >= 1.0:
set_child_arg(rule, "opacity", 0.9)
effect = _ensure_background_effect(rule)
set_child_arg(effect, "blur", True)
_finalize_window_rule(rule)
return
existing_rule = _global_window_rule(nodes)
if existing_rule is None:
return
existing_effect = _background_effect(existing_rule)
if existing_effect is not None:
remove_child(existing_effect, "blur")
_remove_background_effect_if_empty(existing_rule)
remove_child(existing_rule, "opacity")
_finalize_window_rule(existing_rule)
_remove_rule_if_empty(nodes, existing_rule)
def set_focused_window_blur(nodes: list[KdlNode], enabled: bool) -> None:
if enabled:
rule = _ensure_focused_window_rule(nodes)
effect = _ensure_background_effect(rule)
set_child_arg(effect, "blur", True)
_finalize_window_rule(rule)
return
existing_rule = _focused_window_rule(nodes)
if existing_rule is None:
return
existing_effect = _background_effect(existing_rule)
if existing_effect is not None:
remove_child(existing_effect, "blur")
_remove_background_effect_if_empty(existing_rule)
_finalize_window_rule(existing_rule)
if len(existing_rule.children) == 1 and existing_rule.get_child("match"):
nodes.remove(existing_rule)
def global_window_xray_enabled(nodes: list[KdlNode]) -> bool:
rule = _global_window_rule(nodes)
if rule is None:
return True
effect = _background_effect(rule)
if effect is None:
return True
xray = effect.get_child("xray")
return xray is None or not xray.args or xray.args[0] is True
def set_global_window_xray(nodes: list[KdlNode], enabled: bool) -> None:
rule = _ensure_global_window_rule(nodes)
effect = _ensure_background_effect(rule)
set_child_arg(effect, "xray", enabled)
_finalize_window_rule(rule)
def get_global_window_opacity(nodes: list[KdlNode]) -> float:
return _rule_opacity(_global_window_rule(nodes))
def set_global_window_opacity(nodes: list[KdlNode], opacity: float) -> None:
rule = _ensure_global_window_rule(nodes)
if opacity < 1.0:
set_child_arg(rule, "opacity", round(opacity, 2))
else:
remove_child(rule, "opacity")
_finalize_window_rule(rule)
_remove_rule_if_empty(nodes, rule)
def get_global_corner_radius(nodes: list[KdlNode]) -> int:
rule = _global_window_rule(nodes)
if rule is None:
return 0
value = rule.child_arg("geometry-corner-radius", 0)
try:
return int(value)
except (TypeError, ValueError):
return 0
def set_global_corner_radius(nodes: list[KdlNode], radius: int) -> None:
rule = _ensure_global_window_rule(nodes)
if radius > 0:
set_child_arg(rule, "geometry-corner-radius", radius)
set_child_arg(rule, "clip-to-geometry", True)
else:
remove_child(rule, "geometry-corner-radius")
remove_child(rule, "clip-to-geometry")
_finalize_window_rule(rule)
_remove_rule_if_empty(nodes, rule)