(Init): Added shit
This commit is contained in:
200
nirimod/pages/gestures.py
Normal file
200
nirimod/pages/gestures.py
Normal file
@@ -0,0 +1,200 @@
|
||||
"""Gestures & Miscellaneous settings page."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "4.0")
|
||||
gi.require_version("Adw", "1")
|
||||
from gi.repository import Adw, Gtk
|
||||
|
||||
from nirimod.kdl_parser import (
|
||||
KdlNode,
|
||||
find_or_create,
|
||||
set_node_flag,
|
||||
safe_switch_connect,
|
||||
)
|
||||
from nirimod.pages.base import BasePage
|
||||
|
||||
_CORNERS = [
|
||||
("top-left", "Top-Left", "Moves cursor to the top-left corner"),
|
||||
("top-right", "Top-Right", "Moves cursor to the top-right corner"),
|
||||
("bottom-left", "Bottom-Left", "Moves cursor to the bottom-left corner"),
|
||||
("bottom-right", "Bottom-Right", "Moves cursor to the bottom-right corner"),
|
||||
]
|
||||
|
||||
|
||||
class GesturesPage(BasePage):
|
||||
def build(self) -> Gtk.Widget:
|
||||
tb, _, _, content = self._make_toolbar_page("Gestures & Misc")
|
||||
self._content = content
|
||||
self._build_content()
|
||||
return tb
|
||||
|
||||
def _build_content(self):
|
||||
content = self._content
|
||||
nodes = self._nodes
|
||||
|
||||
# ── Hot Corners ───────────────────────────────────────────────────────
|
||||
hc_grp = Adw.PreferencesGroup(
|
||||
title="Hot Corners",
|
||||
description="Trigger the overview when the cursor touches a screen corner (niri ≥ 25.05)",
|
||||
)
|
||||
gestures_node = next((n for n in nodes if n.name == "gestures"), None)
|
||||
hc_node = gestures_node.get_child("hot-corners") if gestures_node else None
|
||||
hc_off = hc_node is not None and hc_node.get_child("off") is not None
|
||||
hc_enabled = not hc_off
|
||||
|
||||
# Which individual corners are active
|
||||
active_corners: set[str] = set()
|
||||
if hc_node and not hc_off:
|
||||
for corner_key, _, _ in _CORNERS:
|
||||
if hc_node.get_child(corner_key) is not None:
|
||||
active_corners.add(corner_key)
|
||||
|
||||
# ExpanderRow = the enable/disable switch + collapsible corner list
|
||||
hc_expander = Adw.ExpanderRow(
|
||||
title="Enable Hot Corners",
|
||||
subtitle="Expand to choose which corners are active (default: top-left)",
|
||||
)
|
||||
hc_expander.set_expanded(hc_enabled)
|
||||
hc_expander.set_show_enable_switch(True)
|
||||
hc_expander.set_enable_expansion(hc_enabled)
|
||||
|
||||
# Per-corner rows nested inside the expander
|
||||
corner_rows: dict[str, Adw.SwitchRow] = {}
|
||||
for corner_key, corner_label, corner_subtitle in _CORNERS:
|
||||
sr = Adw.SwitchRow(title=corner_label, subtitle=corner_subtitle)
|
||||
is_active = corner_key in active_corners
|
||||
sr.set_active(is_active)
|
||||
safe_switch_connect(
|
||||
sr, is_active,
|
||||
lambda enabled, k=corner_key: self._set_corner(k, enabled),
|
||||
)
|
||||
hc_expander.add_row(sr)
|
||||
corner_rows[corner_key] = sr
|
||||
|
||||
# Wire the expander's enable-switch to the hot corners on/off mutation
|
||||
hc_expander._last_enabled = hc_enabled
|
||||
|
||||
def _on_expander_toggled(expander, _param):
|
||||
val = expander.get_enable_expansion()
|
||||
if val != getattr(expander, "_last_enabled", None):
|
||||
expander._last_enabled = val
|
||||
self._set_hot_corners(val)
|
||||
|
||||
hc_expander.connect("notify::enable-expansion", _on_expander_toggled)
|
||||
|
||||
hc_grp.add(hc_expander)
|
||||
content.append(hc_grp)
|
||||
|
||||
|
||||
# ── Hotkey Overlay ────────────────────────────────────────────────────
|
||||
hko_grp = Adw.PreferencesGroup(title="Hotkey Overlay")
|
||||
hko_node = next((n for n in nodes if n.name == "hotkey-overlay"), None)
|
||||
|
||||
skip_initial = (
|
||||
hko_node is not None and hko_node.get_child("skip-at-startup") is not None
|
||||
)
|
||||
skip_row = Adw.SwitchRow(
|
||||
title="Skip at Startup",
|
||||
subtitle="Don't show the hotkey overlay when niri starts",
|
||||
)
|
||||
skip_row.set_active(skip_initial)
|
||||
safe_switch_connect(skip_row, skip_initial, self._set_skip_hotkey_overlay)
|
||||
hko_grp.add(skip_row)
|
||||
content.append(hko_grp)
|
||||
|
||||
# ── Screenshots ───────────────────────────────────────────────────────
|
||||
ss_grp = Adw.PreferencesGroup(
|
||||
title="Screenshots", description="Path template for saved screenshots"
|
||||
)
|
||||
cur_path = next(
|
||||
(n.args[0] for n in nodes if n.name == "screenshot-path" and n.args),
|
||||
"~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png",
|
||||
)
|
||||
path_row = Adw.EntryRow(title="Save Path (strftime format)")
|
||||
path_row.set_text(str(cur_path))
|
||||
path_row.set_show_apply_button(True)
|
||||
path_row.connect("apply", lambda r: self._set_screenshot_path(r.get_text()))
|
||||
ss_grp.add(path_row)
|
||||
content.append(ss_grp)
|
||||
|
||||
# ── Overview ──────────────────────────────────────────────────────────
|
||||
ov_grp = Adw.PreferencesGroup(title="Overview")
|
||||
ov_node = next((n for n in nodes if n.name == "overview"), None)
|
||||
ws_shadow_node = ov_node.get_child("workspace-shadow") if ov_node else None
|
||||
|
||||
ws_shadow_initial = (
|
||||
ws_shadow_node is None or ws_shadow_node.get_child("off") is None
|
||||
)
|
||||
ws_shadow_row = Adw.SwitchRow(
|
||||
title="Workspace Shadow in Overview",
|
||||
subtitle="Show drop shadows under workspaces in overview mode",
|
||||
)
|
||||
ws_shadow_row.set_active(ws_shadow_initial)
|
||||
safe_switch_connect(
|
||||
ws_shadow_row, ws_shadow_initial, self._set_overview_ws_shadow
|
||||
)
|
||||
ov_grp.add(ws_shadow_row)
|
||||
content.append(ov_grp)
|
||||
|
||||
# ── Mutation methods ──────────────────────────────────────────────────────
|
||||
|
||||
def _get_hot_corners_node(self) -> KdlNode:
|
||||
gestures = find_or_create(self._nodes, "gestures")
|
||||
hc = gestures.get_child("hot-corners")
|
||||
if hc is None:
|
||||
hc = KdlNode("hot-corners")
|
||||
hc.leading_trivia = "\n"
|
||||
gestures.children.append(hc)
|
||||
return hc
|
||||
|
||||
def _set_hot_corners(self, enabled: bool):
|
||||
hc = self._get_hot_corners_node()
|
||||
set_node_flag(hc, "off", not enabled)
|
||||
self._commit("gestures hot-corners")
|
||||
|
||||
def _set_corner(self, corner_key: str, enabled: bool):
|
||||
"""Enable or disable an individual hot corner (niri ≥ 25.11)."""
|
||||
hc = self._get_hot_corners_node()
|
||||
# Remove 'off' if it exists — enabling a corner implicitly enables hot corners
|
||||
set_node_flag(hc, "off", False)
|
||||
set_node_flag(hc, corner_key, enabled)
|
||||
self._commit(f"hot-corner {corner_key}")
|
||||
|
||||
def _set_skip_hotkey_overlay(self, skip: bool):
|
||||
nodes = self._nodes
|
||||
hko = next((n for n in nodes if n.name == "hotkey-overlay"), None)
|
||||
if hko is None:
|
||||
hko = KdlNode("hotkey-overlay")
|
||||
nodes.append(hko)
|
||||
set_node_flag(hko, "skip-at-startup", skip)
|
||||
self._commit("hotkey-overlay skip-at-startup")
|
||||
|
||||
def _set_screenshot_path(self, path: str):
|
||||
nodes = self._nodes
|
||||
existing = next((n for n in nodes if n.name == "screenshot-path"), None)
|
||||
if path.strip():
|
||||
if existing:
|
||||
existing.args = [path.strip()]
|
||||
else:
|
||||
nodes.append(KdlNode("screenshot-path", args=[path.strip()]))
|
||||
elif existing:
|
||||
nodes.remove(existing)
|
||||
self._commit("screenshot-path")
|
||||
|
||||
def _set_overview_ws_shadow(self, enabled: bool):
|
||||
ov = find_or_create(self._nodes, "overview")
|
||||
ws_shadow = ov.get_child("workspace-shadow")
|
||||
if ws_shadow is None:
|
||||
ws_shadow = KdlNode("workspace-shadow")
|
||||
ov.children.append(ws_shadow)
|
||||
set_node_flag(ws_shadow, "off", not enabled)
|
||||
self._commit("overview workspace-shadow")
|
||||
|
||||
def refresh(self):
|
||||
for child in list(self._content):
|
||||
self._content.remove(child)
|
||||
self._build_content()
|
||||
Reference in New Issue
Block a user