#!/bin/sh set -euo pipefail get_layout_display_name() { idx="$1" dbus-send --session --print-reply --dest=org.kde.keyboard /Layouts org.kde.KeyboardLayouts.getLayoutsList 2>/dev/null \ | grep 'string "' \ | sed 's/.*string "\([^"]*\)".*/\1/' \ | awk -v idx="$idx" 'NR%3==0 { if (c++ == idx) { print; exit } }' } get_layout_index() { dbus-send --session --print-reply --dest=org.kde.keyboard /Layouts org.kde.KeyboardLayouts.getLayout 2>/dev/null \ | awk '/uint32/ { print $2; exit }' } LAST_LAYOUT="" apply_layout() { idx="$1" CURRENT_LAYOUT=$(get_layout_display_name "$idx") if test "$LAST_LAYOUT" = "$CURRENT_LAYOUT"; then return 0 elif test "$CURRENT_LAYOUT" = "English (Colemak)"; then echo "Setting layout to colemak" setxkbmap us colemak elif test "$CURRENT_LAYOUT" = "Portuguese (Brazil)"; then echo "Setting layout to br" setxkbmap br fi LAST_LAYOUT="$CURRENT_LAYOUT" } update_layout() { INDEX=$(get_layout_index) apply_layout "$INDEX" } while ! get_layout_index; do sleep 1s done update_layout dbus-monitor --session \ "type='signal',interface='org.kde.KeyboardLayouts',member='layoutChanged',path='/Layouts'" \ | while read -r line; do update_layout done