diff --git a/I38.md b/I38.md index ed71e92..ae0a36a 100644 --- a/I38.md +++ b/I38.md @@ -1,6 +1,6 @@ # Welcome to I38 - Accessible i3 Window Manager -> **Note:** This help guide has been tailored to your specific configuration. You've chosen **BROWSER** as your web browser, **MODKEY** as your mod key, and you're using the **SCREENREADER** screen reader. +> **Note:** This help guide has been tailored to your specific configuration. You've chosen **@WEBBROWSER@** as your web browser, **@MODKEY@** as your mod key, and you're using the **@SCREENREADER@** screen reader. ## Introduction to I38 @@ -36,10 +36,10 @@ Workspaces act like virtual desktops, allowing you to organize applications. You Windows in I38 are arranged in a tabbed layout by default, which means windows take up the entire screen and you can switch between them like browser tabs. - Switch between windows: `Alt` + `Tab` (next) or `Alt` + `Shift` + `Tab` (previous) -- Launch terminal: `MODKEY` + `Return` -- Close window: `MODKEY` + `F4` -- Toggle fullscreen: `MODKEY` + `BackSpace` -- List windows in current workspace: `RATPOISONKEY` then `'` (apostrophe) +- Launch terminal: `@MODKEY@` + `Return` +- Close window: `@MODKEY@` + `F4` +- Toggle fullscreen: `@MODKEY@` + `BackSpace` +- List windows in current workspace: `@RATPOISONKEY@` then `'` (apostrophe) *GNOME/MATE comparison:* Alt+Tab works similarly to GNOME/MATE, but window placement is automatic rather than manual. @@ -48,22 +48,22 @@ Windows in I38 are arranged in a tabbed layout by default, which means windows t ### Default Mode -This is the standard mode for working with applications. Most commands start with your mod key (`MODKEY`). +This is the standard mode for working with applications. Most commands start with your mod key (`@MODKEY@`). TOPLEVELKEYBINDINGS ### Ratpoison Mode -Ratpoison mode allows quick access to common actions using shorter key combinations. To enter Ratpoison mode, press `RATPOISONKEY`. After pressing this key, you can execute commands with single keystrokes. +Ratpoison mode allows quick access to common actions using shorter key combinations. To enter Ratpoison mode, press `@RATPOISONKEY@`. After pressing this key, you can execute commands with single keystrokes. Common Ratpoison mode commands: | Key | Action | |-----|--------| | `c` | Launch a terminal | -| `e` | Open text editor (TEXTEDITOR) | +| `e` | Open text editor (@TEXTEDITOR@) | | `i` | Launch IRC client | -| `w` | Launch web browser (BROWSER) | +| `w` | Launch web browser (@WEBBROWSER@) | | `k` | Kill (close) the current window | | `F1` | Show ratpoison mode keybindings | | `Escape` or `Control` + `g` | Exit Ratpoison mode without taking action | @@ -80,7 +80,7 @@ Common Ratpoison mode commands: ### Bypass Mode -Bypass mode passes all keys directly to the application, which is useful for applications that need many keyboard shortcuts. To enter bypass mode, press `MODKEY` + `Shift` + `BackSpace`. Use the same key combination to exit bypass mode. +Bypass mode passes all keys directly to the application, which is useful for applications that need many keyboard shortcuts. To enter bypass mode, press `@MODKEY@` + `Shift` + `BackSpace`. Use the same key combination to exit bypass mode. *GNOME/MATE comparison:* In GNOME/MATE, applications always receive keyboard input directly. Bypass mode simulates this behavior within i3. @@ -136,7 +136,7 @@ In Panel Mode, single keypresses launch different information panels: | `Shift` + `b` | Show detailed battery information | | `m` | Launch password manager | | `p` | Show power options | -| `Control` + `MODKEY` + `l` | Lock screen *(if screen lock PIN is configured)* | +| `Control` + `@MODKEY@` + `l` | Lock screen *(if screen lock PIN is configured)* | | `Escape` or `Control` + `g` | Exit Panel Mode without taking action | Just like Ratpoison Mode, Panel Mode automatically returns you to Default Mode after a selection is made or when you press Escape/Control+g to cancel. @@ -200,11 +200,11 @@ waytray is an optional dependency. If installed, I38 will automatically configur ### Screen Reader -I38 is configured to work with your screen reader (SCREENREADER). The screen reader will provide spoken feedback about what's happening on screen so long as there is a window. If you don't have a window open and need to change something SCREENREADER related, press Control+Alt+d to bring up the desktop, then screen reader keys should work. +I38 is configured to work with your screen reader (@SCREENREADER@). The screen reader will provide spoken feedback about what's happening on screen so long as there is a window. If you don't have a window open and need to change something @SCREENREADER@ related, press Control+Alt+d to bring up the desktop, then screen reader keys should work. -- Toggle screen reader: `RATPOISONKEY` then `Shift` + `t` -- Restart screen reader: `RATPOISONKEY` then `Shift` + `o` (for Orca) or `Shift` + `c` (for Cthulhu) -- Interrupt speech: `MODKEY` + `Shift` + `F5` +- Toggle screen reader: `@RATPOISONKEY@` then `Shift` + `t` +- Restart screen reader: `@RATPOISONKEY@` then `Shift` + `o` (for Orca) or `Shift` + `c` (for Cthulhu) +- Interrupt speech: `@MODKEY@` + `Shift` + `F5` *GNOME/MATE comparison:* GNOME uses Orca by default with its own keyboard shortcuts. I38 integrates screen readers more deeply with the window manager. @@ -216,14 +216,14 @@ If you've enabled braille display support during setup, I38 will start XBrlAPI a If required dependencies are installed, you can use OCR to read text from images or inaccessible applications: -- `MODKEY` + `F5`: Perform OCR on the entire screen and speak the content -- In Ratpoison mode: `Print` or `MODKEY` + `r`: Perform OCR and save to clipboard +- `@MODKEY@` + `F5`: Perform OCR on the entire screen and speak the content +- In Ratpoison mode: `Print` or `@MODKEY@` + `r`: Perform OCR and save to clipboard *GNOME/MATE comparison:* OCR features are typically not integrated into GNOME/MATE by default. ### Screen Lock -If you enabled the I38 privacy screen lock during setup, press `Control` + `Alt` + `Tab` to enter panel mode, then press `Control` + `MODKEY` + `l` to lock the screen. This is a privacy screen for I38, not a secure system lock. +If you enabled the I38 privacy screen lock during setup, press `Control` + `Alt` + `Tab` to enter panel mode, then press `Control` + `@MODKEY@` + `l` to lock the screen. This is a privacy screen for I38, not a secure system lock. When a screen lock PIN is configured, I38 can also autolock after an idle timeout. The default is never. Autolock is X11/i3-only and requires `xprintidle`; if `playerctl` is installed, I38 will avoid autolocking during likely video playback. @@ -244,8 +244,8 @@ This audio feedback provides non-visual confirmation of actions and state change Access applications in multiple ways: -- Applications menu: `MODKEY` + `F1` -- Run dialog (enter a command): `MODKEY` + `F2` or in Ratpoison mode, `!` (exclamation mark) +- Applications menu: `@MODKEY@` + `F1` +- Run dialog (enter a command): `@MODKEY@` + `F2` or in Ratpoison mode, `!` (exclamation mark) - Common applications have dedicated shortcuts in Ratpoison mode (see table above) The applications menu is organized by categories similar to traditional desktop environments. @@ -276,9 +276,9 @@ The reminder tool provides the following features: ### System Volume -- Increase volume: `MODKEY` + `XF86AudioRaiseVolume` -- Decrease volume: `MODKEY` + `XF86AudioLowerVolume` -- Mute/unmute: `MODKEY` + `XF86AudioMute` +- Increase volume: `@MODKEY@` + `XF86AudioRaiseVolume` +- Decrease volume: `@MODKEY@` + `XF86AudioLowerVolume` +- Mute/unmute: `@MODKEY@` + `XF86AudioMute` ### Media Player Controls @@ -286,7 +286,7 @@ The reminder tool provides the following features: - Next track: `XF86AudioNext` - Previous track: `XF86AudioPrev` - Stop: `XF86AudioStop` -- Media info: `MODKEY` + `XF86AudioPlay` +- Media info: `@MODKEY@` + `XF86AudioPlay` In Ratpoison mode, these are also available with Alt+Shift combinations: @@ -304,7 +304,7 @@ In Ratpoison mode, these are also available with Alt+Shift combinations: ## File Management -I38 uses FILEBROWSER for file management. Launch it in Ratpoison mode with the `f` key. +@FILEBROWSERHELP@ *GNOME/MATE comparison:* Similar functionality to Nautilus (GNOME) or Caja (MATE), but launched via keyboard shortcut rather than from a desktop icon or menu. @@ -333,26 +333,26 @@ This is only available if you chose multiple keyboard layouts during setup. Unlike GNOME or MATE, i3 uses minimal window decorations. Windows don't have title bars with minimize/maximize buttons. Instead, windows fill their available space automatically, and interactions are performed through keyboard shortcuts. -- Show desktop icons: `MODKEY` + `Control` + `d` +- Show desktop icons: `@MODKEY@` + `Control` + `d` ## Clipboard Management I38 includes clipboard management features: -- Access clipboard history: `MODKEY` + `Control` + `c` +- Access clipboard history: `@MODKEY@` + `Control` + `c` ## Bookmark Management -- Access bookmarks: `MODKEY` + `Control` + `b` +- Access bookmarks: `@MODKEY@` + `Control` + `b` *GNOME/MATE comparison:* Bookmarks are typically managed within applications in GNOME/MATE. I38 provides a system-wide bookmark manager. ## Tips for New Users -- **Use the window list**: When you're lost, use `RATPOISONKEY` then `'` to show all windows in the current workspace. -- **Bookmark important websites**: Use `MODKEY` + `Control` + `b` to access bookmarks. +- **Use the window list**: When you're lost, use `@RATPOISONKEY@` then `'` to show all windows in the current workspace. +- **Bookmark important websites**: Use `@MODKEY@` + `Control` + `b` to access bookmarks. - **Remember the help shortcuts**: - - `MODKEY` + `Shift` + `F1` opens the complete I38 HTML guide + - `@MODKEY@` + `Shift` + `F1` opens the complete I38 HTML guide - Press `F1` in ratpoison or panel mode for quick keybinding reference specific to that mode - **Let the sound effects guide you**: Pay attention to the audio cues to understand what's happening. - **Take advantage of OCR**: If an application isn't accessible, try the OCR function. @@ -388,8 +388,8 @@ I38 checks for updates in the background during your desktop session. If a newer To update I38 on this system: -1. Open a terminal with `MODKEY` + `Return`. -2. Type `cd "I38CHECKOUTPATH"` and press Enter. +1. Open a terminal with `@MODKEY@` + `Return`. +2. Type `cd "@I38CHECKOUTPATH@"` and press Enter. 3. Type `git pull` and press Enter. 4. Type `./i38.sh` and press Enter. @@ -401,7 +401,7 @@ If you only need to copy the latest scripts and do not want to regenerate the fu If you need assistance with I38, you can: -- Press `MODKEY` + `Shift` + `F1` to view the help documentation +- Press `@MODKEY@` + `Shift` + `F1` to view the help documentation - Visit the Stormux website at [stormux.org](https://stormux.org) - Join the Stormux irc at irc.stormux.org #stormux or #a11y - Check the i3 documentation at [i3wm.org/docs/userguide.html](https://i3wm.org/docs/userguide.html) diff --git a/README.md b/README.md index 56270a3..35a5cd0 100644 --- a/README.md +++ b/README.md @@ -14,24 +14,32 @@ An uppercase I looks like a 1, 3 from i3, and 8 because the song [We Are 138](ht ## 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. +- python-i3ipc: For i3 integration scripts. +- yad: For screen reader accessible dialogs. +- 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. -- i3-wm: The i3 window manager. -- jq: for getting the current workspace - 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 -- pandoc or markdown: To generate html files. - pcmanfm: [optional] Graphical file manager. - playerctl: music controls - python-gobject: for applications menu. -- python-i3ipc: for sounds etc. - 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 +- scrot: For OCR - sox: for sounds. - tesseract: For OCR - xprintidle: [optional] For screen lock autolock on X11/i3 @@ -42,31 +50,6 @@ scrot: For OCR - xclip: Clipboard support - xfce4-notifyd: For sending notifications. Replaces notification-daemon - xorg-setxkbmap: [optional] for multiple keyboard layouts -- yad: For screen reader accessible dialogs - -### Sway/Wayland Specific Dependencies - -When using I38 with Sway instead of i3, the following Wayland-native alternatives are recommended for optimal compatibility. I38 will automatically detect and use these when running with the `-s` flag: - -- **Recommended (Wayland-native)**: - - mako: Wayland-native notification daemon (preferred over xfce4-notifyd) - - wl-clipboard: Wayland clipboard utilities (provides wl-copy and wl-paste) - - clipman: Wayland clipboard manager (works with wl-clipboard) - - wlr-randr: [optional] Wayland display configuration tool for screen brightness control - - brightnessctl: [optional] Alternative brightness control tool for Sway - -- **Not needed on Sway/Wayland** (these are X11-only): - - xbrlapi: X11 braille helper - not needed on Wayland, BRLTTY works directly - - x11bell: X11 bell support - Wayland has native alternatives - - xdotool: X11 window manipulation - Sway uses native IPC instead - - xprop: X11 window properties - Sway uses native IPC instead - - xrandr: X11 display configuration - use wlr-randr or brightnessctl instead - - setxkbmap: X11 keyboard layout - Sway uses native input configuration - -- **Works on both** (via XWayland fallback if Wayland-native not available): - - xfce4-notifyd: Works via XWayland, but mako is preferred for native Wayland support - -**Note**: On Sway, keyboard layouts must be configured in the Sway config file (`~/.config/sway/config`) using the `input` block. The keyboard.sh script will cycle through configured layouts but cannot set layouts directly like on X11. ### AI Assistant (Optional) - python-requests: For Ollama integration diff --git a/i38.sh b/i38.sh index dde229e..e561900 100755 --- a/i38.sh +++ b/i38.sh @@ -406,15 +406,25 @@ chmod +x ~/.xinitrc } write_xprofile() { -if [[ -f "$HOME/.xprofile" ]]; then -if ! yesno "Would you like to add accessibility variables to your $HOME/.xprofile? Without these, accessibility will be limited or may not work at all. Do you want to continue?"; then -exit 0 +local xprofilePath="$HOME/.xprofile" + +if [[ -f "$xprofilePath" ]]; then + if ! yesno "Would you like to add accessibility variables to your $xprofilePath? Without these, accessibility will be limited or may not work at all. Do you want to continue?"; then + exit 0 + fi fi -fi -cat << 'EOF' > ~/.xprofile + +I38_XPROFILE_PATH="$xprofilePath" python3 - << 'PY' +import os +from pathlib import Path + +xprofile_path = Path(os.environ["I38_XPROFILE_PATH"]) +start_marker = "# I38 accessibility variables start" +end_marker = "# I38 accessibility variables end" +block = """\ +{start} export XDG_CURRENT_DESKTOP=i3 export XDG_SESSION_DESKTOP=i3 -# Accessibility variables export ACCESSIBILITY_ENABLED=1 export CHROME_FLAGS="--force-renderer-accessibility" export GTK_MODULES=gail:atk-bridge @@ -422,7 +432,32 @@ export GNOME_ACCESSIBILITY=1 export QT_ACCESSIBILITY=1 export QT_LINUX_ACCESSIBILITY_ALWAYS_ON=1 export SAL_USE_VCLPLUGIN=gtk3 -EOF +{end} +""".format(start=start_marker, end=end_marker) + +content = "" +if xprofile_path.exists(): + content = xprofile_path.read_text(encoding="utf-8") + +lines = content.splitlines() +output = [] +in_i38_block = False +for line in lines: + if line == start_marker: + in_i38_block = True + continue + if line == end_marker: + in_i38_block = False + continue + if not in_i38_block: + output.append(line) + +new_content = "\n".join(output).rstrip() +if new_content: + new_content += "\n\n" +new_content += block +xprofile_path.write_text(new_content, encoding="utf-8") +PY exit 0 } @@ -1331,6 +1366,14 @@ screenReader="${screenReader##*/}" textEditor="${textEditor##*/}" fileBrowser="${fileBrowser##*/}" ircClient="${ircClient##*/}" +webBrowserHelp="${webBrowser:-no web browser was configured}" +screenReaderHelp="${screenReader:-no screen reader was configured}" +textEditorHelp="${textEditor:-no text editor was configured}" +if [[ -n "$fileBrowser" ]]; then + fileBrowserHelp="I38 uses ${fileBrowser} for file management. Launch it in Ratpoison mode with the \`f\` key." +else + fileBrowserHelp="No file manager was configured when this help file was generated." +fi # Extract and categorize top-level keybindings for documentation # Generate HTML directly since we're inserting into an already-converted HTML file @@ -1490,13 +1533,34 @@ awk ' rm -f "${i3Path}/toplevel_temp.txt" # Customize the html file to the user's choices. -sed -i -e "s|BROWSER|${webBrowser}|g" \ - -e "s|MODKEY|${mod}|g" \ - -e "s|SCREENREADER|${screenReader}|g" \ - -e "s|RATPOISONKEY|${escapeKey}|g" \ - -e "s|TEXTEDITOR|${textEditor}|g" \ - -e "s|FILEBROWSER|${fileBrowser}|g" \ - -e "s|I38CHECKOUTPATH|${i38CheckoutPath}|g" "${i3Path}/I38.html" +I38_HELP_WEBBROWSER="$webBrowserHelp" \ +I38_HELP_MODKEY="$mod" \ +I38_HELP_SCREENREADER="$screenReaderHelp" \ +I38_HELP_RATPOISONKEY="$escapeKey" \ +I38_HELP_TEXTEDITOR="$textEditorHelp" \ +I38_HELP_FILEBROWSERHELP="$fileBrowserHelp" \ +I38_HELP_CHECKOUTPATH="$i38CheckoutPath" \ +python3 - "${i3Path}/I38.html" << 'PY' +import os +import sys +from pathlib import Path + +html_path = Path(sys.argv[1]) +replacements = { + "@WEBBROWSER@": os.environ["I38_HELP_WEBBROWSER"], + "@MODKEY@": os.environ["I38_HELP_MODKEY"], + "@SCREENREADER@": os.environ["I38_HELP_SCREENREADER"], + "@RATPOISONKEY@": os.environ["I38_HELP_RATPOISONKEY"], + "@TEXTEDITOR@": os.environ["I38_HELP_TEXTEDITOR"], + "@FILEBROWSERHELP@": os.environ["I38_HELP_FILEBROWSERHELP"], + "@I38CHECKOUTPATH@": os.environ["I38_HELP_CHECKOUTPATH"], +} + +content = html_path.read_text(encoding="utf-8") +for placeholder, value in replacements.items(): + content = content.replace(placeholder, value) +html_path.write_text(content, encoding="utf-8") +PY # Create the firstrun file touch "${i3Path}/firstrun" diff --git a/scripts/battery_alert.sh b/scripts/battery_alert.sh index 5e28c64..4e1717e 100755 --- a/scripts/battery_alert.sh +++ b/scripts/battery_alert.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # This file is part of I38. diff --git a/scripts/game_controller.sh b/scripts/game_controller.sh index 9742043..249e729 100755 --- a/scripts/game_controller.sh +++ b/scripts/game_controller.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This file is part of I38. @@ -23,7 +23,9 @@ if [[ "$batteryName" == "" ]]; then fi # If there's no file, we don't check it. -if [[ ! -f "/sys/class/power_supply/${batteryName}/capacity" ]]; then +batteryCapacityPath="/sys/class/power_supply/${batteryName}/capacity" +batteryStatusPath="/sys/class/power_supply/${batteryName}/status" +if [[ ! -f "$batteryCapacityPath" ]]; then spd-say -P important -Cw "Battery not found." exit 0 fi @@ -31,8 +33,8 @@ fi oldPercent="$(tail -1 "$0" | tr -cd '[:digit:]')" oldPercent="${oldPercent:-0}" -percent=$(cat "/sys/class/power_supply/${batteryName}/capacity" | tr -cd '[:digit:]') -status="$(cat "/sys/class/power_supply/${batteryName}/status")" +percent=$(tr -cd '[:digit:]' < "$batteryCapacityPath") +status="$(cat "$batteryStatusPath")" # If status is requested, give it and exit. if [[ "$1" == "-s" || "$1" == "--status" ]]; then @@ -41,24 +43,25 @@ if [[ "$1" == "-s" || "$1" == "--status" ]]; then fi if [[ $percent -ne $oldPercent && $percent -gt 10 ]]; then - spd-say "Battery $(> "$0" exit 0 +# shellcheck disable=SC2317 50 diff --git a/scripts/i38-help-panel.sh b/scripts/i38-help-panel.sh index 26e34e7..624ffb7 100755 --- a/scripts/i38-help-panel.sh +++ b/scripts/i38-help-panel.sh @@ -14,6 +14,7 @@ configPath="$(readlink -f "$0")" configPath="${configPath%/*/*}" if [[ -f "${configPath}/config" ]]; then + # shellcheck disable=SC2016 mod="$(grep 'set $mod ' "${configPath}/config" | cut -d ' ' -f3)" mod="${mod//Mod1/Alt}" mod="${mod//Mod4/Super}" @@ -30,9 +31,9 @@ else fi for i in "${!helpText[@]}" ; do - helpText[$i]="${helpText[$i]//${configPath}\/scripts\//}" - helpText[$i]="${helpText[$i]/.sh/}" - helpText[$i]="${helpText[$i]/.py/}" + helpText[i]="${helpText[i]//${configPath}\/scripts\//}" + helpText[i]="${helpText[i]/.sh/}" + helpText[i]="${helpText[i]/.py/}" done header="Panel Mode Keybindings\n\nPress Control+Alt+Tab to enter panel mode, then use these shortcuts:\n\n" diff --git a/scripts/i38-help-rp.sh b/scripts/i38-help-rp.sh index 13cc717..acf704c 100755 --- a/scripts/i38-help-rp.sh +++ b/scripts/i38-help-rp.sh @@ -14,6 +14,7 @@ configPath="$(readlink -f "$0")" configPath="${configPath%/*/*}" if [[ -f "${configPath}/config" ]]; then + # shellcheck disable=SC2016 mod="$(grep 'set $mod ' "${configPath}/config" | cut -d ' ' -f3)" mod="${mod//Mod1/Alt}" mod="${mod//Mod4/Super}" @@ -31,10 +32,10 @@ else fi for i in "${!helpText[@]}" ; do - helpText[$i]="${helpText[$i]//${configPath}\/scripts\//}" - helpText[$i]="${helpText[$i]/.sh/}" - helpText[$i]="${helpText[$i]/, exec announce*/$'\n'}" - helpText[$i]="${helpText[$i]/, exec spd-say*/$'\n'}" + helpText[i]="${helpText[i]//${configPath}\/scripts\//}" + helpText[i]="${helpText[i]/.sh/}" + helpText[i]="${helpText[i]/, exec announce*/$'\n'}" + helpText[i]="${helpText[i]/, exec spd-say*/$'\n'}" done header="Ratpoison Mode Keybindings\n\nEnter ratpoison mode with your configured escape key, then use these shortcuts:\n\n" diff --git a/scripts/i38-help.sh b/scripts/i38-help.sh index 2976869..0b20cbe 100755 --- a/scripts/i38-help.sh +++ b/scripts/i38-help.sh @@ -15,9 +15,11 @@ configPath="$(readlink -f "$0")" configPath="${configPath%/*/*}" if [[ -f "${configPath}/config" ]]; then + # shellcheck disable=SC2016 mod="$(grep 'set $mod ' "${configPath}/config" | cut -d ' ' -f3)" mod="${mod//Mod1/Alt}" mod="${mod//Mod4/Super}" + # shellcheck disable=SC2016 mapfile helpText < <(sed -e '/set \($mod\|mod\)/d' \ -e '/set $ws/d' \ -e 's/bindsym/Key:/g' \ @@ -31,10 +33,10 @@ else exit 1 fi for i in "${!helpText[@]}" ; do - helpText[$i]="${helpText[$i]//${configPath}\/scripts\//}" - helpText[$i]="${helpText[$i]/.sh/}" - helpText[$i]="${helpText[$i]/, exec announce*/$'\n'}" - helpText[$i]="${helpText[$i]/, exec spd-say*/$'\n'}" + helpText[i]="${helpText[i]//${configPath}\/scripts\//}" + helpText[i]="${helpText[i]/.sh/}" + helpText[i]="${helpText[i]/, exec announce*/$'\n'}" + helpText[i]="${helpText[i]/, exec spd-say*/$'\n'}" done helpText+=("End of text. Please press Control+Home to jump to the beginning of this document.") echo -e "${helpText[@]}" | yad --text-info --show-cursor --title "I38 help" --button "Close:0" --listen diff --git a/scripts/launch_remind.sh b/scripts/launch_remind.sh index 9f9c006..292b5e3 100755 --- a/scripts/launch_remind.sh +++ b/scripts/launch_remind.sh @@ -12,4 +12,4 @@ pgrep remind > /dev/null 2>&1 && exit 0 -command remind -z '-k:${HOME}/.config/i3/scripts/reminder.sh %s &' ${HOME}/.reminders < /dev/null > /dev/null 2>&1 & +command remind -z "-k:${HOME}/.config/i3/scripts/reminder.sh %s &" "${HOME}/.reminders" < /dev/null > /dev/null 2>&1 & diff --git a/scripts/music_controler.sh b/scripts/music_controler.sh index 7bd60da..7b595cb 100755 --- a/scripts/music_controler.sh +++ b/scripts/music_controler.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This file is part of I38. @@ -12,7 +12,7 @@ run_command() { - playerctl -p '%any,chromium,firefox' $1 + playerctl -p '%any,chromium,firefox' "$1" sleep 0.25 } diff --git a/scripts/mute-unmute.sh b/scripts/mute-unmute.sh index 7e2db35..cfe1f39 100755 --- a/scripts/mute-unmute.sh +++ b/scripts/mute-unmute.sh @@ -11,7 +11,7 @@ # You should have received a copy of the GNU General Public License along with I38. If not, see . -if [ $(pamixer --get-mute) = false ]; then +if [ "$(pamixer --get-mute)" = false ]; then spd-say -P important -Cw 'Muting!' pamixer -t else diff --git a/scripts/run_dialog.sh b/scripts/run_dialog.sh index 1d38bdc..604e29c 100755 --- a/scripts/run_dialog.sh +++ b/scripts/run_dialog.sh @@ -12,12 +12,12 @@ write_history(){ -oldHistory="$(grep -v "$txt" "${historyPath}/.history" | head -n 49)" -echo -e "$txt\n$oldHistory" | sed 's/^$//g' > "${historyPath}/.history" +oldHistory="$(grep -Fvx -- "$txt" "${historyPath}/.history" | head -n 49)" +printf '%s\n%s\n' "$txt" "$oldHistory" | sed 's/^$//g' > "${historyPath}/.history" } -historyPath="$(readlink -f $0)" +historyPath="$(readlink -f "$0")" historyPath="${historyPath%/*}" if ! [[ -d "$historyPath" ]]; then mkdir -p "$historyPath" @@ -32,12 +32,12 @@ if [[ -z "$txt" ]]; then exit 0 fi if [[ "$txt" =~ ^ftp://|^http://|^https://|^www.* ]]; then - xdg-open $txt + xdg-open "$txt" write_history exit 0 fi if [[ "$txt" =~ ^mailto://.* ]]; then - xdg-email $txt + xdg-email "$txt" write_history exit 0 fi @@ -47,9 +47,9 @@ if [[ "$txt" =~ ^man://.* ]]; then exit 0 fi if command -v "$(echo "$txt" | cut -d " " -f1)" &> /dev/null ; then - eval $txt& + eval "$txt" & else - xdg-open $txt& + xdg-open "$txt" & fi write_history exit 0 diff --git a/scripts/slideshow_record_toggle.sh b/scripts/slideshow_record_toggle.sh index f9d4fdf..6c5a9f7 100755 --- a/scripts/slideshow_record_toggle.sh +++ b/scripts/slideshow_record_toggle.sh @@ -7,7 +7,6 @@ lockDir="/tmp/i38SlideshowRecord.lock" audioPrefix="/tmp/i38SlideshowRecord" videosDir="${HOME}/Videos" progressTitle="I38" -audioServer="" defaultSink="" sourceMonitor="" micSource="" @@ -67,11 +66,7 @@ verify_pulse_monitor() { fi serverName="$(pactl info 2>/dev/null | awk -F': ' '/Server Name/ {print $2; exit}')" - if [[ "$serverName" =~ [Pp]ipe[Ww]ire ]]; then - audioServer="pipewire" - elif [[ "$serverName" =~ [Pp]ulse[Aa]udio ]]; then - audioServer="pulseaudio" - else + if [[ ! "$serverName" =~ [Pp]ipe[Ww]ire ]] && [[ ! "$serverName" =~ [Pp]ulse[Aa]udio ]]; then show_error_dialog "Unsupported audio server: ${serverName:-unknown}" exit 1 fi