Oops, I broke it. Hopefully cthulhu will actually run again.
This commit is contained in:
parent
fd2e782b5b
commit
7ef8ea8ce3
@ -610,8 +610,19 @@ def loadUserSettings(script=None, inputEvent=None, skipReloadMessage=False):
|
||||
_storeXmodmap(_cthulhuModifiers)
|
||||
_createCthulhuXmodmap()
|
||||
|
||||
activePlugins = list(_settingsManager.getSetting('activePlugins'))
|
||||
cthulhuApp.getPluginSystemManager().setActivePlugins(activePlugins)
|
||||
# Safe plugin initialization
|
||||
try:
|
||||
debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Loading plugins', True)
|
||||
pluginManager = cthulhuApp.getPluginSystemManager()
|
||||
pluginManager.rescanPlugins() # First scan for available plugins
|
||||
|
||||
activePlugins = list(_settingsManager.getSetting('activePlugins'))
|
||||
debug.printMessage(debug.LEVEL_INFO, f'CTHULHU: Setting active plugins: {activePlugins}', True)
|
||||
pluginManager.setActivePlugins(activePlugins)
|
||||
except Exception as e:
|
||||
debug.printMessage(debug.LEVEL_WARNING, f'CTHULHU: Error loading plugins: {e}', True)
|
||||
import traceback
|
||||
debug.printMessage(debug.LEVEL_INFO, traceback.format_exc(), True)
|
||||
|
||||
_scriptManager.activate()
|
||||
_eventManager.activate()
|
||||
@ -1018,8 +1029,7 @@ class Cthulhu(GObject.Object):
|
||||
self.APIHelper = APIHelper(self)
|
||||
self.createCompatAPI()
|
||||
self.pluginSystemManager = plugin_system_manager.PluginSystemManager(self)
|
||||
# Scan for available plugins at startup
|
||||
self.pluginSystemManager.rescanPlugins()
|
||||
# DO NOT scan for plugins during initialization - will be done later in loadUserSettings
|
||||
def getAPIHelper(self):
|
||||
return self.APIHelper
|
||||
def getPluginSystemManager(self):
|
||||
|
@ -222,7 +222,8 @@ class PluginSystemManager:
|
||||
|
||||
# Simple regex-like search for class definition that inherits from Plugin
|
||||
import re
|
||||
matches = re.findall(r'class\s+(\w+)\s*\([^)]*Plugin[^)]*\)', content)
|
||||
# Simpler regex to reduce chance of regex hang
|
||||
matches = re.findall(r'class\s+(\w+).*Plugin', content)
|
||||
if matches:
|
||||
return matches[0]
|
||||
except Exception as e:
|
||||
@ -271,11 +272,25 @@ class PluginSystemManager:
|
||||
logger.info(f"Active plugins: {self._active_plugins}")
|
||||
|
||||
# Find missing plugins
|
||||
missing_plugins = [p for p in self._active_plugins if p not in available_plugins]
|
||||
missing_plugins = [p for p in self._active_plugins if p not in available_plugins and p.lower() not in [x.lower() for x in available_plugins]]
|
||||
if missing_plugins:
|
||||
logger.warning(f"Active plugins not found: {missing_plugins}")
|
||||
|
||||
self.syncAllPluginsActive()
|
||||
|
||||
# Start plugin activation in a background thread
|
||||
import threading
|
||||
def activate_plugins_thread():
|
||||
try:
|
||||
self.syncAllPluginsActive()
|
||||
except Exception as e:
|
||||
logger.error(f"Error activating plugins: {e}")
|
||||
import traceback
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
# Start a background thread for plugin activation
|
||||
thread = threading.Thread(target=activate_plugins_thread)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
logger.info("Plugin activation started in background thread")
|
||||
|
||||
def setPluginActive(self, pluginInfo, active):
|
||||
"""Set the active state of a plugin."""
|
||||
@ -335,12 +350,20 @@ class PluginSystemManager:
|
||||
logger.warning("Pluggy not available, skipping plugin sync")
|
||||
return
|
||||
|
||||
# Don't do anything if there are no plugins
|
||||
if not self.plugins:
|
||||
logger.warning("No plugins found, skipping plugin sync")
|
||||
return
|
||||
|
||||
# Log plugin status before syncing
|
||||
if PLUGIN_DEBUG:
|
||||
for pluginInfo in self.plugins:
|
||||
is_active = self.isPluginActive(pluginInfo)
|
||||
is_loaded = pluginInfo.loaded
|
||||
logger.debug(f"Plugin {pluginInfo.get_module_name()}: active={is_active}, loaded={is_loaded}")
|
||||
try:
|
||||
is_active = self.isPluginActive(pluginInfo)
|
||||
is_loaded = pluginInfo.loaded
|
||||
logger.debug(f"Plugin {pluginInfo.get_module_name()}: active={is_active}, loaded={is_loaded}")
|
||||
except Exception as e:
|
||||
logger.error(f"Error checking plugin status: {e}")
|
||||
|
||||
try:
|
||||
# First unload inactive plugins
|
||||
@ -368,13 +391,52 @@ class PluginSystemManager:
|
||||
|
||||
def loadPlugin(self, pluginInfo):
|
||||
"""Load a plugin."""
|
||||
# Skip if pluggy is not available
|
||||
if not PLUGGY_AVAILABLE:
|
||||
logger.info(f"Skipping plugin {pluginInfo.get_name()}: pluggy not available")
|
||||
return False
|
||||
# Set a reasonable timeout for plugin loading - 10 seconds
|
||||
import threading
|
||||
import time
|
||||
|
||||
# Create an event to signal when loading is done
|
||||
load_complete = threading.Event()
|
||||
result = [False] # Use a list to store result from the thread
|
||||
|
||||
# Create a thread to load the plugin
|
||||
def load_plugin_thread():
|
||||
try:
|
||||
# Skip if pluggy is not available
|
||||
if not PLUGGY_AVAILABLE:
|
||||
logger.info(f"Skipping plugin {pluginInfo.get_name()}: pluggy not available")
|
||||
result[0] = False
|
||||
load_complete.set()
|
||||
return
|
||||
|
||||
module_name = pluginInfo.get_module_name()
|
||||
logger.info(f"Attempting to load plugin: {module_name}")
|
||||
|
||||
# Actual loading logic will continue below
|
||||
result[0] = self._load_plugin_impl(pluginInfo)
|
||||
except Exception as e:
|
||||
logger.error(f"Error in plugin loading thread: {e}")
|
||||
import traceback
|
||||
logger.error(traceback.format_exc())
|
||||
result[0] = False
|
||||
finally:
|
||||
load_complete.set()
|
||||
|
||||
# Start the loading thread
|
||||
thread = threading.Thread(target=load_plugin_thread)
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
|
||||
# Wait for loading to complete with a timeout
|
||||
if not load_complete.wait(10): # 10 second timeout
|
||||
logger.error(f"Plugin loading timeout for {pluginInfo.get_name()}")
|
||||
return False
|
||||
|
||||
return result[0]
|
||||
|
||||
def _load_plugin_impl(self, pluginInfo):
|
||||
"""Implementation of plugin loading that runs in a thread."""
|
||||
module_name = pluginInfo.get_module_name()
|
||||
logger.info(f"Attempting to load plugin: {module_name}")
|
||||
|
||||
try:
|
||||
# Already loaded?
|
||||
@ -400,11 +462,18 @@ class PluginSystemManager:
|
||||
logger.error(f"Plugin file not found: {plugin_file}")
|
||||
return False
|
||||
|
||||
# Add a delay to improve stability
|
||||
import time
|
||||
time.sleep(0.1)
|
||||
|
||||
logger.info(f"Loading plugin from: {plugin_file}")
|
||||
spec = importlib.util.spec_from_file_location(module_name, plugin_file)
|
||||
if spec is None:
|
||||
logger.error(f"Failed to create spec for plugin: {module_name}")
|
||||
return False
|
||||
|
||||
# Add another small delay
|
||||
time.sleep(0.1)
|
||||
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
@ -450,6 +519,9 @@ class PluginSystemManager:
|
||||
logger.info(f"Registering plugin with pluggy: {module_name}")
|
||||
self.plugin_manager.register(plugin_instance)
|
||||
|
||||
# Add another small delay
|
||||
time.sleep(0.1)
|
||||
|
||||
try:
|
||||
logger.info(f"Activating plugin: {module_name}")
|
||||
self.plugin_manager.hook.activate(plugin=plugin_instance)
|
||||
|
Loading…
x
Reference in New Issue
Block a user