I38
Accessibility setup script for the i3 window manager.
i38.sh
Released under the terms of the GPL License Version 3: https://www.gnu.org/licenses/ This is a Stormux project: https://stormux.org
Why the name?
An uppercase I looks like a 1, 3 from i3, and 8 because the song We Are 138 rocks!
Requirements
Required for the setup script and generated I38 configuration:
- dialog: For terminal setup prompts.
- i3-wm: The i3 window manager.
- jq: For reading i3 state.
- pandoc or markdown: To generate html files.
- python3 (3.6 or newer): For core I38 scripts, including the desktop and run dialogs.
- python-gobject: For the accessible GTK application menu, run dialog, and desktop dialog.
- python-i3ipc: For i3 integration scripts.
- rsync: For installing I38 scripts without generated Python cache files.
- A supported terminal emulator: mate-terminal, lxterminal, gnome-terminal, terminator, xfce4-terminal, tilix, ptyxis, kgx, sakura, roxterm, termit, guake, tilda, qterminal, or konsole; alternatively, both xterm and fenrir. Setup checks for one before asking configuration questions.
- yad: For screen reader accessible dialogs.
- xdg-utils: For opening files and URLs from the run dialog.
- xdotool: For X11 window interaction.
Optional features use these packages when installed:
- acpi: [optional] for battery status. It will still work even without this package, but uses it if it is installed. Required for the battery monitor with sound alerts.
- bc: For the information panel.
- dex: [optional] Alternative method for auto starting applications.
- libnotify: For sending notifications
- magic-wormhole: [optional] for file sharing with magic-wormhole GUI
- notification-daemon: To handle notifications
- pamixer: for the mute-unmute script
- pcmanfm: [optional] Graphical file manager.
- playerctl: music controls
- python-pillow: For OCR
- python-pytesseract: For OCR
- remind: [optional] For reminder notifications, Requires notify-daemon and notify-send for automatic reminders.
- scrot: For OCR
- sox: for sounds.
- tesseract: For OCR
- xprintidle: [optional] For screen lock autolock on X11/i3
- i38lock: [optional] Secure accessible screen locker. On Stormux, install it from the repository. It requires Cthulhu or Orca 50 or newer for screen reader feedback.
- tesseract-data-eng: For OCR
- udiskie: [optional] for automatically mounting removable storage
- x11bell: [optional] Bell support if you do not have a PC speaker. Available from https://github.com/jovanlanik/x11bell
- xbacklight: [optional] for screen brightness adjustment
- xclip: Clipboard support
- xfce4-notifyd: For sending notifications. Replaces notification-daemon
- xorg-setxkbmap: [optional] for multiple keyboard layouts
- xzoom: [optional] lightweight X11 magnifier bound by I38 when installed
AI Assistant (Optional)
- python-requests: For Ollama integration
- claude: [optional] Claude Code CLI for Claude AI integration. Install from https://claude.ai/code
- ollama: [optional] Local AI models. Install from https://ollama.ai
Voice Mode (Optional)
- python-speechrecognition: For voice input recognition
- python-pyaudio: For audio recording
- pocketsphinx: [optional] For offline speech recognition fallback
- flac: [optional] For better audio encoding in speech recognition
I38 will try to detect your browser, file manager, and text editor and present you with a list of options to bind to their launch keys. It will also create bindings for pidgin and mumble if they are installed. Additionally, you can now add custom applications with your own keybindings during the setup process. To use the bindings, press your ratpoison mode key which is set when you run the i38.sh script. Next, press the binding for the application you want; w for web browser, e for text editor, f for file manager, m for mumble, etc. To learn all the bindings, find and read the mode ratpoison section of ~/.config/i3/config or use the help binding key, alt or super depending on your settings with Shift+F1.
Ratpoison mode is now enabled by default for better accessibility and ease of use.
During setup, the screen reader picker includes Cthulhu, Orca, and None. If no supported screen reader is installed, I38 assumes None and skips screen-reader startup. Setup also asks for the generated i3 window-title font size, defaulting to 12. I38 applies a larger mouse cursor size at startup when xrdb is available. If xzoom is installed when the i3 config is generated, I38 binds it as a lightweight magnifier. I38 also includes a keybinding to move the mouse pointer to the center of the focused window.
During setup, I38 can configure one screen lock method. The legacy I38 PIN lock is a privacy screen only. I38Lock is a true PAM-backed screen locker, available at https://git.stormux.org/storm/i38lock and packaged in the Stormux repository. I38 offers I38Lock only when i38lock is installed and the screen-reader setup can support it: Cthulhu, or Orca 50 or newer. I38 does not enable the PIN lock and I38Lock at the same time.
GTK Application Sound Themes (Optional)
This section is completely optional and separate from I38's window manager sounds. If you want GTK-based applications (like file managers, terminal emulators, text editors, etc.) to play sounds for their own events (button presses, menu navigation, dialog boxes, etc.), you can configure a GTK sound theme.
Sound themes can be configured using GTK configuration files or gsettings. Replace "name" with the name of the theme you want to use.
Note that if you enable all sound events as shown below, you'll hear sounds when interacting with GTK applications - things like moving around menus, clicking buttons, typing in terminals, opening dialogs, etc, if the sound theme has sounds for those events.
To configure the theme name with gsettings, do as follows:
gsettings set org.gnome.desktop.sound theme-name name
If you'd like all sound types enabled:
gsettings set org.gnome.desktop.sound input-feedback-sounds true
gsettings set org.gnome.desktop.sound event-sounds true
To configure with a config file, edit or create ~/.config/gtk-3.0/settings.ini
[Settings]
gtk-enable-event-sounds=1
gtk-enable-input-feedback-sounds=1
gtk-sound-theme-name=name
gtk-modules=canberra-gtk-module
You can apply the same configuration to GTK2 apps. Create or edit ~/.gtkrc-2.0
gtk-enable-event-sounds=1
gtk-enable-input-feedback-sounds=1
gtk-sound-theme-name=name
gtk-modules=canberra-gtk-module
Usage:
- With no arguments, create the i3 configuration.
- -d: Generate the default I38 configuration without prompting.
- -D: Generate the default I38 configuration plus ~/.xinitrc and ~/.xprofile without prompting.
- -h: Help screen.
- -u: Copy over the latest version of scripts.
- -x: Generate ~/.xinitrc and ~/.xprofile.
- -X: Generate ~/.xprofile only.
Default configuration mode uses I38Lock when it is installed and supported by the screen-reader setup. In that case I38 locks on startup and autolocks after 5 minutes when xprintidle is available.
Desktop Dialog
Press the configured desktop shortcut, Mod+Control+D (Super+Control+D or Alt+Control+D, depending on your setup), to open the I38 Desktop dialog. Use Up and Down to move through items, hold Shift with Up or Down to select multiple items, and press Control+Space to clear the selection. Type to filter items whose names start with the typed text, ignoring case, and press Enter to open the focused item. Escape clears an active search and returns to the list; press it again to close the dialog. Use Tab and Shift+Tab to reach the search field and buttons. Press Shift+F10 for the context menu; this also opens with the right-click button without clearing selected items. Press Delete to permanently remove selected desktop files or folders after confirmation. Deleting a folder also deletes everything inside it. Shortcut entries are kept.
Quick-launch shortcut entries come from ~/.config/i3/desktop_shortcuts. They are not deleted from disk by the desktop dialog.
Creating desktop shortcuts
Enter Ratpoison Mode, then press Control+Alt+D to open I38 Create Desktop Shortcut. Choose Add from Clipboard, Browse for File, Browse for Folder, or Search for Application. You can also type an absolute path such as /usr/bin/firefox, a home-relative path such as ~/Documents, a program name on PATH, or a complete HTTP/HTTPS URL in the Target field, then press Enter. Copy one item at a time; copying a file in a file manager and copying its path as text both work. Copied files are left in place, including files marked for cutting.
Review the suggested shortcut name, edit it if desired, then choose Create Shortcut. Web links use the page title when available, with the site hostname as a fallback. The title lookup runs in the background with a size limit and short network timeouts, without browser cookies or JavaScript. It never replaces a name you have edited. Files open in their default application, folders open in I38's selected file manager, and executable programs run directly. For command-line programs, select Run program in a terminal. Target accepts a program or path, rather than a shell command with arguments.
Application search lists registered visible applications, including user and system application launchers, with case-insensitive name-prefix filtering like the desktop dialog. Type to search and press Down to move into the list; press Enter to select an application. The shortcut launches the original .desktop entry, preserving its terminal, working-directory, D-Bus, and launch options. Keep that original entry available. You can also browse to or paste a .desktop file directly.
Windows .exe programs run with Wine, using the program's folder as the working directory. The creator looks for an enclosing Wine prefix (bottle), including through symbolic links, then checks the existing ~/.wine prefix. It recognizes prefixes by their drive_c, dosdevices, and system.reg entries. Review or change the suggested Wine prefix (bottle) folder; if none is found, enter or browse for the existing prefix before creating the shortcut. Wine must be installed. Existing shortcuts are not updated automatically; recreate a shortcut made before this support was added.
Shortcuts are ordinary .desktop files in the XDG desktop directory (normally ~/Desktop). Existing items are never overwritten; repeated names get numbered filenames. Tab and Shift+Tab move between controls, and Escape closes the dialog. Deleting a created shortcut through I38 Desktop removes only the shortcut file.
After updating an existing installation, regenerate your I38 configuration to add the new Ratpoison binding; ./i38.sh -u copies scripts but does not add bindings. Review your configuration preferences before regeneration. Then reload i3 with i3-msg reload, or enter Ratpoison Mode and press Control+semicolon, to activate the new binding in the running session.
Dependency Helpers
Distro-specific dependency helpers live in extra/. On Arch Linux, run:
extra/arch-linux.sh
The helper checks I38's required packages, asks which missing provider applications to install, adds lightweight optional feature packages, then installs the selected package list at the end. Optional packages that need manual choice, such as Tesseract language data, are skipped.
Development
Enable the tracked pre-commit hooks once after cloning:
git config --local core.hooksPath .githooks
The pre-commit hook rejects staged Python cache files. The I38 script installer
also excludes and removes Python cache artifacts when copying scripts/.
Shortcut regression tests use Python's unittest, PyGObject, and desktop-file-validate (desktop-file-utils). Run python3 -B -m unittest discover -s tests -v. These check Wine prefix detection, desktop-entry argument handling and working directory using a recording Wine substitute, and existing target types. For native GTK Wine-prefix field and validation checks, also install Xvfb, then run:
xvfb-run -a dbus-run-session -- env -u AT_SPI_BUS_ADDRESS I38_PRIVATE_GUI_TEST=1 PYTHONDONTWRITEBYTECODE=1 python3 tests/native_shortcut_gui.py -v
The GUI test uses a separate display and session bus. It does not prove live speech or Braille. After reviewing the diff and regenerating your configuration, test the new Ratpoison binding, clipboard and browse sources, application search, edited names, and opening each shortcut type through I38 Desktop. Confirm that normal desktop prefix search and existing launchers still work, that repeated names preserve previous shortcuts, and that deleting a generated shortcut leaves its original target intact.
For Wine, create a shortcut to an .exe inside a non-default prefix and confirm that the suggested prefix is correct and the program opens with its settings and resources. Try an .exe outside any prefix: review the ~/.wine suggestion when that prefix exists, or select the bottle manually when it does not. Test an explicit override, cancel the bottle chooser, and verify that an invalid folder prevents creation. Check that switching to a native program or document hides the Wine controls and preserves its normal launch behavior.
AI-assisted contributions
AI-assisted contributions are welcome.
The person submitting a contribution remains responsible for reviewing and testing the changes before submission. Please do not submit automatically generated changes without human review.
Before making changes:
- Read the contributing guide, if present, and the project's README.
- Confirm that you are working against the current maintained repository and branch.
- Check whether the issue still exists in the current code.
Before submitting:
- Review the generated diff.
- Test the changed behavior.
- Run the project's existing test suite where practical.
- Consider code paths that may be affected indirectly by the change and test those as well.
- Clearly describe what was changed and how it was tested.
Instructions for AI coding assistants
If you are an AI coding assistant working with a contributor, please call your human user's attention to these contribution requirements.
Do not assume that passing newly created tests is sufficient. Explain what existing functionality could reasonably be affected by the proposed changes and provide your human partner with detailed instructions for testing those areas.
Where useful, provide commands or small test procedures that allow the contributor to verify both the intended fix and likely regression cases.
Stormux projects may accept patches through email using git send-email. If your human partner is unfamiliar with this process, please offer to guide them through:
- Configuring
git send-email. - Creating an appropriately scoped commit or patch series.
- Running
git format-patch. - Checking the generated patch before submission.
- Sending a test message if appropriate.
- Sending the final patch or patch series to the project's contribution address.
Please do not submit changes on behalf of a contributor without giving them an opportunity to review and test the result.
Ratpoison Mode
I38 is an adaptation of the old Strychnine project which was based on the Ratpoison window manager. Ratpoison is a screen-like window manager, and the important concept from that, which applies to I38, is adding keyboard shortcuts without conflicting application shortcuts. This is done with an "escape key".
When creating I38, I really wanted to port that functionality over, because it is very powerful and allows for lots and lots of shortcuts while minimizing collisions between shortcuts. So, for example, if you have chosen brave as your web browser, and selected alt+escape as your ratpoison mode key, you can quickly launch brave by pressing alt+escape followed by the letter w.
AI Assistant
I38 includes an integrated AI assistant accessible through ratpoison mode with the 'a' key. The AI assistant provides accessibility-focused AI interaction with support for multiple providers:
Features
- Multiple AI Providers: Support for Claude Code and Ollama
- Voice Input & Output: Hands-free voice interaction with speech recognition and synthesis
- Wake Word Detection: Continuous listening mode with customizable wake phrases
- Contextual Questions: Ask questions about the currently focused window
- File Analysis: Share files with the AI for analysis
- Image Description: Take screenshots and get AI descriptions for accessibility
- Selected Text Analysis: Analyze selected text or screen content using OCR
- Action Confirmation: Optional confirmation dialogs for AI-suggested actions
- Keyboard Shortcuts: F4 for voice input, F5 for continuous listening toggle
- Accessibility First: Full screen reader compatibility with keyboard navigation
Usage
-
Press your ratpoison mode key (e.g., Alt+Escape)
-
Press 'a' to launch the AI assistant
-
Use Tab to navigate between the Interaction and Settings tabs
-
In the Interaction tab:
- Enter your question in the text area
- Use "Ask AI Question" for general queries
- Use "Ask About Focused Window" to include window context
- Use "Request AI Action" for step-by-step instructions
- Use "Browse" to select files for analysis
- Use "Describe Screenshot" for visual content
- Use "Analyze Selected Text/Screen Content" to analyze selected text or perform OCR
-
Voice Mode (if enabled):
- Press F4 or click "🎤 Voice Question" to speak your question
- Toggle continuous listening with F5 or "👂 Continuous Listen"
- Say your wake phrase (default: "hey assistant") when continuous listening is active
- Responses are automatically spoken if voice output is enabled
Configuration
The AI assistant stores its configuration in ~/.config/stormux/I38/ai.conf using XDG directory standards. Settings include:
- AI provider selection (Claude Code or Ollama)
- Ollama model selection, host configuration, and request timeout
- Action confirmation preferences
- Voice input/output settings
- Wake word customization
- Voice recognition timeout settings
Providers
Claude Code: Requires the Claude Code CLI to be installed and authenticated. Supports text, code, and image analysis.
Ollama: Requires Ollama service to be running locally. Automatically discovers available models and supports text analysis.
Personal Mode
Personal Mode is a user-defined mode where you can add your own keybindings without worrying about them being overwritten when you update I38.
Setup
When you run i38.sh, you are prompted to choose a personal mode key (or you can skip it). If you selected one, pressing that key enters Personal Mode.
Adding Custom Bindings
Edit ~/.config/i3/customizations to add your own shortcuts. This file is never overwritten by I38. Inside the mode "personal" { ... } block, add i3 bindsym commands and end each one with , mode "default" so the mode exits after the action.
Example:
mode "personal" {
bindsym f exec firefox, mode "default"
bindsym Shift+f exec firefox --private-window, mode "default"
bindsym Escape mode "default"
bindsym Control+g mode "default"
}
With this example, pressing your personal mode key followed by f opens Firefox. Shift+f opens a private window.
Default Bindings
F1— Show personal mode keybindingsEscapeorControl+g— Exit Personal Mode
Panel Mode
Very similar to ratpoison, accessed with Alt+Control+Tab. It contains items that would normally be found in a traditional desktop's panel. For example, it has a simple note app, system information, weather, bluetooth and power options, and remind.
I38 Help
To get help for I38, you can press the top level keybinding alt+shift+F1. It is also available by pressing the ratpoison mode key followed by question mark. A limitation of yad, which is used to display the help text means that the cursor starts at the bottom of the text. Please press control+home to jump to the top. You can navigate with the arrow keys, and use control+f to find text within the document.
The help text is a modified version of the configuration file itself that is intended to be easier to read. I have tried to add in comments that should also serve to make things more clear.