🔧 This commit includes various changes to the launcher, such as updating colors and icons in the config files. New plugins, like 'scripts' and 'kanban', have been added along with new features in existing plugins like 'bluetooth' and 'screencapture'. Notifications have been improved with better error handling and a new service for caching notifications. The scripts plugin now supports more system utilities and commands, providing better control over the system.

This commit is contained in:
sankalp committed 2025-06-19 21:55:00 +05:45
1 parent e0691986c2
commit 761e7bfd61
13 files changed
+746 -378

No files matched your search

+21 -65
View File
@@ -29,7 +29,7 @@ class BluetoothPlugin(PluginBase):
def initialize(self):
"""Initialize the bluetooth plugin."""
self.set_triggers(["bt", "bt "])
self.set_triggers(["bluetooth", "bt", "blue"])
def cleanup(self):
"""Cleanup the bluetooth plugin."""
@@ -41,7 +41,6 @@ class BluetoothPlugin(PluginBase):
if self._scan_timeout_id:
try:
from gi.repository import GLib
GLib.source_remove(self._scan_timeout_id)
self._scan_timeout_id = None
except Exception:
@@ -65,9 +64,7 @@ class BluetoothPlugin(PluginBase):
self.bluetooth_client.connect("device-added", self._on_device_changed)
self.bluetooth_client.connect("device-removed", self._on_device_changed)
self._bluetooth_available = True
print("✓ Bluetooth client initialized successfully")
except TimeoutError:
print("Warning: Bluetooth client initialization timed out")
self.bluetooth_client = None
except Exception as e:
print(f"Warning: Failed to initialize BluetoothClient: {e}")
@@ -117,15 +114,9 @@ class BluetoothPlugin(PluginBase):
battery_info = ""
if device.battery_percentage > 0:
battery_info = f" ({device.battery_percentage:.0f}%)"
return (
f"Connected to {device.alias}",
f"Device: {device.type}{battery_info}",
)
return f"Connected to {device.alias}", f"Device: {device.type}{battery_info}"
else:
return (
f"Connected to {len(connected_devices)} devices",
"Multiple devices connected",
)
return f"Connected to {len(connected_devices)} devices", "Multiple devices connected"
elif self.bluetooth_client.scanning:
return "Scanning for devices...", "Looking for nearby Bluetooth devices"
else:
@@ -135,11 +126,7 @@ class BluetoothPlugin(PluginBase):
"""Get appropriate icon for a bluetooth device based on its type."""
device_type = device.type.lower()
if (
"audio" in device_type
or "headphone" in device_type
or "headset" in device_type
):
if "audio" in device_type or "headphone" in device_type or "headset" in device_type:
return icons.headphones
elif "mouse" in device_type or "keyboard" in device_type:
return icons.keyboard
@@ -166,7 +153,6 @@ class BluetoothPlugin(PluginBase):
if self._scan_timeout_id:
try:
from gi.repository import GLib
GLib.source_remove(self._scan_timeout_id)
self._scan_timeout_id = None
except Exception:
@@ -194,14 +180,12 @@ class BluetoothPlugin(PluginBase):
def _stop_scanning(self):
"""Stop bluetooth scanning."""
if self.bluetooth_client and self.bluetooth_client.scanning:
print("Stopping bluetooth scanning...")
self.bluetooth_client.scanning = False
# Cancel any pending auto-stop timeout
if self._scan_timeout_id:
try:
from gi.repository import GLib
GLib.source_remove(self._scan_timeout_id)
self._scan_timeout_id = None
except Exception:
@@ -216,16 +200,13 @@ class BluetoothPlugin(PluginBase):
# Stop scanning if plugin hasn't been used for 10 seconds
import time
current_time = time.time()
if current_time - self._last_query_time > 10:
print("Stopping bluetooth scan due to inactivity...")
self._stop_scanning()
def _connect_device(self, device: BluetoothDevice):
"""Connect to a bluetooth device."""
if device and not device.connected:
print(f"Connecting to {device.alias}...")
device.connected = True # This will trigger the connection
# Force launcher refresh to show updated status
self._force_launcher_refresh()
@@ -234,7 +215,6 @@ class BluetoothPlugin(PluginBase):
def _disconnect_device(self, device: BluetoothDevice):
"""Disconnect from a bluetooth device."""
if device and device.connected:
print(f"Disconnecting from {device.alias}...")
device.connected = False # This will trigger the disconnection
# Force launcher refresh to show updated status
self._force_launcher_refresh()
@@ -242,18 +222,14 @@ class BluetoothPlugin(PluginBase):
def _create_connect_action(self, device: BluetoothDevice):
"""Create a connect action function with proper closure."""
def connect_action():
return self._connect_device(device)
return connect_action
def _create_disconnect_action(self, device: BluetoothDevice):
"""Create a disconnect action function with proper closure."""
def disconnect_action():
return self._disconnect_device(device)
return disconnect_action
def _force_launcher_refresh(self):
@@ -266,16 +242,13 @@ class BluetoothPlugin(PluginBase):
try:
# Try to access the launcher through the fabric Application
from fabric import Application
app = Application.get_default()
if app and hasattr(app, "launcher"):
if app and hasattr(app, 'launcher'):
launcher = app.launcher
if launcher and hasattr(launcher, "_perform_search"):
if launcher and hasattr(launcher, '_perform_search'):
# Get current query and trigger a search
current_query = (
launcher.query if hasattr(launcher, "query") else ""
)
current_query = launcher.query if hasattr(launcher, 'query') else ""
if not current_query:
# If no query, use the trigger to force refresh
current_query = "bt list"
@@ -286,15 +259,9 @@ class BluetoothPlugin(PluginBase):
# Fallback: try to find launcher instance through other means
import gc
for obj in gc.get_objects():
if (
hasattr(obj, "__class__")
and obj.__class__.__name__ == "Launcher"
):
if hasattr(obj, "_perform_search") and hasattr(
obj, "query"
):
if hasattr(obj, '__class__') and obj.__class__.__name__ == 'Launcher':
if hasattr(obj, '_perform_search') and hasattr(obj, 'query'):
current_query = obj.query if obj.query else "bt list"
obj._perform_search(current_query)
return False
@@ -314,16 +281,12 @@ class BluetoothPlugin(PluginBase):
"""Process bluetooth queries."""
# Update last query time to track plugin activity
import time
self._last_query_time = time.time()
# Schedule periodic check for inactive scanning
try:
from gi.repository import GLib
GLib.timeout_add_seconds(
15, lambda: (self._check_and_stop_inactive_scanning(), False)
)
GLib.timeout_add_seconds(15, lambda: (self._check_and_stop_inactive_scanning(), False))
except Exception:
pass
@@ -377,6 +340,7 @@ class BluetoothPlugin(PluginBase):
)
)
else:
results.append(
Result(
@@ -447,10 +411,7 @@ class BluetoothPlugin(PluginBase):
relevance = 1.0
elif device.connecting:
subtitle = f"Connecting... • {device.type}"
def action():
return None
action = lambda: None
relevance = 0.9
else:
subtitle = f"Disconnected • {device.type} • Click to connect"
@@ -470,7 +431,7 @@ class BluetoothPlugin(PluginBase):
"device_address": device.address,
"device_name": device.alias,
"connected": device.connected,
"keep_launcher_open": True,
"keep_launcher_open": True
},
)
)
@@ -509,14 +470,14 @@ class BluetoothPlugin(PluginBase):
return results
# Search for devices by name (like network plugin search)
if self.bluetooth_client and self.bluetooth_client.enabled:
devices = self.bluetooth_client.devices
matching_devices = [
device
for device in devices
if query_lower in device.alias.lower()
or query_lower in device.name.lower()
device for device in devices
if query_lower in device.alias.lower() or query_lower in device.name.lower()
]
if matching_devices:
@@ -540,10 +501,7 @@ class BluetoothPlugin(PluginBase):
relevance = 1.0
elif device.connecting:
subtitle = f"Connecting... • {device.type}"
def action():
return None
action = lambda: None
relevance = 0.9
else:
subtitle = f"Disconnected • {device.type} • Click to connect"
@@ -563,7 +521,7 @@ class BluetoothPlugin(PluginBase):
"device_address": device.address,
"device_name": device.alias,
"connected": device.connected,
"keep_launcher_open": True,
"keep_launcher_open": True
},
)
)
@@ -591,13 +549,11 @@ class BluetoothPlugin(PluginBase):
title="Bluetooth Not Available",
subtitle="Enable Bluetooth to search for devices",
icon_markup=icons.bluetooth_off,
action=lambda: self._toggle_bluetooth()
if self.bluetooth_client
else None,
action=lambda: self._toggle_bluetooth() if self.bluetooth_client else None,
relevance=0.5,
plugin_name=self.display_name,
data={"type": "info"},
)
)
return results
return results