diff --git a/modules/launcher/plugin_manager.py b/modules/launcher/plugin_manager.py index 2fcd550..5e1c123 100644 --- a/modules/launcher/plugin_manager.py +++ b/modules/launcher/plugin_manager.py @@ -97,8 +97,7 @@ class PluginManager: "calendar", "reminders", "network", - "bluetooth", - "scripts", + "bluetooth" ] for plugin_name in default_plugins: diff --git a/modules/launcher/plugins/bluetooth.py b/modules/launcher/plugins/bluetooth.py index 95061f5..2d98d94 100644 --- a/modules/launcher/plugins/bluetooth.py +++ b/modules/launcher/plugins/bluetooth.py @@ -29,7 +29,7 @@ class BluetoothPlugin(PluginBase): def initialize(self): """Initialize the bluetooth plugin.""" - self.set_triggers(["bluetooth", "bt", "blue"]) + self.set_triggers(["bt"]) def cleanup(self): """Cleanup the bluetooth plugin.""" diff --git a/modules/launcher/plugins/network.py b/modules/launcher/plugins/network.py index d1c21d8..ed7cf0f 100644 --- a/modules/launcher/plugins/network.py +++ b/modules/launcher/plugins/network.py @@ -104,7 +104,7 @@ class NetworkPlugin(PluginBase): def initialize(self): """Initialize the network plugin.""" - self.set_triggers(["wifi", "network", "net"]) + self.set_triggers(["net"]) def cleanup(self): """Cleanup the network plugin.""" diff --git a/modules/launcher/plugins/scripts.py b/modules/launcher/plugins/scripts.py deleted file mode 100644 index 9e17e74..0000000 --- a/modules/launcher/plugins/scripts.py +++ /dev/null @@ -1,265 +0,0 @@ -""" -Scripts plugin for the launcher. -Provides access to various system scripts and utilities. -""" - -import os -import subprocess -from typing import List - -from fabric.utils import exec_shell_command_async -import utils.icons as icons -from modules.launcher.plugin_base import PluginBase -from modules.launcher.result import Result - - -class ScriptsPlugin(PluginBase): - """ - Plugin for executing system scripts and utilities. - """ - - def __init__(self): - super().__init__() - self.display_name = "Scripts" - self.description = "System scripts and utilities" - - def initialize(self): - """Initialize the scripts plugin.""" - self.set_triggers(["script", "scripts", "cmd", "util"]) - - def cleanup(self): - """Cleanup the scripts plugin.""" - pass - - def _check_gamemode_status(self) -> bool: - """Check if gamemode (animations disabled) is currently active.""" - try: - # Use the gamemode script's check function - script_path = self._get_script_path("gamemode.sh") - result = subprocess.run( - ["bash", script_path, "check"], - capture_output=True, - text=True, - timeout=2 - ) - if result.returncode == 0: - # Script returns "t" for true (gamemode on), "f" for false (gamemode off) - return result.stdout.strip() == "t" - except Exception: - pass - return False - - def _toggle_gamemode(self): - """Toggle gamemode using the gamemode script.""" - script_path = self._get_script_path("gamemode.sh") - exec_shell_command_async(f"bash '{script_path}'") - - def _run_colorpicker(self, format_type: str): - """Run color picker with specified format.""" - script_path = self._get_script_path("hyprpicker.sh") - exec_shell_command_async(f"bash '{script_path}' -{format_type}") - - - - def _reload_css(self): - """Reload application CSS.""" - exec_shell_command_async("$fabricSend 'app.set_css()'") - - def _restart_modus(self): - """Restart Modus application.""" - exec_shell_command_async("killall modus; uwsm-app python ~/Modus/main.py") - - def _run_system_command(self, command: str): - """Run a system command.""" - exec_shell_command_async(command) - - - - def _toggle_service(self, service_name: str): - """Toggle a systemd service.""" - exec_shell_command_async(f"systemctl --user is-active {service_name} && systemctl --user stop {service_name} || systemctl --user start {service_name}") - - def _get_script_path(self, script_name: str) -> str: - """Get the full path to a script from the scripts directory.""" - # Get the current working directory (should be Modus root) - current_dir = os.getcwd() - - # Try scripts directory relative to current working directory - script_path = os.path.join(current_dir, "scripts", script_name) - if os.path.exists(script_path): - return script_path - - # Try relative to this file's location - plugin_dir = os.path.dirname(os.path.abspath(__file__)) - modus_root = os.path.dirname(os.path.dirname(os.path.dirname(plugin_dir))) - script_path = os.path.join(modus_root, "scripts", script_name) - if os.path.exists(script_path): - return script_path - - # Fallback to relative path - return f"scripts/{script_name}" - - def query(self, query_string: str) -> List[Result]: - """Search for script actions based on query.""" - query = query_string.strip().lower() - results = [] - - # Check gamemode status for dynamic display - gamemode_active = self._check_gamemode_status() - gamemode_icon = icons.gamemode if gamemode_active else icons.gamemode_off - gamemode_status = "ON" if gamemode_active else "OFF" - - # Define script actions - script_actions = { - # Gamemode - "gamemode": { - "title": f"Toggle Gamemode (Currently {gamemode_status})", - "subtitle": "Toggle Hyprland game mode - disable animations, gaps, and effects", - "icon": gamemode_icon, - "action": self._toggle_gamemode, - "keywords": ["gamemode", "game", "performance", "toggle"], - "relevance": 1.0 - }, - - # Color Picker - "colorpicker-hex": { - "title": "Color Picker (HEX)", - "subtitle": "Pick a color and copy HEX value to clipboard", - "icon": icons.colorpicker, - "action": lambda: self._run_colorpicker("hex"), - "keywords": ["color", "picker", "hex", "colorpicker"], - "relevance": 0.9 - }, - "colorpicker-rgb": { - "title": "Color Picker (RGB)", - "subtitle": "Pick a color and copy RGB value to clipboard", - "icon": icons.colorpicker, - "action": lambda: self._run_colorpicker("rgb"), - "keywords": ["color", "picker", "rgb", "colorpicker"], - "relevance": 0.9 - }, - "colorpicker-hsv": { - "title": "Color Picker (HSV)", - "subtitle": "Pick a color and copy HSV value to clipboard", - "icon": icons.colorpicker, - "action": lambda: self._run_colorpicker("hsv"), - "keywords": ["color", "picker", "hsv", "colorpicker"], - "relevance": 0.9 - }, - - - - # System Controls - "reload-css": { - "title": "Reload CSS", - "subtitle": "Reload application stylesheets", - "icon": icons.reload, - "action": self._reload_css, - "keywords": ["reload", "css", "style", "stylesheet"], - "relevance": 0.6 - }, - "restart-modus": { - "title": "Restart Modus", - "subtitle": "Restart the Modus application", - "icon": icons.reload, - "action": self._restart_modus, - "keywords": ["restart", "modus", "reload", "reboot"], - "relevance": 0.6 - }, - - - - # System Utilities - "kill-all": { - "title": "Kill All Processes", - "subtitle": "Kill all user processes (useful for cleanup)", - "icon": icons.close, - "action": lambda: self._run_system_command("killall -u $USER"), - "keywords": ["kill", "killall", "processes", "cleanup"], - "relevance": 0.5 - }, - "clear-cache": { - "title": "Clear Cache", - "subtitle": "Clear system and user cache directories", - "icon": icons.trash, - "action": lambda: self._run_system_command("rm -rf ~/.cache/* /tmp/*"), - "keywords": ["clear", "cache", "clean", "tmp", "cleanup"], - "relevance": 0.5 - }, - - - # Night Light / Blue Light Filter - "night-light": { - "title": "Toggle Night Light", - "subtitle": "Toggle blue light filter for eye comfort", - "icon": icons.night, - "action": lambda: self._run_system_command("hyprctl keyword decoration:screen_shader ~/.config/hypr/shaders/blue_light_filter.glsl"), - "keywords": ["night", "light", "blue", "filter", "eye", "comfort"], - "relevance": 0.6 - }, - - # Clipboard - "clear-clipboard": { - "title": "Clear Clipboard", - "subtitle": "Clear clipboard contents", - "icon": icons.clipboard, - "action": lambda: self._run_system_command("wl-copy --clear"), - "keywords": ["clipboard", "clear", "empty"], - "relevance": 0.5 - }, - } - - # If no query, show all actions - if not query: - for action_id, action_data in script_actions.items(): - results.append(Result( - title=action_data["title"], - subtitle=action_data["subtitle"], - icon_markup=action_data["icon"], - action=action_data["action"], - relevance=action_data["relevance"], - plugin_name=self.display_name, - data={"action_id": action_id} - )) - else: - # Search through actions - for action_id, action_data in script_actions.items(): - relevance = self._calculate_relevance(query, action_data["keywords"], action_data["title"]) - if relevance > 0: - results.append(Result( - title=action_data["title"], - subtitle=action_data["subtitle"], - icon_markup=action_data["icon"], - action=action_data["action"], - relevance=relevance, - plugin_name=self.display_name, - data={"action_id": action_id} - )) - - return sorted(results, key=lambda x: x.relevance, reverse=True) - - def _calculate_relevance(self, query: str, keywords: List[str], title: str) -> float: - """Calculate relevance score for a script action.""" - query_lower = query.lower() - title_lower = title.lower() - - # Check for exact matches in keywords - for keyword in keywords: - if query_lower == keyword.lower(): - return 1.0 - - # Check if query starts with any keyword - for keyword in keywords: - if keyword.lower().startswith(query_lower): - return 0.9 - - # Check if title contains query - if query_lower in title_lower: - return 0.8 - - # Check if any keyword contains query - for keyword in keywords: - if query_lower in keyword.lower(): - return 0.7 - - return 0.0