u/_HolyHell

▲ 8 r/niri

Please help me set up keyboard layout switching

Hi, everyone

I actively use three keyboard layouts and have gotten used to the behavior in GNOME DE—switching between the last two by quickly holding down Mod + Space, and cycling through them by holding down Mod and slowly tapping Space.

By default, the layout cycles as follows: 1 -> 2 -> 3 -> 1 ...

I can't get the perfect result using a custom keyboard layout switching script.

Here are my attempts to switch the keyboard layout to the one I'm used to:

{ pkgs, USERNAME, ... }:
let
  #   Tap  (>500ms since last press): toggle between last two used layouts
  #   Hold (<500ms between presses):  cycle through all layouts
  # State file: "<timestamp_ms> <prev_layout_index>"
  switchLayout = pkgs.writeShellScript "niri-switch-layout" ''
    STATE="/tmp/niri-switch-layout-state"
    THRESHOLD=1500

    now=$(date +%s%3N)
    current=$(niri msg keyboard-layouts | awk '/^\s*\*/{print $2}')

    last_time=0
    prev=""
    if [ -f "$STATE" ]; then
      last_time=$(cut -d' ' -f1 "$STATE")
      prev=$(cut -d' ' -f2 "$STATE")
    fi

    elapsed=$((now - last_time))

    if [ "$elapsed" -lt "$THRESHOLD" ]; then
      # Hold mode: cycle to next, keep prev unchanged
      printf '%s %s\n' "$now" "$prev" > "$STATE"
      niri msg action switch-layout next
    else
      # Tap mode: toggle to previous layout
      printf '%s %s\n' "$now" "$current" > "$STATE"
      if [ -z "$prev" ] || [ "$prev" = "$current" ]; then
        niri msg action switch-layout next
      else
        niri msg action switch-layout "$prev"
      fi
    fi
  '';
in
{
  xdg.configFile."niri/config.kdl".text = ''
    binds {
...
        Mod+Space       { spawn-sh "${switchLayout}"; }
...
    }
  '';
}

How do you handle that?

reddit.com
u/_HolyHell — 4 days ago