diff --git a/README.md b/README.md index 5c9e9608..c9f46cc8 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,13 @@ subcommands: resizer window resizer daemon ``` +Examples: + +``` +# Region screenshot -> swappy preview -> clipboard +caelestia screenshot --region --clipboard +``` + ## Configuring All configuration options are in `~/.config/caelestia/cli.json`. diff --git a/completions/caelestia.fish b/completions/caelestia.fish index 5257f3f6..5baf4e3a 100644 --- a/completions/caelestia.fish +++ b/completions/caelestia.fish @@ -101,6 +101,7 @@ complete -c caelestia -n "$seen scheme && $seen set" -s 'v' -l 'variant' -d 'Set # Screenshot complete -c caelestia -n "$seen screenshot" -s 'r' -l 'region' -d 'Capture region' complete -c caelestia -n "$seen screenshot" -s 'f' -l 'freeze' -d 'Freeze while selecting region' +complete -c caelestia -n "$seen screenshot" -s 'c' -l 'clipboard' -d 'Copy region and open in editor' # Record complete -c caelestia -n "$seen record" -s 'r' -l 'region' -d 'Capture region' diff --git a/src/caelestia/parser.py b/src/caelestia/parser.py index 840ead5c..d7fe7edd 100644 --- a/src/caelestia/parser.py +++ b/src/caelestia/parser.py @@ -64,6 +64,12 @@ def parse_args() -> (argparse.ArgumentParser, argparse.Namespace): screenshot_parser.add_argument( "-f", "--freeze", action="store_true", help="freeze the screen while selecting a region" ) + screenshot_parser.add_argument( + "-c", + "--clipboard", + action="store_true", + help="copy region capture to clipboard and open it in the editor", + ) # Create parser for record opts record_parser = command_parser.add_parser("record", help="start a screen recording") diff --git a/src/caelestia/subcommands/screenshot.py b/src/caelestia/subcommands/screenshot.py index 6b4c00ad..db5cb6bb 100644 --- a/src/caelestia/subcommands/screenshot.py +++ b/src/caelestia/subcommands/screenshot.py @@ -1,6 +1,9 @@ import subprocess +import tempfile +import time from argparse import Namespace from datetime import datetime +from pathlib import Path from caelestia.utils.notify import notify from caelestia.utils.paths import screenshots_cache_dir, screenshots_dir @@ -19,6 +22,20 @@ def run(self) -> None: self.fullscreen() def region(self) -> None: + if self.args.clipboard: + geometry = self.args.region + if geometry == "slurp": + try: + geometry = subprocess.check_output(["slurp", "-d"], text=True).strip() + except subprocess.CalledProcessError: + return + + if not geometry: + return + + self.capture_region_with_clipboard(geometry.strip()) + return + if self.args.region == "slurp": subprocess.run( ["qs", "-c", "caelestia", "ipc", "call", "picker", "openFreeze" if self.args.freeze else "open"] @@ -56,3 +73,21 @@ def fullscreen(self) -> None: new_dest.parent.mkdir(exist_ok=True, parents=True) dest.rename(new_dest) notify("Screenshot saved", f"Saved to {new_dest}") + + def capture_region_with_clipboard(self, geometry: str) -> None: + tmpfile = Path(tempfile.mkstemp(prefix="caelestia-screenshot-", suffix=".png")[1]) + + try: + # Give slurp a moment to dismiss its overlay to avoid tinting the capture + time.sleep(0.05) + subprocess.run(["grim", "-g", geometry, str(tmpfile)], check=True) + + data = tmpfile.read_bytes() + subprocess.run(["wl-copy", "--type", "image/png"], input=data) + + subprocess.run(["swappy", "-f", str(tmpfile), "-o", str(tmpfile)], start_new_session=True) + + data = tmpfile.read_bytes() + subprocess.run(["wl-copy", "--type", "image/png"], input=data) + finally: + tmpfile.unlink(missing_ok=True) diff --git a/src/caelestia/subcommands/toggle.py b/src/caelestia/subcommands/toggle.py index ba5a351f..104fa657 100644 --- a/src/caelestia/subcommands/toggle.py +++ b/src/caelestia/subcommands/toggle.py @@ -79,6 +79,12 @@ def __init__(self, args: Namespace) -> None: "command": ["spicetify", "watch", "-s"], "move": True, }, + "youtube-music": { + "enable": True, + "match": [{"class": "com.github.th_ch.youtube_music"}, {"class": "youtube-music"}, {"title": "YouTube Music"}], + "command": ["youtube-music"], + "move": True, + }, "feishin": { "enable": True, "match": [{"class": "feishin"}],