Files
Modus/modules/launcher/plugins/applications.py
T
2025-06-13 21:00:45 +05:45

79 lines
2.4 KiB
Python

from typing import List, Dict, Any
from fabric.utils import get_desktop_applications, DesktopApp, exec_shell_command_async
from . import LauncherPlugin
class ApplicationsPlugin(LauncherPlugin):
"""Plugin for searching desktop applications"""
@property
def name(self) -> str:
return "Applications"
@property
def category(self) -> str:
return "Applications"
@property
def icon_name(self) -> str:
return "application-x-executable-symbolic"
def search(self, query: str) -> List[Dict[str, Any]]:
all_apps = get_desktop_applications()
# Filter apps based on query
filtered_apps = [
app
for app in all_apps
if query.casefold()
in (
(app.display_name or "")
+ (" " + app.name + " ")
+ (app.generic_name or "")
).casefold()
]
# Sort by relevance - exact matches first
if query:
exact_matches = []
partial_matches = []
for app in filtered_apps:
name = (app.display_name or app.name or "").casefold()
if name == query.casefold() or name.startswith(query.casefold()):
exact_matches.append(app)
else:
partial_matches.append(app)
filtered_apps = exact_matches + partial_matches
# Convert to result format
results = []
for app in filtered_apps:
results.append(
{
"title": app.display_name or app.name or "Unknown",
"description": app.description or "Application",
"icon": app, # Pass the whole app object for icon rendering
"action": lambda app=app: self.launch_app(app),
"app": app, # Store the original app object
}
)
return results
def launch_app(self, app: DesktopApp):
command = (
" ".join([arg for arg in app.command_line.split() if "%" not in arg])
if app.command_line
else None
)
(
exec_shell_command_async(
f"hyprctl dispatch exec -- {command}",
lambda *_: print(f"Launched {app.name}"),
)
if command
else None
)