Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions completions/caelestia.fish
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ complete -c caelestia -n "$seen screenshot" -s 'f' -l 'freeze' -d 'Freeze while
complete -c caelestia -n "$seen record" -s 'r' -l 'region' -d 'Capture region'
complete -c caelestia -n "$seen record" -s 's' -l 'sound' -d 'Capture sound'
complete -c caelestia -n "$seen record" -s 'c' -l 'clipboard' -d 'Copy recording path to clipboard'
complete -c caelestia -n "$seen record" -s 'n' -l 'allow-notifs' -d 'Allow notifications to show during recording'

# Clipboard
complete -c caelestia -n "$seen clipboard" -s 'd' -l 'delete' -d 'Delete from cliboard history'
Expand Down
2 changes: 2 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ python3.pkgs.buildPythonApplication {
--replace-fail '"qs", "-c", "caelestia"' '"caelestia-shell"'
substituteInPlace src/caelestia/subcommands/screenshot.py \
--replace-fail '"qs", "-c", "caelestia"' '"caelestia-shell"'
substituteInPlace src/caelestia/subcommands/record.py \
--replace-fail '"qs", "-c", "caelestia"' '"caelestia-shell"'

# Use config bin instead of discord + fix todoist + fix app2unit
substituteInPlace src/caelestia/subcommands/toggle.py \
Expand Down
3 changes: 3 additions & 0 deletions src/caelestia/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ def parse_args() -> tuple[argparse.ArgumentParser, argparse.Namespace]:
record_parser.add_argument("-s", "--sound", action="store_true", help="record audio")
record_parser.add_argument("-p", "--pause", action="store_true", help="pause/resume the recording")
record_parser.add_argument("-c", "--clipboard", action="store_true", help="copy recording path to clipboard")
record_parser.add_argument(
"-n", "--allow-notifs", action="store_true", help="allow notifications to show during recording"
)

# Create parser for clipboard opts
clipboard_parser = command_parser.add_parser("clipboard", help="open clipboard history")
Expand Down
33 changes: 32 additions & 1 deletion src/caelestia/subcommands/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
from pathlib import Path

from caelestia.utils.notify import close_notification, notify
from caelestia.utils.paths import recording_notif_path, recording_path, recordings_dir, user_config_path
from caelestia.utils.paths import (
recording_dnd_state_path,
recording_notif_path,
recording_path,
recordings_dir,
user_config_path,
)

RECORDER = "gpu-screen-recorder"

Expand All @@ -33,6 +39,25 @@ def proc_running(self) -> bool:
def intersects(self, a: tuple[int, int, int, int], b: tuple[int, int, int, int]) -> bool:
return a[0] < b[0] + b[2] and a[0] + a[2] > b[0] and a[1] < b[1] + b[3] and a[1] + a[3] > b[1]

def set_dnd(self, enable: bool) -> None:
subprocess.run(["qs", "-c", "caelestia", "ipc", "call", "notifs", "enableDnd" if enable else "disableDnd"])

def save_dnd_state(self) -> None:
state = subprocess.check_output(
["qs", "-c", "caelestia", "ipc", "call", "notifs", "isDndEnabled"], text=True
).strip() == "true"
recording_dnd_state_path.write_text("true" if state else "false")

def restore_dnd_state(self) -> None:
try:
state = recording_dnd_state_path.read_text().strip() == "true"
self.set_dnd(state)
except FileNotFoundError:
return
finally:
recording_dnd_state_path.unlink(missing_ok=True)


def start(self) -> None:
args = ["-w"]

Expand Down Expand Up @@ -74,13 +99,18 @@ def start(self) -> None:
raise ValueError(f"Config option 'record.extraArgs' should be an array: {e}")

recording_path.parent.mkdir(parents=True, exist_ok=True)

if not self.args.allow_notifs:
self.save_dnd_state()
self.set_dnd(True)
proc = subprocess.Popen([RECORDER, *args, "-o", str(recording_path)], start_new_session=True)

notif = notify("-p", "Recording started", "Recording...")
recording_notif_path.write_text(notif)

try:
if proc.wait(1) != 0:
self.restore_dnd_state()
close_notification(notif)
notify(
"Recording failed",
Expand All @@ -93,6 +123,7 @@ def start(self) -> None:
def stop(self) -> None:
# Start killing recording process
subprocess.run(["pkill", "-f", RECORDER], stdout=subprocess.DEVNULL)
self.restore_dnd_state()

# Wait for recording to finish to avoid corrupted video file
while self.proc_running():
Expand Down
1 change: 1 addition & 0 deletions src/caelestia/utils/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
recordings_dir: Path = Path(os.getenv("CAELESTIA_RECORDINGS_DIR", videos_dir / "Recordings"))
recording_path: Path = c_state_dir / "record/recording.mp4"
recording_notif_path: Path = c_state_dir / "record/notifid.txt"
recording_dnd_state_path: Path = c_state_dir / "record/dnd_state.txt"


def compute_hash(path: Path | str) -> str:
Expand Down