From ade5b01e06311f9fba3038955d82bdb8a49000d5 Mon Sep 17 00:00:00 2001 From: B Stack Date: Thu, 13 Feb 2020 19:24:24 -0500 Subject: initial commit --- README.md | 30 ++++ src/etc/keyboard-leds-trayicons.conf | 5 + src/usr/bin/keyboard-leds-trayicons.sh | 157 +++++++++++++++++++++ .../icons/hicolor/scalable/status/capslock-off.svg | 4 + .../icons/hicolor/scalable/status/capslock-on.svg | 4 + .../icons/hicolor/scalable/status/numlock-off.svg | 4 + .../icons/hicolor/scalable/status/numlock-on.svg | 4 + 7 files changed, 208 insertions(+) create mode 100644 README.md create mode 100644 src/etc/keyboard-leds-trayicons.conf create mode 100755 src/usr/bin/keyboard-leds-trayicons.sh create mode 100644 src/usr/share/icons/hicolor/scalable/status/capslock-off.svg create mode 100644 src/usr/share/icons/hicolor/scalable/status/capslock-on.svg create mode 100644 src/usr/share/icons/hicolor/scalable/status/numlock-off.svg create mode 100644 src/usr/share/icons/hicolor/scalable/status/numlock-on.svg diff --git a/README.md b/README.md new file mode 100644 index 0000000..b1b727e --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# Readme for keyboard-leds-trayicons + +This tool, written in POSIX shell, places two icons in the notification area (aka system tray), that substitute for the keyboard LEDs for Capslock and Numlock. + +## How to configure +You can set environment variable `KLT_CONF` to point to a config file, which gets loaded in a style similar to dot-sourcing a shell script. Existing environment variables will be preserved. `Keyboard-leds-trayicons` will already load the global values from `/etc/keyboard-leds-trayicons.conf` and from your user settings in `$HOME/.config/keyboard-leds-trayicons.conf`. + +Here is example config file. + + KLT_CAPS_ON_ICON=capslock-on + KLT_CAPS_OFF_ICON=capslock-off + KLT_NUM_ON_ICON=numlock-on + KLT_NUM_OFF_ICON=numlock-off + +As a side effect of using `mktrayicon`, you can use an icon name that follows the [xdg spec](https://www.freedesktop.org/wiki/Specifications/icon-theme-spec/) or you can point to a specific filename. This project includes some simple letter icons in svg format. + +## Project license +[CC-BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) + +## Dependencies +Package manager | packages +--------------- | ------------------------------------------------------------------ +binary name | [mktrayicon](https://gitlab.com/bgstack15/mktrayicon), awk, xset +deb | [mktrayicon](https://build.opensuse.org/package/show/home:bgstack15/mktrayicon), mawk | gawk, x11-xserver-utils +rpm | undefined + +## Credits +Bundled icons are used under license from Icon8. +* little `c`: [https://visualpharm.com/free-icons/c%20letter-595b40b65ba036ed117d1027](https://visualpharm.com/free-icons/c%20letter-595b40b65ba036ed117d1027) +* License for icons: Use for free, but link to [icons8](https://icons8.com/license) diff --git a/src/etc/keyboard-leds-trayicons.conf b/src/etc/keyboard-leds-trayicons.conf new file mode 100644 index 0000000..db9e4ff --- /dev/null +++ b/src/etc/keyboard-leds-trayicons.conf @@ -0,0 +1,5 @@ +KLT_CAPS_ON_ICON=capslock-on +KLT_CAPS_OFF_ICON=capslock-off +KLT_NUM_ON_ICON=numlock-on +KLT_NUM_OFF_ICON=numlock-off +KLT_KILLFILE="/var/run/user/$( id -u )/kill-all-leds-trayicons" diff --git a/src/usr/bin/keyboard-leds-trayicons.sh b/src/usr/bin/keyboard-leds-trayicons.sh new file mode 100755 index 0000000..18ce82a --- /dev/null +++ b/src/usr/bin/keyboard-leds-trayicons.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env sh +# File: keyboard-leds-trayicons.sh +# License: CC-BY-SA 4.0 +# Author: bgstack15 +# Startdate: 2020-02-13 15:30 +# Title: Substitute for Keyboard LED Indicators +# Purpose: For systems that do not show LEDs for capslock and numlock +# History: +# Usage: +# Reference: +# some Internet place that demonstrated how to use xset q +# some Internet place that showed how to convert the decimal to binary with awk +# get_conf comes from framework.sh +# Improve: +# provide way to change status of capslock by clicking the icon? +# Dependencies: +# binaries: mktrayicon, awk, xset + +# little c: https://visualpharm.com/free-icons/c%20letter-595b40b65ba036ed117d1027 +# license for icons: Use for free, but link to [icons8](https://icons8.com/license) + +# CONFIG FILES +test -z "${KLT_GLOBAL_CONF}" && KLT_GLOBAL_CONF=/etc/keyboard-leds-trayicons.conf +test -z "${KLT_USER_CONF}" && KLT_USER_CONF="${HOME}/.config/keyboard-leds-trayicons.conf" +# also accept KLT_CONF + +# FUNCTIONS + +get_conf() { + # Ripped from framework.sh + # call: get_conf "${conffile}" + local _infile="$1" + local _tmpfile1="$( mktemp )" + sed -e 's/^\s*//;s/\s*$//;/^[#$]/d;s/\s*[^\]#.*$//;' "${_infile}" | grep -viE "^$" | while read _line ; + do + local _left="$( echo "${_line}" | cut -d'=' -f1 )" + eval "_thisval=\"\${${_left}}\"" + test -z "${_thisval}" && echo "${_line}" >> "${_tmpfile1}" + done + test -f "${_tmpfile1}" && { . "${_tmpfile1}" 1>/dev/null 2>&1 ; } + /bin/rm -rf "${_tmpfile1}" 1>/dev/null 2>&1 +} + +clean_keyboard_leds_trayicons() { + { test -e "${capslockicon}" && echo "q" > "${capslockicon}" ; } 1>/dev/null 2>&1 & + { test -e "${numlockicon}" && echo "q" > "${numlockicon}" ; } 1>/dev/null 2>&1 & + sleep 1 && rm -f "${capslockicon}" "${numlockicon}" "${KLT_KILLFILE}" +} + +get_led_mask() { + xset q | awk 'function d2b(d,b) {while(d) {b=d%2b;d=int(d/2)}return(b)} /LED/{print d2b($NF)}' +} + +mask_position_on() { + # call: mask_position_on "${LEDS}" "${ledposition}" + ___result="$( printf "%08d" "${1}" | tail -c "${2}" | head -c 1 )" + ___result=$(( 1 - ___result )) + return "${___result}" +} + +is_capslock_on() { + # call: get_led_mask | is_capslock_on && echo "yes" + read ___ico + mask_position_on "${___ico}" "1" +} + +is_numlock_on() { + # call: get_led_mask | is_numlock_on && echo "yes" + read ___ico + mask_position_on "${___ico}" "2" +} + +# LOAD CONFIGS +# order is important! The last one called gets precedence. +# instead of simply dot-sourcing the conf file, pass it to get_conf which only applies new values, so this process's environment is preserved +for thisconf in "${KLT_GLOBAL_CONF}" "${KLT_USER_CONF}" "${KLT_CONF}" ; +do + test -r "${thisconf}" && get_conf "${thisconf}" +done + +# DEFAULTS in case configs did not have these values +test -z "${KLT_CAPS_ON_ICON}" && KLT_CAPS_ON_ICON=capslock-on +test -z "${KLT_CAPS_OFF_ICON}" && KLT_CAPS_OFF_ICON=capslock-off +test -z "${KLT_CAPS_ON_ICON}" && KLT_CAPS_ON_ICON=numlock-on +test -z "${KLT_CAPS_OFF_ICON}" && KLT_CAPS_OFF_ICON=numlock-off +test -z "${KLT_KILLFILE}" && KLT_KILLFILE="/tmp/kill-all-leds-trayicons" + +# INITIALIZATION + +capslockicon="/var/run/user/$( id -u )/${$}.cap.icon" +numlockicon="/var/run/user/$( id -u )/${$}.num.icon" + +test "ON" = "ON" && { + mkfifo "${capslockicon}" + mkfifo "${numlockicon}" + + mktrayicon "${capslockicon}" & + mktrayicon "${numlockicon}" & + + echo "m quit,echo 'q' > ${capslockicon} ; touch "${KLT_KILLFILE}"" > "${capslockicon}" + echo "m quit,echo 'q' > ${numlockicon} ; touch "${KLT_KILLFILE}"" > "${numlockicon}" +} + +caps_status_old=-1 +num_status_old=-1 + +rm -f "${KLT_KILLFILE}" + +trap 'trap "" 2 ; touch "${KLT_KILLFILE}" ' 2 # CTRL-C + +while ! test -e "${KLT_KILLFILE}" 2>/dev/null ; +do + x="$( get_led_mask )" + caps_status_now=0 + num_status_now=0 + echo "${x}" | is_capslock_on && caps_status_now=1 + echo "${x}" | is_numlock_on && num_status_now=1 + + if test "${caps_status_now}" != "${caps_status_old}" ; + then + test -p "${capslockicon}" && case "${caps_status_now}" in + 1) + test -n "${KLT_DEBUG}" && echo "capslock on (icon file ${KLT_CAPS_ON_ICON})" 1>&2 + echo "i ${KLT_CAPS_ON_ICON}" > "${capslockicon}" + echo "t capslock on" > "${capslockicon}" + ;; + 0) + test -n "${KLT_DEBUG}" && echo "capslock off (icon file ${KLT_CAPS_OFF_ICON})" 1>&2 + echo "i ${KLT_CAPS_OFF_ICON}" > "${capslockicon}" + echo "t capslock off" > "${capslockicon}" + ;; + esac + fi + + if test "${num_status_now}" != "${num_status_old}" ; + then + test -p "${numlockicon}" && case "${num_status_now}" in + 1) + test -n "${KLT_DEBUG}" && echo "numlock on (icon file ${KLT_NUM_ON_ICON})" 1>&2 + echo "i ${KLT_NUM_ON_ICON}" > "${numlockicon}" + echo "t numlock on" > "${numlockicon}" + ;; + 0) + test -n "${KLT_DEBUG}" && echo "numlock off (icon file ${KLT_NUM_OFF_ICON})" 1>&2 + echo "i ${KLT_NUM_OFF_ICON}" > "${numlockicon}" + echo "t numlock off" > "${numlockicon}" + ;; + esac + fi + + caps_status_old="${caps_status_now}" + num_status_old="${num_status_now}" + sleep 0.75 +done + +# safety shutoff +clean_keyboard_leds_trayicons diff --git a/src/usr/share/icons/hicolor/scalable/status/capslock-off.svg b/src/usr/share/icons/hicolor/scalable/status/capslock-off.svg new file mode 100644 index 0000000..3d3be8e --- /dev/null +++ b/src/usr/share/icons/hicolor/scalable/status/capslock-off.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/usr/share/icons/hicolor/scalable/status/capslock-on.svg b/src/usr/share/icons/hicolor/scalable/status/capslock-on.svg new file mode 100644 index 0000000..f4db539 --- /dev/null +++ b/src/usr/share/icons/hicolor/scalable/status/capslock-on.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/usr/share/icons/hicolor/scalable/status/numlock-off.svg b/src/usr/share/icons/hicolor/scalable/status/numlock-off.svg new file mode 100644 index 0000000..549e284 --- /dev/null +++ b/src/usr/share/icons/hicolor/scalable/status/numlock-off.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/usr/share/icons/hicolor/scalable/status/numlock-on.svg b/src/usr/share/icons/hicolor/scalable/status/numlock-on.svg new file mode 100644 index 0000000..ef65035 --- /dev/null +++ b/src/usr/share/icons/hicolor/scalable/status/numlock-on.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file -- cgit