♻️ refactor(launcher/plugins/screencapture): use screen-capture.sh script for screenshot and screen recording functionality

This commit is contained in:
sankalp committed 2025-06-19 14:06:57 +05:45
1 parent e257ec2a2b
commit d6dee7c50d
1 file changed
+306 -34
+306 -34
View File
@@ -1,26 +1,28 @@
"""
Screencapture plugin for the launcher.
Provides screenshot and screen recording functionality.
Provides screenshot and screen recording functionality using screen-capture.sh script.
"""
import os
import subprocess
from typing import List
from modules.launcher.plugin_base import PluginBase
from modules.launcher.result import Result
from services.screencapture import ScreenCapture
from utils.icons import screenrecord, screenshots, ssfull, ssregion, stop
class ScreencapturePlugin(PluginBase):
"""
Plugin for taking screenshots and screen recordings.
Plugin for taking screenshots and screen recordings using screen-capture.sh script.
"""
def __init__(self):
super().__init__()
self.display_name = "Screencapture"
self.description = "Take screenshots and screen recordings"
self.screencapture = ScreenCapture()
# Path to the screen-capture script
self.script_path = os.path.expanduser("~/Modus/scripts/screen-capture.sh")
def initialize(self):
"""Initialize the screencapture plugin."""
@@ -30,35 +32,191 @@ class ScreencapturePlugin(PluginBase):
"""Cleanup the screencapture plugin."""
pass
def get_commands(self):
"""Return available commands for this plugin."""
return {
# Screenshot commands
"screenshot": "Take a screenshot of the main display",
"ss": "Take a screenshot of the main display",
"screenshot-region": "Take a screenshot of selected region",
"ss-region": "Take a screenshot of selected region",
"screenshot-both": "Take a screenshot of both displays",
"ss-both": "Take a screenshot of both displays",
"screenshot-hdmi": "Take a screenshot of HDMI display",
"ss-hdmi": "Take a screenshot of HDMI display",
# Recording commands (with audio)
"record": "Start recording main display with audio",
"rec": "Start recording main display with audio",
"record-region": "Start recording selected region with audio",
"rec-region": "Start recording selected region with audio",
"record-hdmi": "Start recording HDMI display with audio",
"rec-hdmi": "Start recording HDMI display with audio",
# Recording commands (no audio)
"record-noaudio": "Start recording main display without audio",
"rec-noaudio": "Start recording main display without audio",
"record-noaudio-region": "Start recording selected region without audio",
"rec-noaudio-region": "Start recording selected region without audio",
"record-noaudio-hdmi": "Start recording HDMI display without audio",
"rec-noaudio-hdmi": "Start recording HDMI display without audio",
# High-quality recording commands
"record-hq": "Start high-quality recording of main display",
"rec-hq": "Start high-quality recording of main display",
"record-hq-region": "Start high-quality recording of selected region",
"rec-hq-region": "Start high-quality recording of selected region",
"record-hq-hdmi": "Start high-quality recording of HDMI display",
"rec-hq-hdmi": "Start high-quality recording of HDMI display",
# GIF recording commands
"record-gif": "Start GIF recording of main display",
"rec-gif": "Start GIF recording of main display",
"record-gif-region": "Start GIF recording of selected region",
"rec-gif-region": "Start GIF recording of selected region",
# Control commands
"stop": "Stop current recording",
# Conversion commands
"convert-webm": "Convert recordings to WebM format",
"conv-webm": "Convert recordings to WebM format",
"convert-iphone": "Convert recordings for iPhone compatibility",
"conv-iphone": "Convert recordings for iPhone compatibility",
"convert-youtube": "Convert recordings for YouTube upload",
"conv-youtube": "Convert recordings for YouTube upload",
"convert-gif": "Convert recordings to GIF format",
"conv-gif": "Convert recordings to GIF format",
}
def _run_script(self, *args):
"""Execute the screen-capture script with given arguments."""
try:
subprocess.Popen([self.script_path] + list(args))
except Exception as e:
print(f"Error running screen-capture script: {e}")
def _is_recording(self):
"""Check if recording is currently active."""
try:
result = subprocess.run(
[self.script_path, "status"],
capture_output=True,
text=True
)
return result.stdout.strip() == "true"
except Exception:
return False
def _get_command_result(self, command: str) -> Result:
"""Get a Result object for a specific command."""
# Import here to avoid circular imports
from utils.icons import ssfull, ssregion, screenshots, screenrecord, stop
command_info = {
# Screenshot commands
"screenshot": ("Take Screenshot (eDP-1)", "Capture the main display", ssfull, lambda: self._run_script("screenshot", "eDP-1")),
"ss": ("Take Screenshot (eDP-1)", "Capture the main display", ssfull, lambda: self._run_script("screenshot", "eDP-1")),
"screenshot-region": ("Take Region Screenshot", "Capture a selected region", ssregion, lambda: self._run_script("screenshot", "selection")),
"ss-region": ("Take Region Screenshot", "Capture a selected region", ssregion, lambda: self._run_script("screenshot", "selection")),
"screenshot-both": ("Take Screenshot (Both Displays)", "Capture both displays combined", screenshots, lambda: self._run_script("screenshot", "both")),
"ss-both": ("Take Screenshot (Both Displays)", "Capture both displays combined", screenshots, lambda: self._run_script("screenshot", "both")),
"screenshot-hdmi": ("Take Screenshot (HDMI-A-1)", "Capture HDMI display", ssfull, lambda: self._run_script("screenshot", "HDMI-A-1")),
"ss-hdmi": ("Take Screenshot (HDMI-A-1)", "Capture HDMI display", ssfull, lambda: self._run_script("screenshot", "HDMI-A-1")),
# Recording commands (with audio)
"record": ("Start Recording (eDP-1)", "Record the main display with audio", screenrecord, lambda: self._run_script("record", "eDP-1")),
"rec": ("Start Recording (eDP-1)", "Record the main display with audio", screenrecord, lambda: self._run_script("record", "eDP-1")),
"record-region": ("Start Region Recording", "Record a selected region with audio", screenrecord, lambda: self._run_script("record", "selection")),
"rec-region": ("Start Region Recording", "Record a selected region with audio", screenrecord, lambda: self._run_script("record", "selection")),
"record-hdmi": ("Start Recording (HDMI-A-1)", "Record HDMI display with audio", screenrecord, lambda: self._run_script("record", "HDMI-A-1")),
"rec-hdmi": ("Start Recording (HDMI-A-1)", "Record HDMI display with audio", screenrecord, lambda: self._run_script("record", "HDMI-A-1")),
# Recording commands (no audio)
"record-noaudio": ("Start Recording No Audio (eDP-1)", "Record the main display without audio", screenrecord, lambda: self._run_script("record-noaudio", "eDP-1")),
"rec-noaudio": ("Start Recording No Audio (eDP-1)", "Record the main display without audio", screenrecord, lambda: self._run_script("record-noaudio", "eDP-1")),
"record-noaudio-region": ("Start Region Recording No Audio", "Record a selected region without audio", screenrecord, lambda: self._run_script("record-noaudio", "selection")),
"rec-noaudio-region": ("Start Region Recording No Audio", "Record a selected region without audio", screenrecord, lambda: self._run_script("record-noaudio", "selection")),
"record-noaudio-hdmi": ("Start Recording No Audio (HDMI-A-1)", "Record HDMI display without audio", screenrecord, lambda: self._run_script("record-noaudio", "HDMI-A-1")),
"rec-noaudio-hdmi": ("Start Recording No Audio (HDMI-A-1)", "Record HDMI display without audio", screenrecord, lambda: self._run_script("record-noaudio", "HDMI-A-1")),
# High-quality recording commands
"record-hq": ("Start HQ Recording (eDP-1)", "High-quality recording for YouTube", screenrecord, lambda: self._run_script("record-hq", "eDP-1")),
"rec-hq": ("Start HQ Recording (eDP-1)", "High-quality recording for YouTube", screenrecord, lambda: self._run_script("record-hq", "eDP-1")),
"record-hq-region": ("Start HQ Region Recording", "High-quality region recording", screenrecord, lambda: self._run_script("record-hq", "selection")),
"rec-hq-region": ("Start HQ Region Recording", "High-quality region recording", screenrecord, lambda: self._run_script("record-hq", "selection")),
"record-hq-hdmi": ("Start HQ Recording (HDMI-A-1)", "High-quality HDMI recording", screenrecord, lambda: self._run_script("record-hq", "HDMI-A-1")),
"rec-hq-hdmi": ("Start HQ Recording (HDMI-A-1)", "High-quality HDMI recording", screenrecord, lambda: self._run_script("record-hq", "HDMI-A-1")),
# GIF recording commands
"record-gif": ("Start GIF Recording (eDP-1)", "Record as optimized GIF", screenrecord, lambda: self._run_script("record-gif", "eDP-1")),
"rec-gif": ("Start GIF Recording (eDP-1)", "Record as optimized GIF", screenrecord, lambda: self._run_script("record-gif", "eDP-1")),
"record-gif-region": ("Start GIF Region Recording", "Record selected region as GIF", screenrecord, lambda: self._run_script("record-gif", "selection")),
"rec-gif-region": ("Start GIF Region Recording", "Record selected region as GIF", screenrecord, lambda: self._run_script("record-gif", "selection")),
# Control commands
"stop": ("Stop Recording", "Stop the current screen recording", stop, lambda: self._run_script("record", "stop")),
# Conversion commands
"convert-webm": ("Convert to WebM", "Convert MKV recordings to WebM format", screenrecord, lambda: self._run_script("convert", "webm")),
"conv-webm": ("Convert to WebM", "Convert MKV recordings to WebM format", screenrecord, lambda: self._run_script("convert", "webm")),
"convert-iphone": ("Convert for iPhone", "Convert recordings for iPhone compatibility", screenrecord, lambda: self._run_script("convert", "iphone")),
"conv-iphone": ("Convert for iPhone", "Convert recordings for iPhone compatibility", screenrecord, lambda: self._run_script("convert", "iphone")),
"convert-youtube": ("Convert for YouTube", "Convert recordings for YouTube upload", screenrecord, lambda: self._run_script("convert", "youtube")),
"conv-youtube": ("Convert for YouTube", "Convert recordings for YouTube upload", screenrecord, lambda: self._run_script("convert", "youtube")),
"convert-gif": ("Convert to GIF", "Convert video recordings to GIF", screenrecord, lambda: self._run_script("convert", "gif")),
"conv-gif": ("Convert to GIF", "Convert video recordings to GIF", screenrecord, lambda: self._run_script("convert", "gif")),
}
if command in command_info:
title, subtitle, icon, action = command_info[command]
return Result(
title=title,
subtitle=subtitle,
icon_markup=icon,
action=action,
relevance=1.0,
plugin_name=self.display_name,
)
return None
def query(self, query_string: str) -> List[Result]:
"""Search for screencapture actions based on query."""
# Remove the trigger word from the query
query = query_string.replace("screencapture", "").strip().lower()
# Clean the query string
query = query_string.strip().lower()
results = []
# If recording is active, show stop button first
if self.screencapture.is_recording:
# Check if query matches a command and return it as a result
command_result = self._get_command_result(query)
if command_result:
return [command_result]
# Check recording status
is_recording = self._is_recording()
# If recording is active, show stop button first with highest relevance
if is_recording:
results.append(
Result(
title="Stop Recording",
subtitle="Stop the current screen recording",
icon_markup=stop,
action=self.screencapture.screencast_stop,
relevance=1.0,
action=lambda: self._run_script("record", "stop"),
relevance=2.0, # Highest relevance to appear at top
plugin_name=self.display_name,
)
)
return results
# Screenshot actions
results.extend(
[
Result(
title="Take Screenshot",
subtitle="Capture the entire screen",
subtitle="Capture the entire screen (eDP-1)",
icon_markup=ssfull,
action=lambda: self.screencapture.screenshot(fullscreen=True),
action=lambda: self._run_script("screenshot", "eDP-1"),
relevance=1.0,
plugin_name=self.display_name,
),
@@ -66,29 +224,37 @@ class ScreencapturePlugin(PluginBase):
title="Take Region Screenshot",
subtitle="Capture a selected region",
icon_markup=ssregion,
action=lambda: self.screencapture.screenshot(fullscreen=False),
action=lambda: self._run_script("screenshot", "selection"),
relevance=0.9,
plugin_name=self.display_name,
),
Result(
title="Take Screenshot (Clipboard Only)",
subtitle="Capture and copy to clipboard",
title="Take Screenshot (Both Displays)",
subtitle="Capture both displays combined",
icon_markup=screenshots,
action=lambda: self.screencapture.screenshot(save_copy=False),
action=lambda: self._run_script("screenshot", "both"),
relevance=0.8,
plugin_name=self.display_name,
),
Result(
title="Take Screenshot (HDMI-A-1)",
subtitle="Capture HDMI display",
icon_markup=ssfull,
action=lambda: self._run_script("screenshot", "HDMI-A-1"),
relevance=0.7,
plugin_name=self.display_name,
),
]
)
# Screen recording actions
# Standard recording actions
results.extend(
[
Result(
title="Start Fullscreen Recording",
subtitle="Record the entire screen",
title="Start Recording (eDP-1)",
subtitle="Record the main display with audio",
icon_markup=screenrecord,
action=lambda: self.screencapture.screencast_start(fullscreen=True),
action=lambda: self._run_script("record", "eDP-1"),
relevance=0.7,
plugin_name=self.display_name,
),
@@ -96,32 +262,138 @@ class ScreencapturePlugin(PluginBase):
title="Start Region Recording",
subtitle="Record a selected region",
icon_markup=screenrecord,
action=lambda: self.screencapture.screencast_start(
fullscreen=False
),
action=lambda: self._run_script("record", "selection"),
relevance=0.6,
plugin_name=self.display_name,
),
Result(
title="Start Fullscreen Recording with Audio",
subtitle="Record entire screen with system audio",
title="Start Recording (HDMI-A-1)",
subtitle="Record HDMI display with audio",
icon_markup=screenrecord,
action=lambda: self.screencapture.screencast_start(
fullscreen=True, audio=True
),
action=lambda: self._run_script("record", "HDMI-A-1"),
relevance=0.5,
plugin_name=self.display_name,
),
]
)
# No-audio recording actions
results.extend(
[
Result(
title="Start Region Recording with Audio",
subtitle="Record selected region with system audio",
title="Start Recording No Audio (eDP-1)",
subtitle="Record the main display without audio",
icon_markup=screenrecord,
action=lambda: self.screencapture.screencast_start(
fullscreen=False, audio=True
),
action=lambda: self._run_script("record-noaudio", "eDP-1"),
relevance=0.65,
plugin_name=self.display_name,
),
Result(
title="Start Region Recording No Audio",
subtitle="Record a selected region without audio",
icon_markup=screenrecord,
action=lambda: self._run_script("record-noaudio", "selection"),
relevance=0.55,
plugin_name=self.display_name,
),
Result(
title="Start Recording No Audio (HDMI-A-1)",
subtitle="Record HDMI display without audio",
icon_markup=screenrecord,
action=lambda: self._run_script("record-noaudio", "HDMI-A-1"),
relevance=0.45,
plugin_name=self.display_name,
),
]
)
# High-quality recording actions
results.extend(
[
Result(
title="Start HQ Recording (eDP-1)",
subtitle="High-quality recording for YouTube",
icon_markup=screenrecord,
action=lambda: self._run_script("record-hq", "eDP-1"),
relevance=0.4,
plugin_name=self.display_name,
),
Result(
title="Start HQ Region Recording",
subtitle="High-quality region recording",
icon_markup=screenrecord,
action=lambda: self._run_script("record-hq", "selection"),
relevance=0.3,
plugin_name=self.display_name,
),
Result(
title="Start HQ Recording (HDMI-A-1)",
subtitle="High-quality HDMI recording",
icon_markup=screenrecord,
action=lambda: self._run_script("record-hq", "HDMI-A-1"),
relevance=0.2,
plugin_name=self.display_name,
),
]
)
# GIF recording actions
results.extend(
[
Result(
title="Start GIF Recording (eDP-1)",
subtitle="Record as optimized GIF",
icon_markup=screenrecord,
action=lambda: self._run_script("record-gif", "eDP-1"),
relevance=0.1,
plugin_name=self.display_name,
),
Result(
title="Start GIF Region Recording",
subtitle="Record selected region as GIF",
icon_markup=screenrecord,
action=lambda: self._run_script("record-gif", "selection"),
relevance=0.05,
plugin_name=self.display_name,
),
]
)
# Conversion actions
results.extend(
[
Result(
title="Convert to WebM",
subtitle="Convert MKV recordings to WebM format",
icon_markup=screenrecord,
action=lambda: self._run_script("convert", "webm"),
relevance=0.01,
plugin_name=self.display_name,
),
Result(
title="Convert for iPhone",
subtitle="Convert recordings for iPhone compatibility",
icon_markup=screenrecord,
action=lambda: self._run_script("convert", "iphone"),
relevance=0.01,
plugin_name=self.display_name,
),
Result(
title="Convert for YouTube",
subtitle="Convert recordings for YouTube upload",
icon_markup=screenrecord,
action=lambda: self._run_script("convert", "youtube"),
relevance=0.01,
plugin_name=self.display_name,
),
Result(
title="Convert to GIF",
subtitle="Convert video recordings to GIF",
icon_markup=screenrecord,
action=lambda: self._run_script("convert", "gif"),
relevance=0.01,
plugin_name=self.display_name,
),
]
)