Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions bin/omarchy-brightness-keyboard-auto
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
# Inverse of display auto-brightness: dark rooms need the keys lit, bright
# rooms do not. Manual Shift+F1/F2 (or any other write to the LED) pauses
# auto until ambient light moves enough that the old choice no longer fits.
# A write while locked, while the lid is closed, or across a gap long enough
# to be suspend is not a manual choice.

set -euo pipefail

Expand Down Expand Up @@ -143,6 +145,21 @@ max=$(<"$kbd_path/max_brightness")
last_set=""
paused=0
pause_lux=0
last_tick_at=""

# Suspend freezes this process, so the next poll is late. A brightness-key
# change lands between normal polls. Forget a manual pause after a late poll
# so a controller that woke at 0 is driven from the sensor again.
note_tick_time() {
local now
now=$(date +%s) || return 0
[[ $now =~ ^[0-9]+$ ]] || return 0
if [[ -n $last_tick_at ]] && (( now - last_tick_at > POLL_SECONDS * 3 )); then
last_set=""
paused=0
fi
last_tick_at=$now
}

session_locked() {
omarchy-hyprland-session-locked >/dev/null 2>&1
Expand Down Expand Up @@ -183,9 +200,13 @@ apply_percent() {
tick() {
local lux current delta threshold

note_tick_time

lux=$(read_lux) || return 0

if session_locked || lid_closed; then
last_set=""
paused=0
return 0
fi

Expand Down
2 changes: 1 addition & 1 deletion manual/34-keyboard-mouse-trackpad.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ The Mac-specific brightness and capture combinations are listed in

### Keyboard backlight

Laptops with a keyboard backlight LED and an ambient light sensor light the keys in the dark and dim them as the room brightens. `Shift + Brightness Up/Down` still sets the level by hand; automatic control resumes when the ambient light changes enough that the old choice no longer fits. Automatic control pauses while the screen is locked or the lid is closed.
Laptops with a keyboard backlight LED and an ambient light sensor light the keys in the dark and dim them as the room brightens. `Shift + Brightness Up/Down` still sets the level by hand; automatic control resumes when the ambient light changes enough that the old choice no longer fits. Automatic control pauses while the screen is locked or the lid is closed, and a level left behind by that pause, or by suspend, is not kept as a manual setting.

Apple trackpads default to natural scrolling, physical clicks instead of
tap-to-click, two-finger right-click, and a `0.4` scroll factor. Override any
Expand Down
161 changes: 161 additions & 0 deletions test/shell.d/brightness-keyboard-auto-resume-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#!/bin/bash

set -euo pipefail

source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"

auto="$ROOT/bin/omarchy-brightness-keyboard-auto"
work=$(mktemp -d)
stop_loop() {
if [[ -n ${loop_pid:-} ]]; then
kill "$loop_pid" 2>/dev/null || true
wait "$loop_pid" 2>/dev/null || true
loop_pid=""
fi
}

trap 'stop_loop; rm -rf "$work"' EXIT

mkdir -p "$work/bin" "$work/iio/iio:device0" "$work/leds/kbd_backlight"
printf '0\n' >"$work/clock"
printf '0\n' >"$work/release"
printf '0\n' >"$work/sleeps"
printf '0\n' >"$work/lock"
printf '0\n' >"$work/lid"
printf 'aop-sensors-als\n' >"$work/iio/iio:device0/name"
printf '0\n' >"$work/iio/iio:device0/in_illuminance_input"
printf '255\n' >"$work/leds/kbd_backlight/max_brightness"
printf '0\n' >"$work/leds/kbd_backlight/brightness"

cat >"$work/bin/date" <<'EOF'
#!/bin/bash
[[ $1 == "+%s" ]] || exit 1
tr -d '[:space:]' <"$OMARCHY_TEST_CLOCK"
EOF

cat >"$work/bin/sleep" <<'EOF'
#!/bin/bash
n=$(tr -d '[:space:]' <"$OMARCHY_TEST_SLEEPS")
printf '%s\n' "$((n + 1))" >"$OMARCHY_TEST_SLEEPS"
while [[ -f $OMARCHY_TEST_RELEASE ]] && [[ $(tr -d '[:space:]' <"$OMARCHY_TEST_RELEASE") -le $n ]]; do
/bin/sleep 0.02
done
[[ -f $OMARCHY_TEST_CLOCK ]] || exit 0
clock=$(tr -d '[:space:]' <"$OMARCHY_TEST_CLOCK")
printf '%s\n' "$((clock + ${1%.*}))" >"$OMARCHY_TEST_CLOCK"
EOF

cat >"$work/bin/brightnessctl" <<'EOF'
#!/bin/bash
device=""
while (($#)); do
case "$1" in
-d) device=$2; shift 2 ;;
get)
tr -d '[:space:]' <"$OMARCHY_TEST_BRIGHTNESS"
exit 0
;;
set)
printf '%s\n' "$2" >"$OMARCHY_TEST_BRIGHTNESS"
exit 0
;;
*) exit 1 ;;
esac
done
exit 1
EOF

cat >"$work/bin/omarchy-hyprland-session-locked" <<'EOF'
#!/bin/bash
[[ $(tr -d '[:space:]' <"$OMARCHY_TEST_LOCK") == 1 ]]
EOF

cat >"$work/bin/omarchy-hw-laptop-closed" <<'EOF'
#!/bin/bash
[[ $(tr -d '[:space:]' <"$OMARCHY_TEST_LID") == 1 ]]
EOF

chmod +x "$work/bin/"*

export OMARCHY_TEST_CLOCK="$work/clock"
export OMARCHY_TEST_RELEASE="$work/release"
export OMARCHY_TEST_SLEEPS="$work/sleeps"
export OMARCHY_TEST_LOCK="$work/lock"
export OMARCHY_TEST_LID="$work/lid"
export OMARCHY_TEST_BRIGHTNESS="$work/leds/kbd_backlight/brightness"
export OMARCHY_IIO_DEVICES_DIR="$work/iio"
export OMARCHY_LEDS_DIR="$work/leds"
export PATH="$work/bin:$PATH"

brightness() {
tr -d '[:space:]' <"$OMARCHY_TEST_BRIGHTNESS"
}

wait_for_sleeps() {
local want=$1
local i
for ((i = 0; i < 200; i++)); do
[[ $(tr -d '[:space:]' <"$OMARCHY_TEST_SLEEPS") -ge $want ]] && return 0
/bin/sleep 0.02
done
fail "keyboard auto loop did not reach sleep $want" "sleeps=$(<"$OMARCHY_TEST_SLEEPS") brightness=$(brightness)"
}

release_sleep() {
local n
n=$(tr -d '[:space:]' <"$OMARCHY_TEST_RELEASE")
printf '%s\n' "$((n + 1))" >"$OMARCHY_TEST_RELEASE"
}

start_loop() {
"$auto" &
loop_pid=$!
wait_for_sleeps 1
[[ $(brightness) == 255 ]] || fail "pitch dark lights the keys on the first poll" "got $(brightness)"
}

start_loop
pass "pitch dark lights the keys on the first poll"

printf '0\n' >"$OMARCHY_TEST_BRIGHTNESS"
release_sleep
wait_for_sleeps 2
[[ $(brightness) == 0 ]] || fail "a brightness-key change in steady dark stays put" "got $(brightness)"
pass "a brightness-key change in steady dark stays put"

kill "$loop_pid" 2>/dev/null || true
wait "$loop_pid" 2>/dev/null || true
loop_pid=""

printf '0\n' >"$work/clock"
printf '0\n' >"$work/release"
printf '0\n' >"$work/sleeps"
printf '0\n' >"$OMARCHY_TEST_BRIGHTNESS"
start_loop

printf '0\n' >"$OMARCHY_TEST_BRIGHTNESS"
printf '1060\n' >"$work/clock"
release_sleep
wait_for_sleeps 2
[[ $(brightness) == 255 ]] || fail "waking from suspend in the dark lights the keys again" "got $(brightness)"
pass "waking from suspend in the dark lights the keys again"

kill "$loop_pid" 2>/dev/null || true
wait "$loop_pid" 2>/dev/null || true
loop_pid=""

printf '0\n' >"$work/clock"
printf '0\n' >"$work/release"
printf '0\n' >"$work/sleeps"
printf '0\n' >"$OMARCHY_TEST_BRIGHTNESS"
start_loop

printf '1\n' >"$work/lock"
release_sleep
wait_for_sleeps 2
printf '0\n' >"$OMARCHY_TEST_BRIGHTNESS"
printf '0\n' >"$work/lock"
release_sleep
wait_for_sleeps 3
[[ $(brightness) == 255 ]] || fail "unlocking in the dark lights the keys again" "got $(brightness)"
pass "unlocking in the dark lights the keys again"
Loading