Attempt to stop plugins from spontaneously re-enabling themselves.
This commit is contained in:
@@ -85,12 +85,16 @@ class Backend:
|
||||
with open(fileName, 'w', encoding='utf-8') as settingsFile:
|
||||
settingsFile.write(dumps(prefsDoc))
|
||||
|
||||
def _updateTable(self, targetTable, newValues):
|
||||
def _updateTable(self, targetTable, newValues, preserveMissingKeys=None):
|
||||
if not isinstance(newValues, dict):
|
||||
return
|
||||
|
||||
preserveMissingKeys = set(preserveMissingKeys or [])
|
||||
|
||||
for key in list(targetTable.keys()):
|
||||
if key not in newValues:
|
||||
if key in preserveMissingKeys:
|
||||
continue
|
||||
del targetTable[key]
|
||||
continue
|
||||
newValue = newValues[key]
|
||||
@@ -173,7 +177,12 @@ class Backend:
|
||||
profiles[profile] = {}
|
||||
profileTable = profiles[profile]
|
||||
|
||||
self._updateTable(profileTable, general)
|
||||
# Keep plugin persistence keys when callers provide partial updates.
|
||||
self._updateTable(
|
||||
profileTable,
|
||||
general,
|
||||
preserveMissingKeys={"activePlugins", "pluginSources"},
|
||||
)
|
||||
self._writeDocument(self.settingsFile, prefsDoc)
|
||||
|
||||
def _getSettings(self):
|
||||
@@ -219,6 +228,9 @@ class Backend:
|
||||
self._getSettings()
|
||||
generalSettings = self.general.copy()
|
||||
generalSettings = self._migrateSettings(generalSettings)
|
||||
# Plugin state is profile-scoped; ignore legacy/global values.
|
||||
generalSettings.pop('activePlugins', None)
|
||||
generalSettings.pop('pluginSources', None)
|
||||
defaultProfile = generalSettings.get('startingProfile',
|
||||
['Default', 'default'])
|
||||
if profile is None:
|
||||
|
||||
@@ -21,10 +21,8 @@ from gi.repository import Gtk, Gdk, Pango
|
||||
from cthulhu.plugin import Plugin, cthulhu_hookimpl
|
||||
from cthulhu import cthulhu
|
||||
from cthulhu import debug
|
||||
from cthulhu import settings_manager
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
_settingsManager = None # Removed - use cthulhu.cthulhuApp.settingsManager
|
||||
|
||||
|
||||
class PluginManager(Plugin):
|
||||
@@ -473,25 +471,11 @@ class PluginManager(Plugin):
|
||||
current_general['activePlugins'] = active_plugins
|
||||
|
||||
cthulhu.cthulhuApp.settingsManager.profile = profile_name
|
||||
cthulhu.cthulhuApp.settingsManager._setProfileGeneral(current_general)
|
||||
|
||||
pronunciations = cthulhu.cthulhuApp.settingsManager.getPronunciations(profile_name) or {}
|
||||
keybindings = cthulhu.cthulhuApp.settingsManager.getKeybindings(profile_name) or {}
|
||||
|
||||
backend = cthulhu.cthulhuApp.settingsManager._backend
|
||||
if backend:
|
||||
backend.saveProfileSettings(
|
||||
profile_name,
|
||||
cthulhu.cthulhuApp.settingsManager.profileGeneral,
|
||||
pronunciations,
|
||||
keybindings
|
||||
)
|
||||
debug.printMessage(debug.LEVEL_INFO, f"PluginManager: Settings saved to backend (profile {profile_name})", True)
|
||||
else:
|
||||
debug.printMessage(debug.LEVEL_INFO, "PluginManager: No backend available for saving", True)
|
||||
cthulhu.cthulhuApp.settingsManager.saveProfileSettings(current_general)
|
||||
debug.printMessage(debug.LEVEL_INFO, f"PluginManager: Settings saved via settings manager (profile {profile_name})", True)
|
||||
|
||||
except Exception as save_error:
|
||||
debug.printMessage(debug.LEVEL_INFO, f"PluginManager: Error saving via backend: {save_error}", True)
|
||||
debug.printMessage(debug.LEVEL_INFO, f"PluginManager: Error saving plugin state: {save_error}", True)
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, f"PluginManager: Updated active plugins: {active_plugins}", True)
|
||||
|
||||
|
||||
@@ -379,6 +379,18 @@ class SettingsManager(object):
|
||||
def getSetting(self, settingName: str) -> Any:
|
||||
return getattr(settings, settingName, None)
|
||||
|
||||
def _getListSetting(self, settingName: str) -> List[str]:
|
||||
value = self.getSetting(settingName)
|
||||
if isinstance(value, (list, tuple)):
|
||||
return [item for item in value if isinstance(item, str)]
|
||||
return []
|
||||
|
||||
def _ensurePluginPersistenceSettings(self, general: Dict[str, Any]) -> None:
|
||||
if 'activePlugins' not in general:
|
||||
general['activePlugins'] = self._getListSetting('activePlugins')
|
||||
if 'pluginSources' not in general:
|
||||
general['pluginSources'] = self._getListSetting('pluginSources')
|
||||
|
||||
def getVoiceLocale(self, voice: str = 'default') -> str:
|
||||
voices = self.getSetting('voices')
|
||||
v = ACSS(voices.get(voice, {}))
|
||||
@@ -626,6 +638,8 @@ class SettingsManager(object):
|
||||
continue
|
||||
elif key == 'profile':
|
||||
self.profileGeneral[key] = value
|
||||
elif key in ['activePlugins', 'pluginSources']:
|
||||
self.profileGeneral[key] = copy.deepcopy(value)
|
||||
elif value != self.defaultGeneral.get(key):
|
||||
self.profileGeneral[key] = value
|
||||
elif self.general.get(key) != value:
|
||||
@@ -634,6 +648,46 @@ class SettingsManager(object):
|
||||
msg = 'SETTINGS MANAGER: General settings for profile set'
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
def saveProfileSettings(
|
||||
self,
|
||||
general: Dict[str, Any],
|
||||
pronunciations: Optional[Dict[str, Any]] = None,
|
||||
keybindings: Optional[Dict[str, Any]] = None,
|
||||
) -> None:
|
||||
profileName: Optional[str] = self.profile
|
||||
profileSetting = general.get('profile')
|
||||
if isinstance(profileSetting, (list, tuple)) and len(profileSetting) > 1:
|
||||
profileName = profileSetting[1]
|
||||
elif not profileName:
|
||||
defaultProfile = settings.profile
|
||||
if isinstance(defaultProfile, (list, tuple)) and len(defaultProfile) > 1:
|
||||
profileName = defaultProfile[1]
|
||||
else:
|
||||
profileName = 'default'
|
||||
|
||||
self.profile = profileName
|
||||
generalCopy = dict(general)
|
||||
self._ensurePluginPersistenceSettings(generalCopy)
|
||||
self._setProfileGeneral(generalCopy)
|
||||
|
||||
if self.profile is None:
|
||||
return
|
||||
|
||||
profileName = self.profile
|
||||
if pronunciations is None:
|
||||
pronunciations = self.getPronunciations(profileName) or {}
|
||||
if keybindings is None:
|
||||
keybindings = self.getKeybindings(profileName) or {}
|
||||
|
||||
self._setProfilePronunciations(pronunciations)
|
||||
self._setProfileKeybindings(keybindings)
|
||||
|
||||
if self._backend:
|
||||
self._backend.saveProfileSettings(self.profile,
|
||||
self.profileGeneral,
|
||||
self.profilePronunciations,
|
||||
self.profileKeybindings)
|
||||
|
||||
def _setProfilePronunciations(self, pronunciations: Dict[str, Any]) -> None:
|
||||
"""Set the changed pronunciations settings from the defaults' ones
|
||||
as the profile's."""
|
||||
@@ -664,9 +718,12 @@ class SettingsManager(object):
|
||||
if not self._backend:
|
||||
return
|
||||
|
||||
profileScopedKeys = {'activePlugins', 'pluginSources'}
|
||||
appGeneral = {}
|
||||
profileGeneral = self.getGeneralSettings(self.profile) if self.profile else {}
|
||||
for key, value in general.items():
|
||||
if key in profileScopedKeys:
|
||||
continue
|
||||
if value != profileGeneral.get(key):
|
||||
appGeneral[key] = value
|
||||
|
||||
@@ -705,24 +762,17 @@ class SettingsManager(object):
|
||||
currentProfile = _profile[1]
|
||||
|
||||
self.profile = currentProfile
|
||||
self._ensurePluginPersistenceSettings(general)
|
||||
|
||||
# Elements that need to stay updated in main configuration.
|
||||
self.defaultGeneral['startingProfile'] = general.get('startingProfile',
|
||||
_profile)
|
||||
|
||||
self._setProfileGeneral(general)
|
||||
self._setProfilePronunciations(pronunciations)
|
||||
self._setProfileKeybindings(keybindings)
|
||||
self.saveProfileSettings(general, pronunciations, keybindings)
|
||||
|
||||
tokens = ["SETTINGS MANAGER: Saving for backend", self._backend]
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
|
||||
if self._backend and self.profile:
|
||||
self._backend.saveProfileSettings(self.profile,
|
||||
self.profileGeneral,
|
||||
self.profilePronunciations,
|
||||
self.profileKeybindings)
|
||||
|
||||
tokens = ["SETTINGS MANAGER: Settings for", script, "(app:", script.app, ") saved"]
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
return self._enableAccessibility()
|
||||
|
||||
Reference in New Issue
Block a user