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)
|
_storeXmodmap(_cthulhuModifiers)
|
||||||
_createCthulhuXmodmap()
|
_createCthulhuXmodmap()
|
||||||
|
|
||||||
activePlugins = list(_settingsManager.getSetting('activePlugins'))
|
# Safe plugin initialization
|
||||||
cthulhuApp.getPluginSystemManager().setActivePlugins(activePlugins)
|
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()
|
_scriptManager.activate()
|
||||||
_eventManager.activate()
|
_eventManager.activate()
|
||||||
@ -1018,8 +1029,7 @@ class Cthulhu(GObject.Object):
|
|||||||
self.APIHelper = APIHelper(self)
|
self.APIHelper = APIHelper(self)
|
||||||
self.createCompatAPI()
|
self.createCompatAPI()
|
||||||
self.pluginSystemManager = plugin_system_manager.PluginSystemManager(self)
|
self.pluginSystemManager = plugin_system_manager.PluginSystemManager(self)
|
||||||
# Scan for available plugins at startup
|
# DO NOT scan for plugins during initialization - will be done later in loadUserSettings
|
||||||
self.pluginSystemManager.rescanPlugins()
|
|
||||||
def getAPIHelper(self):
|
def getAPIHelper(self):
|
||||||
return self.APIHelper
|
return self.APIHelper
|
||||||
def getPluginSystemManager(self):
|
def getPluginSystemManager(self):
|
||||||
|
@ -222,7 +222,8 @@ class PluginSystemManager:
|
|||||||
|
|
||||||
# Simple regex-like search for class definition that inherits from Plugin
|
# Simple regex-like search for class definition that inherits from Plugin
|
||||||
import re
|
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:
|
if matches:
|
||||||
return matches[0]
|
return matches[0]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -271,11 +272,25 @@ class PluginSystemManager:
|
|||||||
logger.info(f"Active plugins: {self._active_plugins}")
|
logger.info(f"Active plugins: {self._active_plugins}")
|
||||||
|
|
||||||
# Find missing 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:
|
if missing_plugins:
|
||||||
logger.warning(f"Active plugins not found: {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):
|
def setPluginActive(self, pluginInfo, active):
|
||||||
"""Set the active state of a plugin."""
|
"""Set the active state of a plugin."""
|
||||||
@ -335,12 +350,20 @@ class PluginSystemManager:
|
|||||||
logger.warning("Pluggy not available, skipping plugin sync")
|
logger.warning("Pluggy not available, skipping plugin sync")
|
||||||
return
|
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
|
# Log plugin status before syncing
|
||||||
if PLUGIN_DEBUG:
|
if PLUGIN_DEBUG:
|
||||||
for pluginInfo in self.plugins:
|
for pluginInfo in self.plugins:
|
||||||
is_active = self.isPluginActive(pluginInfo)
|
try:
|
||||||
is_loaded = pluginInfo.loaded
|
is_active = self.isPluginActive(pluginInfo)
|
||||||
logger.debug(f"Plugin {pluginInfo.get_module_name()}: active={is_active}, loaded={is_loaded}")
|
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:
|
try:
|
||||||
# First unload inactive plugins
|
# First unload inactive plugins
|
||||||
@ -368,13 +391,52 @@ class PluginSystemManager:
|
|||||||
|
|
||||||
def loadPlugin(self, pluginInfo):
|
def loadPlugin(self, pluginInfo):
|
||||||
"""Load a plugin."""
|
"""Load a plugin."""
|
||||||
# Skip if pluggy is not available
|
# Set a reasonable timeout for plugin loading - 10 seconds
|
||||||
if not PLUGGY_AVAILABLE:
|
import threading
|
||||||
logger.info(f"Skipping plugin {pluginInfo.get_name()}: pluggy not available")
|
import time
|
||||||
return False
|
|
||||||
|
# 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()
|
module_name = pluginInfo.get_module_name()
|
||||||
logger.info(f"Attempting to load plugin: {module_name}")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Already loaded?
|
# Already loaded?
|
||||||
@ -400,11 +462,18 @@ class PluginSystemManager:
|
|||||||
logger.error(f"Plugin file not found: {plugin_file}")
|
logger.error(f"Plugin file not found: {plugin_file}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# Add a delay to improve stability
|
||||||
|
import time
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
logger.info(f"Loading plugin from: {plugin_file}")
|
logger.info(f"Loading plugin from: {plugin_file}")
|
||||||
spec = importlib.util.spec_from_file_location(module_name, plugin_file)
|
spec = importlib.util.spec_from_file_location(module_name, plugin_file)
|
||||||
if spec is None:
|
if spec is None:
|
||||||
logger.error(f"Failed to create spec for plugin: {module_name}")
|
logger.error(f"Failed to create spec for plugin: {module_name}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# Add another small delay
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
module = importlib.util.module_from_spec(spec)
|
module = importlib.util.module_from_spec(spec)
|
||||||
spec.loader.exec_module(module)
|
spec.loader.exec_module(module)
|
||||||
@ -450,6 +519,9 @@ class PluginSystemManager:
|
|||||||
logger.info(f"Registering plugin with pluggy: {module_name}")
|
logger.info(f"Registering plugin with pluggy: {module_name}")
|
||||||
self.plugin_manager.register(plugin_instance)
|
self.plugin_manager.register(plugin_instance)
|
||||||
|
|
||||||
|
# Add another small delay
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logger.info(f"Activating plugin: {module_name}")
|
logger.info(f"Activating plugin: {module_name}")
|
||||||
self.plugin_manager.hook.activate(plugin=plugin_instance)
|
self.plugin_manager.hook.activate(plugin=plugin_instance)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user