add basic plugin capability
This commit is contained in:
parent
09bb9b149f
commit
8c21412b54
@ -28,6 +28,7 @@ Cthulhu also has the following dependencies:
|
|||||||
|
|
||||||
* Python 3 - Python platform
|
* Python 3 - Python platform
|
||||||
* pygobject-3.0 - Python bindings for the GObject library
|
* pygobject-3.0 - Python bindings for the GObject library
|
||||||
|
* libpeas - GObject based Plugin engine
|
||||||
* gtk+-3.0 - GTK+ toolkit
|
* gtk+-3.0 - GTK+ toolkit
|
||||||
* json-py - a JSON (<https://json.org/>) reader and writer in Python
|
* json-py - a JSON (<https://json.org/>) reader and writer in Python
|
||||||
* python-speechd - Python bindings for Speech Dispatcher (optional)
|
* python-speechd - Python bindings for Speech Dispatcher (optional)
|
||||||
@ -71,4 +72,4 @@ within Cthulhu as well as at: <https://help.gnome.org/users/cthulhu/stable/>
|
|||||||
|
|
||||||
So, you want to write a script for Cthulhu? The best thing to do is
|
So, you want to write a script for Cthulhu? The best thing to do is
|
||||||
start by looking at other scripts under the src/cthulhu/scripts/ hierarchy
|
start by looking at other scripts under the src/cthulhu/scripts/ hierarchy
|
||||||
of the source tree.
|
of the source tree.
|
||||||
|
2
TODO
2
TODO
@ -1,6 +1,4 @@
|
|||||||
- Add Simple Orca Plugin System as native code for Cthulhu
|
- Add Simple Orca Plugin System as native code for Cthulhu
|
||||||
- Merge Chrys' plugin work.
|
|
||||||
- Merge in sleep mode.
|
- Merge in sleep mode.
|
||||||
- Add in system for Cthulhu to have self voicing option. Probably based on socat.
|
|
||||||
- Add in ocrdesktop code so that Cthulhu has native ocr support.
|
- Add in ocrdesktop code so that Cthulhu has native ocr support.
|
||||||
- Get rid of build systems. My hope is git clone and run so long as requirements are satisfied.
|
- Get rid of build systems. My hope is git clone and run so long as requirements are satisfied.
|
||||||
|
11
configure.ac
11
configure.ac
@ -118,6 +118,17 @@ src/cthulhu/scripts/toolkits/GAIL/Makefile
|
|||||||
src/cthulhu/scripts/toolkits/Qt/Makefile
|
src/cthulhu/scripts/toolkits/Qt/Makefile
|
||||||
src/cthulhu/scripts/toolkits/WebKitGtk/Makefile
|
src/cthulhu/scripts/toolkits/WebKitGtk/Makefile
|
||||||
src/cthulhu/scripts/toolkits/gtk/Makefile
|
src/cthulhu/scripts/toolkits/gtk/Makefile
|
||||||
|
src/cthulhu/plugins/Makefile
|
||||||
|
src/cthulhu/plugins/ByeCthulhu/Makefile
|
||||||
|
src/cthulhu/plugins/HelloCthulhu/Makefile
|
||||||
|
src/cthulhu/plugins/PluginManager/Makefile
|
||||||
|
src/cthulhu/plugins/Clipboard/Makefile
|
||||||
|
src/cthulhu/plugins/HelloWorld/Makefile
|
||||||
|
src/cthulhu/plugins/CapsLockHack/Makefile
|
||||||
|
src/cthulhu/plugins/SelfVoice/Makefile
|
||||||
|
src/cthulhu/plugins/Date/Makefile
|
||||||
|
src/cthulhu/plugins/Time/Makefile
|
||||||
|
src/cthulhu/plugins/MouseReview/Makefile
|
||||||
src/cthulhu/backends/Makefile
|
src/cthulhu/backends/Makefile
|
||||||
src/cthulhu/cthulhu_bin.py
|
src/cthulhu/cthulhu_bin.py
|
||||||
src/cthulhu/cthulhu_i18n.py
|
src/cthulhu/cthulhu_i18n.py
|
||||||
|
@ -32,6 +32,7 @@ cthulhu_python_PYTHON = \
|
|||||||
date_and_time_presenter.py \
|
date_and_time_presenter.py \
|
||||||
debug.py \
|
debug.py \
|
||||||
desktop_keyboardmap.py \
|
desktop_keyboardmap.py \
|
||||||
|
dynamic_api_manager.py \
|
||||||
event_manager.py \
|
event_manager.py \
|
||||||
find.py \
|
find.py \
|
||||||
flat_review.py \
|
flat_review.py \
|
||||||
@ -63,14 +64,18 @@ cthulhu_python_PYTHON = \
|
|||||||
cthulhu_i18n.py \
|
cthulhu_i18n.py \
|
||||||
cthulhu_state.py \
|
cthulhu_state.py \
|
||||||
phonnames.py \
|
phonnames.py \
|
||||||
|
plugin.py \
|
||||||
cthulhu_platform.py \
|
cthulhu_platform.py \
|
||||||
|
plugin_system_manager.py \
|
||||||
pronunciation_dict.py \
|
pronunciation_dict.py \
|
||||||
punctuation_settings.py \
|
punctuation_settings.py \
|
||||||
|
resource_manager.py \
|
||||||
script.py \
|
script.py \
|
||||||
script_manager.py \
|
script_manager.py \
|
||||||
script_utilities.py \
|
script_utilities.py \
|
||||||
settings.py \
|
settings.py \
|
||||||
settings_manager.py \
|
settings_manager.py \
|
||||||
|
signal_manager.py \
|
||||||
sound.py \
|
sound.py \
|
||||||
sound_generator.py \
|
sound_generator.py \
|
||||||
speech_and_verbosity_manager.py \
|
speech_and_verbosity_manager.py \
|
||||||
@ -81,14 +86,17 @@ cthulhu_python_PYTHON = \
|
|||||||
speechserver.py \
|
speechserver.py \
|
||||||
structural_navigation.py \
|
structural_navigation.py \
|
||||||
text_attribute_names.py \
|
text_attribute_names.py \
|
||||||
|
translation_context.py \
|
||||||
|
translation_manager.py \
|
||||||
tutorialgenerator.py \
|
tutorialgenerator.py \
|
||||||
where_am_i_presenter.py
|
where_am_i_presenter.py
|
||||||
|
|
||||||
cthulhu_pythondir=$(pkgpythondir)
|
cthulhu_pythondir=$(pkgpythondir)
|
||||||
|
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
scripts \
|
backends \
|
||||||
backends
|
scripts \
|
||||||
|
plugins
|
||||||
|
|
||||||
ui_DATA = \
|
ui_DATA = \
|
||||||
cthulhu-find.ui \
|
cthulhu-find.ui \
|
||||||
|
@ -42,6 +42,7 @@ gi.require_version("Atspi", "2.0")
|
|||||||
gi.require_version("Gdk", "3.0")
|
gi.require_version("Gdk", "3.0")
|
||||||
from gi.repository import Atspi
|
from gi.repository import Atspi
|
||||||
from gi.repository import Gdk
|
from gi.repository import Gdk
|
||||||
|
from gi.repository import GObject
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from gi.repository.Gio import Settings
|
from gi.repository.Gio import Settings
|
||||||
@ -52,10 +53,11 @@ except Exception:
|
|||||||
from . import braille
|
from . import braille
|
||||||
from . import debug
|
from . import debug
|
||||||
from . import event_manager
|
from . import event_manager
|
||||||
|
from . import keybindings
|
||||||
from . import learn_mode_presenter
|
from . import learn_mode_presenter
|
||||||
from . import logger
|
from . import logger
|
||||||
from . import messages
|
from . import messages
|
||||||
from . import mouse_review
|
from . import notification_presenter
|
||||||
from . import cthulhu_state
|
from . import cthulhu_state
|
||||||
from . import cthulhu_platform
|
from . import cthulhu_platform
|
||||||
from . import script_manager
|
from . import script_manager
|
||||||
@ -63,9 +65,24 @@ from . import settings
|
|||||||
from . import settings_manager
|
from . import settings_manager
|
||||||
from . import speech
|
from . import speech
|
||||||
from . import sound
|
from . import sound
|
||||||
|
from . import mouse_review
|
||||||
from .ax_object import AXObject
|
from .ax_object import AXObject
|
||||||
from .ax_utilities import AXUtilities
|
from .ax_utilities import AXUtilities
|
||||||
from .input_event import BrailleEvent
|
from .input_event import BrailleEvent
|
||||||
|
from . import cmdnames
|
||||||
|
from . import plugin_system_manager
|
||||||
|
from . import guilabels
|
||||||
|
from . import acss
|
||||||
|
from . import text_attribute_names
|
||||||
|
from . import speechserver
|
||||||
|
from . import input_event
|
||||||
|
from . import pronunciation_dict
|
||||||
|
from . import cthulhu_gtkbuilder
|
||||||
|
from . import signal_manager
|
||||||
|
from . import dynamic_api_manager
|
||||||
|
from . import translation_manager
|
||||||
|
from . import resource_manager
|
||||||
|
|
||||||
|
|
||||||
_eventManager = event_manager.getManager()
|
_eventManager = event_manager.getManager()
|
||||||
_scriptManager = script_manager.getManager()
|
_scriptManager = script_manager.getManager()
|
||||||
@ -428,6 +445,7 @@ def loadUserSettings(script=None, inputEvent=None, skipReloadMessage=False):
|
|||||||
braille.shutdown()
|
braille.shutdown()
|
||||||
|
|
||||||
_scriptManager.deactivate()
|
_scriptManager.deactivate()
|
||||||
|
cthulhuApp.getSignalManager().emitSignal('load-setting-begin')
|
||||||
|
|
||||||
reloaded = False
|
reloaded = False
|
||||||
if _userSettings:
|
if _userSettings:
|
||||||
@ -500,9 +518,14 @@ def loadUserSettings(script=None, inputEvent=None, skipReloadMessage=False):
|
|||||||
_storeXmodmap(_cthulhuModifiers)
|
_storeXmodmap(_cthulhuModifiers)
|
||||||
_createCthulhuXmodmap()
|
_createCthulhuXmodmap()
|
||||||
|
|
||||||
|
activePlugins = list(_settingsManager.getSetting('activePlugins'))
|
||||||
|
cthulhuApp.getPluginSystemManager().setActivePlugins(activePlugins)
|
||||||
|
|
||||||
_scriptManager.activate()
|
_scriptManager.activate()
|
||||||
_eventManager.activate()
|
_eventManager.activate()
|
||||||
|
|
||||||
|
cthulhuApp.getSignalManager().emitSignal('load-setting-completed')
|
||||||
|
|
||||||
debug.printMessage(debug.LEVEL_INFO, 'ORCA: User Settings Loaded', True)
|
debug.printMessage(debug.LEVEL_INFO, 'ORCA: User Settings Loaded', True)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
@ -721,7 +744,9 @@ def shutdown(script=None, inputEvent=None):
|
|||||||
signal.alarm(settings.timeoutTime)
|
signal.alarm(settings.timeoutTime)
|
||||||
|
|
||||||
cthulhu_state.activeScript.presentationInterrupt()
|
cthulhu_state.activeScript.presentationInterrupt()
|
||||||
cthulhu_state.activeScript.presentMessage(messages.STOP_ORCA, resetStyles=False)
|
|
||||||
|
cthulhuApp.getSignalManager().emitSignal('stop-application-completed')
|
||||||
|
cthulhuApp.getPluginSystemManager().unloadAllPlugins(ForceAllPlugins=True)
|
||||||
|
|
||||||
# Deactivate the event manager first so that it clears its queue and will not
|
# Deactivate the event manager first so that it clears its queue and will not
|
||||||
# accept new events. Then let the script manager unregister script event listeners.
|
# accept new events. Then let the script manager unregister script event listeners.
|
||||||
@ -797,11 +822,6 @@ def crashOnSignal(signum, frame):
|
|||||||
debug.printMessage(debug.LEVEL_SEVERE, msg, True)
|
debug.printMessage(debug.LEVEL_SEVERE, msg, True)
|
||||||
debug.printStack(debug.LEVEL_SEVERE)
|
debug.printStack(debug.LEVEL_SEVERE)
|
||||||
_restoreXmodmap(_cthulhuModifiers)
|
_restoreXmodmap(_cthulhuModifiers)
|
||||||
try:
|
|
||||||
cthulhu_state.activeScript.presentationInterrupt()
|
|
||||||
cthulhu_state.activeScript.presentMessage(messages.STOP_ORCA, resetStyles=False)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@ -847,14 +867,8 @@ def main():
|
|||||||
init()
|
init()
|
||||||
debug.printMessage(debug.LEVEL_INFO, "ORCA: Initialized.", True)
|
debug.printMessage(debug.LEVEL_INFO, "ORCA: Initialized.", True)
|
||||||
|
|
||||||
try:
|
|
||||||
message = messages.START_ORCA
|
|
||||||
script = _scriptManager.getDefaultScript()
|
|
||||||
script.presentMessage(message)
|
|
||||||
except Exception:
|
|
||||||
debug.printException(debug.LEVEL_SEVERE)
|
|
||||||
|
|
||||||
script = cthulhu_state.activeScript
|
script = cthulhu_state.activeScript
|
||||||
|
cthulhuApp.getSignalManager().emitSignal('start-application-completed')
|
||||||
if script:
|
if script:
|
||||||
window = script.utilities.activeWindow()
|
window = script.utilities.activeWindow()
|
||||||
|
|
||||||
@ -887,5 +901,94 @@ def main():
|
|||||||
die(EXIT_CODE_HANG)
|
die(EXIT_CODE_HANG)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
class Cthulhu(GObject.Object):
|
||||||
|
# basic signals
|
||||||
|
__gsignals__ = {
|
||||||
|
"start-application-completed": (GObject.SignalFlags.RUN_LAST, None, ()),
|
||||||
|
"stop-application-completed": (GObject.SignalFlags.RUN_LAST, None, ()),
|
||||||
|
"load-setting-begin": (GObject.SignalFlags.RUN_LAST, None, ()),
|
||||||
|
"load-setting-completed": (GObject.SignalFlags.RUN_LAST, None, ()),
|
||||||
|
"setup-inputeventhandlers-completed": (GObject.SignalFlags.RUN_LAST, None, ()), # compat signal for register input event handlers
|
||||||
|
"request-cthulhu-preferences": (GObject.SignalFlags.RUN_LAST, None, ()),
|
||||||
|
"request-application-preferences": (GObject.SignalFlags.RUN_LAST, None, ()),
|
||||||
|
}
|
||||||
|
def __init__(self):
|
||||||
|
GObject.Object.__init__(self)
|
||||||
|
# add members
|
||||||
|
self.resourceManager = resource_manager.ResourceManager(self)
|
||||||
|
self.APIHelper = plugin_system_manager.APIHelper(self)
|
||||||
|
self.eventManager = _eventManager
|
||||||
|
self.settingsManager = _settingsManager
|
||||||
|
self.scriptManager = _scriptManager
|
||||||
|
self.signalManager = signal_manager.SignalManager(self)
|
||||||
|
self.dynamicApiManager = dynamic_api_manager.DynamicApiManager(self)
|
||||||
|
self.translationManager = translation_manager.TranslationManager(self)
|
||||||
|
self.debugManager = debug
|
||||||
|
self.createCompatAPI()
|
||||||
|
self.pluginSystemManager = plugin_system_manager.PluginSystemManager(self)
|
||||||
|
def getAPIHelper(self):
|
||||||
|
return self.APIHelper
|
||||||
|
def getPluginSystemManager(self):
|
||||||
|
return self.pluginSystemManager
|
||||||
|
def getDynamicApiManager(self):
|
||||||
|
return self.dynamicApiManager
|
||||||
|
def getSignalManager(self):
|
||||||
|
return self.signalManager
|
||||||
|
def getEventManager(self):
|
||||||
|
return self.eventManager
|
||||||
|
def getSettingsManager(self):
|
||||||
|
return self.settingsManager
|
||||||
|
def getScriptManager(self):
|
||||||
|
return self.scriptManager
|
||||||
|
def getDebugManager(self):
|
||||||
|
return self.debugManager
|
||||||
|
def getTranslationManager(self):
|
||||||
|
return self.translationManager
|
||||||
|
def getResourceManager(self):
|
||||||
|
return self.resourceManager
|
||||||
|
def run(self, cacheValues=True):
|
||||||
|
return main(cacheValues)
|
||||||
|
def stop(self):
|
||||||
|
pass
|
||||||
|
def createCompatAPI(self):
|
||||||
|
# for now add compatibility layer using Dynamic API
|
||||||
|
# should be removed step by step
|
||||||
|
# use clean objects, getters and setters instead
|
||||||
|
|
||||||
|
self.getDynamicApiManager().registerAPI('Logger', _logger)
|
||||||
|
self.getDynamicApiManager().registerAPI('SettingsManager', settings_manager)
|
||||||
|
self.getDynamicApiManager().registerAPI('ScriptManager', script_manager)
|
||||||
|
self.getDynamicApiManager().registerAPI('EventManager', event_manager)
|
||||||
|
self.getDynamicApiManager().registerAPI('Speech', speech)
|
||||||
|
self.getDynamicApiManager().registerAPI('Sound', sound)
|
||||||
|
self.getDynamicApiManager().registerAPI('Braille', braille)
|
||||||
|
self.getDynamicApiManager().registerAPI('Debug', debug)
|
||||||
|
self.getDynamicApiManager().registerAPI('Messages', messages)
|
||||||
|
self.getDynamicApiManager().registerAPI('Cmdnames', cmdnames)
|
||||||
|
self.getDynamicApiManager().registerAPI('NotificationPresenter', notification_presenter)
|
||||||
|
self.getDynamicApiManager().registerAPI('CthulhuState', cthulhu_state)
|
||||||
|
self.getDynamicApiManager().registerAPI('CthulhuPlatform', cthulhu_platform)
|
||||||
|
self.getDynamicApiManager().registerAPI('Settings', settings)
|
||||||
|
self.getDynamicApiManager().registerAPI('Keybindings', keybindings)
|
||||||
|
self.getDynamicApiManager().registerAPI('GuiLabels', guilabels)
|
||||||
|
self.getDynamicApiManager().registerAPI('Acss', acss)
|
||||||
|
self.getDynamicApiManager().registerAPI('TextAttributeNames', text_attribute_names)
|
||||||
|
self.getDynamicApiManager().registerAPI('PronunciationDict', pronunciation_dict)
|
||||||
|
self.getDynamicApiManager().registerAPI('InputEvent', input_event)
|
||||||
|
self.getDynamicApiManager().registerAPI('SpeechServer', speechserver)
|
||||||
|
self.getDynamicApiManager().registerAPI('CthulhuGtkbuilder', cthulhu_gtkbuilder)
|
||||||
|
self.getDynamicApiManager().registerAPI('AXObject', AXObject)
|
||||||
|
self.getDynamicApiManager().registerAPI('AXUtilities', AXUtilities)
|
||||||
|
self.getDynamicApiManager().registerAPI('LearnModePresenter', learn_mode_presenter)
|
||||||
|
# cthulhu lets say, special compat handling....
|
||||||
|
self.getDynamicApiManager().registerAPI('EmitRegionChanged', emitRegionChanged)
|
||||||
|
self.getDynamicApiManager().registerAPI('LoadUserSettings', loadUserSettings)
|
||||||
|
|
||||||
|
cthulhuApp = Cthulhu()
|
||||||
|
|
||||||
|
def getManager():
|
||||||
|
return cthulhuApp
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
sys.exit(main())
|
GObject.threads_init()
|
||||||
|
sys.exit(cthulhuApp.run())
|
||||||
|
@ -115,6 +115,7 @@ userCustomizableSettings = [
|
|||||||
"presentDateFormat",
|
"presentDateFormat",
|
||||||
"presentTimeFormat",
|
"presentTimeFormat",
|
||||||
"activeProfile",
|
"activeProfile",
|
||||||
|
"activePlugins",
|
||||||
"startingProfile",
|
"startingProfile",
|
||||||
"spellcheckSpellError",
|
"spellcheckSpellError",
|
||||||
"spellcheckSpellSuggestion",
|
"spellcheckSpellSuggestion",
|
||||||
@ -404,3 +405,6 @@ structNavInSayAll = False
|
|||||||
enableSadPidginHack = False
|
enableSadPidginHack = False
|
||||||
presentChatRoomLast = False
|
presentChatRoomLast = False
|
||||||
presentLiveRegionFromInactiveTab = False
|
presentLiveRegionFromInactiveTab = False
|
||||||
|
|
||||||
|
# Plugins
|
||||||
|
activePlugins = ['Clipboard', 'MouseReview', 'Date', 'ByeCthulhu', 'Time', 'HelloCthulhu', 'HelloWorld', 'SelfVoice', 'PluginManager']
|
||||||
|
Loading…
Reference in New Issue
Block a user