Support for a fork of i3lock called i38lock added. In stormus, install i38lock. To build from source, https://git.stormux.org/storm/i38lock This is more secure than the pin implementation but it remains available.

This commit is contained in:
Storm Dragon
2026-06-02 22:15:03 -04:00
parent e5bd73213d
commit 5fd51c61a3
4 changed files with 173 additions and 19 deletions
+6 -4
View File
@@ -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 a screen lock method 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.
@@ -234,11 +234,13 @@ If required dependencies are installed, you can use OCR to read text from images
### 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 a screen lock during setup, press `Control` + `Alt` + `Tab` to enter panel mode, then press `Control` + `@MODKEY@` + `l` to lock the screen.
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.
I38 can configure either the legacy I38 PIN lock or I38Lock. The PIN lock is a privacy screen only, not a secure system lock. I38Lock is a true PAM-backed locker and unlocks with your account password. On Stormux, install I38Lock from the repository. The I38Lock repository is https://git.stormux.org/storm/i38lock. I38Lock requires Cthulhu or Orca 50 or newer for screen-reader feedback.
If you chose to lock the screen when I38 starts, I38 launches the privacy screen shortly after i3 startup. Startup lock is meant to prevent casual snooping, not to secure the system against a determined user.
I38 enables only one lock method at a time. When a screen lock method 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.
If you chose to lock the screen when I38 starts, I38 launches the configured lock shortly after i3 startup. With the PIN lock, startup lock is meant to prevent casual snooping, not to secure the system against a determined user.
### Sound Effects
+3
View File
@@ -46,6 +46,7 @@ Optional features use these packages when installed:
- 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
@@ -72,6 +73,8 @@ Ratpoison mode is now enabled by default for better accessibility and ease of us
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.
+150 -13
View File
@@ -236,6 +236,7 @@ select_screenlock_autolock_seconds() {
--backtitle "Use the arrow keys to choose how long I38 should wait before locking the screen automatically." \
--clear \
--default-item "0" \
--no-tags \
--menu "Autolock screen after:" 0 0 0 \
"0" "Never" \
"180" "3 minutes" \
@@ -250,6 +251,101 @@ select_screenlock_autolock_seconds() {
echo "$selectedAutolock"
}
select_screenlock_method() {
local defaultMethod="$1"
local -a lockOptions=(
"pin" "I38 PIN privacy screen"
"none" "Do not configure screen lock"
)
if i38lock_is_supported; then
lockOptions=(
"i38lock" "I38Lock secure PAM locker"
"${lockOptions[@]}"
)
fi
if [[ "$defaultMethod" != "pin" && "$defaultMethod" != "i38lock" && "$defaultMethod" != "none" ]]; then
if i38lock_is_supported; then
defaultMethod="i38lock"
else
defaultMethod="pin"
fi
fi
dialog --title "I38" \
--backtitle "Use the arrow keys to choose the screen lock I38 should configure." \
--clear \
--default-item "$defaultMethod" \
--menu "Screen lock method:" 0 0 0 \
"${lockOptions[@]}" \
--stdout
}
screen_reader_name() {
if [[ "$screenReader" == "none" || -z "$screenReader" ]]; then
echo "none"
return
fi
echo "${screenReader##*/}"
}
orca_major_version() {
local orcaPath="$1"
local versionLine
versionLine="$("$orcaPath" --version 2>&1 | awk '/^Orca version / { split($3, parts, "."); print parts[1]; exit }')"
if [[ "$versionLine" =~ ^[0-9]+$ ]]; then
echo "$versionLine"
fi
}
orca_is_i38lock_supported() {
local orcaPath="$1"
local majorVersion
if [[ -z "$orcaPath" ]] || ! command -v "$orcaPath" &> /dev/null; then
return 1
fi
majorVersion="$(orca_major_version "$orcaPath")"
[[ "$majorVersion" =~ ^[0-9]+$ ]] && [[ "$majorVersion" -ge 50 ]]
}
i38lock_is_supported() {
local readerName orcaPath
if ! command -v i38lock &> /dev/null; then
return 1
fi
readerName="$(screen_reader_name)"
if [[ "$readerName" == "cthulhu" ]] || command -v cthulhu &> /dev/null; then
return 0
fi
if [[ "$readerName" == "orca" ]]; then
orcaPath="$screenReader"
else
orcaPath="$(command -v orca 2> /dev/null || true)"
fi
orca_is_i38lock_supported "$orcaPath"
}
screenlock_is_configured() {
[[ "$screenlockMethod" == "pin" || "$screenlockMethod" == "i38lock" ]]
}
screenlock_command() {
if [[ "$screenlockMethod" == "i38lock" ]]; then
command -v i38lock
else
printf '%s/scripts/screenlock.sh\n' "$i3Path"
fi
}
update_personal_customizations() {
local customizationsPath="${i3Path}/customizations"
local startMarker="# I38 Personal mode start"
@@ -362,6 +458,7 @@ brlapi="$brlapi"
sounds="$sounds"
# Screen lock
screenlockMethod="${screenlockMethod:-none}"
screenlockPinHash="$screenlockPinHash"
screenlockAutolockSeconds="${screenlockAutolockSeconds:-0}"
screenlockOnStartup="${screenlockOnStartup:-1}"
@@ -486,7 +583,7 @@ apply_screenlock_pin() {
local pinFile="${i3Path}/.screenpin"
local pinValue="$screenlockPinHash"
if [[ -z "$pinValue" ]]; then
if [[ "$screenlockMethod" != "pin" ]] || [[ -z "$pinValue" ]]; then
rm -f "$pinFile"
return 0
fi
@@ -526,6 +623,7 @@ update_scripts() {
write_desktop_shortcuts_template
if [[ -n "$existingPinHash" ]]; then
screenlockPinHash="$existingPinHash"
screenlockMethod="${screenlockMethod:-pin}"
apply_screenlock_pin
fi
exit 0
@@ -894,13 +992,42 @@ if [[ -z "$screenlockPinHash" ]]; then
read -r screenlockPinHash < "$screenlockPinFile"
fi
fi
if [[ -z "$screenlockPinHash" ]]; then
if yesno "Do you want to enable the I38 screen lock (privacy screen only, not a secure system lock)?"; then
screenlockNeedsSelection=0
if [[ -z "${screenlockMethod+x}" ]]; then
screenlockNeedsSelection=1
fi
if [[ -z "$screenlockMethod" || "$screenlockMethod" == "none" ]]; then
if [[ -n "$screenlockPinHash" ]]; then
screenlockMethod="pin"
else
screenlockMethod="none"
fi
fi
if [[ "$screenlockMethod" != "pin" && "$screenlockMethod" != "i38lock" && "$screenlockMethod" != "none" ]]; then
screenlockMethod="none"
fi
if [[ "$screenlockMethod" == "i38lock" ]] && ! i38lock_is_supported; then
dialog --title "I38" --msgbox "I38Lock is not available with the current screen reader setup. I38Lock requires the i38lock command and either Cthulhu or Orca 50 or newer. Please choose another screen lock method." -1 -1
screenlockMethod="none"
screenlockNeedsSelection=1
configChanged=1
fi
if [[ $screenlockNeedsSelection -eq 1 ]]; then
selectedScreenlockMethod="$(select_screenlock_method "$screenlockMethod")"
dialogResult=$?
if [[ $dialogResult -eq 0 ]]; then
screenlockMethod="$selectedScreenlockMethod"
configChanged=1
fi
fi
if [[ "$screenlockMethod" == "pin" ]]; then
if [[ -z "$screenlockPinHash" ]]; then
while : ; do
screenlockPin="$(dialog --title "I38" --clear --passwordbox "Enter a 4-digit PIN to enable screen lock." -1 -1 --stdout)"
dialogResult=$?
if [[ $dialogResult -ne 0 ]]; then
screenlockPinHash=""
screenlockMethod="none"
break
fi
if [[ ! "$screenlockPin" =~ ^[0-9]{4}$ ]]; then
@@ -924,11 +1051,13 @@ if [[ -z "$screenlockPinHash" ]]; then
break
done
fi
else
screenlockPinHash=""
fi
if [[ -n "$screenlockPinHash" ]]; then
if screenlock_is_configured; then
if [[ -z "${screenlockOnStartup+x}" ]]; then
configChanged=1
if yesno "Lock the screen automatically when I38 starts? This is useful for privacy, but if your screen reader or display setup fails you may need to enter the PIN without feedback."; then
if yesno "Lock the screen automatically when I38 starts? If your screen reader or display setup fails, you may need to unlock without feedback."; then
screenlockOnStartup=0
else
screenlockOnStartup=1
@@ -1172,7 +1301,7 @@ bindsym $mod+Shift+BackSpace mode "default"
EOF
if [[ -n "$screenlockPinHash" ]]; then
if [[ "$screenlockMethod" == "pin" ]]; then
cat << EOF >> "${i3Path}/config"
# Screen lock mode (managed by screenlock.sh)
mode "screenlock" {
@@ -1237,9 +1366,13 @@ fi)
# Power options bound to p
bindsym p exec --no-startup-id ${i3Path}/scripts/power.sh, mode "default"
$(if [[ -n "$screenlockPinHash" ]]; then
echo " # Screen lock (privacy screen only)"
echo " bindsym Control+\$mod+l exec --no-startup-id ${i3Path}/scripts/screenlock.sh, mode \"default\""
$(if screenlock_is_configured; then
if [[ "$screenlockMethod" == "i38lock" ]]; then
echo " # Screen lock (I38Lock secure PAM locker)"
else
echo " # Screen lock (I38 PIN privacy screen)"
fi
echo " bindsym Control+\$mod+l exec --no-startup-id $(screenlock_command), mode \"default\""
echo " "
fi)
@@ -1387,11 +1520,15 @@ fi
if [[ $batteryAlert -eq 0 ]]; then
echo "exec_always --no-startup-id ${i3Path}/scripts/battery_alert.sh"
fi
if [[ -n "$screenlockPinHash" ]] && [[ "${screenlockAutolockSeconds:-0}" -gt 0 ]] && command -v xprintidle &> /dev/null; then
echo "exec_always --no-startup-id ${i3Path}/scripts/screenlock_autolock.sh ${screenlockAutolockSeconds}"
if screenlock_is_configured && [[ "${screenlockAutolockSeconds:-0}" -gt 0 ]] && command -v xprintidle &> /dev/null; then
if [[ "$screenlockMethod" == "i38lock" ]]; then
echo "exec_always --no-startup-id ${i3Path}/scripts/screenlock_autolock.sh ${screenlockAutolockSeconds} $(screenlock_command) --nofork"
else
echo "exec_always --no-startup-id ${i3Path}/scripts/screenlock_autolock.sh ${screenlockAutolockSeconds} $(screenlock_command)"
fi
fi
if [[ -n "$screenlockPinHash" ]] && [[ "${screenlockOnStartup:-1}" -eq 0 ]]; then
echo "exec --no-startup-id bash -c 'sleep 2; ${i3Path}/scripts/screenlock.sh'"
if screenlock_is_configured && [[ "${screenlockOnStartup:-1}" -eq 0 ]]; then
echo "exec --no-startup-id bash -c 'sleep 2; $(screenlock_command)'"
fi
# WayTray system tray daemon
if command -v waytray-daemon &> /dev/null ; then
+14 -2
View File
@@ -16,6 +16,11 @@ scriptDir="${scriptPath%/*}"
runtimeDir="${XDG_RUNTIME_DIR:-/tmp}"
lockDir="${runtimeDir}/i38-screenlock-autolock"
pollSeconds=5
lockCommand=("${@:2}")
if [[ ${#lockCommand[@]} -eq 0 ]]; then
lockCommand=("${scriptDir}/screenlock.sh")
fi
notify_autolock_disabled() {
local message="$1"
@@ -56,7 +61,14 @@ focused_window_is_fullscreen() {
}
screenlock_is_running() {
pgrep -f "${scriptDir}/screenlock.sh" &> /dev/null
case "${lockCommand[0]##*/}" in
i38lock)
pgrep -x i38lock &> /dev/null
;;
*)
pgrep -f "${lockCommand[0]}" &> /dev/null
;;
esac
}
cleanup() {
@@ -103,7 +115,7 @@ while : ; do
idleMilliseconds="$(xprintidle 2> /dev/null || echo 0)"
if [[ "$idleMilliseconds" =~ ^[0-9]+$ ]] && [[ "$idleMilliseconds" -ge $((autolockSeconds * 1000)) ]]; then
if ! screenlock_is_running && ! video_is_playing && ! focused_window_is_fullscreen; then
"${scriptDir}/screenlock.sh"
"${lockCommand[@]}"
sleep "$pollSeconds"
fi
fi