Compare commits
76 Commits
68766b7643
...
2025.04.03
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f7d60763d | |||
| 084d4fe85f | |||
| 6bbe6e47fc | |||
| 312476bbed | |||
| 0005d5ec71 | |||
| 88ad9833d2 | |||
| 654f1acc21 | |||
| dfb53fff89 | |||
| 9cdb9f74e5 | |||
| 41dae26d90 | |||
| edc1cbf7af | |||
| d3d268004b | |||
| a8e16fcf01 | |||
| 6bbf3d0e67 | |||
| cbe3424e29 | |||
| 1cf566c37c | |||
| 936153f307 | |||
| 29f8697a9f | |||
| ba735c554b | |||
| 1c9ca14272 | |||
| d6af91bf42 | |||
| 5dd872535d | |||
| 8e9ea3af5a | |||
| a40087cd20 | |||
| 35acddeb8f | |||
| 327ad99e49 | |||
| c46cf1c939 | |||
| 80033b3f37 | |||
| 53e6e095b3 | |||
| d863cf0353 | |||
| a97bb30ed3 | |||
| e9916bbcc4 | |||
| 6e480db630 | |||
| 384479a0a5 | |||
| deccf846d8 | |||
| 92a909edb8 | |||
| 55c7de8c65 | |||
| 5a744a6809 | |||
| 63539e8122 | |||
| 5178a66a6f | |||
| 89891f18af | |||
| 71add76898 | |||
| 1a9eb35418 | |||
| ba6382c3cd | |||
| 17febf488c | |||
| 09718e5901 | |||
| 03bed6c5d4 | |||
| d28e0086d9 | |||
| 515827e830 | |||
| 4f6260eb6f | |||
| b6a44df82a | |||
| 0cadb12c00 | |||
| 2f6fde6896 | |||
| 89467b6988 | |||
| 17d2773344 | |||
| 0abe30791d | |||
| 087dcc3ab2 | |||
| 4eaa4fae86 | |||
| ba0169b016 | |||
| 7605e7d60f | |||
| 9562c08130 | |||
| 8a9bbefeac | |||
| 9f2a349239 | |||
| 9e749ef62e | |||
| 3f1eb6e5af | |||
| f6085a187e | |||
| 814e210a7f | |||
| 41cf7ad88d | |||
| dfc0ea7351 | |||
| 064c325e60 | |||
| 4a90dfa38f | |||
| 8245135cbd | |||
| 604dc67407 | |||
| 524bdd049a | |||
| 7445eacbca | |||
| bc660dc217 |
@@ -1867,7 +1867,7 @@
|
||||
|
||||
* Release Cthulhu v2.24.0. Somehow I forgot to mark this.
|
||||
The svn version is 4292 and can be found at the tag
|
||||
of ORCA_24_0.
|
||||
of CTHULHU_24_0.
|
||||
|
||||
2008-09-20 Joanmarie Diggs <joanmarie.diggs@gmail.com>
|
||||
|
||||
@@ -5747,7 +5747,7 @@
|
||||
* src/cthulhu/app_gui_prefs.py:
|
||||
src/cthulhu/cthulhu_gui_prefs.py:
|
||||
src/cthulhu/cthulhu_state.py:
|
||||
Fix breakage to ORCA_MODIFIER-Control-Space to bring up the
|
||||
Fix breakage to CTHULHU_MODIFIER-Control-Space to bring up the
|
||||
application specific Cthulhu preferences dialog.
|
||||
|
||||
2007-12-12 Willie Walker <william.walker@sun.com>
|
||||
@@ -10456,7 +10456,7 @@
|
||||
Fix for bug #372273 - Add ability to configure app-specific
|
||||
settings via GUI.
|
||||
|
||||
Adjusted <ORCA MODIFIER>+Control+Space to now bring up
|
||||
Adjusted <CTHULHU MODIFIER>+Control+Space to now bring up
|
||||
the application specific preferences dialog. The previous
|
||||
usage (reload user settings) is now gone.
|
||||
|
||||
@@ -12574,7 +12574,7 @@
|
||||
|
||||
2007-01-07 Willie Walker <william.walker@sun.com>
|
||||
|
||||
* svn+ssh://wwalker@svn.gnome.org/svn/cthulhu/tags/ORCA_2_17_5:
|
||||
* svn+ssh://wwalker@svn.gnome.org/svn/cthulhu/tags/CTHULHU_2_17_5:
|
||||
final prep for v2.17.5. Everything below this line is included
|
||||
in v2.17.5 - many many thanks to all involved.
|
||||
|
||||
@@ -17730,7 +17730,7 @@
|
||||
|
||||
* po/POTFILES.in: remove Gecko.py.
|
||||
|
||||
* configure.in: get the ORCA_SETUP_GLADE_DIR working better.
|
||||
* configure.in: get the CTHULHU_SETUP_GLADE_DIR working better.
|
||||
|
||||
* src/cthulhu/mag.py: minor attempt to follow the caret when it
|
||||
moves.
|
||||
@@ -19296,7 +19296,7 @@
|
||||
* src/cthulhu/{default.py, gnomespeechfactory.py, cthulhu-setup.in,
|
||||
cthulhu.py, settings.py, speech.py}, src/cthulhu/scripts/Gecko.py:
|
||||
migrate voice defaults to setting.py.
|
||||
NOTE: THIS REQUIRES YOU TO RERUN ORCA-SETUP.
|
||||
NOTE: THIS REQUIRES YOU TO RERUN CTHULHU-SETUP.
|
||||
|
||||
* src/cthulhu/*.py: use string constants to get settings (I got
|
||||
bit by a mispelling when using raw strings).
|
||||
@@ -19335,7 +19335,7 @@
|
||||
src/cthulhu/scripts/{Gecko.py,metacity.py}: new speech structure
|
||||
done in collaboration with T.V. Raman of Google who donated
|
||||
code under the LGPL license. NOTE: THIS REQUIRES YOU TO
|
||||
RERUN ORCA-SETUP.
|
||||
RERUN CTHULHU-SETUP.
|
||||
|
||||
2005-11-14 Rich Burridge <rich.burridge@sun.com>
|
||||
|
||||
@@ -19359,7 +19359,7 @@
|
||||
src/cthulhu/scripts/Gecko.py, src/cthulhu/scripts/gaim.py,
|
||||
src/cthulhu/scripts/gcalctool.py, src/cthulhu/scripts/metacity.py: First
|
||||
pass at new speech system based on conversations with T.V. Raman.
|
||||
NOTE: THIS REQUIRES YOU TO RERUN ORCA-SETUP. If you don't cthulhu
|
||||
NOTE: THIS REQUIRES YOU TO RERUN CTHULHU-SETUP. If you don't cthulhu
|
||||
will fail on startup.
|
||||
|
||||
2005-11-09 Mike Pedersen <michael.pedersen@sun.com>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Welcome to Cthulhu
|
||||
|
||||
We are excited to have you here and welcome your contributions to the Cthulhu screen reader project! This project is a fork of Orca, with a focus on creating an open and collaborative community where contributions are encouraged.
|
||||
We are excited to have you here and welcome your contributions to the Cthulhu screen reader project! This project is a fork of Cthulhu, with a focus on creating an open and collaborative community where contributions are encouraged.
|
||||
|
||||
|
||||
How to Contribute
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ dist-hook:
|
||||
echo Creating ChangeLog && \
|
||||
( cd "$(top_srcdir)" && \
|
||||
echo '# Generated by Makefile. Do not edit.'; echo; \
|
||||
$(top_srcdir)/missing --run git log --pretty=format:"%ai %an <%ae>%n%n %s%n" --name-status ORCA_2_26_0.. ) > ChangeLog.tmp \
|
||||
$(top_srcdir)/missing --run git log --pretty=format:"%ai %an <%ae>%n%n %s%n" --name-status CTHULHU_2_26_0.. ) > ChangeLog.tmp \
|
||||
&& mv -f ChangeLog.tmp $(top_distdir)/ChangeLog \
|
||||
|| ( rm -f ChangeLog.tmp ; \
|
||||
echo Failed to generate ChangeLog >&2 ); \
|
||||
|
||||
@@ -11255,7 +11255,7 @@ Firefox:
|
||||
|
||||
* Fix for bug 445578 - Link preview information would be desirable for
|
||||
Firefox. This is obtained when performing a "Where Am I" operation
|
||||
(KP_Enter for desktop bindings, ORCA_MODIFIER+Return for laptop
|
||||
(KP_Enter for desktop bindings, CTHULHU_MODIFIER+Return for laptop
|
||||
bindings). Many thanks to new community member Scott Haeger for
|
||||
this functionality!
|
||||
|
||||
@@ -11439,7 +11439,7 @@ General Cthulhu:
|
||||
of tool tips
|
||||
|
||||
* Fix for bug 372273 - Add ability to configure app-specific settings
|
||||
via GUI. NOTE: Adjusted ORCA_MODIFIER+Control+Space to now bring
|
||||
via GUI. NOTE: Adjusted CTHULHU_MODIFIER+Control+Space to now bring
|
||||
up the application-specific preferences dialog. The previous usage
|
||||
(reload user settings) is now gone.
|
||||
|
||||
@@ -11476,7 +11476,7 @@ Firefox:
|
||||
stylesheet results in bad behavior
|
||||
|
||||
* Partial fix for bug 420540 - Firefox keyboard control wish list.
|
||||
ORCA_MODIFIER+Z will now toggle the structural navigation keys
|
||||
CTHULHU_MODIFIER+Z will now toggle the structural navigation keys
|
||||
on/off.
|
||||
|
||||
* Fix for bug 422924 - Add more support for accessing HTML tables in
|
||||
@@ -11493,8 +11493,8 @@ Firefox:
|
||||
of verbiage. Therefore, these are all customizable settings.
|
||||
|
||||
* Fix for bug 423427 - Need to add form field structural navigation in
|
||||
Firefox. ORCA_MODIFIER+Tab should move you to the next form field
|
||||
and ORCA_MODIFIER+Shift+Tab should move you to the previous form
|
||||
Firefox. CTHULHU_MODIFIER+Tab should move you to the next form field
|
||||
and CTHULHU_MODIFIER+Shift+Tab should move you to the previous form
|
||||
field.
|
||||
|
||||
* Fix for bug 423435 - Cthulhu is too chatty when loading a page in
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Cthulhu v45.3
|
||||
# Cthulhu
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -11,20 +11,12 @@ technology service provider interface (AT-SPI), which is the primary
|
||||
assistive technology infrastructure for the Solaris and Linux
|
||||
operating environments. Applications and toolkits supporting the
|
||||
AT-SPI include the GNOME GTK+ toolkit, the Java platform's Swing
|
||||
toolkit, OpenOffice/LibreOffice, Gecko, and WebKitGtk. AT-SPI support
|
||||
for the KDE Qt toolkit is currently being pursued.
|
||||
toolkit, OpenOffice/LibreOffice, Gecko, WebKitGtk, and KDE Qt toolkit.
|
||||
|
||||
See also <http://wiki.gnome.org/Projects/Cthulhu> for detailed information
|
||||
on Cthulhu, including how to run Cthulhu, how to communicate with the Cthulhu user
|
||||
community, and where to log bugs and feature requests.
|
||||
|
||||
## Dependencies
|
||||
|
||||
Cthulhu v45.x is supported on GNOME 45.x only. We highly suggest you
|
||||
use the latest releases of GNOME because they contain accessibility
|
||||
infrastructure and application bug fixes that help Cthulhu work better.
|
||||
|
||||
Cthulhu also has the following dependencies:
|
||||
Cthulhu has the following dependencies:
|
||||
|
||||
* Python 3 - Python platform
|
||||
* pygobject-3.0 - Python bindings for the GObject library
|
||||
@@ -37,12 +29,14 @@ Cthulhu also has the following dependencies:
|
||||
* liblouis - Liblouis (<http://liblouis.org/>) support for contracted braille (optional)
|
||||
* py-setproctitle - Python library to set the process title (optional)
|
||||
* gstreamer-1.0 - GStreamer - Streaming media framework (optional)
|
||||
* socat - Used for self-voicing functionality.
|
||||
* libpeas - For the plugin system.
|
||||
|
||||
You are strongly encouraged to also have the latest stable versions
|
||||
of AT-SPI2 and ATK for the GNOME 45.x release.
|
||||
of AT-SPI2 and ATK.
|
||||
|
||||
|
||||
## NOTE FOR BRLTTY USERS:
|
||||
## Braille
|
||||
|
||||
Cthulhu depends upon the Python bindings for BrlAPI available in BrlTTY v4.5
|
||||
or better. You can determine if the Python bindings for BrlAPI are
|
||||
@@ -66,10 +60,23 @@ learn mode, press "Escape." Finally, the preferences dialog contains
|
||||
a "Key Bindings" tab that lists the keyboard binding for Cthulhu.
|
||||
|
||||
For more information, see the Cthulhu documentation which is available
|
||||
within Cthulhu as well as at: <https://help.gnome.org/users/cthulhu/stable/>
|
||||
within Cthulhu.
|
||||
|
||||
## Scripting Cthulhu
|
||||
|
||||
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
|
||||
of the source tree.
|
||||
of the source tree. Cthulhu also has an excellent plugin system, more documentation and examples coming soon.
|
||||
|
||||
## Self-voicing
|
||||
|
||||
Cthulhu offers a mechanism through which messages may be spoken directly by the screen reader. Usage is as follows:
|
||||
|
||||
```bash
|
||||
# Speak hello world.
|
||||
echo "Hello world." | socat - UNIX-CLIENT:/tmp/cthulhu.sock
|
||||
# Speak Hello world without interrupting the previous speech.
|
||||
echo "<!#APPEND#!>Hello world." | socat - UNIX-CLIENT:/tmp/cthulhu.sock
|
||||
# Make hello world persistant in Braille.
|
||||
echo "Hello world.<#APPEND#>" | socat - UNIX-CLIENT:/tmp/cthulhu.sock
|
||||
```
|
||||
|
||||
+7
-7
@@ -22,17 +22,17 @@ Make sure you are up to date:
|
||||
Update ./NEWS with changes from the last tagged release. You can use
|
||||
commands like the following:
|
||||
|
||||
Detailed commits since the ORCA_40_BETA tag:
|
||||
Detailed commits since the CTHULHU_40_BETA tag:
|
||||
|
||||
git log ORCA_40_BETA..
|
||||
git log CTHULHU_40_BETA..
|
||||
|
||||
Short list of translation changes with author names and files:
|
||||
|
||||
git log ORCA_40_BETA.. --grep translation --pretty=format:"%s - %an" --name-only
|
||||
git log CTHULHU_40_BETA.. --grep translation --pretty=format:"%s - %an" --name-only
|
||||
|
||||
Quick-and-dirty formatted list of translation changes:
|
||||
|
||||
git log ORCA_40_BETA.. --grep translation --pretty=format:"%s,%an" --name-only |
|
||||
git log CTHULHU_40_BETA.. --grep translation --pretty=format:"%s,%an" --name-only |
|
||||
awk -F/ '/\.(po|am)/ {gsub("(\.po|Makefile.am)", "", $NF); printf(",%s",$NF); next;}
|
||||
{gsub("(Updated* |Add(ed)* | translation| help)", "", $0); printf("\n%s",$0);}' |
|
||||
awk -F, '!seen[$0]++ {if (NF == 3) printf(" %-15s %-25s %s\n", $3, $1, $2);}' |
|
||||
@@ -40,7 +40,7 @@ Quick-and-dirty formatted list of translation changes:
|
||||
|
||||
Short list of non-translation commits:
|
||||
|
||||
git log ORCA_40_BETA.. --grep translation --invert-grep --pretty=format:" * %s%n"
|
||||
git log CTHULHU_40_BETA.. --grep translation --invert-grep --pretty=format:" * %s%n"
|
||||
|
||||
NOTE: You should also make sure the external dependencies listed in
|
||||
configure.ac and README are accurate.
|
||||
@@ -56,8 +56,8 @@ COMMIT RELEASE CHANGES AND TAG THE RELEASE:
|
||||
|
||||
git commit -a
|
||||
git push
|
||||
git tag -a -s ORCA_40_RC
|
||||
git push origin ORCA_40_RC
|
||||
git tag -a -s CTHULHU_40_RC
|
||||
git push origin CTHULHU_40_RC
|
||||
|
||||
|
||||
UPLOAD THE RELEASE:
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
- Add Simple Orca Plugin System as native code for Cthulhu
|
||||
- Merge in sleep mode.
|
||||
- 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.
|
||||
|
||||
+16
-3
@@ -1,4 +1,7 @@
|
||||
m4_define([cthulhu_version], [0.1])
|
||||
m4_define([get_version], [m4_esyscmd_s([
|
||||
grep "^version = " src/cthulhu/cthulhuVersion.py | sed 's/version = "\(.*\)"/\1/'
|
||||
])])
|
||||
m4_define([cthulhu_version], [get_version])
|
||||
|
||||
m4_define(pygobject_required_version, 3.18)
|
||||
m4_define(atspi_required_version, 2.48)
|
||||
@@ -28,6 +31,7 @@ PKG_CHECK_MODULES([PYGOBJECT], [pygobject-3.0 >= pygobject_required_version])
|
||||
PKG_CHECK_MODULES([ATSPI2], [atspi-2 >= atspi_required_version])
|
||||
PKG_CHECK_MODULES([ATKBRIDGE], [atk-bridge-2.0 >= atkbridge_required_version])
|
||||
PKG_CHECK_MODULES([GSTREAMER], [gstreamer-1.0], [gstreamer="yes"], [gstreamer="no"])
|
||||
PKG_CHECK_MODULES([LIBPEAS], [libpeas-1.0])
|
||||
|
||||
dnl Needed programs
|
||||
AC_PROG_INSTALL
|
||||
@@ -42,6 +46,7 @@ AM_PATH_PYTHON(3.3)
|
||||
|
||||
AM_CHECK_PYMOD(gi,,,[AC_MSG_ERROR(Could not find python module: gi)])
|
||||
AM_CHECK_PYMOD(json,,,[AC_MSG_ERROR(Could not find python module: json)])
|
||||
AM_CHECK_PYMOD(pluggy,,[pluggy_available="yes"],[pluggy_available="no"])
|
||||
AM_CHECK_PYMOD(brlapi,,[brlapi_available="yes"],[brlapi_available="no"])
|
||||
AM_CHECK_PYMOD(speechd,,[speechd_available="yes"],[speechd_available="no"])
|
||||
AC_ARG_WITH([liblouis],
|
||||
@@ -106,6 +111,7 @@ src/cthulhu/scripts/apps/SeaMonkey/Makefile
|
||||
src/cthulhu/scripts/apps/smuxi-frontend-gnome/Makefile
|
||||
src/cthulhu/scripts/apps/Thunderbird/Makefile
|
||||
src/cthulhu/scripts/apps/xfwm4/Makefile
|
||||
src/cthulhu/scripts/sleepmode/Makefile
|
||||
src/cthulhu/scripts/switcher/Makefile
|
||||
src/cthulhu/scripts/terminal/Makefile
|
||||
src/cthulhu/scripts/web/Makefile
|
||||
@@ -123,12 +129,14 @@ 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/DisplayVersion/Makefile
|
||||
src/cthulhu/plugins/hello_world/Makefile
|
||||
src/cthulhu/plugins/CapsLockHack/Makefile
|
||||
src/cthulhu/plugins/SelfVoice/Makefile
|
||||
src/cthulhu/plugins/self_voice/Makefile
|
||||
src/cthulhu/plugins/Date/Makefile
|
||||
src/cthulhu/plugins/Time/Makefile
|
||||
src/cthulhu/plugins/MouseReview/Makefile
|
||||
src/cthulhu/plugins/SimplePluginSystem/Makefile
|
||||
src/cthulhu/backends/Makefile
|
||||
src/cthulhu/cthulhu_bin.py
|
||||
src/cthulhu/cthulhu_i18n.py
|
||||
@@ -156,7 +164,12 @@ echo
|
||||
echo "NOTE: Sound support requires gstreamer-1.0."
|
||||
fi
|
||||
|
||||
if test "$have_libpeas" = "no"; then
|
||||
AC_MSG_ERROR([libpeas-1.0 >= 1.20 is required])
|
||||
fi
|
||||
|
||||
echo
|
||||
echo Use pluggy: $pluggy_available
|
||||
echo Use speech-dispatcher: $speechd_available
|
||||
echo Use brltty: $brlapi_available
|
||||
echo Use liblouis: $louis_available
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<schemalist gettext-domain="slint">
|
||||
<schema id="toggle.screenreader" path="/toggle/screenreader/">
|
||||
<key name="binding" type="s">
|
||||
<default>'<Shift><Alt>v'</default>
|
||||
<summary>Keybinding</summary>
|
||||
<description>Keybinding associated to toggle screen reader.</description>
|
||||
</key>
|
||||
<key name="action" type="s">
|
||||
<default>'/opt/I38/scripts/toggle_screenreader.sh 1>/dev/null'</default>
|
||||
<summary>Command</summary>
|
||||
<description>Command to toggle the screen reader between orca and cthulhu.</description>
|
||||
</key>
|
||||
<key name="name" type="s">
|
||||
<default>'Toggle screenreader'</default>
|
||||
<summary>Name</summary>
|
||||
<description>Description associated to toggle screen reader.</description>
|
||||
</key>
|
||||
</schema>
|
||||
</schemalist>
|
||||
+29
-42
@@ -1,59 +1,46 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name[an]=Lector de pantalla Cthulhu
|
||||
Name[ast]=Llector de pantalla d'Cthulhu
|
||||
Name[be]=Чытач з экрана Cthulhu
|
||||
Name[bg]=Cthulhu — екранен четец
|
||||
Name[bs]=Cthulhu čitač ekrana
|
||||
Name[ast]=Llector de pantalla Cthulhu
|
||||
Name[be]=ÐÑÑÐÑÑÐ Cthulhu
|
||||
Name[bg]=Cthulhu âÐÐÐ ÑÑÑName[bs]=Cthulhu ÄtaÄekrana
|
||||
Name[ca]=Lector de pantalla Cthulhu
|
||||
Name[cs]=Čtečka obrazovky Cthulhu
|
||||
Name[da]=Skærmlæseren Cthulhu
|
||||
Name[cs]=ÄeÄa obrazovky Cthulhu
|
||||
Name[da]=SkÃmlÃeren Cthulhu
|
||||
Name[de]=Cthulhu-Bildschirmleser
|
||||
Name[el]=Αναγνώστης οθόνης Cthulhu
|
||||
Name[el]=ÎÎÎÏÎ ÎÏÎ Cthulhu
|
||||
Name[en_GB]=Cthulhu Screen Reader
|
||||
Name[eo]=Ekranlegilo Orko
|
||||
Name[eo]=Ekranlegilo Cthulhu
|
||||
Name[es]=Lector de pantalla Cthulhu
|
||||
Name[eu]=Cthulhu pantaila-irakurlea
|
||||
Name[fa]=صفحهخوان اورکا
|
||||
Name[fi]=Cthulhu-näytönlukija
|
||||
Name[fr]=Lecteur d’écran Cthulhu
|
||||
Name[fa]=ØØâØ Cthulhu
|
||||
Name[fi]=Cthulhu-nÃtÃlukija
|
||||
Name[fr]=Lecteur dâran Cthulhu
|
||||
Name[gl]=Lector da pantalla Cthulhu
|
||||
Name[he]=מקריא המסך Cthulhu
|
||||
Name[hi]=Cthulhu स्क्रीन वाचक
|
||||
Name[hu]=Orka képernyőolvasó
|
||||
Name[id]=Pembaca Layar Cthulhu
|
||||
Name[is]=Cthulhu skjálestur
|
||||
Name[he]=××××× Cthulhu
|
||||
Name[hi]=Cthulhu àààà
|
||||
Name[hu]=Cthulhu kÃernyÅlvasÃName[id]=Pembaca Layar Cthulhu
|
||||
Name[is]=Cthulhu skjÃestur
|
||||
Name[it]=Lettore schermo Cthulhu
|
||||
Name[ka]=Cthulhu - ეკრანის მკითხველი
|
||||
Name[kk]=Cthulhu экраннан оқитын қолданбасы
|
||||
Name[lt]=Cthulhu ekrano skaityklė
|
||||
Name[lv]=Cthulhu ekrāna lasītājs
|
||||
Name[mk]=Cthulhu читач на екранот
|
||||
Name[nb]=Cthulhu skjermleser
|
||||
Name[ne]=ओर्का दृष्टि वाचक
|
||||
Name[nl]=Cthulhu schermlezer
|
||||
Name[ka]=Cthulhu - ááááááName[kk]=Cthulhu ÑÑÐÐ ÐÐÑ ÒÐÐÐÑ
|
||||
Name[lt]=Cthulhu ekrano skaityklÄName[lv]=Cthulhu ekrÄa lasÄÄs
|
||||
Name[mk]=Cthulhu ÑÑÑÐ ÐÑÐÑName[nb]=Cthulhu skjermleser
|
||||
Name[ne]=Cthulhu àà ààame[nl]=Cthulhu schermlezer
|
||||
Name[oc]=Lector d'ecran Cthulhu
|
||||
Name[pa]=ਓਰਕਾ ਸਕਰੀਨ ਰੀਡਰ
|
||||
Name[pl]=Czytnik ekranowy Cthulhu
|
||||
Name[pt]=Leitor de ecrã Cthulhu
|
||||
Name[pa]=Cthulhu ààààame[pl]=Czytnik ekranowy Cthulhu
|
||||
Name[pt]=Leitor de ecrÃCthulhu
|
||||
Name[pt_BR]=Leitor de tela Cthulhu
|
||||
Name[ro]=Cititorul de ecran Cthulhu
|
||||
Name[ru]=Экранный диктор Cthulhu
|
||||
Name[sl]=Zaslonski bralnik Orka
|
||||
Name[sr]=Читач екрана Орка
|
||||
Name[sv]=Cthulhu skärmläsare
|
||||
Name[ta]=ஆர்கா திரை படிப்பி
|
||||
Name[te]=ఓర్కా తెరచదువరి
|
||||
Name[tg]=Хонандаи экрани Cthulhu
|
||||
Name[ru]=ÐÑÐÑ ÐÐÐ Cthulhu
|
||||
Name[sl]=Zaslonski bralnik Cthulhu
|
||||
Name[sr]=ÐÑÑÐÑÐ Cthulhu
|
||||
Name[sv]=Cthulhu skÃmlÃare
|
||||
Name[ta]=Cthulhu àààà
|
||||
Name[te]=Cthulhu ààà
|
||||
Name[tg]=ÐÐÐÐ ÑÑÐ Cthulhu
|
||||
Name[tr]=Cthulhu Ekran Okuyucu
|
||||
Name[ug]=Cthulhu ئېكران ئوقۇغۇ
|
||||
Name[uk]=Інструмент читання з екрана «Cthulhu»
|
||||
Name[zh_CN]=Cthulhu 屏幕阅读器
|
||||
Name[zh_HK]=Cthulhu 螢幕閱讀器
|
||||
Name=Cthulhu Screen Reader
|
||||
Name[ug]=Cthulhu ØÙØ ØÙØ
|
||||
Name[uk]=ÐÑÑÐÐ ÑÑÐÑÐÐÑÐ ÂthulhuÂName[zh_CN]=Cthulhu åèName[zh_HK]=Cthulhu èèName=Cthulhu Screen Reader
|
||||
Exec=cthulhu
|
||||
NoDisplay=true
|
||||
AutostartCondition=GSettings org.gnome.desktop.a11y.applications screen-reader-enabled
|
||||
X-GNOME-AutoRestart=true
|
||||
#X-GNOME-Autostart-Phase=Initialization
|
||||
OnlyShowIn=GNOME;MATE;Unity;Cinnamon;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Storm Dragon <storm_dragon@stormux.org>
|
||||
|
||||
pkgname=cthulhu
|
||||
pkgver=0.1
|
||||
pkgver=0.4
|
||||
pkgrel=1
|
||||
pkgdesc="Screen reader for individuals who are blind or visually impaired forked from Orca"
|
||||
url="https://git.stormux.org/storm/cthulhu"
|
||||
@@ -26,6 +26,7 @@ depends=(
|
||||
python-cairo
|
||||
python-gobject
|
||||
python-setproctitle
|
||||
socat
|
||||
speech-dispatcher
|
||||
xorg-xkbcomp
|
||||
xorg-xmodmap
|
||||
@@ -35,8 +36,6 @@ makedepends=(
|
||||
itstool
|
||||
yelp-tools
|
||||
)
|
||||
groups=(gnome)
|
||||
_commit=9e77d1baf9bd24b78d7499ad9b2e8bb80c9a0c81 # tags/ORCA_45_1^0
|
||||
source=("git+https://git.stormux.org/storm/cthulhu.git")
|
||||
b2sums=('SKIP')
|
||||
|
||||
@@ -45,6 +44,11 @@ prepare() {
|
||||
NOCONFIGURE=1 ./autogen.sh
|
||||
}
|
||||
|
||||
pkgver() {
|
||||
cd cthulhu
|
||||
grep "^version = " src/cthulhu/cthulhuVersion.py | sed 's/version = "\(.*\)"/\1/'
|
||||
}
|
||||
|
||||
build() {
|
||||
cd cthulhu
|
||||
./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
|
||||
|
||||
Executable
+98
@@ -0,0 +1,98 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Slackware build script for cthulhu
|
||||
# Created based on PKGBUILD from Storm Dragon <storm_dragon@stormux.org>
|
||||
|
||||
cd $(dirname $0) ; CWD=$(pwd)
|
||||
|
||||
PRGNAM=cthulhu
|
||||
VERSION=${VERSION:-0.4}
|
||||
BUILD=${BUILD:-1}
|
||||
TAG=storm
|
||||
PKGTYPE=txz
|
||||
export PYTHON=/usr/bin/python3.11
|
||||
|
||||
if [ -z "$ARCH" ]; then
|
||||
case "$( uname -m )" in
|
||||
i?86) ARCH=i586 ;;
|
||||
arm*) ARCH=arm ;;
|
||||
*) ARCH=$( uname -m ) ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
|
||||
# the name of the created package would be, and then exit. This information
|
||||
# could be useful to other scripts.
|
||||
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
|
||||
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
TMP=$CWD
|
||||
PKG=$TMP/package-$PRGNAM
|
||||
OUTPUT=$CWD
|
||||
|
||||
if [ "$ARCH" = "i586" ]; then
|
||||
SLKCFLAGS="-O2 -march=i586 -mtune=i686"
|
||||
LIBDIRSUFFIX=""
|
||||
elif [ "$ARCH" = "i686" ]; then
|
||||
SLKCFLAGS="-O2 -march=i686 -mtune=i686"
|
||||
LIBDIRSUFFIX=""
|
||||
elif [ "$ARCH" = "x86_64" ]; then
|
||||
SLKCFLAGS="-O2 -fPIC"
|
||||
LIBDIRSUFFIX="64"
|
||||
else
|
||||
SLKCFLAGS="-O2"
|
||||
LIBDIRSUFFIX=""
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
rm -rf $PKG
|
||||
mkdir -p $TMP $PKG $OUTPUT
|
||||
cd $TMP
|
||||
rm -rf $PRGNAM-$VERSION
|
||||
git clone https://git.stormux.org/storm/cthulhu.git $PRGNAM-$VERSION
|
||||
cd $PRGNAM-$VERSION
|
||||
chown -R root:root .
|
||||
find -L . \
|
||||
\( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
|
||||
-o -perm 511 \) -exec chmod 755 {} \; -o \
|
||||
\( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
|
||||
-o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
|
||||
|
||||
# Prepare the source
|
||||
NOCONFIGURE=1 ./autogen.sh
|
||||
|
||||
CFLAGS="$SLKCFLAGS" \
|
||||
CXXFLAGS="$SLKCFLAGS" \
|
||||
./configure \
|
||||
--prefix=/usr \
|
||||
--libdir=/usr/lib${LIBDIRSUFFIX} \
|
||||
--sysconfdir=/etc \
|
||||
--localstatedir=/var \
|
||||
--mandir=/usr/man \
|
||||
--docdir=/usr/doc/$PRGNAM-$VERSION \
|
||||
--build=$ARCH-slackware-linux
|
||||
|
||||
make
|
||||
make install DESTDIR=$PKG
|
||||
|
||||
find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \
|
||||
| cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
|
||||
|
||||
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
|
||||
cp -a AUTHORS COPYING ChangeLog NEWS README.md \
|
||||
$PKG/usr/doc/$PRGNAM-$VERSION
|
||||
cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
|
||||
|
||||
mkdir -p $PKG/install
|
||||
cat $CWD/slack-desc > $PKG/install/slack-desc
|
||||
cat $CWD/doinst.sh > $PKG/install/doinst.sh
|
||||
|
||||
cd $PKG
|
||||
# let's avoid a "bad interpreter error
|
||||
sed "s,#!python3.11,#!/usr/bin/python3.11," usr/bin/cthulhu > dummy
|
||||
mv dummy usr/bin/cthulhu
|
||||
chmod 755 usr/bin/cthulhu
|
||||
/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE
|
||||
@@ -0,0 +1,28 @@
|
||||
Cthulhu is a screen reader for individuals who are blind or visually impaired,
|
||||
forked from Orca. It provides access to applications and toolkits that support
|
||||
the AT-SPI (e.g., the GNOME desktop).
|
||||
|
||||
This screen reader helps users navigate their desktop environment and applications
|
||||
through speech synthesis and braille output.
|
||||
|
||||
After installation, you can start Cthulhu through the GNOME desktop environment
|
||||
or by running 'cthulhu' from the command line.
|
||||
|
||||
DEPENDENCIES:
|
||||
This package requires the following packages, all available from SlackBuilds.org:
|
||||
- at-spi2-core
|
||||
- brltty
|
||||
- gobject-introspection
|
||||
- gsettings-desktop-schemas
|
||||
- gstreamer
|
||||
- gst-plugins-base
|
||||
- gst-plugins-good
|
||||
- gtk3
|
||||
- liblouis
|
||||
- libpeas
|
||||
- libwnck3
|
||||
- python3-atspi
|
||||
- python3-cairo
|
||||
- python3-gobject
|
||||
- python3-setproctitle
|
||||
- speech-dispatcher
|
||||
@@ -0,0 +1,10 @@
|
||||
PRGNAM="cthulhu"
|
||||
VERSION="0.4"
|
||||
HOMEPAGE="https://git.stormux.org/storm/cthulhu"
|
||||
DOWNLOAD="https://git.stormux.org/storm/cthulhu.git"
|
||||
MD5SUM="SKIP"
|
||||
DOWNLOAD_x86_64=""
|
||||
MD5SUM_x86_64=""
|
||||
REQUIRES="at-spi2-core brltty gobject-introspection gsettings-desktop-schemas gstreamer gst-plugins-base gst-plugins-good gtk3 liblouis libpeas libwnck3 python3-atspi python3-cairo python3-gobject python3-setproctitle speech-dispatcher"
|
||||
MAINTAINER="Storm Dragon"
|
||||
EMAIL="storm_dragon@stormux.org"
|
||||
Executable
+98
@@ -0,0 +1,98 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Slackware build script for cthulhu
|
||||
# Created based on PKGBUILD from Storm Dragon <storm_dragon@stormux.org>
|
||||
|
||||
cd $(dirname $0) ; CWD=$(pwd)
|
||||
|
||||
PRGNAM=cthulhu
|
||||
VERSION=${VERSION:-0.4}
|
||||
BUILD=${BUILD:-1}
|
||||
TAG=storm
|
||||
PKGTYPE=txz
|
||||
export PYTHON=/usr/bin/python3.11
|
||||
|
||||
if [ -z "$ARCH" ]; then
|
||||
case "$( uname -m )" in
|
||||
i?86) ARCH=i586 ;;
|
||||
arm*) ARCH=arm ;;
|
||||
*) ARCH=$( uname -m ) ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
|
||||
# the name of the created package would be, and then exit. This information
|
||||
# could be useful to other scripts.
|
||||
if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
|
||||
echo "$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
TMP=$CWD
|
||||
PKG=$TMP/package-$PRGNAM
|
||||
OUTPUT=$CWD
|
||||
|
||||
if [ "$ARCH" = "i586" ]; then
|
||||
SLKCFLAGS="-O2 -march=i586 -mtune=i686"
|
||||
LIBDIRSUFFIX=""
|
||||
elif [ "$ARCH" = "i686" ]; then
|
||||
SLKCFLAGS="-O2 -march=i686 -mtune=i686"
|
||||
LIBDIRSUFFIX=""
|
||||
elif [ "$ARCH" = "x86_64" ]; then
|
||||
SLKCFLAGS="-O2 -fPIC"
|
||||
LIBDIRSUFFIX="64"
|
||||
else
|
||||
SLKCFLAGS="-O2"
|
||||
LIBDIRSUFFIX=""
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
rm -rf $PKG
|
||||
mkdir -p $TMP $PKG $OUTPUT
|
||||
cd $TMP
|
||||
rm -rf $PRGNAM-$VERSION
|
||||
git clone https://git.stormux.org/storm/cthulhu.git $PRGNAM-$VERSION
|
||||
cd $PRGNAM-$VERSION
|
||||
chown -R root:root .
|
||||
find -L . \
|
||||
\( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
|
||||
-o -perm 511 \) -exec chmod 755 {} \; -o \
|
||||
\( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
|
||||
-o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
|
||||
|
||||
# Prepare the source
|
||||
NOCONFIGURE=1 ./autogen.sh
|
||||
|
||||
CFLAGS="$SLKCFLAGS" \
|
||||
CXXFLAGS="$SLKCFLAGS" \
|
||||
./configure \
|
||||
--prefix=/usr \
|
||||
--libdir=/usr/lib${LIBDIRSUFFIX} \
|
||||
--sysconfdir=/etc \
|
||||
--localstatedir=/var \
|
||||
--mandir=/usr/man \
|
||||
--docdir=/usr/doc/$PRGNAM-$VERSION \
|
||||
--build=$ARCH-slackware-linux
|
||||
|
||||
make
|
||||
make install DESTDIR=$PKG
|
||||
|
||||
find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | grep ELF \
|
||||
| cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
|
||||
|
||||
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
|
||||
cp -a AUTHORS COPYING ChangeLog NEWS README.md \
|
||||
$PKG/usr/doc/$PRGNAM-$VERSION
|
||||
cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
|
||||
|
||||
mkdir -p $PKG/install
|
||||
cat $CWD/slack-desc > $PKG/install/slack-desc
|
||||
cat $CWD/doinst.sh > $PKG/install/doinst.sh
|
||||
|
||||
cd $PKG
|
||||
# let's avoid a "bad interpreter error
|
||||
sed "s,#!python3.11,#!/usr/bin/python3.11," usr/bin/cthulhu > dummy
|
||||
mv dummy usr/bin/cthulhu
|
||||
chmod 755 usr/bin/cthulhu
|
||||
/sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.$PKGTYPE
|
||||
@@ -0,0 +1,9 @@
|
||||
if [ -x /usr/bin/update-desktop-database ]; then
|
||||
/usr/bin/update-desktop-database -q usr/share/applications >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
if [ -e usr/share/icons/hicolor/icon-theme.cache ]; then
|
||||
if [ -x /usr/bin/gtk-update-icon-cache ]; then
|
||||
/usr/bin/gtk-update-icon-cache usr/share/icons/hicolor >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
@@ -0,0 +1,19 @@
|
||||
# HOW TO EDIT THIS FILE:
|
||||
# The "handy ruler" below makes it easier to edit a package description.
|
||||
# Line up the first '|' above the ':' following the base package name, and
|
||||
# the '|' on the right side marks the last column you can put a character in.
|
||||
# You must make exactly 11 lines for the formatting to be correct. It's also
|
||||
# customary to leave one space after the ':' except on otherwise blank lines.
|
||||
|
||||
|-----handy-ruler------------------------------------------------------|
|
||||
cthulhu: cthulhu (Screen reader for blind or visually impaired users)
|
||||
cthulhu:
|
||||
cthulhu: Cthulhu is a screen reader for individuals who are blind or visually
|
||||
cthulhu: impaired, forked from Orca. It provides a way to access applications
|
||||
cthulhu: and toolkits that support the AT-SPI (e.g., the GNOME desktop).
|
||||
cthulhu:
|
||||
cthulhu: Homepage: https://git.stormux.org/storm/cthulhu
|
||||
cthulhu:
|
||||
cthulhu:
|
||||
cthulhu:
|
||||
cthulhu:
|
||||
@@ -2710,7 +2710,7 @@ msgstr ""
|
||||
"DENGUNA GARANTÍA; ensin denguna implicación de garantía de COMERCIABILIDÁ o CALIDÁ PA DENGÚN PROPÓSITU PARTICULAR. Consulta la Llicencia Pública Xeneral Reducida GNU pa más\n"
|
||||
"detalles.\n"
|
||||
"\n"
|
||||
"Tendríes de recibir una copia de la Llicencia Pública Xeneral Reducida de GNU xuntu con ORCA, de lo contrario, escribi a la Free Software Foundation, Inc, Franklin\n"
|
||||
"Tendríes de recibir una copia de la Llicencia Pública Xeneral Reducida de GNU xuntu con CTHULHU, de lo contrario, escribi a la Free Software Foundation, Inc, Franklin\n"
|
||||
"Street, Fifth Floor, Boston, MA 02110-1301, EE. UU."
|
||||
|
||||
#. DESCRIP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# translation of cthulhu.HEAD.po to Español
|
||||
# Traducción de Cthulhu al Español
|
||||
# This file is distributed under the same license as the ORCA package.
|
||||
# This file is distributed under the same license as the CTHULHU package.
|
||||
# Copyright (C) 2005 GNOME Foundation.
|
||||
#
|
||||
# Francisco Javier F. Serrador <serrador@cvs.gnome.org>, 2004, 2006.
|
||||
@@ -15099,7 +15099,7 @@ msgstr ""
|
||||
#~ "detalles.\n"
|
||||
#~ "\n"
|
||||
#~ "Debería haber recibido una copia de la Licencia Pública General Reducida "
|
||||
#~ "de GNU junto con ORCA, de lo contrario, escriba a la Free Software "
|
||||
#~ "de GNU junto con CTHULHU, de lo contrario, escriba a la Free Software "
|
||||
#~ "Foundation, Inc, \n"
|
||||
#~ "Franklin Street, Fifth Floor, Boston, MA 02110-1301, EE. UU."
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Përkthimi i cthulhu.HEAD në shqip.
|
||||
# Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
# This file is distributed under the same license as the ORCA package.
|
||||
# This file is distributed under the same license as the CTHULHU package.
|
||||
#
|
||||
# Laurent Dhima <laurenti@alblinux.net>, 2007.
|
||||
msgid ""
|
||||
|
||||
+26
-9
@@ -1,10 +1,27 @@
|
||||
# Ruff linter.
|
||||
#
|
||||
# Repository: https://github.com/astral-sh/ruff
|
||||
#
|
||||
# Documentation: https://beta.ruff.rs/docs/
|
||||
[tool.ruff]
|
||||
line-length = 100 # same as rustfmt
|
||||
ignore = [
|
||||
"E402", # Module level import not at top of file
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "cthulhu"
|
||||
dynamic = ["version"]
|
||||
description = "Fork of the Orca screen reader based on gnome-45"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.3"
|
||||
license = { text = "LGPL-2.1-or-later" }
|
||||
dependencies = [
|
||||
"pygobject>=3.18",
|
||||
"python-atspi>=2.48",
|
||||
"brlapi; extra == 'braille'",
|
||||
"python-speechd; extra == 'speech'",
|
||||
"louis; extra == 'braille'"
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
cthulhu = "cthulhu.cthulhu:main"
|
||||
|
||||
[tool.hatch.version]
|
||||
path = "src/cthulhu/__init__.py"
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["src/cthulhu"]
|
||||
|
||||
+294
@@ -0,0 +1,294 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
import argparse
|
||||
import gi
|
||||
gi.require_version("Atspi", "2.0")
|
||||
from gi.repository import Atspi
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
def setup_paths():
|
||||
"""Configure paths for both installed and source directory execution."""
|
||||
currentDir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# Check if running from source
|
||||
if os.path.exists(os.path.join(currentDir, 'plugins')):
|
||||
# Running from source directory
|
||||
sys.path.insert(0, os.path.dirname(currentDir))
|
||||
pythondir = currentDir
|
||||
else:
|
||||
# Running installed
|
||||
sys.prefix = '/usr'
|
||||
pythondir = os.path.join(sys.prefix, 'lib', f'python{sys.version_info.major}.{sys.version_info.minor}', 'site-packages')
|
||||
|
||||
sys.path.insert(1, pythondir)
|
||||
|
||||
# Set environment variables for resource paths
|
||||
if 'CTHULHU_DATA_DIR' not in os.environ:
|
||||
if os.path.exists(os.path.join(currentDir, 'plugins')):
|
||||
os.environ['CTHULHU_DATA_DIR'] = currentDir
|
||||
else:
|
||||
os.environ['CTHULHU_DATA_DIR'] = os.path.join(sys.prefix, 'share', 'cthulhu')
|
||||
|
||||
# Set up paths before importing Cthulhu modules
|
||||
setup_paths()
|
||||
|
||||
from cthulhu import debug
|
||||
from cthulhu import messages
|
||||
from cthulhu import settings
|
||||
from cthulhu.ax_object import AXObject
|
||||
from cthulhu.ax_utilities import AXUtilities
|
||||
from cthulhu.cthulhu_platform import version
|
||||
|
||||
class ListApps(argparse.Action):
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
desktop = AXUtilities.get_desktop()
|
||||
for app in AXObject.iter_children(desktop):
|
||||
pid = AXObject.get_process_id(app)
|
||||
try:
|
||||
name = Atspi.Accessible.get_name(app) or "(none)"
|
||||
except Exception:
|
||||
name = "[DEAD]"
|
||||
|
||||
try:
|
||||
cmdline = subprocess.getoutput('cat /proc/%s/cmdline' % pid)
|
||||
except Exception:
|
||||
cmdline = '(exception encountered)'
|
||||
else:
|
||||
cmdline = cmdline.replace('\x00', ' ')
|
||||
|
||||
print(time.strftime('%H:%M:%S', time.localtime()),
|
||||
' pid: %5s %-25s %s' % (pid, name, cmdline))
|
||||
|
||||
parser.exit()
|
||||
|
||||
class Settings(argparse.Action):
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
settingsDict = getattr(namespace, 'settings', {})
|
||||
invalid = getattr(namespace, 'invalid', [])
|
||||
for value in values.split(','):
|
||||
item = str.title(value).replace('-', '')
|
||||
try:
|
||||
test = 'enable%s' % item
|
||||
eval('settings.%s' % test)
|
||||
except AttributeError:
|
||||
try:
|
||||
test = 'show%s' % item
|
||||
eval('settings.%s' % test)
|
||||
except AttributeError:
|
||||
invalid.append(value)
|
||||
continue
|
||||
settingsDict[test] = self.const
|
||||
setattr(namespace, 'settings', settingsDict)
|
||||
setattr(namespace, 'invalid', invalid)
|
||||
|
||||
class HelpFormatter(argparse.HelpFormatter):
|
||||
def __init__(self, prog, indent_increment=2, max_help_position=32,
|
||||
width=None):
|
||||
|
||||
super().__init__(prog, indent_increment, max_help_position, width)
|
||||
|
||||
def add_usage(self, usage, actions, groups, prefix=None):
|
||||
super().add_usage(usage, actions, groups, messages.CLI_USAGE)
|
||||
|
||||
class Parser(argparse.ArgumentParser):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Parser, self).__init__(
|
||||
epilog=messages.CLI_EPILOG, formatter_class=HelpFormatter, add_help=False)
|
||||
self.add_argument(
|
||||
"-h", "--help", action="help", help=messages.CLI_HELP)
|
||||
self.add_argument(
|
||||
"-v", "--version", action="version", version=version, help=messages.CLI_VERSION)
|
||||
self.add_argument(
|
||||
"-r", "--replace", action="store_true", help=messages.CLI_REPLACE)
|
||||
self.add_argument(
|
||||
"-s", "--setup", action="store_true", help=messages.CLI_GUI_SETUP)
|
||||
self.add_argument(
|
||||
"-l", "--list-apps", action=ListApps, nargs=0,
|
||||
help=messages.CLI_LIST_APPS)
|
||||
self.add_argument(
|
||||
"-e", "--enable", action=Settings, const=True,
|
||||
help=messages.CLI_ENABLE_OPTION, metavar=messages.CLI_OPTION)
|
||||
self.add_argument(
|
||||
"-d", "--disable", action=Settings, const=False,
|
||||
help=messages.CLI_DISABLE_OPTION, metavar=messages.CLI_OPTION)
|
||||
self.add_argument(
|
||||
"-p", "--profile", action="store",
|
||||
help=messages.CLI_LOAD_PROFILE, metavar=messages.CLI_PROFILE_NAME)
|
||||
self.add_argument(
|
||||
"-u", "--user-prefs", action="store",
|
||||
help=messages.CLI_LOAD_PREFS, metavar=messages.CLI_PREFS_DIR)
|
||||
self.add_argument(
|
||||
"--debug-file", action="store",
|
||||
help=messages.CLI_DEBUG_FILE, metavar=messages.CLI_DEBUG_FILE_NAME)
|
||||
self.add_argument(
|
||||
"--debug", action="store_true", help=messages.CLI_ENABLE_DEBUG)
|
||||
|
||||
self._optionals.title = messages.CLI_OPTIONAL_ARGUMENTS
|
||||
|
||||
def parse_known_args(self, *args, **kwargs):
|
||||
opts, invalid = super(Parser, self).parse_known_args(*args, **kwargs)
|
||||
try:
|
||||
invalid.extend(opts.invalid)
|
||||
except Exception:
|
||||
pass
|
||||
if invalid:
|
||||
print((messages.CLI_INVALID_OPTIONS + " ".join(invalid)))
|
||||
|
||||
if opts.debug_file:
|
||||
opts.debug = True
|
||||
elif opts.debug:
|
||||
opts.debug_file = time.strftime('debug-%Y-%m-%d-%H:%M:%S.out')
|
||||
|
||||
return opts, invalid
|
||||
|
||||
def setProcessName(name):
|
||||
"""Attempts to set the process name to the specified name."""
|
||||
|
||||
sys.argv[0] = name
|
||||
|
||||
try:
|
||||
from setproctitle import setproctitle
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
setproctitle(name)
|
||||
return True
|
||||
|
||||
try:
|
||||
from ctypes import cdll, byref, create_string_buffer
|
||||
libc = cdll.LoadLibrary('libc.so.6')
|
||||
stringBuffer = create_string_buffer(len(name) + 1)
|
||||
stringBuffer.value = bytes(name, 'UTF-8')
|
||||
libc.prctl(15, byref(stringBuffer), 0, 0, 0)
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
def inGraphicalDesktop():
|
||||
"""Returns True if we are in a graphical desktop."""
|
||||
|
||||
# TODO - JD: Make this desktop environment agnostic
|
||||
try:
|
||||
import gi
|
||||
gi.require_version("Gdk", "3.0")
|
||||
from gi.repository import Gdk
|
||||
display = Gdk.Display.get_default()
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
return display is not None
|
||||
|
||||
def otherCthulhus():
|
||||
"""Returns the pid of any other instances of Cthulhu owned by this user."""
|
||||
|
||||
openFile = subprocess.Popen('pgrep -u %s -x cthulhu' % os.getuid(),
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE).stdout
|
||||
pids = openFile.read()
|
||||
openFile.close()
|
||||
cthulhus = [int(p) for p in pids.split()]
|
||||
|
||||
pid = os.getpid()
|
||||
return [p for p in cthulhus if p != pid]
|
||||
|
||||
def cleanup(sigval):
|
||||
"""Tries to clean up any other running Cthulhu instances owned by this user."""
|
||||
|
||||
cthulhusToKill = otherCthulhus()
|
||||
debug.printMessage(debug.LEVEL_INFO, "INFO: Cleaning up these PIDs: %s" % cthulhusToKill)
|
||||
|
||||
def onTimeout(signum, frame):
|
||||
cthulhusToKill = otherCthulhus()
|
||||
debug.printMessage(debug.LEVEL_INFO, "INFO: Timeout cleaning up: %s" % cthulhusToKill)
|
||||
for pid in cthulhusToKill:
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
|
||||
for pid in cthulhusToKill:
|
||||
os.kill(pid, sigval)
|
||||
signal.signal(signal.SIGALRM, onTimeout)
|
||||
signal.alarm(2)
|
||||
while otherCthulhus():
|
||||
time.sleep(0.5)
|
||||
|
||||
def main():
|
||||
setProcessName('cthulhu')
|
||||
|
||||
parser = Parser()
|
||||
args, invalid = parser.parse_known_args()
|
||||
|
||||
if args.debug:
|
||||
debug.debugLevel = debug.LEVEL_ALL
|
||||
debug.eventDebugLevel = debug.LEVEL_OFF
|
||||
debug.debugFile = open(args.debug_file, 'w')
|
||||
|
||||
if args.replace:
|
||||
cleanup(signal.SIGKILL)
|
||||
|
||||
settingsDict = getattr(args, 'settings', {})
|
||||
|
||||
if not inGraphicalDesktop():
|
||||
print(messages.CLI_NO_DESKTOP_ERROR)
|
||||
return 1
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, "INFO: Preparing to launch.", True)
|
||||
|
||||
from cthulhu import cthulhu
|
||||
manager = cthulhu.getSettingsManager()
|
||||
|
||||
if not manager:
|
||||
print(messages.CLI_SETTINGS_MANAGER_ERROR)
|
||||
return 1
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, "INFO: About to activate settings manager.", True)
|
||||
manager.activate(args.user_prefs, settingsDict)
|
||||
sys.path.insert(0, manager.getPrefsDir())
|
||||
|
||||
if args.profile:
|
||||
try:
|
||||
manager.setProfile(args.profile)
|
||||
except Exception:
|
||||
print(messages.CLI_LOAD_PROFILE_ERROR % args.profile)
|
||||
manager.setProfile()
|
||||
|
||||
if args.setup:
|
||||
cleanup(signal.SIGKILL)
|
||||
cthulhu.showPreferencesGUI()
|
||||
|
||||
if otherCthulhus():
|
||||
print(messages.CLI_OTHER_CTHULHUS_ERROR)
|
||||
return 1
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, "INFO: About to launch Cthulhu.", True)
|
||||
return cthulhu.main()
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -29,6 +29,7 @@ cthulhu_python_PYTHON = \
|
||||
cmdnames.py \
|
||||
colornames.py \
|
||||
common_keyboardmap.py \
|
||||
cthulhuVersion.py \
|
||||
date_and_time_presenter.py \
|
||||
debug.py \
|
||||
desktop_keyboardmap.py \
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Cthulhu Screen Reader"""
|
||||
|
||||
__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc."
|
||||
|
||||
+8
-3
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2008 Google Inc.
|
||||
# Portions Copyright 2007-2008, Sun Microsystems, Inc.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -18,6 +20,9 @@
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""ACSS --- Aural CSS.
|
||||
|
||||
Class ACSS defines a simple wrapper for holding ACSS voice
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2023 Igalia, S.L.
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Module for performing accessible actions via a menu"""
|
||||
|
||||
@@ -81,7 +86,7 @@ class ActionPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"a",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_SHIFT_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_SHIFT_MODIFIER_MASK,
|
||||
self._handlers.get("show_actions_menu")))
|
||||
|
||||
return bindings
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Utilities for obtaining objects via the collection interface.
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2023 Igalia, S.L.
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""
|
||||
Utilities for obtaining objects via the collection interface.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2008 Sun Microsystems Inc.
|
||||
# Copyright 2018-2023 Igalia, S.L.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Provides support for synthesizing accessible input events."""
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Utilities for obtaining information about accessible objects.
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2023 Igalia, S.L.
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""
|
||||
Utilities for obtaining information about accessible objects.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Utilities for obtaining information about containers supporting selection
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2023 Igalia, S.L.
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""
|
||||
Utilities for obtaining information about containers supporting selection.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Utilities for performing tasks related to accessibility inspection.
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2023 Igalia, S.L.
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""
|
||||
Utilities for performing tasks related to accessibility inspection.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Utilities for finding all objects that meet a certain criteria.
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2023 Igalia, S.L.
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""
|
||||
Utilities for finding all objects that meet a certain criteria.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Utilities for obtaining role-related information.
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2023 Igalia, S.L.
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""
|
||||
Utilities for obtaining role-related information.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Utilities for obtaining state-related information.
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2023 Igalia, S.L.
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""
|
||||
Utilities for obtaining state-related information.
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2010-2011 Consorcio Fernando de los Rios.
|
||||
# Author: Juanje Ojeda Croissier <jojeda@emergya.es>
|
||||
# Author: Javier Hernandez Antunez <jhernandez@emergya.es>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -18,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""JSON backend for Cthulhu settings"""
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2008 Sun Microsystems Inc.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Provides the default implementation for bookmarks in Cthulhu."""
|
||||
|
||||
@@ -95,21 +101,21 @@ class Bookmarks:
|
||||
keybindings.KeyBinding(
|
||||
"b",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("goToNextBookmark")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"b",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_SHIFT_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_SHIFT_MODIFIER_MASK,
|
||||
self._handlers.get("goToPrevBookmark")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"b",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_ALT_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_ALT_MODIFIER_MASK,
|
||||
self._handlers.get("saveBookmarks")))
|
||||
|
||||
for i in range(6):
|
||||
@@ -117,14 +123,14 @@ class Bookmarks:
|
||||
keybindings.KeyBinding(
|
||||
str(i + 1),
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("goToBookmark")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
str(i + 1),
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_ALT_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_ALT_MODIFIER_MASK,
|
||||
self._handlers.get("addBookmark")))
|
||||
|
||||
return bindings
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2009 Sun Microsystems Inc.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""A very experimental approach to the refreshable Braille display. This
|
||||
module treats each line of the display as a sequential set of regions, where
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2009 Sun Microsystems Inc.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Utilities for obtaining braille presentations for objects."""
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2012 Igalia, S.L.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Dictionary of abbreviated rolenames for use with braille."""
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2006-2008 Sun Microsystems Inc.
|
||||
# Copyright 2011 The Cthulhu Team.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -18,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Provides a graphical braille display, mainly for development tasks."""
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2004-2009 Sun Microsystems Inc.
|
||||
# Copyright 2010-2013 The Cthulhu Team
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Braille translation table names. These have been put in their own module
|
||||
so that we can present them in the correct language when users change the
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2013-2015 Igalia, S.L.
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Provides an Cthulhu-controlled caret for text content."""
|
||||
|
||||
@@ -144,7 +149,7 @@ class CaretNavigation:
|
||||
keybindings.KeyBinding(
|
||||
"F12",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("toggle_enabled")))
|
||||
|
||||
bindings.add(
|
||||
@@ -229,7 +234,7 @@ class CaretNavigation:
|
||||
_settings_manager = settings_manager.getManager()
|
||||
enabled = not _settings_manager.getSetting('caretNavigationEnabled')
|
||||
if enabled:
|
||||
string = messages.CARET_CONTROL_ORCA
|
||||
string = messages.CARET_CONTROL_CTHULHU
|
||||
else:
|
||||
string = messages.CARET_CONTROL_APP
|
||||
|
||||
|
||||
+10
-4
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2010-2011 The Cthulhu Team
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Implements generic chat support."""
|
||||
|
||||
@@ -308,7 +314,7 @@ class Chat:
|
||||
#
|
||||
self.messageKeys = \
|
||||
["F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"]
|
||||
self.messageKeyModifier = keybindings.ORCA_MODIFIER_MASK
|
||||
self.messageKeyModifier = keybindings.CTHULHU_MODIFIER_MASK
|
||||
self.inputEventHandlers = {}
|
||||
self.setupInputEventHandlers()
|
||||
self.keyBindings = self.getKeyBindings()
|
||||
@@ -387,7 +393,7 @@ class Chat:
|
||||
keybindings.KeyBinding(
|
||||
messageKey,
|
||||
self.messageKeyModifier,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self.inputEventHandlers["reviewMessage"]))
|
||||
|
||||
return keyBindings
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2004-2008 Sun Microsystems Inc.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Provides getCharacterName that maps punctuation marks and other
|
||||
individual characters into localized words."""
|
||||
|
||||
+12
-4
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2004-2009 Sun Microsystems Inc.
|
||||
# Copyright 2010-2013 The Cthulhu Team
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Command names which Cthulhu presents in speech and/or braille. These
|
||||
have been put in their own module so that we can present them in
|
||||
@@ -455,9 +460,12 @@ TOGGLE_SPEECH = _("Toggle the silencing of speech")
|
||||
# This string describes that command.
|
||||
TOGGLE_SPEECH_VERBOSITY = _("Toggle speech verbosity level")
|
||||
|
||||
# Translators: this string is associated with the keyboard shortcut to toggle sleepmode
|
||||
TOGGLE_SLEEP_MODE = _("Toggle sleep mode")
|
||||
|
||||
# Translators: this string is associated with the keyboard shortcut to quit
|
||||
# Cthulhu.
|
||||
QUIT_ORCA = _("Quit the screen reader")
|
||||
QUIT_CTHULHU = _("Quit the screen reader")
|
||||
|
||||
# Translators: the preferences configuration dialog is the dialog that allows
|
||||
# users to set their preferences for Cthulhu.
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2014 Igalia, S.L.
|
||||
#
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -18,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
__id__ = "$Id$"
|
||||
__version__ = "$Revision$"
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2010-2011 The Cthulhu Team
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
""" A list of common keybindings and unbound keys
|
||||
pulled out from default.py: getKeyBindings()
|
||||
@@ -32,26 +38,29 @@ from . import keybindings
|
||||
|
||||
# Storing values
|
||||
defaultModifierMask = keybindings.defaultModifierMask
|
||||
ORCA_MODIFIER_MASK = keybindings.ORCA_MODIFIER_MASK
|
||||
CTHULHU_MODIFIER_MASK = keybindings.CTHULHU_MODIFIER_MASK
|
||||
NO_MODIFIER_MASK = keybindings.NO_MODIFIER_MASK
|
||||
ORCA_SHIFT_MODIFIER_MASK = keybindings.ORCA_SHIFT_MODIFIER_MASK
|
||||
ORCA_CTRL_MODIFIER_MASK = keybindings.ORCA_CTRL_MODIFIER_MASK
|
||||
ORCA_ALT_MODIFIER_MASK = keybindings.ORCA_ALT_MODIFIER_MASK
|
||||
ORCA_CTRL_ALT_MODIFIER_MASK = keybindings.ORCA_CTRL_ALT_MODIFIER_MASK
|
||||
CTHULHU_SHIFT_MODIFIER_MASK = keybindings.CTHULHU_SHIFT_MODIFIER_MASK
|
||||
CTHULHU_CTRL_MODIFIER_MASK = keybindings.CTHULHU_CTRL_MODIFIER_MASK
|
||||
CTHULHU_ALT_MODIFIER_MASK = keybindings.CTHULHU_ALT_MODIFIER_MASK
|
||||
CTHULHU_CTRL_ALT_MODIFIER_MASK = keybindings.CTHULHU_CTRL_ALT_MODIFIER_MASK
|
||||
SHIFT_ALT_MODIFIER_MASK = keybindings.SHIFT_ALT_MODIFIER_MASK
|
||||
|
||||
keymap = (
|
||||
|
||||
("space", defaultModifierMask, ORCA_MODIFIER_MASK,
|
||||
("space", defaultModifierMask, CTHULHU_MODIFIER_MASK,
|
||||
"preferencesSettingsHandler"),
|
||||
|
||||
("space", defaultModifierMask, ORCA_CTRL_MODIFIER_MASK,
|
||||
("space", defaultModifierMask, CTHULHU_CTRL_MODIFIER_MASK,
|
||||
"appPreferencesSettingsHandler"),
|
||||
|
||||
("BackSpace", defaultModifierMask, ORCA_MODIFIER_MASK,
|
||||
("BackSpace", defaultModifierMask, CTHULHU_MODIFIER_MASK,
|
||||
"bypassNextCommandHandler"),
|
||||
|
||||
("q", defaultModifierMask, ORCA_MODIFIER_MASK,
|
||||
("q", defaultModifierMask, CTHULHU_CTRL_ALT_MODIFIER_MASK, CTHULHU_SHIFT_MODIFIER_MASK,
|
||||
"toggleSleepModeHandler"),
|
||||
|
||||
("q", defaultModifierMask, CTHULHU_MODIFIER_MASK,
|
||||
"shutdownHandler"),
|
||||
|
||||
|
||||
|
||||
+141
-48
@@ -1,8 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2004-2009 Sun Microsystems Inc.
|
||||
# Copyright 2010-2011 The Cthulhu Team
|
||||
# Copyright 2012 Igalia, S.L.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -18,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""The main module for the Cthulhu screen reader."""
|
||||
|
||||
@@ -30,6 +34,94 @@ __copyright__ = "Copyright (c) 2004-2009 Sun Microsystems Inc." \
|
||||
__license__ = "LGPL"
|
||||
|
||||
import faulthandler
|
||||
|
||||
class APIHelper:
|
||||
"""Helper class for plugin API interactions, including keybindings."""
|
||||
|
||||
def __init__(self, app):
|
||||
"""Initialize the APIHelper.
|
||||
|
||||
Arguments:
|
||||
- app: the Cthulhu application
|
||||
"""
|
||||
self.app = app
|
||||
self._gestureBindings = {}
|
||||
|
||||
def registerGestureByString(self, function, name, gestureString,
|
||||
inputEventType='default', normalizer='cthulhu',
|
||||
learnModeEnabled=True, contextName=None):
|
||||
"""Register a gesture by string.
|
||||
|
||||
Arguments:
|
||||
- function: the function to call when the gesture is performed
|
||||
- name: a human-readable name for this gesture
|
||||
- gestureString: string representation of the gesture (e.g., 'kb:cthulhu+z')
|
||||
- inputEventType: the type of input event
|
||||
- normalizer: the normalizer to use
|
||||
- learnModeEnabled: whether this should be available in learn mode
|
||||
- contextName: the context for this gesture (e.g., plugin name)
|
||||
|
||||
Returns the binding ID or None if registration failed
|
||||
"""
|
||||
if not gestureString.startswith("kb:"):
|
||||
return None
|
||||
|
||||
# Extract the key portion from the gesture string
|
||||
key = gestureString.split(":", 1)[1]
|
||||
|
||||
# Handle Cthulhu modifier specially
|
||||
if "cthulhu+" in key.lower():
|
||||
from . import keybindings
|
||||
key = key.lower().replace("cthulhu+", "")
|
||||
|
||||
# Create a keybinding handler
|
||||
class GestureHandler:
|
||||
def __init__(self, function, description):
|
||||
self.function = function
|
||||
self.description = description
|
||||
|
||||
def __call__(self, script, inputEvent):
|
||||
return self.function(script, inputEvent)
|
||||
|
||||
handler = GestureHandler(function, name)
|
||||
|
||||
# Register the binding with the active script
|
||||
from . import cthulhu_state
|
||||
if cthulhu_state.activeScript:
|
||||
bindings = cthulhu_state.activeScript.getKeyBindings()
|
||||
binding = keybindings.KeyBinding(
|
||||
key,
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
handler)
|
||||
bindings.add(binding)
|
||||
|
||||
# Store binding for later reference
|
||||
if contextName not in self._gestureBindings:
|
||||
self._gestureBindings[contextName] = []
|
||||
self._gestureBindings[contextName].append(binding)
|
||||
|
||||
return binding
|
||||
|
||||
return None
|
||||
|
||||
def unregisterShortcut(self, binding, contextName=None):
|
||||
"""Unregister a previously registered shortcut.
|
||||
|
||||
Arguments:
|
||||
- binding: the binding to unregister
|
||||
- contextName: the context for this gesture
|
||||
"""
|
||||
# Remove from script's keybindings
|
||||
from . import cthulhu_state
|
||||
if cthulhu_state.activeScript:
|
||||
bindings = cthulhu_state.activeScript.getKeyBindings()
|
||||
bindings.remove(binding)
|
||||
|
||||
# Remove from our tracking
|
||||
if contextName in self._gestureBindings:
|
||||
if binding in self._gestureBindings[contextName]:
|
||||
self._gestureBindings[contextName].remove(binding)
|
||||
import gi
|
||||
import importlib
|
||||
import os
|
||||
@@ -70,7 +162,7 @@ from .ax_object import AXObject
|
||||
from .ax_utilities import AXUtilities
|
||||
from .input_event import BrailleEvent
|
||||
from . import cmdnames
|
||||
from . import plugin_system_manager
|
||||
from . import plugin_system_manager # This will now be your pluggy-based implementation
|
||||
from . import guilabels
|
||||
from . import acss
|
||||
from . import text_attribute_names
|
||||
@@ -132,7 +224,7 @@ OBJECT_NAVIGATOR = "object-navigator"
|
||||
SAY_ALL = "say-all"
|
||||
|
||||
def getActiveModeAndObjectOfInterest():
|
||||
tokens = ["ORCA: Active mode:", cthulhu_state.activeMode,
|
||||
tokens = ["CTHULHU: Active mode:", cthulhu_state.activeMode,
|
||||
"Object of interest:", cthulhu_state.objOfInterest]
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
return cthulhu_state.activeMode, cthulhu_state.objOfInterest
|
||||
@@ -150,42 +242,42 @@ def emitRegionChanged(obj, startOffset=None, endOffset=None, mode=None):
|
||||
try:
|
||||
obj.emit("mode-changed::" + mode, 1, "")
|
||||
except Exception:
|
||||
msg = "ORCA: Exception emitting mode-changed notification"
|
||||
msg = "CTHULHU: Exception emitting mode-changed notification"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
if mode != cthulhu_state.activeMode:
|
||||
tokens = ["ORCA: Switching active mode from", cthulhu_state.activeMode, "to", mode]
|
||||
tokens = ["CTHULHU: Switching active mode from", cthulhu_state.activeMode, "to", mode]
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
cthulhu_state.activeMode = mode
|
||||
|
||||
try:
|
||||
tokens = ["ORCA: Region of interest:", obj, "(", startOffset, ")", endOffset]
|
||||
tokens = ["CTHULHU: Region of interest:", obj, "(", startOffset, ")", endOffset]
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
obj.emit("region-changed", startOffset, endOffset)
|
||||
except Exception:
|
||||
msg = "ORCA: Exception emitting region-changed notification"
|
||||
msg = "CTHULHU: Exception emitting region-changed notification"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
if obj != cthulhu_state.objOfInterest:
|
||||
tokens = ["ORCA: Switching object of interest from", cthulhu_state.objOfInterest, "to", obj]
|
||||
tokens = ["CTHULHU: Switching object of interest from", cthulhu_state.objOfInterest, "to", obj]
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
cthulhu_state.objOfInterest = obj
|
||||
|
||||
def setActiveWindow(frame, app=None, alsoSetLocusOfFocus=False, notifyScript=False):
|
||||
tokens = ["ORCA: Request to set active window to", frame]
|
||||
tokens = ["CTHULHU: Request to set active window to", frame]
|
||||
if app is not None:
|
||||
tokens.extend(["in", app])
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
|
||||
if frame == cthulhu_state.activeWindow:
|
||||
msg = "ORCA: Setting activeWindow to existing activeWindow"
|
||||
msg = "CTHULHU: Setting activeWindow to existing activeWindow"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
elif frame is None:
|
||||
cthulhu_state.activeWindow = None
|
||||
else:
|
||||
real_app, real_frame = AXObject.find_real_app_and_window_for(frame, app)
|
||||
if real_frame != frame:
|
||||
tokens = ["ORCA: Correcting active window to", real_frame, "in", real_app]
|
||||
tokens = ["CTHULHU: Correcting active window to", real_frame, "in", real_app]
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
cthulhu_state.activeWindow = real_frame
|
||||
else:
|
||||
@@ -208,7 +300,7 @@ def setLocusOfFocus(event, obj, notifyScript=True, force=False):
|
||||
"""
|
||||
|
||||
if not force and obj == cthulhu_state.locusOfFocus:
|
||||
msg = "ORCA: Setting locusOfFocus to existing locusOfFocus"
|
||||
msg = "CTHULHU: Setting locusOfFocus to existing locusOfFocus"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
return
|
||||
|
||||
@@ -222,13 +314,13 @@ def setLocusOfFocus(event, obj, notifyScript=True, force=False):
|
||||
oldFocus = None
|
||||
|
||||
if obj is None:
|
||||
msg = "ORCA: New locusOfFocus is null (being cleared)"
|
||||
msg = "CTHULHU: New locusOfFocus is null (being cleared)"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
cthulhu_state.locusOfFocus = None
|
||||
return
|
||||
|
||||
if cthulhu_state.activeScript:
|
||||
tokens = ["ORCA: Active script is:", cthulhu_state.activeScript]
|
||||
tokens = ["CTHULHU: Active script is:", cthulhu_state.activeScript]
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
if cthulhu_state.activeScript.utilities.isZombie(obj):
|
||||
tokens = ["ERROR: New locusOfFocus (", obj, ") is zombie. Not updating."]
|
||||
@@ -239,7 +331,7 @@ def setLocusOfFocus(event, obj, notifyScript=True, force=False):
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
return
|
||||
|
||||
tokens = ["ORCA: Changing locusOfFocus from", oldFocus, "to", obj, ". Notify:", notifyScript]
|
||||
tokens = ["CTHULHU: Changing locusOfFocus from", oldFocus, "to", obj, ". Notify:", notifyScript]
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
cthulhu_state.locusOfFocus = obj
|
||||
|
||||
@@ -247,7 +339,7 @@ def setLocusOfFocus(event, obj, notifyScript=True, force=False):
|
||||
return
|
||||
|
||||
if not cthulhu_state.activeScript:
|
||||
msg = "ORCA: Cannot notify active script because there isn't one"
|
||||
msg = "CTHULHU: Cannot notify active script because there isn't one"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
return
|
||||
|
||||
@@ -299,7 +391,7 @@ def deviceChangeHandler(deviceManager, device):
|
||||
so we have to re-apply"""
|
||||
source = device.get_source()
|
||||
if source == Gdk.InputSource.KEYBOARD:
|
||||
msg = "ORCA: Keyboard change detected, re-creating the xmodmap"
|
||||
msg = "CTHULHU: Keyboard change detected, re-creating the xmodmap"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
_createCthulhuXmodmap()
|
||||
|
||||
@@ -409,7 +501,7 @@ def _restoreXmodmap(keyList=[]):
|
||||
to restore the entire saved xmodmap.
|
||||
"""
|
||||
|
||||
msg = "ORCA: Attempting to restore original xmodmap"
|
||||
msg = "CTHULHU: Attempting to restore original xmodmap"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
global _capsLockCleared
|
||||
@@ -418,7 +510,7 @@ def _restoreXmodmap(keyList=[]):
|
||||
stdin=subprocess.PIPE, stdout=None, stderr=None)
|
||||
p.communicate(_originalXmodmap)
|
||||
|
||||
msg = "ORCA: Original xmodmap restored"
|
||||
msg = "CTHULHU: Original xmodmap restored"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
def setKeyHandling(new):
|
||||
@@ -433,7 +525,7 @@ def loadUserSettings(script=None, inputEvent=None, skipReloadMessage=False):
|
||||
Returns True to indicate the input event has been consumed.
|
||||
"""
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, 'ORCA: Loading User Settings', True)
|
||||
debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Loading User Settings', True)
|
||||
|
||||
global _userSettings
|
||||
|
||||
@@ -473,7 +565,7 @@ def loadUserSettings(script=None, inputEvent=None, skipReloadMessage=False):
|
||||
_settingsManager.loadAppSettings(script)
|
||||
|
||||
if _settingsManager.getSetting('enableSpeech'):
|
||||
msg = 'ORCA: About to enable speech'
|
||||
msg = 'CTHULHU: About to enable speech'
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
try:
|
||||
speech.init()
|
||||
@@ -482,20 +574,20 @@ def loadUserSettings(script=None, inputEvent=None, skipReloadMessage=False):
|
||||
except Exception:
|
||||
debug.printException(debug.LEVEL_SEVERE)
|
||||
else:
|
||||
msg = 'ORCA: Speech is not enabled in settings'
|
||||
msg = 'CTHULHU: Speech is not enabled in settings'
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
if _settingsManager.getSetting('enableBraille'):
|
||||
msg = 'ORCA: About to enable braille'
|
||||
msg = 'CTHULHU: About to enable braille'
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
try:
|
||||
braille.init(_processBrailleEvent)
|
||||
except Exception:
|
||||
debug.printException(debug.LEVEL_WARNING)
|
||||
msg = 'ORCA: Could not initialize connection to braille.'
|
||||
msg = 'CTHULHU: Could not initialize connection to braille.'
|
||||
debug.printMessage(debug.LEVEL_WARNING, msg, True)
|
||||
else:
|
||||
msg = 'ORCA: Braille is not enabled in settings'
|
||||
msg = 'CTHULHU: Braille is not enabled in settings'
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
|
||||
@@ -526,7 +618,7 @@ def loadUserSettings(script=None, inputEvent=None, skipReloadMessage=False):
|
||||
|
||||
cthulhuApp.getSignalManager().emitSignal('load-setting-completed')
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, 'ORCA: User Settings Loaded', True)
|
||||
debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: User Settings Loaded', True)
|
||||
|
||||
return True
|
||||
|
||||
@@ -641,12 +733,12 @@ def init():
|
||||
module has already been initialized.
|
||||
"""
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, 'ORCA: Initializing', True)
|
||||
debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Initializing', True)
|
||||
|
||||
global _initialized
|
||||
|
||||
if _initialized and _settingsManager.isScreenReaderServiceEnabled():
|
||||
debug.printMessage(debug.LEVEL_INFO, 'ORCA: Already initialized', True)
|
||||
debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Already initialized', True)
|
||||
return False
|
||||
|
||||
# Do not hang on initialization if we can help it.
|
||||
@@ -667,14 +759,14 @@ def init():
|
||||
if a11yAppSettings:
|
||||
a11yAppSettings.connect('changed', onEnabledChanged)
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, 'ORCA: Initialized', True)
|
||||
debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Initialized', True)
|
||||
|
||||
return True
|
||||
|
||||
def start():
|
||||
"""Starts Cthulhu."""
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, 'ORCA: Starting', True)
|
||||
debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Starting', True)
|
||||
|
||||
if not _initialized:
|
||||
init()
|
||||
@@ -698,10 +790,10 @@ def start():
|
||||
devmanager.connect("device-removed", deviceChangeHandler)
|
||||
|
||||
Gdk.notify_startup_complete()
|
||||
msg = 'ORCA: Startup complete notification made'
|
||||
msg = 'CTHULHU: Startup complete notification made'
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, 'ORCA: Starting Atspi main event loop', True)
|
||||
debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Starting Atspi main event loop', True)
|
||||
Atspi.event_main()
|
||||
|
||||
def die(exitCode=1):
|
||||
@@ -730,7 +822,7 @@ def shutdown(script=None, inputEvent=None):
|
||||
was never initialized.
|
||||
"""
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, 'ORCA: Shutting down', True)
|
||||
debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Shutting down', True)
|
||||
|
||||
global _initialized
|
||||
|
||||
@@ -769,9 +861,9 @@ def shutdown(script=None, inputEvent=None):
|
||||
_initialized = False
|
||||
_restoreXmodmap(_cthulhuModifiers)
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, 'ORCA: Quitting Atspi main event loop', True)
|
||||
debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Quitting Atspi main event loop', True)
|
||||
Atspi.event_quit()
|
||||
debug.printMessage(debug.LEVEL_INFO, 'ORCA: Shutdown complete', True)
|
||||
debug.printMessage(debug.LEVEL_INFO, 'CTHULHU: Shutdown complete', True)
|
||||
|
||||
return True
|
||||
|
||||
@@ -780,7 +872,7 @@ def shutdownOnSignal(signum, frame):
|
||||
global exitCount
|
||||
|
||||
signalString = f'({signal.strsignal(signum)})'
|
||||
msg = f"ORCA: Shutting down and exiting due to signal={signum} {signalString}"
|
||||
msg = f"CTHULHU: Shutting down and exiting due to signal={signum} {signalString}"
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
|
||||
# Well...we'll try to exit nicely, but if we keep getting called,
|
||||
@@ -818,7 +910,7 @@ def shutdownOnSignal(signum, frame):
|
||||
|
||||
def crashOnSignal(signum, frame):
|
||||
signalString = f'({signal.strsignal(signum)})'
|
||||
msg = f"ORCA: Shutting down and exiting due to signal={signum} {signalString}"
|
||||
msg = f"CTHULHU: Shutting down and exiting due to signal={signum} {signalString}"
|
||||
debug.printMessage(debug.LEVEL_SEVERE, msg, True)
|
||||
debug.printStack(debug.LEVEL_SEVERE)
|
||||
_restoreXmodmap(_cthulhuModifiers)
|
||||
@@ -831,7 +923,7 @@ def main():
|
||||
an exit code of 0 means normal completion and an exit code of 50
|
||||
means Cthulhu exited because of a hang."""
|
||||
|
||||
msg = f"ORCA: Launching version {cthulhu_platform.version}"
|
||||
msg = f"CTHULHU: Launching version {cthulhu_platform.version}"
|
||||
if cthulhu_platform.revision:
|
||||
msg += f" (rev {cthulhu_platform.revision})"
|
||||
|
||||
@@ -859,13 +951,13 @@ def main():
|
||||
signal.signal(signal.SIGQUIT, shutdownOnSignal)
|
||||
signal.signal(signal.SIGSEGV, crashOnSignal)
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, "ORCA: Enabling accessibility (if needed).", True)
|
||||
debug.printMessage(debug.LEVEL_INFO, "CTHULHU: Enabling accessibility (if needed).", True)
|
||||
if not _settingsManager.isAccessibilityEnabled():
|
||||
_settingsManager.setAccessibility(True)
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, "ORCA: Initializing.", True)
|
||||
debug.printMessage(debug.LEVEL_INFO, "CTHULHU: Initializing.", True)
|
||||
init()
|
||||
debug.printMessage(debug.LEVEL_INFO, "ORCA: Initialized.", True)
|
||||
debug.printMessage(debug.LEVEL_INFO, "CTHULHU: Initialized.", True)
|
||||
|
||||
script = cthulhu_state.activeScript
|
||||
cthulhuApp.getSignalManager().emitSignal('start-application-completed')
|
||||
@@ -883,7 +975,7 @@ def main():
|
||||
_scriptManager.setActiveScript(script, "Launching.")
|
||||
|
||||
focusedObject = AXUtilities.get_focused_object(window)
|
||||
tokens = ["ORCA: Focused object is:", focusedObject]
|
||||
tokens = ["CTHULHU: Focused object is:", focusedObject]
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
if focusedObject:
|
||||
setLocusOfFocus(None, focusedObject)
|
||||
@@ -892,11 +984,11 @@ def main():
|
||||
_scriptManager.setActiveScript(script, "Found focused object.")
|
||||
|
||||
try:
|
||||
msg = "ORCA: Starting ATSPI registry."
|
||||
msg = "CTHULHU: Starting ATSPI registry."
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
start() # waits until we stop the registry
|
||||
except Exception:
|
||||
msg = "ORCA: Exception starting ATSPI registry."
|
||||
msg = "CTHULHU: Exception starting ATSPI registry."
|
||||
debug.printMessage(debug.LEVEL_SEVERE, msg, True)
|
||||
die(EXIT_CODE_HANG)
|
||||
return 0
|
||||
@@ -916,7 +1008,6 @@ class Cthulhu(GObject.Object):
|
||||
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
|
||||
@@ -924,6 +1015,7 @@ class Cthulhu(GObject.Object):
|
||||
self.dynamicApiManager = dynamic_api_manager.DynamicApiManager(self)
|
||||
self.translationManager = translation_manager.TranslationManager(self)
|
||||
self.debugManager = debug
|
||||
self.APIHelper = APIHelper(self)
|
||||
self.createCompatAPI()
|
||||
self.pluginSystemManager = plugin_system_manager.PluginSystemManager(self)
|
||||
def getAPIHelper(self):
|
||||
@@ -983,6 +1075,7 @@ class Cthulhu(GObject.Object):
|
||||
# cthulhu lets say, special compat handling....
|
||||
self.getDynamicApiManager().registerAPI('EmitRegionChanged', emitRegionChanged)
|
||||
self.getDynamicApiManager().registerAPI('LoadUserSettings', loadUserSettings)
|
||||
self.getDynamicApiManager().registerAPI('APIHelper', self.APIHelper)
|
||||
|
||||
cthulhuApp = Cthulhu()
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
version = "2025.04.03"
|
||||
codeName = "testing"
|
||||
@@ -1,9 +1,9 @@
|
||||
#!@PYTHON@
|
||||
#
|
||||
# Cthulhu
|
||||
#
|
||||
# Copyright 2010-2012 The Cthulhu Team
|
||||
# Copyright 2012 Igalia, S.L.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -19,13 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
|
||||
__id__ = "$Id$"
|
||||
__version__ = "$Revision$"
|
||||
__date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2010-2012 The Cthulhu Team" \
|
||||
"Copyright (c) 2012 Igalia, S.L."
|
||||
__license__ = "LGPL"
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
import argparse
|
||||
import gi
|
||||
@@ -272,7 +268,7 @@ def main():
|
||||
cthulhu.showPreferencesGUI()
|
||||
|
||||
if otherCthulhus():
|
||||
print(messages.CLI_OTHER_ORCAS_ERROR)
|
||||
print(messages.CLI_OTHER_CTHULHUS_ERROR)
|
||||
return 1
|
||||
|
||||
debug.printMessage(debug.LEVEL_INFO, "INFO: About to launch Cthulhu.", True)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2009 Sun Microsystems Inc.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Displays a GUI for the user to quit Cthulhu."""
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2009 Sun Microsystems Inc.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Displays a GUI for the Cthulhu Find window"""
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2012 Igalia, S.L.
|
||||
#
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -18,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Displays a GUI for Cthulhu navigation list dialogs"""
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2009 Sun Microsystems Inc.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Displays a GUI for the user to set Cthulhu preferences."""
|
||||
|
||||
@@ -187,7 +193,7 @@ class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper):
|
||||
# ***** Key Bindings treeview initialization *****
|
||||
|
||||
self.keyBindView = self.get_widget("keyBindingsTreeview")
|
||||
|
||||
|
||||
if self.keyBindView.get_columns():
|
||||
for column in self.keyBindView.get_columns():
|
||||
self.keyBindView.remove_column(column)
|
||||
@@ -331,7 +337,7 @@ class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper):
|
||||
column.set_resizable(True)
|
||||
column.set_sort_column_id(EDITABLE)
|
||||
self.keyBindView.append_column(column)
|
||||
|
||||
|
||||
# Populates the treeview with all the keybindings:
|
||||
#
|
||||
self._populateKeyBindings()
|
||||
@@ -576,7 +582,7 @@ class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper):
|
||||
self.get_widget("rateScale").set_value(rate)
|
||||
else:
|
||||
self.get_widget("rateScale").set_value(50.0)
|
||||
|
||||
|
||||
pitch = self._getPitchForVoiceType(voiceType)
|
||||
if pitch is not None:
|
||||
self.get_widget("pitchScale").set_value(pitch)
|
||||
@@ -1144,7 +1150,7 @@ class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper):
|
||||
grid = self.get_widget('flashMessageDurationGrid')
|
||||
grid.set_sensitive(not checkbox.get_active())
|
||||
self.prefsDict["flashIsPersistent"] = checkbox.get_active()
|
||||
|
||||
|
||||
def textAttributeSpokenToggled(self, cell, path, model):
|
||||
"""The user has toggled the state of one of the text attribute
|
||||
checkboxes to be spoken. Update our model to reflect this, then
|
||||
@@ -1590,7 +1596,7 @@ class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper):
|
||||
elif dateFormat == messages.DATE_FORMAT_ABBREVIATED_YMD:
|
||||
indexdate = DATE_FORMAT_ABBREVIATED_YMD
|
||||
combobox2.set_active (indexdate)
|
||||
|
||||
|
||||
combobox3 = self.get_widget("timeFormatCombo")
|
||||
self.populateComboBox(combobox3,
|
||||
[sdtime(messages.TIME_FORMAT_LOCALE, ltime()),
|
||||
@@ -1751,7 +1757,7 @@ class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper):
|
||||
prefs["enableEchoByWord"])
|
||||
self.get_widget("enableEchoBySentenceCheckButton").set_active( \
|
||||
prefs["enableEchoBySentence"])
|
||||
|
||||
|
||||
# Text attributes pane.
|
||||
#
|
||||
self._createTextAttributesTreeView()
|
||||
@@ -1779,7 +1785,7 @@ class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper):
|
||||
self.get_widget("generalDesktopButton").set_active(True)
|
||||
else:
|
||||
self.get_widget("generalLaptopButton").set_active(True)
|
||||
|
||||
|
||||
combobox = self.get_widget("sayAllStyle")
|
||||
self.populateComboBox(combobox, [guilabels.SAY_ALL_STYLE_LINE,
|
||||
guilabels.SAY_ALL_STYLE_SENTENCE])
|
||||
@@ -2742,7 +2748,7 @@ class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper):
|
||||
elif dateFormatCombo == DATE_FORMAT_ABBREVIATED_YMD:
|
||||
newFormat = messages.DATE_FORMAT_ABBREVIATED_YMD
|
||||
self.prefsDict["presentDateFormat"] = newFormat
|
||||
|
||||
|
||||
def timeFormatChanged(self, widget):
|
||||
"""Signal handler for the "changed" signal for the timeFormat
|
||||
GtkComboBox widget. Set the 'timeFormat' preference to the
|
||||
@@ -2878,7 +2884,7 @@ class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper):
|
||||
|
||||
cthulhuMods = settings.cthulhuModifierKeys
|
||||
if eventString in cthulhuMods:
|
||||
self._capturedKey = ['', keybindings.ORCA_MODIFIER_MASK, 0]
|
||||
self._capturedKey = ['', keybindings.CTHULHU_MODIFIER_MASK, 0]
|
||||
return False
|
||||
|
||||
modifierKeys = ['Alt_L', 'Alt_R', 'Control_L', 'Control_R',
|
||||
@@ -2894,9 +2900,9 @@ class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper):
|
||||
return True
|
||||
|
||||
string, modifiers, clickCount = self._capturedKey
|
||||
isCthulhuModifier = modifiers & keybindings.ORCA_MODIFIER_MASK
|
||||
isCthulhuModifier = modifiers & keybindings.CTHULHU_MODIFIER_MASK
|
||||
if isCthulhuModifier:
|
||||
eventState |= keybindings.ORCA_MODIFIER_MASK
|
||||
eventState |= keybindings.CTHULHU_MODIFIER_MASK
|
||||
self._capturedKey = [eventString, eventState, clickCount + 1]
|
||||
|
||||
return True
|
||||
@@ -2918,7 +2924,7 @@ class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper):
|
||||
if not keyName or keyName in ["Return", "Escape"]:
|
||||
return False
|
||||
|
||||
isCthulhuModifier = modifiers & keybindings.ORCA_MODIFIER_MASK
|
||||
isCthulhuModifier = modifiers & keybindings.CTHULHU_MODIFIER_MASK
|
||||
if keyName in ["Delete", "BackSpace"] and not isCthulhuModifier:
|
||||
editable.set_text("")
|
||||
self._presentMessage(messages.KB_DELETED)
|
||||
@@ -2983,7 +2989,7 @@ class CthulhuSetupGUI(cthulhu_gtkbuilder.GtkBuilderWrapper):
|
||||
|
||||
mods = mods & Gdk.ModifierType.MODIFIER_MASK
|
||||
if mods & (1 << Atspi.ModifierType.SHIFTLOCK) \
|
||||
and mods & keybindings.ORCA_MODIFIER_MASK:
|
||||
and mods & keybindings.CTHULHU_MODIFIER_MASK:
|
||||
mods ^= (1 << Atspi.ModifierType.SHIFTLOCK)
|
||||
|
||||
treeModel.set(myiter,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2010 Consorcio Fernando de los Rios.
|
||||
# Author: Javier Hernandez Antunez <jhernandez@emergya.es>
|
||||
# Author: Alejandro Leiva <aleiva@emergya.es>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -18,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Displays the Save Profile As dialog."""
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
|
||||
from cthulhu import cthulhuVersion
|
||||
|
||||
"""Holds platform-specific settings.
|
||||
"""
|
||||
|
||||
@@ -26,9 +28,9 @@ __date__ = "$Date$"
|
||||
__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
|
||||
__license__ = "LGPL"
|
||||
|
||||
# $ORCA_VERSION
|
||||
# $CTHULHU_VERSION
|
||||
#
|
||||
version = "@VERSION@"
|
||||
version = f"Cthulhu screen reader version {cthulhuVersion.version}-{cthulhuVersion.codeName}"
|
||||
|
||||
# The revision if built from git; otherwise an empty string
|
||||
#
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2009 Sun Microsystems Inc.
|
||||
# Copyright 2010 Joanmarie Diggs, Mesar Hameed
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Holds state that is shared among many modules.
|
||||
"""
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2008 Sun Microsystems Inc.
|
||||
# Copyright 2016-2023 Igalia, S.L.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Module for date and time presentation"""
|
||||
|
||||
@@ -79,7 +84,7 @@ class DateAndTimePresenter:
|
||||
keybindings.KeyBinding(
|
||||
"t",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("presentTimeHandler"),
|
||||
1))
|
||||
|
||||
@@ -87,7 +92,7 @@ class DateAndTimePresenter:
|
||||
keybindings.KeyBinding(
|
||||
"t",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("presentDateHandler"),
|
||||
2))
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2008 Sun Microsystems Inc.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Provides debug utilities for Cthulhu. Debugging is managed by a debug
|
||||
level, which is held in the debugLevel field. All other methods take
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2010 Joanmarie Diggs, Mesar Hameed.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
""" A list of common keybindings and unbound keys
|
||||
pulled out from default.py: __getDesktopBindings()
|
||||
@@ -32,13 +38,13 @@ from . import keybindings
|
||||
|
||||
# Storing values
|
||||
defaultModifierMask = keybindings.defaultModifierMask
|
||||
ORCA_MODIFIER_MASK = keybindings.ORCA_MODIFIER_MASK
|
||||
CTHULHU_MODIFIER_MASK = keybindings.CTHULHU_MODIFIER_MASK
|
||||
NO_MODIFIER_MASK = keybindings.NO_MODIFIER_MASK
|
||||
ORCA_SHIFT_MODIFIER_MASK = keybindings.ORCA_SHIFT_MODIFIER_MASK
|
||||
CTHULHU_SHIFT_MODIFIER_MASK = keybindings.CTHULHU_SHIFT_MODIFIER_MASK
|
||||
|
||||
keymap = (
|
||||
|
||||
("KP_Divide", defaultModifierMask, ORCA_MODIFIER_MASK,
|
||||
("KP_Divide", defaultModifierMask, CTHULHU_MODIFIER_MASK,
|
||||
"routePointerToItemHandler"),
|
||||
|
||||
# We want the user to be able to combine modifiers with the
|
||||
@@ -46,10 +52,10 @@ keymap = (
|
||||
# do not "care" about the modifiers -- unless it's the Cthulhu
|
||||
# modifier.
|
||||
#
|
||||
("KP_Divide", ORCA_MODIFIER_MASK, NO_MODIFIER_MASK,
|
||||
("KP_Divide", CTHULHU_MODIFIER_MASK, NO_MODIFIER_MASK,
|
||||
"leftClickReviewItemHandler"),
|
||||
|
||||
("KP_Multiply", ORCA_MODIFIER_MASK, NO_MODIFIER_MASK,
|
||||
("KP_Multiply", CTHULHU_MODIFIER_MASK, NO_MODIFIER_MASK,
|
||||
"rightClickReviewItemHandler"),
|
||||
|
||||
("KP_Add", defaultModifierMask, NO_MODIFIER_MASK,
|
||||
@@ -58,9 +64,9 @@ keymap = (
|
||||
("KP_Delete", defaultModifierMask, NO_MODIFIER_MASK,
|
||||
"findHandler"),
|
||||
|
||||
("KP_Delete", defaultModifierMask, ORCA_MODIFIER_MASK,
|
||||
("KP_Delete", defaultModifierMask, CTHULHU_MODIFIER_MASK,
|
||||
"findNextHandler"),
|
||||
|
||||
("KP_Delete", defaultModifierMask, ORCA_SHIFT_MODIFIER_MASK,
|
||||
("KP_Delete", defaultModifierMask, CTHULHU_SHIFT_MODIFIER_MASK,
|
||||
"findPreviousHandler"),
|
||||
)
|
||||
@@ -1,3 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
import gi
|
||||
from gi.repository import GObject
|
||||
|
||||
@@ -41,7 +66,7 @@ class DynamicApiManager():
|
||||
def getAPI(self, key, application = '', fallback = True):
|
||||
# get dynamic API
|
||||
api = None
|
||||
|
||||
|
||||
try:
|
||||
api = self.api[application][key]
|
||||
return api
|
||||
@@ -58,5 +83,5 @@ class DynamicApiManager():
|
||||
api = self.api[application]['']
|
||||
except:
|
||||
print('API Key: "{}/{}" not found,'.format(application, key))
|
||||
|
||||
|
||||
return api
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2011. Cthulhu Team.
|
||||
# Author: Joanmarie Diggs <joanmarie.diggs@gmail.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
__id__ = "$Id$"
|
||||
__version__ = "$Revision$"
|
||||
|
||||
+8
-3
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2006-2008 Sun Microsystems Inc.
|
||||
# Copyright 2022 Igalia, S.L.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Provides support for a flat review find."""
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2008 Sun Microsystems Inc.
|
||||
# Copyright 2016 Igalia, S.L.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Provides the default implementation for flat review for Cthulhu."""
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2008 Sun Microsystems Inc.
|
||||
# Copyright 2016-2023 Igalia, S.L.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Module for flat-review commands"""
|
||||
|
||||
@@ -320,7 +325,7 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"KP_Home",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewHomeHandler")))
|
||||
|
||||
bindings.add(
|
||||
@@ -365,7 +370,7 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"KP_Page_Up",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewEndHandler")))
|
||||
|
||||
bindings.add(
|
||||
@@ -379,7 +384,7 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"KP_Left",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewAboveHandler")))
|
||||
|
||||
bindings.add(
|
||||
@@ -410,7 +415,7 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"KP_Begin",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewCurrentAccessibleHandler")))
|
||||
|
||||
bindings.add(
|
||||
@@ -424,7 +429,7 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"KP_Right",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewBelowHandler")))
|
||||
|
||||
bindings.add(
|
||||
@@ -438,7 +443,7 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"KP_End",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewEndOfLineHandler")))
|
||||
|
||||
bindings.add(
|
||||
@@ -511,14 +516,14 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"p",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("toggleFlatReviewModeHandler")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"semicolon",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("flatReviewSayAllHandler"),
|
||||
2))
|
||||
|
||||
@@ -526,21 +531,21 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"u",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewPreviousLineHandler")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"u",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_CTRL_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_CTRL_MODIFIER_MASK,
|
||||
self._handlers.get("reviewHomeHandler")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"i",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewCurrentLineHandler"),
|
||||
1))
|
||||
|
||||
@@ -548,7 +553,7 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"i",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewSpellCurrentLineHandler"),
|
||||
2))
|
||||
|
||||
@@ -556,7 +561,7 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"i",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewPhoneticCurrentLineHandler"),
|
||||
3))
|
||||
|
||||
@@ -564,35 +569,35 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"o",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewNextLineHandler")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"o",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_CTRL_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_CTRL_MODIFIER_MASK,
|
||||
self._handlers.get("reviewEndHandler")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"j",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewPreviousItemHandler")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"j",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_CTRL_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_CTRL_MODIFIER_MASK,
|
||||
self._handlers.get("reviewAboveHandler")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"k",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewCurrentItemHandler"),
|
||||
1))
|
||||
|
||||
@@ -600,7 +605,7 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"k",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewSpellCurrentItemHandler"),
|
||||
2))
|
||||
|
||||
@@ -608,7 +613,7 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"k",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewPhoneticCurrentItemHandler"),
|
||||
3))
|
||||
|
||||
@@ -616,42 +621,42 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"k",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_CTRL_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_CTRL_MODIFIER_MASK,
|
||||
self._handlers.get("reviewCurrentAccessibleHandler")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"l",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewNextItemHandler")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"l",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_CTRL_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_CTRL_MODIFIER_MASK,
|
||||
self._handlers.get("reviewBelowHandler")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"m",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewPreviousCharacterHandler")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"m",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_CTRL_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_CTRL_MODIFIER_MASK,
|
||||
self._handlers.get("reviewEndOfLineHandler")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"comma",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewCurrentCharacterHandler"),
|
||||
1))
|
||||
|
||||
@@ -659,7 +664,7 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"comma",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewSpellCurrentCharacterHandler"),
|
||||
2))
|
||||
|
||||
@@ -667,7 +672,7 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"comma",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewUnicodeCurrentCharacterHandler"),
|
||||
3))
|
||||
|
||||
@@ -675,7 +680,7 @@ class FlatReviewPresenter:
|
||||
keybindings.KeyBinding(
|
||||
"period",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("reviewNextCharacterHandler")))
|
||||
|
||||
bindings.add(
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2004-2009 Sun Microsystems Inc.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Manages the formatting settings for Cthulhu."""
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2009 Sun Microsystems Inc.
|
||||
# Copyright 2015-2016 Igalia, S.L.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Superclass of classes used to generate presentations for objects."""
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2004-2009 Sun Microsystems Inc.
|
||||
# Copyright 2010-2013 The Cthulhu Team
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Labels for Cthulhu's GUIs. These have been put in their own module so that we
|
||||
can present them in the correct language when users change the language on the
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2023 Igalia, S.L.
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Module for drawing highlights over an area of interest."""
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2008 Sun Microsystems Inc.
|
||||
# Copyright 2011-2016 Igalia, S.L.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Provides support for handling input events."""
|
||||
|
||||
@@ -309,7 +314,7 @@ class KeyboardEvent(InputEvent):
|
||||
and not KeyboardEvent.lastCthulhuModifierAlone:
|
||||
doubleEvent = self._getDoubleClickCandidate()
|
||||
if doubleEvent and \
|
||||
doubleEvent.modifiers & keybindings.ORCA_MODIFIER_MASK:
|
||||
doubleEvent.modifiers & keybindings.CTHULHU_MODIFIER_MASK:
|
||||
# this is the second event of a double-click, and sticky Cthulhu
|
||||
# affected the first, so copy over the modifiers to the second
|
||||
KeyboardEvent.cthulhuStickyModifiers = doubleEvent.modifiers
|
||||
@@ -395,7 +400,7 @@ class KeyboardEvent(InputEvent):
|
||||
KeyboardEvent.cthulhuModifierPressed = False
|
||||
|
||||
if KeyboardEvent.cthulhuModifierPressed:
|
||||
self.modifiers |= keybindings.ORCA_MODIFIER_MASK
|
||||
self.modifiers |= keybindings.CTHULHU_MODIFIER_MASK
|
||||
|
||||
if KeyboardEvent.stickyKeys:
|
||||
# apply all recorded sticky modifiers
|
||||
@@ -482,7 +487,7 @@ class KeyboardEvent(InputEvent):
|
||||
|
||||
if self.modifiers & keybindings.CTRL_MODIFIER_MASK \
|
||||
or self.modifiers & keybindings.ALT_MODIFIER_MASK \
|
||||
or self.modifiers & keybindings.ORCA_MODIFIER_MASK:
|
||||
or self.modifiers & keybindings.CTHULHU_MODIFIER_MASK:
|
||||
return False
|
||||
|
||||
return True
|
||||
@@ -627,7 +632,7 @@ class KeyboardEvent(InputEvent):
|
||||
if cthulhu_state.bypassNextCommand:
|
||||
return False
|
||||
|
||||
return self.modifiers & keybindings.ORCA_MODIFIER_MASK
|
||||
return self.modifiers & keybindings.CTHULHU_MODIFIER_MASK
|
||||
|
||||
def isKeyPadKeyWithNumlockOn(self):
|
||||
"""Return True if this is a key pad key with numlock on."""
|
||||
|
||||
+18
-12
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2008 Sun Microsystems Inc.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Provides support for defining keybindings and matching them to input
|
||||
events."""
|
||||
@@ -43,19 +49,19 @@ from .cthulhu_i18n import _
|
||||
_keysymsCache = {}
|
||||
_keycodeCache = {}
|
||||
|
||||
MODIFIER_ORCA = 8
|
||||
MODIFIER_CTHULHU = 8
|
||||
NO_MODIFIER_MASK = 0
|
||||
ALT_MODIFIER_MASK = 1 << Atspi.ModifierType.ALT
|
||||
CTRL_MODIFIER_MASK = 1 << Atspi.ModifierType.CONTROL
|
||||
ORCA_MODIFIER_MASK = 1 << MODIFIER_ORCA
|
||||
ORCA_ALT_MODIFIER_MASK = (1 << MODIFIER_ORCA |
|
||||
CTHULHU_MODIFIER_MASK = 1 << MODIFIER_CTHULHU
|
||||
CTHULHU_ALT_MODIFIER_MASK = (1 << MODIFIER_CTHULHU |
|
||||
1 << Atspi.ModifierType.ALT)
|
||||
ORCA_CTRL_MODIFIER_MASK = (1 << MODIFIER_ORCA |
|
||||
CTHULHU_CTRL_MODIFIER_MASK = (1 << MODIFIER_CTHULHU |
|
||||
1 << Atspi.ModifierType.CONTROL)
|
||||
ORCA_CTRL_ALT_MODIFIER_MASK = (1 << MODIFIER_ORCA |
|
||||
CTHULHU_CTRL_ALT_MODIFIER_MASK = (1 << MODIFIER_CTHULHU |
|
||||
1 << Atspi.ModifierType.CONTROL |
|
||||
1 << Atspi.ModifierType.ALT)
|
||||
ORCA_SHIFT_MODIFIER_MASK = (1 << MODIFIER_ORCA |
|
||||
CTHULHU_SHIFT_MODIFIER_MASK = (1 << MODIFIER_CTHULHU |
|
||||
1 << Atspi.ModifierType.SHIFT)
|
||||
SHIFT_MODIFIER_MASK = 1 << Atspi.ModifierType.SHIFT
|
||||
SHIFT_ALT_MODIFIER_MASK = (1 << Atspi.ModifierType.SHIFT |
|
||||
@@ -71,7 +77,7 @@ NON_LOCKING_MODIFIER_MASK = (1 << Atspi.ModifierType.SHIFT |
|
||||
1 << Atspi.ModifierType.CONTROL |
|
||||
1 << Atspi.ModifierType.META2 |
|
||||
1 << Atspi.ModifierType.META3 |
|
||||
1 << MODIFIER_ORCA)
|
||||
1 << MODIFIER_CTHULHU)
|
||||
defaultModifierMask = NON_LOCKING_MODIFIER_MASK
|
||||
|
||||
def getKeycode(keysym):
|
||||
@@ -137,7 +143,7 @@ def getModifierNames(mods):
|
||||
"""
|
||||
|
||||
text = ""
|
||||
if mods & ORCA_MODIFIER_MASK:
|
||||
if mods & CTHULHU_MODIFIER_MASK:
|
||||
if settings.keyboardLayout == settings.GENERAL_KEYBOARD_LAYOUT_DESKTOP:
|
||||
# Translators: this is presented in a GUI to represent the
|
||||
# "insert" key when used as the Cthulhu modifier.
|
||||
@@ -280,12 +286,12 @@ class KeyBinding:
|
||||
if not self.keycode:
|
||||
self.keycode = getKeycode(self.keysymstring)
|
||||
|
||||
if self.modifiers & ORCA_MODIFIER_MASK:
|
||||
if self.modifiers & CTHULHU_MODIFIER_MASK:
|
||||
device = cthulhu_state.device
|
||||
if device is None:
|
||||
return ret
|
||||
modList = []
|
||||
otherMods = self.modifiers & ~ORCA_MODIFIER_MASK
|
||||
otherMods = self.modifiers & ~CTHULHU_MODIFIER_MASK
|
||||
numLockMod = device.get_modifier(getKeycode("Num_Lock"))
|
||||
lockedMods = device.get_locked_modifiers()
|
||||
numLockOn = lockedMods & numLockMod
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2006-2008 Sun Microsystems Inc.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Exposes a dictionary, keynames, that maps key events
|
||||
into localized words."""
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (C) 2011-2013 Igalia, S.L.
|
||||
#
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -18,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Heuristic means to infer the functional/displayed label of a widget."""
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2010 Joanmarie Diggs, Mesar Hameed.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
""" A list of common keybindings and unbound keys
|
||||
pulled out from default.py: __getLaptopBindings()
|
||||
@@ -32,14 +38,14 @@ from . import keybindings
|
||||
|
||||
# Storing values
|
||||
defaultModifierMask = keybindings.defaultModifierMask
|
||||
ORCA_MODIFIER_MASK = keybindings.ORCA_MODIFIER_MASK
|
||||
CTHULHU_MODIFIER_MASK = keybindings.CTHULHU_MODIFIER_MASK
|
||||
NO_MODIFIER_MASK = keybindings.NO_MODIFIER_MASK
|
||||
ORCA_SHIFT_MODIFIER_MASK = keybindings.ORCA_SHIFT_MODIFIER_MASK
|
||||
ORCA_CTRL_MODIFIER_MASK = keybindings.ORCA_CTRL_MODIFIER_MASK
|
||||
CTHULHU_SHIFT_MODIFIER_MASK = keybindings.CTHULHU_SHIFT_MODIFIER_MASK
|
||||
CTHULHU_CTRL_MODIFIER_MASK = keybindings.CTHULHU_CTRL_MODIFIER_MASK
|
||||
|
||||
keymap = (
|
||||
|
||||
("9", defaultModifierMask, ORCA_MODIFIER_MASK,
|
||||
|
||||
("9", defaultModifierMask, CTHULHU_MODIFIER_MASK,
|
||||
"routePointerToItemHandler"),
|
||||
|
||||
# We want the user to be able to combine modifiers with the
|
||||
@@ -48,22 +54,22 @@ keymap = (
|
||||
# modifier).
|
||||
#
|
||||
|
||||
("7", ORCA_MODIFIER_MASK, ORCA_MODIFIER_MASK,
|
||||
("7", CTHULHU_MODIFIER_MASK, CTHULHU_MODIFIER_MASK,
|
||||
"leftClickReviewItemHandler"),
|
||||
|
||||
("8", ORCA_MODIFIER_MASK, ORCA_MODIFIER_MASK,
|
||||
("8", CTHULHU_MODIFIER_MASK, CTHULHU_MODIFIER_MASK,
|
||||
"rightClickReviewItemHandler"),
|
||||
|
||||
("semicolon", defaultModifierMask, ORCA_MODIFIER_MASK,
|
||||
("semicolon", defaultModifierMask, CTHULHU_MODIFIER_MASK,
|
||||
"sayAllHandler", 1),
|
||||
|
||||
("bracketleft", defaultModifierMask, ORCA_MODIFIER_MASK,
|
||||
("bracketleft", defaultModifierMask, CTHULHU_MODIFIER_MASK,
|
||||
"findHandler"),
|
||||
|
||||
("bracketright", defaultModifierMask, ORCA_MODIFIER_MASK,
|
||||
("bracketright", defaultModifierMask, CTHULHU_MODIFIER_MASK,
|
||||
"findNextHandler"),
|
||||
|
||||
("bracketright", defaultModifierMask, ORCA_CTRL_MODIFIER_MASK,
|
||||
("bracketright", defaultModifierMask, CTHULHU_CTRL_MODIFIER_MASK,
|
||||
"findPreviousHandler"),
|
||||
|
||||
)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2005-2008 Sun Microsystems Inc.
|
||||
# Copyright 2016-2023 Igalia, S.L.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Module for learn mode"""
|
||||
|
||||
@@ -94,7 +99,7 @@ class LearnModePresenter:
|
||||
keybindings.KeyBinding(
|
||||
"h",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self._handlers.get("enterLearnModeHandler")))
|
||||
|
||||
return bindings
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
import gi
|
||||
gi.require_version("Atspi", "2.0")
|
||||
from gi.repository import Atspi
|
||||
@@ -168,7 +193,7 @@ class LiveRegionManager:
|
||||
keybindings.KeyBinding(
|
||||
"backslash",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_SHIFT_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_SHIFT_MODIFIER_MASK,
|
||||
self.inputEventHandlers.get("monitorLiveRegions")))
|
||||
|
||||
for key in ["F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9"]:
|
||||
@@ -176,7 +201,7 @@ class LiveRegionManager:
|
||||
keybindings.KeyBinding(
|
||||
key,
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_MODIFIER_MASK,
|
||||
self.inputEventHandlers.get("reviewLiveAnnouncement")))
|
||||
|
||||
return keyBindings
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2008 Sun Microsystems Inc.
|
||||
# Copyright 2012 Igalia, S.L.
|
||||
#
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -19,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Output logger for regression testing."""
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2014 Igalia, S.L.
|
||||
#
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -18,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
__id__ = "$Id$"
|
||||
__version__ = "$Revision$"
|
||||
|
||||
+24
-14
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2004-2009 Sun Microsystems Inc.
|
||||
# Copyright 2010-2013 The Cthulhu Team
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Messages which Cthulhu presents in speech and/or braille. These
|
||||
have been put in their own module so that we can present them in
|
||||
@@ -162,7 +167,7 @@ CARET_CONTROL_APP = _("The application is controlling the caret.")
|
||||
# itself controls how the arrow keys move the caret around HTML content. It's
|
||||
# often broken, so Cthulhu needs to provide its own support. As such, Cthulhu offers
|
||||
# the user the ability to toggle which application is controlling the caret.
|
||||
CARET_CONTROL_ORCA = _("The screen reader is controlling the caret.")
|
||||
CARET_CONTROL_CTHULHU = _("Cthulhu is controlling the caret.")
|
||||
|
||||
# Translators: this is the name of a cell in a spreadsheet.
|
||||
CELL = _("Cell %s")
|
||||
@@ -241,7 +246,7 @@ CLI_LOAD_PROFILE_ERROR = _("Profile could not be loaded: %s")
|
||||
# Translators: This message is presented to the user who attempts to launch Cthulhu
|
||||
# from some other environment than the graphical desktop.
|
||||
CLI_NO_DESKTOP_ERROR = \
|
||||
_("Cannot start the screen reader because it cannot connect to the Desktop.")
|
||||
_("Cannot start Cthulhu because it cannot connect to the Desktop.")
|
||||
|
||||
# Translators: This message is presented to the user who attempts to launch Cthulhu
|
||||
# but the launch fails due to an error related to the settings manager.
|
||||
@@ -250,8 +255,8 @@ CLI_SETTINGS_MANAGER_ERROR = \
|
||||
|
||||
# Translators: This message is presented to the user when he/she tries to launch
|
||||
# Cthulhu, but Cthulhu is already running.
|
||||
CLI_OTHER_ORCAS_ERROR = \
|
||||
_('Another screen reader process is already running for this ' \
|
||||
CLI_OTHER_CTHULHUS_ERROR = \
|
||||
_('Another Cthulhu process is already running for this ' \
|
||||
'session.\nRun “cthulhu --replace” to replace that ' \
|
||||
'process with a new one.')
|
||||
|
||||
@@ -274,7 +279,7 @@ CLI_VERSION = _("Version of this application")
|
||||
|
||||
# Translators: This is the description of command line option '-r, --replace'
|
||||
# which tells Cthulhu to replace any existing Cthulhu process that might be running.
|
||||
CLI_REPLACE = _("Replace a currently running instance of this screen reader")
|
||||
CLI_REPLACE = _("Replace a currently running instance of Cthulhu")
|
||||
|
||||
# Translators: this is the description of command line option '-h, --help'
|
||||
# which lists all the available command line options.
|
||||
@@ -1194,9 +1199,9 @@ LEARN_MODE_START_BRAILLE = _("Learn mode. Press escape to exit.")
|
||||
# Mode.
|
||||
LEARN_MODE_START_SPEECH = \
|
||||
_("Entering learn mode. Press any key to hear its function. " \
|
||||
"To view the screen reader’s documentation, press F1. " \
|
||||
"To get a list of the screen reader’s default shortcuts, press F2. " \
|
||||
"To get a list of the screen reader’s shortcuts for the current application, " \
|
||||
"To view Cthulhu’s documentation, press F1. " \
|
||||
"To get a list of Cthulhu’s default shortcuts, press F2. " \
|
||||
"To get a list of Cthulhu’s shortcuts for the current application, " \
|
||||
"press F3. " \
|
||||
"To exit learn mode, press the escape key.")
|
||||
|
||||
@@ -2291,10 +2296,15 @@ SPEECH_VERBOSITY_VERBOSE = C_("Speech", "Verbosity level: verbose")
|
||||
SPOKEN_ELLIPSIS = _(" dot dot dot")
|
||||
|
||||
# Translators: This message is presented to the user when Cthulhu is launched.
|
||||
START_ORCA = _("Cthulhu welcomes you.")
|
||||
START_CTHULHU = _("Cthulhu welcomes you.")
|
||||
|
||||
# Translators: This message is presented to the user when Cthulhu is quit.
|
||||
STOP_ORCA = _("Cthulhu lerks beneath the waves.")
|
||||
STOP_CTHULHU = _("Cthulhu lurks beneath the waves.")
|
||||
|
||||
# Sleep Mode
|
||||
# Translators: This message is presented to the user when Cthulhu enters or leaves sleep mode.
|
||||
SLEEP_MODE_ENABLED_FOR = _("Sleep mode enabled for %s")
|
||||
SLEEP_MODE_DISABLED_FOR = _("Sleep mode disabled for %s")
|
||||
|
||||
# Translators: This message means speech synthesis is not installed or working.
|
||||
SPEECH_UNAVAILABLE = _("Speech is unavailable.")
|
||||
@@ -2512,7 +2522,7 @@ UNDO = C_("command", "undo")
|
||||
REDO = C_("command", "redo")
|
||||
|
||||
# Translators: This message presents the Cthulhu version number.
|
||||
VERSION = _("Screen reader version %s.") % version
|
||||
VERSION = _("Cthulhu version %s.") % version
|
||||
|
||||
# Translators: This is presented when the user has navigated to a line with only
|
||||
# whitespace characters (space, tab, etc.) on it.
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Mouse reviewer for Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2008 Eitan Isaacson
|
||||
# Copyright 2016 Igalia, S.L.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Mouse review mode."""
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2023 Igalia, S.L.
|
||||
# Author: Joanmarie Diggs <jdiggs@igalia.com>
|
||||
# Based on the feature created by:
|
||||
# Author: Jose Vilmar <vilmar@informal.com.br>
|
||||
# Copyright 2010 Informal Informatica LTDA.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -20,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Module for notification messages"""
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2023 The Cthulhu Team
|
||||
# Author: Rynhardt Kruger <rynkruger@gmail.com>
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Provides ability to navigate objects hierarchically."""
|
||||
|
||||
@@ -68,42 +73,42 @@ class ObjectNavigator:
|
||||
keybindings.KeyBinding(
|
||||
"Up",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_CTRL_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_CTRL_MODIFIER_MASK,
|
||||
self._handlers.get("object_navigator_up")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"Down",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_CTRL_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_CTRL_MODIFIER_MASK,
|
||||
self._handlers.get("object_navigator_down")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"Right",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_CTRL_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_CTRL_MODIFIER_MASK,
|
||||
self._handlers.get("object_navigator_next")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"Left",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_CTRL_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_CTRL_MODIFIER_MASK,
|
||||
self._handlers.get("object_navigator_previous")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"Return",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_CTRL_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_CTRL_MODIFIER_MASK,
|
||||
self._handlers.get("object_navigator_perform_action")))
|
||||
|
||||
bindings.add(
|
||||
keybindings.KeyBinding(
|
||||
"s",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.ORCA_CTRL_MODIFIER_MASK,
|
||||
keybindings.CTHULHU_CTRL_MODIFIER_MASK,
|
||||
self._handlers.get("object_navigator_toggle_simplify")))
|
||||
|
||||
return bindings
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2004-2009 Sun Microsystems Inc.
|
||||
# Copyright 2010-2013 The Cthulhu Team
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -17,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Propeerties of accessible objects. These have been put in their own module
|
||||
so that we can present them in the correct language when users change the
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
# Cthulhu
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2006-2008 Sun Microsystems Inc.
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
@@ -16,6 +19,9 @@
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
"""Provides getPhoneticName method that maps each letter of the
|
||||
alphabet into its localized phonetic equivalent."""
|
||||
|
||||
+78
-149
@@ -1,160 +1,89 @@
|
||||
import os, inspect
|
||||
import gi
|
||||
from gi.repository import GObject
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2024 Stormux
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
class Plugin():
|
||||
#__gtype_name__ = 'BasePlugin'
|
||||
"""Base class for Cthulhu plugins using pluggy."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.API = None
|
||||
self.pluginInfo = None
|
||||
self.moduleDir = ''
|
||||
self.hidden = False
|
||||
self.moduleName = ''
|
||||
import os
|
||||
import logging
|
||||
|
||||
# Import pluggy for hook specifications
|
||||
try:
|
||||
import pluggy
|
||||
cthulhu_hookimpl = pluggy.HookimplMarker("cthulhu")
|
||||
PLUGGY_AVAILABLE = True
|
||||
except ImportError:
|
||||
# Fallback if pluggy is not available
|
||||
def cthulhu_hookimpl(func=None, **kwargs):
|
||||
"""Fallback decorator when pluggy is not available.
|
||||
|
||||
This is a no-op decorator that returns the original function.
|
||||
It allows the code to continue working without pluggy, though
|
||||
plugins will be disabled.
|
||||
"""
|
||||
if func is None:
|
||||
return lambda f: f
|
||||
return func
|
||||
PLUGGY_AVAILABLE = False
|
||||
logging.getLogger(__name__).info("Pluggy not available, plugins will be disabled")
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class Plugin:
|
||||
"""Base class for Cthulhu plugins."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the plugin with default attributes."""
|
||||
self.app = None
|
||||
self.plugin_info = None
|
||||
self.module_name = ''
|
||||
self.name = ''
|
||||
self.version = ''
|
||||
self.website = ''
|
||||
self.authors = []
|
||||
self.buildIn = False
|
||||
self.description = ''
|
||||
self.iconName = ''
|
||||
self.copyright = ''
|
||||
self.dependencies = False
|
||||
self.helpUri = ''
|
||||
self.dataDir = ''
|
||||
self.translationContext = None
|
||||
def setApp(self, app):
|
||||
|
||||
def set_app(self, app):
|
||||
"""Set the application reference."""
|
||||
self.app = app
|
||||
self.dynamicApiManager = app.getDynamicApiManager()
|
||||
self.signalManager = app.getSignalManager()
|
||||
|
||||
def getApp(self):
|
||||
return self.app
|
||||
def setPluginInfo(self, pluginInfo):
|
||||
self.pluginInfo = pluginInfo
|
||||
self.updatePluginInfoAttributes()
|
||||
def getPluginInfo(self):
|
||||
return self.pluginInfo
|
||||
def updatePluginInfoAttributes(self):
|
||||
self.moduleDir = ''
|
||||
self.hidden = False
|
||||
self.moduleName = ''
|
||||
self.name = ''
|
||||
self.version = ''
|
||||
self.website = ''
|
||||
self.authors = []
|
||||
self.buildIn = False
|
||||
self.description = ''
|
||||
self.iconName = ''
|
||||
self.copyright = ''
|
||||
self.dependencies = False
|
||||
self.helpUri = ''
|
||||
self.dataDir = ''
|
||||
pluginInfo = self.getPluginInfo()
|
||||
if pluginInfo == None:
|
||||
def set_plugin_info(self, plugin_info):
|
||||
"""Set plugin information and extract relevant attributes."""
|
||||
self.plugin_info = plugin_info
|
||||
if plugin_info:
|
||||
self.module_name = getattr(plugin_info, 'module_name', '')
|
||||
self.name = getattr(plugin_info, 'name', '')
|
||||
self.version = getattr(plugin_info, 'version', '')
|
||||
self.description = getattr(plugin_info, 'description', '')
|
||||
|
||||
@cthulhu_hookimpl
|
||||
def activate(self, plugin=None):
|
||||
"""Activate the plugin. Override this in subclasses."""
|
||||
if plugin is not None and plugin is not self:
|
||||
return
|
||||
self.moduleName = self.getApp().getPluginSystemManager().getPluginModuleName(pluginInfo)
|
||||
self.name = self.getApp().getPluginSystemManager().getPluginName(pluginInfo)
|
||||
self.version = self.getApp().getPluginSystemManager().getPluginVersion(pluginInfo)
|
||||
self.moduleDir = self.getApp().getPluginSystemManager().getPluginModuleDir(pluginInfo)
|
||||
self.buildIn = self.getApp().getPluginSystemManager().isPluginBuildIn(pluginInfo)
|
||||
self.description = self.getApp().getPluginSystemManager().getPluginDescription(pluginInfo)
|
||||
self.hidden = self.getApp().getPluginSystemManager().isPluginHidden(pluginInfo)
|
||||
self.website = self.getApp().getPluginSystemManager().getPluginWebsite(pluginInfo)
|
||||
self.authors = self.getApp().getPluginSystemManager().getPluginAuthors(pluginInfo)
|
||||
self.iconName = self.getApp().getPluginSystemManager().getPluginIconName(pluginInfo)
|
||||
self.copyright = self.getApp().getPluginSystemManager().getPluginCopyright(pluginInfo)
|
||||
self.dependencies = self.getApp().getPluginSystemManager().getPluginDependencies(pluginInfo)
|
||||
logger.info(f"Activating plugin: {self.name}")
|
||||
|
||||
#settings = self.getApp().getPluginSystemManager().getPluginSettings(pluginInfo)
|
||||
#hasDependencies = self.getApp().getPluginSystemManager().hasPluginDependency(pluginInfo)
|
||||
@cthulhu_hookimpl
|
||||
def deactivate(self, plugin=None):
|
||||
"""Deactivate the plugin. Override this in subclasses."""
|
||||
if plugin is not None and plugin is not self:
|
||||
return
|
||||
logger.info(f"Deactivating plugin: {self.name}")
|
||||
|
||||
#externalData = self.getApp().getPluginSystemManager().getPluginExternalData(pluginInfo)
|
||||
self.helpUri = self.getApp().getPluginSystemManager().getPlugingetHelpUri(pluginInfo)
|
||||
self.dataDir = self.getApp().getPluginSystemManager().getPluginDataDir(pluginInfo)
|
||||
self.updateTranslationContext()
|
||||
|
||||
def updateTranslationContext(self, domain = None, localeDir = None, language = None, fallbackToCthulhuTranslation = True):
|
||||
self.translationContext = None
|
||||
useLocaleDir = '{}/locale/'.format(self.getModuleDir())
|
||||
if localeDir:
|
||||
if os.path.isdir(localeDir):
|
||||
useLocaleDir = localeDir
|
||||
useName = self.getModuleName()
|
||||
useDomain = useName
|
||||
if domain:
|
||||
useDomain = domain
|
||||
useLanguage = None
|
||||
if language:
|
||||
useLanguage = language
|
||||
self.translationContext = self.getApp().getTranslationManager().initTranslation(useName, domain=useDomain, localeDir=useLocaleDir, language=useLanguage, fallbackToCthulhuTranslation=fallbackToCthulhuTranslation)
|
||||
# Point _ to the translation object in the globals namespace of the caller frame
|
||||
try:
|
||||
callerFrame = inspect.currentframe().f_back
|
||||
# Install our gettext and ngettext function to the upper frame
|
||||
callerFrame.f_globals['_'] = self.translationContext.gettext
|
||||
callerFrame.f_globals['ngettext'] = self.translationContext.ngettext
|
||||
finally:
|
||||
del callerFrame # Avoid reference problems with frames (per python docs)
|
||||
def getTranslationContext(self):
|
||||
return self.translationContext
|
||||
def isPluginBuildIn(self):
|
||||
return self.buildIn
|
||||
def isPluginHidden(self):
|
||||
return self.hidden
|
||||
def getAuthors(self):
|
||||
return self.authors
|
||||
def getCopyright(self):
|
||||
return self.copyright
|
||||
def getDataDir(self):
|
||||
return self.dataDir
|
||||
def getDependencies(self):
|
||||
return self.dependencies
|
||||
def getDescription(self):
|
||||
return self.description
|
||||
def getgetHelpUri(self):
|
||||
return self.helpUri
|
||||
def getIconName(self):
|
||||
return self.iconName
|
||||
def getModuleDir(self):
|
||||
return self.moduleDir
|
||||
def getModuleName(self):
|
||||
return self.moduleName
|
||||
def getName(self):
|
||||
return self.name
|
||||
def getVersion(self):
|
||||
return self.version
|
||||
def getWebsite(self):
|
||||
return self.website
|
||||
def getSetting(key):
|
||||
#self.getModuleName())
|
||||
def registerGestureByString(self, function, name, gestureString, learnModeEnabled=True):
|
||||
"""Register a gesture by string."""
|
||||
if self.app:
|
||||
api_helper = self.app.getAPIHelper()
|
||||
if api_helper:
|
||||
return api_helper.registerGestureByString(
|
||||
function,
|
||||
name,
|
||||
gestureString,
|
||||
'default',
|
||||
'cthulhu',
|
||||
learnModeEnabled,
|
||||
contextName=self.module_name
|
||||
)
|
||||
return None
|
||||
def setSetting(key, value):
|
||||
#self.getModuleName())
|
||||
pass
|
||||
def registerGestureByString(self, function, name, gestureString, learnModeEnabled = True):
|
||||
keybinding = self.getApp().getAPIHelper().registerGestureByString(function, name, gestureString, 'default', 'cthulhu', learnModeEnabled, contextName = self.getModuleName())
|
||||
return keybinding
|
||||
def unregisterShortcut(self, function, name, gestureString, learnModeEnabled = True):
|
||||
ok = self.getApp().getAPIHelper().unregisterShortcut(keybinding, contextName = self.getModuleName())
|
||||
return ok
|
||||
def registerSignal(self, signalName, signalFlag = GObject.SignalFlags.RUN_LAST, closure = GObject.TYPE_NONE, accumulator=()):
|
||||
ok = self.signalManager.registerSignal(signalName, signalFlag, closure, accumulator, contextName = self.getModuleName())
|
||||
return ok
|
||||
def unregisterSignal(self, signalName):
|
||||
# how to unregister?
|
||||
pass
|
||||
|
||||
def connectSignal(self, signalName, function, param = None):
|
||||
signalID = self.signalManager.connectSignal(signalName, function, param, contextName = self.getModuleName())
|
||||
return signalID
|
||||
def disconnectSignalByFunction(self, function):
|
||||
# need get mapped function
|
||||
mappedFunction = function
|
||||
self.signalManager.disconnectSignalByFunction(mappedFunction, contextName = self.getModuleName())
|
||||
|
||||
def registerAPI(self, key, value, application = ''):
|
||||
ok = self.dynamicApiManager.registerAPI(key, value, application = application, contextName = self.getModuleName())
|
||||
return ok
|
||||
def unregisterAPI(self, key, application = ''):
|
||||
self.dynamicApiManager.unregisterAPI(key, application = application, contextName = self.getModuleName())
|
||||
|
||||
@@ -1,520 +1,343 @@
|
||||
#!/bin/python
|
||||
"""PluginManager for loading cthulhu plugins."""
|
||||
import os, inspect, sys, tarfile, shutil
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2024 Stormux
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
"""Plugin System Manager for Cthulhu using pluggy."""
|
||||
|
||||
import os
|
||||
import inspect
|
||||
import importlib.util
|
||||
import logging
|
||||
from enum import IntEnum
|
||||
|
||||
version = sys.version[:3] # we only need major.minor version.
|
||||
if version in ["3.3","3.4"]:
|
||||
from importlib.machinery import SourceFileLoader
|
||||
else: # Python 3.5+, no support for python < 3.3.
|
||||
import importlib.util
|
||||
# Import pluggy if available
|
||||
try:
|
||||
import pluggy
|
||||
PLUGGY_AVAILABLE = True
|
||||
except ImportError:
|
||||
PLUGGY_AVAILABLE = False
|
||||
logging.getLogger(__name__).info("Pluggy not available, plugins will be disabled")
|
||||
|
||||
import gi
|
||||
gi.require_version('Peas', '1.0')
|
||||
from gi.repository import GObject
|
||||
from gi.repository import Peas
|
||||
|
||||
gi.require_version('Atspi', '2.0')
|
||||
from gi.repository import Atspi
|
||||
|
||||
from cthulhu import resource_manager
|
||||
|
||||
class API(GObject.GObject):
|
||||
"""Interface that gives access to all the objects of Cthulhu."""
|
||||
def __init__(self, app):
|
||||
GObject.GObject.__init__(self)
|
||||
self.app = app
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class PluginType(IntEnum):
|
||||
"""Types of plugins we support, depending on their directory location."""
|
||||
# pylint: disable=comparison-with-callable,inconsistent-return-statements,no-else-return
|
||||
# SYSTEM: provides system wide plugins
|
||||
"""Types of plugins we support."""
|
||||
SYSTEM = 1
|
||||
# USER: provides per user plugin
|
||||
USER = 2
|
||||
|
||||
def __str__(self):
|
||||
if self.value == PluginType.SYSTEM:
|
||||
return _("System plugin")
|
||||
elif self.value == PluginType.USER:
|
||||
return _("User plugin")
|
||||
|
||||
def get_root_dir(self):
|
||||
"""Returns the directory where this type of plugins can be found."""
|
||||
if self.value == PluginType.SYSTEM:
|
||||
return os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe())))) + '/plugins'
|
||||
current_file = inspect.getfile(inspect.currentframe())
|
||||
current_dir = os.path.dirname(os.path.realpath(os.path.abspath(current_file)))
|
||||
return os.path.join(current_dir, 'plugins')
|
||||
elif self.value == PluginType.USER:
|
||||
return os.path.expanduser('~') + '/.local/share/cthulhu/plugins'
|
||||
return os.path.expanduser('~/.local/share/cthulhu/plugins')
|
||||
|
||||
|
||||
class PluginSystemManager():
|
||||
"""Orca Plugin Manager to handle a set of plugins.
|
||||
Attributes:
|
||||
DEFAULT_LOADERS (tuple): Default loaders used by the plugin manager. For
|
||||
possible values see
|
||||
https://developer.gnome.org/libpeas/stable/PeasEngine.html#peas-engine-enable-loader
|
||||
"""
|
||||
DEFAULT_LOADERS = ("python3", )
|
||||
class PluginInfo:
|
||||
"""Information about a plugin."""
|
||||
|
||||
def __init__(self, name, module_name, module_dir, metadata=None):
|
||||
self.name = name
|
||||
self.module_name = module_name
|
||||
self.module_dir = module_dir
|
||||
self.metadata = metadata or {}
|
||||
self.builtin = False
|
||||
self.hidden = False
|
||||
self.module = None
|
||||
self.instance = None
|
||||
self.loaded = False
|
||||
|
||||
def get_module_name(self):
|
||||
return self.module_name
|
||||
|
||||
def get_name(self):
|
||||
return self.metadata.get('name', self.name)
|
||||
|
||||
def get_version(self):
|
||||
return self.metadata.get('version', '0.0.0')
|
||||
|
||||
def get_description(self):
|
||||
return self.metadata.get('description', '')
|
||||
|
||||
def get_module_dir(self):
|
||||
return self.module_dir
|
||||
|
||||
|
||||
class PluginSystemManager:
|
||||
"""Cthulhu Plugin Manager using pluggy."""
|
||||
|
||||
def __init__(self, app):
|
||||
self.app = app
|
||||
self.engine = Peas.Engine.get_default()
|
||||
|
||||
for loader in self.DEFAULT_LOADERS:
|
||||
self.engine.enable_loader(loader)
|
||||
# Initialize plugin manager
|
||||
if PLUGGY_AVAILABLE:
|
||||
self.plugin_manager = pluggy.PluginManager("cthulhu")
|
||||
|
||||
# Define hook specifications
|
||||
hook_spec = pluggy.HookspecMarker("cthulhu")
|
||||
|
||||
class CthulhuHookSpecs:
|
||||
@hook_spec
|
||||
def activate(self, plugin=None):
|
||||
"""Called when the plugin is activated."""
|
||||
pass
|
||||
|
||||
@hook_spec
|
||||
def deactivate(self, plugin=None):
|
||||
"""Called when the plugin is deactivated."""
|
||||
pass
|
||||
|
||||
self.plugin_manager.add_hookspecs(CthulhuHookSpecs)
|
||||
else:
|
||||
self.plugin_manager = None
|
||||
|
||||
# Plugin storage
|
||||
self._plugins = {} # module_name -> PluginInfo
|
||||
self._active_plugins = []
|
||||
|
||||
# Create plugin directories
|
||||
self._setup_plugin_dirs()
|
||||
|
||||
def _setup_plugin_dirs(self):
|
||||
"""Ensure plugin directories exist."""
|
||||
os.makedirs(PluginType.SYSTEM.get_root_dir(), exist_ok=True)
|
||||
os.makedirs(PluginType.USER.get_root_dir(), exist_ok=True)
|
||||
|
||||
self._setupPluginsDir()
|
||||
self._setupExtensionSet()
|
||||
|
||||
if self.app:
|
||||
self.gsettingsManager = self.app.getSettingsManager()
|
||||
# settings else:
|
||||
# settings self.gsettingsManager = gsettings_manager.getSettingsManager(self.app)
|
||||
self._activePlugins = []
|
||||
self._ignorePluginModulePath = []
|
||||
@property
|
||||
def plugins(self):
|
||||
"""Gets the engine's plugin list."""
|
||||
return self.engine.get_plugin_list()
|
||||
@classmethod
|
||||
def getPluginType(cls, pluginInfo):
|
||||
"""Gets the PluginType for the specified Peas.PluginInfo."""
|
||||
paths = [pluginInfo.get_data_dir(), PluginType.SYSTEM.get_root_dir()]
|
||||
if os.path.commonprefix(paths) == PluginType.SYSTEM.get_root_dir():
|
||||
return PluginType.SYSTEM
|
||||
return PluginType.USER
|
||||
"""Get all available plugins."""
|
||||
return list(self._plugins.values())
|
||||
|
||||
def getExtension(self, pluginInfo):
|
||||
if not pluginInfo:
|
||||
return None
|
||||
|
||||
return self.extension_set.get_extension(pluginInfo)
|
||||
def rescanPlugins(self):
|
||||
self.engine.garbage_collect()
|
||||
self.engine.rescan_plugins()
|
||||
def getApp(self):
|
||||
return self.app
|
||||
def getPluginInfoByName(self, pluginName, pluginType=PluginType.USER):
|
||||
"""Gets the plugin info for the specified plugin name.
|
||||
Args:
|
||||
pluginName (str): The name from the .plugin file of the module.
|
||||
Returns:
|
||||
Peas.PluginInfo: The plugin info if it exists. Otherwise, `None`.
|
||||
"""
|
||||
for pluginInfo in self.plugins:
|
||||
if pluginInfo.get_module_name() == pluginName and PluginSystemManager.getPluginType(pluginInfo) == pluginType:
|
||||
return pluginInfo
|
||||
return None
|
||||
|
||||
def rescanPlugins(self):
|
||||
"""Scan for plugins in the plugin directories."""
|
||||
old_plugins = self._plugins.copy()
|
||||
self._plugins = {}
|
||||
|
||||
# Scan system and user plugins
|
||||
self._scan_plugins_in_directory(PluginType.SYSTEM.get_root_dir())
|
||||
self._scan_plugins_in_directory(PluginType.USER.get_root_dir())
|
||||
|
||||
# Preserve state for already loaded plugins
|
||||
for name, old_info in old_plugins.items():
|
||||
if name in self._plugins and old_info.loaded:
|
||||
self._plugins[name].loaded = True
|
||||
self._plugins[name].instance = old_info.instance
|
||||
self._plugins[name].module = old_info.module
|
||||
|
||||
def _scan_plugins_in_directory(self, directory):
|
||||
"""Scan for plugins in a directory."""
|
||||
if not os.path.exists(directory) or not os.path.isdir(directory):
|
||||
return
|
||||
|
||||
for item in os.listdir(directory):
|
||||
plugin_dir = os.path.join(directory, item)
|
||||
if not os.path.isdir(plugin_dir):
|
||||
continue
|
||||
|
||||
plugin_file = os.path.join(plugin_dir, "plugin.py")
|
||||
metadata_file = os.path.join(plugin_dir, "plugin.info")
|
||||
|
||||
if os.path.isfile(plugin_file):
|
||||
# Extract plugin info
|
||||
module_name = os.path.basename(plugin_dir)
|
||||
metadata = self._load_plugin_metadata(metadata_file)
|
||||
|
||||
plugin_info = PluginInfo(
|
||||
metadata.get('name', module_name),
|
||||
module_name,
|
||||
plugin_dir,
|
||||
metadata
|
||||
)
|
||||
|
||||
# Check if it's a built-in or hidden plugin
|
||||
plugin_info.builtin = metadata.get('builtin', 'false').lower() == 'true'
|
||||
plugin_info.hidden = metadata.get('hidden', 'false').lower() == 'true'
|
||||
|
||||
self._plugins[module_name] = plugin_info
|
||||
|
||||
def _load_plugin_metadata(self, metadata_file):
|
||||
"""Load plugin metadata from a file."""
|
||||
metadata = {}
|
||||
|
||||
if os.path.isfile(metadata_file):
|
||||
try:
|
||||
with open(metadata_file, 'r') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith('#'):
|
||||
continue
|
||||
|
||||
if '=' in line:
|
||||
key, value = line.split('=', 1)
|
||||
metadata[key.strip()] = value.strip()
|
||||
except Exception as e:
|
||||
logger.error(f"Error loading plugin metadata: {e}")
|
||||
|
||||
return metadata
|
||||
|
||||
def getActivePlugins(self):
|
||||
return self._activePlugins
|
||||
"""Get the list of active plugin names."""
|
||||
return self._active_plugins
|
||||
|
||||
def setActivePlugins(self, activePlugins):
|
||||
self._activePlugins = activePlugins
|
||||
"""Set active plugins and sync their state."""
|
||||
self._active_plugins = activePlugins
|
||||
self.syncAllPluginsActive()
|
||||
def isPluginBuildIn(self, pluginInfo):
|
||||
return pluginInfo.is_builtin()
|
||||
def isPluginHidden(self, pluginInfo):
|
||||
return pluginInfo.is_hidden()
|
||||
def getPluginAuthors(self, pluginInfo):
|
||||
return pluginInfo.get_authors()
|
||||
def getPluginCopyright(self, pluginInfo):
|
||||
return pluginInfo.get_copyright()
|
||||
def getPluginDataDir(self, pluginInfo):
|
||||
return pluginInfo.get_data_dir()
|
||||
def getPluginDependencies(self, pluginInfo):
|
||||
return pluginInfo.get_dependencies()
|
||||
def getPluginDescription(self, pluginInfo):
|
||||
return pluginInfo.get_description()
|
||||
def getPlugingetHelpUri(self, pluginInfo):
|
||||
return pluginInfo.get_help_uri()
|
||||
def getPluginIconName(self, pluginInfo):
|
||||
return pluginInfo.get_icon_name()
|
||||
def getPluginModuleDir(self, pluginInfo):
|
||||
return pluginInfo.get_module_dir()
|
||||
def getPluginModuleName(self, pluginInfo):
|
||||
return pluginInfo.get_module_name()
|
||||
def getPluginName(self, pluginInfo):
|
||||
return pluginInfo.get_name()
|
||||
def getPluginSettings(self, pluginInfo):
|
||||
return pluginInfo.get_settings()
|
||||
def getPluginVersion(self, pluginInfo):
|
||||
return pluginInfo.get_version()
|
||||
def getPluginWebsite(self, pluginInfo):
|
||||
return pluginInfo.get_website()
|
||||
# has_dependency and get_external_data seems broken-> takes exactly 2 arguments (1 given) but documentation doesnt say any parameter
|
||||
#def hasPluginDependency(self, pluginInfo):
|
||||
# return pluginInfo.has_dependency()
|
||||
#def getPluginExternalData(self, pluginInfo):
|
||||
# return pluginInfo.get_external_data()
|
||||
def isPluginAvailable(self, pluginInfo):
|
||||
try:
|
||||
return pluginInfo.is_available()
|
||||
except:
|
||||
return False
|
||||
def isPluginLoaded(self, pluginInfo):
|
||||
try:
|
||||
return pluginInfo.is_loaded()
|
||||
except:
|
||||
return False
|
||||
|
||||
def getIgnoredPlugins(self):
|
||||
return self._ignorePluginModulePath
|
||||
def setIgnoredPlugins(self, pluginModulePath, ignored):
|
||||
if pluginModulePath.endswith('/'):
|
||||
pluginModulePath = pluginModulePath[:-1]
|
||||
if ignored:
|
||||
if not pluginModulePath in self.getIgnoredPlugins():
|
||||
self._ignorePluginModulePath.append(pluginModulePath)
|
||||
else:
|
||||
if pluginModulePath in self.getIgnoredPlugins():
|
||||
self._ignorePluginModulePath.remove(pluginModulePath)
|
||||
|
||||
def setPluginActive(self, pluginInfo, active):
|
||||
if self.isPluginBuildIn(pluginInfo):
|
||||
"""Set the active state of a plugin."""
|
||||
if pluginInfo.builtin:
|
||||
active = True
|
||||
pluginName = self.getPluginModuleName(pluginInfo)
|
||||
if active:
|
||||
if not pluginName in self.getActivePlugins():
|
||||
if self.loadPlugin(pluginInfo):
|
||||
self._activePlugins.append(pluginName )
|
||||
else:
|
||||
if pluginName in self.getActivePlugins():
|
||||
if self.unloadPlugin(pluginInfo):
|
||||
self._activePlugins.remove(pluginName )
|
||||
def isPluginActive(self, pluginInfo):
|
||||
if self.isPluginBuildIn(pluginInfo):
|
||||
return True
|
||||
if self.isPluginLoaded(pluginInfo):
|
||||
return True
|
||||
active_plugin_names = self.getActivePlugins()
|
||||
return self.getPluginModuleName(pluginInfo) in active_plugin_names
|
||||
def syncAllPluginsActive(self, ForceAllPlugins=False):
|
||||
self.unloadAllPlugins(ForceAllPlugins)
|
||||
self.loadAllPlugins(ForceAllPlugins)
|
||||
|
||||
def loadAllPlugins(self, ForceAllPlugins=False):
|
||||
"""Loads plugins from settings."""
|
||||
pluginName = pluginInfo.get_module_name()
|
||||
|
||||
if active:
|
||||
if pluginName not in self.getActivePlugins():
|
||||
if self.loadPlugin(pluginInfo):
|
||||
self._active_plugins.append(pluginName)
|
||||
else:
|
||||
if pluginName in self.getActivePlugins():
|
||||
if self.unloadPlugin(pluginInfo):
|
||||
self._active_plugins.remove(pluginName)
|
||||
|
||||
def isPluginActive(self, pluginInfo):
|
||||
"""Check if a plugin is active."""
|
||||
if pluginInfo.builtin:
|
||||
return True
|
||||
|
||||
if pluginInfo.loaded:
|
||||
return True
|
||||
|
||||
return pluginInfo.get_module_name() in self.getActivePlugins()
|
||||
|
||||
def syncAllPluginsActive(self):
|
||||
"""Sync the active state of all plugins."""
|
||||
# First unload inactive plugins
|
||||
for pluginInfo in self.plugins:
|
||||
if self.isPluginActive(pluginInfo) or ForceAllPlugins:
|
||||
if not self.isPluginActive(pluginInfo) and pluginInfo.loaded:
|
||||
self.unloadPlugin(pluginInfo)
|
||||
|
||||
# Then load active plugins
|
||||
for pluginInfo in self.plugins:
|
||||
if self.isPluginActive(pluginInfo) and not pluginInfo.loaded:
|
||||
self.loadPlugin(pluginInfo)
|
||||
|
||||
def loadPlugin(self, pluginInfo):
|
||||
resourceManager = self.getApp().getResourceManager()
|
||||
moduleName = pluginInfo.get_module_name()
|
||||
try:
|
||||
if pluginInfo not in self.plugins:
|
||||
print("Plugin missing: {}".format(moduleName))
|
||||
return False
|
||||
resourceManager.addResourceContext(moduleName)
|
||||
self.engine.load_plugin(pluginInfo)
|
||||
except Exception as e:
|
||||
print('loadPlugin:',e)
|
||||
"""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
|
||||
return True
|
||||
|
||||
def unloadAllPlugins(self, ForceAllPlugins=False):
|
||||
"""Loads plugins from settings."""
|
||||
for pluginInfo in self.plugins:
|
||||
if not self.isPluginActive(pluginInfo) or ForceAllPlugins:
|
||||
self.unloadPlugin(pluginInfo)
|
||||
module_name = pluginInfo.get_module_name()
|
||||
|
||||
try:
|
||||
# Already loaded?
|
||||
if pluginInfo.loaded:
|
||||
return True
|
||||
|
||||
# Import plugin module
|
||||
plugin_file = os.path.join(pluginInfo.get_module_dir(), "plugin.py")
|
||||
spec = importlib.util.spec_from_file_location(module_name, plugin_file)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
pluginInfo.module = module
|
||||
|
||||
# Find Plugin class
|
||||
plugin_class = None
|
||||
for attr_name in dir(module):
|
||||
attr = getattr(module, attr_name)
|
||||
if (inspect.isclass(attr) and
|
||||
attr.__module__ == module.__name__ and
|
||||
hasattr(attr, 'activate')):
|
||||
plugin_class = attr
|
||||
break
|
||||
|
||||
if not plugin_class:
|
||||
logger.error(f"No plugin class found in {module_name}")
|
||||
return False
|
||||
|
||||
# Create and initialize plugin instance
|
||||
plugin_instance = plugin_class()
|
||||
pluginInfo.instance = plugin_instance
|
||||
|
||||
# Ensure plugins have a reference to the app
|
||||
plugin_instance.app = self.getApp()
|
||||
|
||||
if hasattr(plugin_instance, 'set_app'):
|
||||
plugin_instance.set_app(self.getApp())
|
||||
|
||||
if hasattr(plugin_instance, 'set_plugin_info'):
|
||||
plugin_instance.set_plugin_info(pluginInfo)
|
||||
|
||||
# Register with pluggy and activate
|
||||
self.plugin_manager.register(plugin_instance)
|
||||
try:
|
||||
self.plugin_manager.hook.activate(plugin=plugin_instance)
|
||||
except Exception as e:
|
||||
logger.error(f"Error activating plugin {module_name}: {e}")
|
||||
return False
|
||||
|
||||
pluginInfo.loaded = True
|
||||
logger.info(f"Loaded plugin: {module_name}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to load plugin {module_name}: {e}")
|
||||
return False
|
||||
|
||||
def unloadPlugin(self, pluginInfo):
|
||||
resourceManager = self.getApp().getResourceManager()
|
||||
moduleName = pluginInfo.get_module_name()
|
||||
try:
|
||||
if pluginInfo not in self.plugins:
|
||||
print("Plugin missing: {}".format(moduleName))
|
||||
return False
|
||||
if self.isPluginBuildIn(pluginInfo):
|
||||
return False
|
||||
self.engine.unload_plugin(pluginInfo)
|
||||
self.getApp().getResourceManager().removeResourceContext(moduleName)
|
||||
self.engine.garbage_collect()
|
||||
except Exception as e:
|
||||
print('unloadPlugin:',e)
|
||||
"""Unload a plugin."""
|
||||
# Skip if pluggy is not available
|
||||
if not PLUGGY_AVAILABLE:
|
||||
return False
|
||||
return True
|
||||
def installPlugin(self, pluginFilePath, pluginType=PluginType.USER):
|
||||
if not self.isValidPluginFile(pluginFilePath):
|
||||
return False
|
||||
pluginFolder = pluginType.get_root_dir()
|
||||
if not pluginFolder.endswith('/'):
|
||||
pluginFolder += '/'
|
||||
if not os.path.exists(pluginFolder):
|
||||
os.mkdir(pluginFolder)
|
||||
else:
|
||||
if not os.path.isdir(pluginFolder):
|
||||
return False
|
||||
try:
|
||||
with tarfile.open(pluginFilePath) as tar:
|
||||
tar.extractall(path=pluginFolder)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
pluginModulePath = self.getModuleDirByPluginFile(pluginFilePath)
|
||||
if pluginModulePath != '':
|
||||
pluginModulePath = pluginFolder + pluginModulePath
|
||||
self.setIgnoredPlugins(pluginModulePath[:-1], False) # without ending /
|
||||
print('install', pluginFilePath)
|
||||
self.callPackageTriggers(pluginModulePath, 'onPostInstall')
|
||||
self.rescanPlugins()
|
||||
|
||||
return True
|
||||
def getModuleDirByPluginFile(self, pluginFilePath):
|
||||
if not isinstance(pluginFilePath, str):
|
||||
return ''
|
||||
if pluginFilePath == '':
|
||||
return ''
|
||||
if not os.path.exists(pluginFilePath):
|
||||
return ''
|
||||
try:
|
||||
with tarfile.open(pluginFilePath) as tar:
|
||||
tarMembers = tar.getmembers()
|
||||
for tarMember in tarMembers:
|
||||
if tarMember.isdir():
|
||||
return tarMember.name
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return ''
|
||||
def isValidPluginFile(self, pluginFilePath):
|
||||
if not isinstance(pluginFilePath, str):
|
||||
if pluginInfo.builtin:
|
||||
return False
|
||||
if pluginFilePath == '':
|
||||
return False
|
||||
if not os.path.exists(pluginFilePath):
|
||||
return False
|
||||
pluginFolder = ''
|
||||
pluginFileExists = False
|
||||
packageFileExists = False
|
||||
try:
|
||||
with tarfile.open(pluginFilePath) as tar:
|
||||
tarMembers = tar.getmembers()
|
||||
for tarMember in tarMembers:
|
||||
if tarMember.isdir():
|
||||
if pluginFolder == '':
|
||||
pluginFolder = tarMember.name
|
||||
if tarMember.isfile():
|
||||
if tarMember.name.endswith('.plugin'):
|
||||
pluginFileExists = True
|
||||
if tarMember.name.endswith('package.py'):
|
||||
pluginFileExists = True
|
||||
if not tarMember.name.startswith(pluginFolder):
|
||||
return False
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
return pluginFileExists
|
||||
def uninstallPlugin(self, pluginInfo):
|
||||
if self.isPluginBuildIn(pluginInfo):
|
||||
return False
|
||||
# do we want to allow removing system plugins?
|
||||
if PluginSystemManager.getPluginType(pluginInfo) == PluginType.SYSTEM:
|
||||
return False
|
||||
pluginFolder = pluginInfo.get_data_dir()
|
||||
if not pluginFolder.endswith('/'):
|
||||
pluginFolder += '/'
|
||||
if not os.path.isdir(pluginFolder):
|
||||
return False
|
||||
if self.isPluginActive(pluginInfo):
|
||||
self.setPluginActive(pluginInfo, False)
|
||||
SettingsManager = self.app.getSettingsManager()
|
||||
# TODO SettingsManager.set_settings_value_list('active-plugins', self.getActivePlugins())
|
||||
self.callPackageTriggers(pluginFolder, 'onPreUninstall')
|
||||
|
||||
try:
|
||||
shutil.rmtree(pluginFolder, ignore_errors=True)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
self.setIgnoredPlugins(pluginFolder, True)
|
||||
self.rescanPlugins()
|
||||
|
||||
return True
|
||||
def callPackageTriggers(self, pluginPath, trigger):
|
||||
if not os.path.exists(pluginPath):
|
||||
module_name = pluginInfo.get_module_name()
|
||||
|
||||
try:
|
||||
# Not loaded?
|
||||
if not pluginInfo.loaded:
|
||||
return True
|
||||
|
||||
# Deactivate plugin
|
||||
plugin_instance = pluginInfo.instance
|
||||
if plugin_instance:
|
||||
try:
|
||||
self.plugin_manager.hook.deactivate(plugin=plugin_instance)
|
||||
except Exception as e:
|
||||
logger.error(f"Error deactivating plugin {module_name}: {e}")
|
||||
|
||||
# Unregister from pluggy
|
||||
self.plugin_manager.unregister(plugin_instance)
|
||||
|
||||
# Clean up
|
||||
pluginInfo.instance = None
|
||||
pluginInfo.loaded = False
|
||||
|
||||
logger.info(f"Unloaded plugin: {module_name}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to unload plugin {module_name}: {e}")
|
||||
return False
|
||||
|
||||
def unloadAllPlugins(self, ForceAllPlugins=False):
|
||||
"""Unload all plugins."""
|
||||
if not PLUGGY_AVAILABLE:
|
||||
return
|
||||
if not pluginPath.endswith('/'):
|
||||
pluginPath += '/'
|
||||
packageModulePath = pluginPath + 'package.py'
|
||||
if not os.path.isfile(packageModulePath):
|
||||
return
|
||||
if not os.access(packageModulePath, os.R_OK):
|
||||
return
|
||||
package = self.getApp().getAPIHelper().importModule('package', packageModulePath)
|
||||
|
||||
if trigger == 'onPostInstall':
|
||||
try:
|
||||
package.onPostInstall(pluginPath, self.getApp())
|
||||
except Exception as e:
|
||||
print(e)
|
||||
elif trigger == 'onPreUninstall':
|
||||
try:
|
||||
package.onPreUninstall(pluginPath, self.getApp())
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
def _setupExtensionSet(self):
|
||||
plugin_iface = API(self.getApp())
|
||||
self.extension_set = Peas.ExtensionSet.new(self.engine,
|
||||
Peas.Activatable,
|
||||
["object"],
|
||||
[plugin_iface])
|
||||
self.extension_set.connect("extension-removed",
|
||||
self.__extensionRemoved)
|
||||
self.extension_set.connect("extension-added",
|
||||
self.__extensionAdded)
|
||||
|
||||
def _setupPluginsDir(self):
|
||||
system_plugins_dir = PluginType.SYSTEM.get_root_dir()
|
||||
user_plugins_dir = PluginType.USER.get_root_dir()
|
||||
if os.path.exists(user_plugins_dir):
|
||||
self.engine.add_search_path(user_plugins_dir)
|
||||
if os.path.exists(system_plugins_dir):
|
||||
self.engine.add_search_path(system_plugins_dir)
|
||||
|
||||
def __extensionRemoved(self, unusedSet, pluginInfo, extension):
|
||||
extension.deactivate()
|
||||
|
||||
def __extensionAdded(self, unusedSet, pluginInfo, extension):
|
||||
extension.setApp(self.getApp())
|
||||
extension.setPluginInfo(pluginInfo)
|
||||
extension.activate()
|
||||
def __loadedPlugins(self, engine, unusedSet):
|
||||
"""Handles the changing of the loaded plugin list."""
|
||||
self.getApp().settings.ActivePlugins = engine.get_property("loaded-plugins")
|
||||
|
||||
class APIHelper():
|
||||
def __init__(self, app):
|
||||
self.app = app
|
||||
self.cthulhuKeyBindings = None
|
||||
|
||||
'''
|
||||
_pluginAPIManager.seCthulhuAPI('Logger', _logger)
|
||||
_pluginAPIManager.setCthulhuAPI('SettingsManager', _settingsManager)
|
||||
_pluginAPIManager.setCthulhuAPI('ScriptManager', _scriptManager)
|
||||
_pluginAPIManager.setCthulhuAPI('EventManager', _eventManager)
|
||||
_pluginAPIManager.setCthulhuAPI('Speech', speech)
|
||||
_pluginAPIManager.setCthulhuAPI('Sound', sound)
|
||||
_pluginAPIManager.setCthulhuAPI('Braille', braille)
|
||||
_pluginAPIManager.setCthulhuAPI('Debug', debug)
|
||||
_pluginAPIManager.setCthulhuAPI('Messages', messages)
|
||||
_pluginAPIManager.setCthulhuAPI('MouseReview', mouse_review)
|
||||
_pluginAPIManager.setCthulhuAPI('NotificationMessages', notification_messages)
|
||||
_pluginAPIManager.setCthulhuAPI('CthulhuState', cthulhu_state)
|
||||
_pluginAPIManager.setCthulhuAPI('CthulhuPlatform', cthulhu_platform)
|
||||
_pluginAPIManager.setCthulhuAPI('Settings', settings)
|
||||
_pluginAPIManager.setCthulhuAPI('Keybindings', keybindings)
|
||||
'''
|
||||
def outputMessage(self, Message, interrupt=False):
|
||||
settings = self.app.getDynamicApiManager().getAPI('Settings')
|
||||
braille = self.app.getDynamicApiManager().getAPI('Braille')
|
||||
speech = self.app.getDynamicApiManager().getAPI('Speech')
|
||||
if speech != None:
|
||||
if (settings.enableSpeech):
|
||||
if interrupt:
|
||||
speech.cancel()
|
||||
if Message != '':
|
||||
speech.speak(Message)
|
||||
if braille != None:
|
||||
if (settings.enableBraille):
|
||||
braille.displayMessage(Message)
|
||||
def createInputEventHandler(self, function, name, learnModeEnabled=True):
|
||||
EventManager = self.app.getDynamicApiManager().getAPI('EventManager')
|
||||
newInputEventHandler = EventManager.input_event.InputEventHandler(function, name, learnModeEnabled)
|
||||
return newInputEventHandler
|
||||
def registerGestureByString(self, function, name, gestureString, profile, application, learnModeEnabled = True, contextName = None):
|
||||
gestureList = gestureString.split(',')
|
||||
registeredGestures = []
|
||||
for gesture in gestureList:
|
||||
if gesture.startswith('kb:'):
|
||||
shortcutString = gesture[3:]
|
||||
registuredGesture = self.registerShortcutByString(function, name, shortcutString, profile, application, learnModeEnabled, contextName=contextName)
|
||||
if registuredGesture:
|
||||
registeredGestures.append(registuredGesture)
|
||||
return registeredGestures
|
||||
def registerShortcutByString(self, function, name, shortcutString, profile, application, learnModeEnabled = True, contextName = None):
|
||||
keybindings = self.app.getDynamicApiManager().getAPI('Keybindings')
|
||||
settings = self.app.getDynamicApiManager().getAPI('Settings')
|
||||
resourceManager = self.app.getResourceManager()
|
||||
|
||||
clickCount = 0
|
||||
cthulhuKey = False
|
||||
shiftKey = False
|
||||
ctrlKey = False
|
||||
altKey = False
|
||||
key = ''
|
||||
shortcutList = shortcutString.split('+')
|
||||
for shortcutElement in shortcutList:
|
||||
shortcutElementLower = shortcutElement.lower()
|
||||
if shortcutElementLower == 'press':
|
||||
clickCount += 1
|
||||
elif shortcutElement == 'cthulhu':
|
||||
cthulhuKey = True
|
||||
elif shortcutElementLower == 'shift':
|
||||
shiftKey = True
|
||||
elif shortcutElementLower == 'control':
|
||||
ctrlKey = True
|
||||
elif shortcutElementLower == 'alt':
|
||||
altKey = True
|
||||
else:
|
||||
key = shortcutElementLower
|
||||
if clickCount == 0:
|
||||
clickCount = 1
|
||||
|
||||
if self.cthulhuKeyBindings == None:
|
||||
self.cthulhuKeyBindings = keybindings.KeyBindings()
|
||||
|
||||
tryFunction = resource_manager.TryFunction(function)
|
||||
newInputEventHandler = self.createInputEventHandler(tryFunction.runInputEvent, name, learnModeEnabled)
|
||||
|
||||
currModifierMask = keybindings.NO_MODIFIER_MASK
|
||||
if cthulhuKey:
|
||||
currModifierMask = currModifierMask | 1 << keybindings.MODIFIER_ORCA
|
||||
if shiftKey:
|
||||
currModifierMask = currModifierMask | 1 << Atspi.ModifierType.SHIFT
|
||||
if altKey:
|
||||
currModifierMask = currModifierMask | 1 << Atspi.ModifierType.ALT
|
||||
if ctrlKey:
|
||||
currModifierMask = currModifierMask | 1 << Atspi.ModifierType.CONTROL
|
||||
|
||||
newKeyBinding = keybindings.KeyBinding(key, keybindings.defaultModifierMask, currModifierMask, newInputEventHandler, clickCount)
|
||||
self.cthulhuKeyBindings.add(newKeyBinding)
|
||||
|
||||
settings.keyBindingsMap["default"] = self.cthulhuKeyBindings
|
||||
|
||||
if contextName:
|
||||
resourceContext = resourceManager.getResourceContext(contextName)
|
||||
if resourceContext:
|
||||
resourceEntry = resource_manager.ResourceEntry('keyboard', newKeyBinding, function, tryFunction, shortcutString)
|
||||
resourceContext.addGesture(profile, application, newKeyBinding, resourceEntry)
|
||||
|
||||
return newKeyBinding
|
||||
|
||||
def unregisterShortcut(self, KeyBindingToRemove, contextName = None):
|
||||
ok = False
|
||||
keybindings = self.app.getDynamicApiManager().getAPI('Keybindings')
|
||||
settings = self.app.getDynamicApiManager().getAPI('Settings')
|
||||
resourceManager = self.app.getResourceManager()
|
||||
|
||||
if self.cthulhuKeyBindings == None:
|
||||
self.cthulhuKeyBindings = keybindings.KeyBindings()
|
||||
try:
|
||||
self.cthulhuKeyBindings.remove(KeyBindingToRemove)
|
||||
settings.keyBindingsMap["default"] = self.cthulhuKeyBindings
|
||||
ok = True
|
||||
except KeyError:
|
||||
pass
|
||||
if contextName:
|
||||
resourceContext = resourceManager.getResourceContext(contextName)
|
||||
if resourceContext:
|
||||
resourceContext.removeGesture(KeyBindingToRemove)
|
||||
|
||||
return ok
|
||||
def importModule(self, moduleName, moduleLocation):
|
||||
if version in ["3.3","3.4"]:
|
||||
return SourceFileLoader(moduleName, moduleLocation).load_module()
|
||||
else:
|
||||
spec = importlib.util.spec_from_file_location(moduleName, moduleLocation)
|
||||
driver_mod = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(driver_mod)
|
||||
return driver_mod
|
||||
for pluginInfo in self.plugins:
|
||||
if ForceAllPlugins or pluginInfo.loaded:
|
||||
self.unloadPlugin(pluginInfo)
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
[Plugin]
|
||||
Module=ByeCthulhu
|
||||
Loader=python3
|
||||
Name=Stop announcement for cthulhu
|
||||
Description=Test plugin for cthulhu
|
||||
Authors=Chrys chrys@linux-a11y.org
|
||||
@@ -1,27 +0,0 @@
|
||||
from cthulhu import plugin
|
||||
|
||||
import gi
|
||||
gi.require_version('Peas', '1.0')
|
||||
from gi.repository import GObject
|
||||
from gi.repository import Peas
|
||||
import time
|
||||
|
||||
|
||||
class ByeOrca(GObject.Object, Peas.Activatable, plugin.Plugin):
|
||||
#__gtype_name__ = 'ByeCthulhu'
|
||||
|
||||
object = GObject.Property(type=GObject.Object)
|
||||
def __init__(self):
|
||||
plugin.Plugin.__init__(self)
|
||||
def do_activate(self):
|
||||
API = self.object
|
||||
self.connectSignal("stop-application-completed", self.process)
|
||||
def do_deactivate(self):
|
||||
API = self.object
|
||||
def do_update_state(self):
|
||||
API = self.object
|
||||
def process(self, app):
|
||||
messages = app.getDynamicApiManager().getAPI('Messages')
|
||||
activeScript = app.getDynamicApiManager().getAPI('CthulhuState').activeScript
|
||||
activeScript.presentationInterrupt()
|
||||
activeScript.presentMessage(messages.STOP_ORCA, resetStyles=False)
|
||||
@@ -1,7 +1,7 @@
|
||||
orca_python_PYTHON = \
|
||||
cthulhu_python_PYTHON = \
|
||||
__init__.py \
|
||||
ByeCthulhu.plugin \
|
||||
ByeCthulhu.py
|
||||
plugin.info \
|
||||
plugin.py
|
||||
|
||||
orca_pythondir=$(pkgpythondir)/plugins/ByeCthulhu
|
||||
cthulhu_pythondir=$(pkgpythondir)/plugins/ByeCthulhu
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
name = Bye Cthulhu
|
||||
version = 1.0.0
|
||||
description = Says goodbye when Cthulhu is shutting down
|
||||
authors = Stormux <storm_dragon@stormux.org>
|
||||
website = https://stormux.org
|
||||
copyright = Copyright 2025
|
||||
builtin = false
|
||||
hidden = false
|
||||
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2025 Stormux
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
"""Bye Cthulhu plugin for Cthulhu."""
|
||||
|
||||
import logging
|
||||
import time
|
||||
from cthulhu.plugin import Plugin, cthulhu_hookimpl
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class ByeCthulhu(Plugin):
|
||||
"""Plugin that speaks a goodbye message when Cthulhu is shutting down."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the plugin."""
|
||||
super().__init__(*args, **kwargs)
|
||||
logger.info("ByeCthulhu plugin initialized")
|
||||
self._signal_handler_id = None
|
||||
|
||||
@cthulhu_hookimpl
|
||||
def activate(self, plugin=None):
|
||||
"""Activate the plugin."""
|
||||
# Skip if this activation call isn't for us
|
||||
if plugin is not None and plugin is not self:
|
||||
return
|
||||
|
||||
logger.info("Activating ByeCthulhu plugin")
|
||||
try:
|
||||
# Connect to the stop-application-completed signal
|
||||
signal_manager = self.app.getSignalManager()
|
||||
self._signal_handler_id = signal_manager.connectSignal(
|
||||
"stop-application-completed",
|
||||
self.process
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error activating ByeCthulhu plugin: {e}")
|
||||
|
||||
@cthulhu_hookimpl
|
||||
def deactivate(self, plugin=None):
|
||||
"""Deactivate the plugin."""
|
||||
# Skip if this deactivation call isn't for us
|
||||
if plugin is not None and plugin is not self:
|
||||
return
|
||||
|
||||
logger.info("Deactivating ByeCthulhu plugin")
|
||||
try:
|
||||
# Disconnect signal if we have an ID
|
||||
if self._signal_handler_id is not None:
|
||||
signal_manager = self.app.getSignalManager()
|
||||
signal_manager.disconnectSignal(
|
||||
"stop-application-completed",
|
||||
self._signal_handler_id
|
||||
)
|
||||
self._signal_handler_id = None
|
||||
except Exception as e:
|
||||
logger.error(f"Error deactivating ByeCthulhu plugin: {e}")
|
||||
|
||||
def process(self, app):
|
||||
"""Process the stop-application-completed signal."""
|
||||
try:
|
||||
messages = app.getDynamicApiManager().getAPI('Messages')
|
||||
state = app.getDynamicApiManager().getAPI('CthulhuState')
|
||||
if state.activeScript:
|
||||
state.activeScript.presentationInterrupt()
|
||||
state.activeScript.presentMessage(messages.STOP_CTHULHU, resetStyles=False)
|
||||
except Exception as e:
|
||||
logger.error(f"Error in ByeCthulhu process: {e}")
|
||||
@@ -1,3 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
from cthulhu import plugin
|
||||
|
||||
import gi
|
||||
@@ -58,16 +83,16 @@ class CapsLockHack(GObject.Object, Peas.Activatable, plugin.Plugin):
|
||||
settings = API.app.getDynamicApiManager().getAPI('Settings')
|
||||
time.sleep(3)
|
||||
while self.isActive():
|
||||
if "Caps_Lock" in settings.orcaModifierKeys \
|
||||
or "Shift_Lock" in settings.orcaModifierKeys:
|
||||
self.setCapsLockAsOrcaModifier(True)
|
||||
if "Caps_Lock" in settings.cthulhuModifierKeys \
|
||||
or "Shift_Lock" in settings.cthulhuModifierKeys:
|
||||
self.setCapsLockAsCthulhuModifier(True)
|
||||
capsLockCleared = True
|
||||
elif capsLockCleared:
|
||||
self.setCapsLockAsOrcaModifier(False)
|
||||
self.setCapsLockAsCthulhuModifier(False)
|
||||
capsLockCleared = False
|
||||
time.sleep(1)
|
||||
|
||||
def setCapsLockAsOrcaModifier(self, enable):
|
||||
def setCapsLockAsCthulhuModifier(self, enable):
|
||||
originalXmodmap = None
|
||||
lines = None
|
||||
try:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
orca_python_PYTHON = \
|
||||
cthulhu_python_PYTHON = \
|
||||
__init__.py \
|
||||
CapsLockHack.plugin \
|
||||
CapsLockHack.py
|
||||
|
||||
orca_pythondir=$(pkgpythondir)/plugins/CapsLockHack
|
||||
cthulhu_pythondir=$(pkgpythondir)/plugins/CapsLockHack
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
from cthulhu import plugin
|
||||
|
||||
import gi, os
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
orca_python_PYTHON = \
|
||||
cthulhu_python_PYTHON = \
|
||||
__init__.py \
|
||||
Clipboard.plugin \
|
||||
Clipboard.py
|
||||
|
||||
orca_pythondir=$(pkgpythondir)/plugins/Clipboard
|
||||
cthulhu_pythondir=$(pkgpythondir)/plugins/Clipboard
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2024 Stormux
|
||||
# Copyright (c) 2010-2012 The Orca Team
|
||||
# Copyright (c) 2012 Igalia, S.L.
|
||||
# Copyright (c) 2005-2010 Sun Microsystems Inc.
|
||||
#
|
||||
# This library is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This library is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this library; if not, write to the
|
||||
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
|
||||
# Boston MA 02110-1301 USA.
|
||||
#
|
||||
# Fork of Orca Screen Reader (GNOME)
|
||||
# Original source: https://gitlab.gnome.org/GNOME/orca
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user