#!/usr/bin/env bash # This file is part of I38. # I38 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, # either version 3 of the License, or (at your option) any later version. # I38 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # PURPOSE. See the GNU General Public License for more details. # You should have received a copy of the GNU General Public License along with I38. If not, see . # This script is a modified version of i3-keyboard-layout. # Originally Copyright (c) 2018 Sergio Gil. # https://github.com/porras/i3-keyboard-layout # The original work was released under the MIT license. set -e # Detect if we're on Wayland or X11 if [[ -n "${WAYLAND_DISPLAY}" ]]; then usingWayland=true else usingWayland=false fi get_kbdlayout() { if [[ "$usingWayland" == "true" ]]; then # Sway: Get keyboard layout from input devices # This gets the xkb_active_layout_name from the first keyboard layout=$(swaymsg -t get_inputs | jq -r '.[] | select(.type=="keyboard") | .xkb_active_layout_name' | head -n 1) echo "$layout" else # i3: Use setxkbmap layout=$(setxkbmap -query | grep -oP 'layout:\s*\K([\w,]+)') variant=$(setxkbmap -query | grep -oP 'variant:\s*\K(\w+)') echo "$layout" "$variant" fi } set_kbdlayout() { eval "array=($1)" if [[ "$usingWayland" == "true" ]]; then # Sway: Switch to next keyboard layout # Sway cycles through layouts configured in the config, so we just trigger next swaymsg input type:keyboard xkb_switch_layout next && spd-say -P important -Cw "${array[@]}" else # i3: Use setxkbmap setxkbmap "${array[@]}" && spd-say -P important -Cw "${array[@]}" fi } cycle() { if [[ "$usingWayland" == "true" ]]; then # Sway: Just switch to next layout (Sway handles cycling internally) swaymsg input type:keyboard xkb_switch_layout next currentLayout=$(get_kbdlayout) spd-say -P important -Cw "$currentLayout" else # i3: Cycle through provided layouts currentLayout=$(get_kbdlayout | xargs) layouts=("$@" "$1") # add the first one at the end so that it cycles index=0 while [ "${layouts[$index]}" != "$currentLayout" ] && [ $index -lt "${#layouts[@]}" ]; do index=$((index + 1)); done nextIndex=$((index + 1)) nextLayout=${layouts[$nextIndex]} set_kbdlayout "$nextLayout" fi } subcommand="$1" shift || exit 1 case $subcommand in "get") echo -n "$(get_kbdlayout)" ;; "cycle") cycle "$@" ;; esac exit 0