diff --git a/hosts/writter-deck/cage-xkb-state.patch b/hosts/writter-deck/cage-xkb-state.patch new file mode 100644 index 0000000..826abce --- /dev/null +++ b/hosts/writter-deck/cage-xkb-state.patch @@ -0,0 +1,52 @@ +# Cage intentionally has no IPC API, so status-line clients cannot query its +# active XKB group. When CAGE_XKB_STATE_FILE is set, keep that file synchronized +# with the zero-based effective layout index. +--- a/seat.c ++++ b/seat.c +@@ -12,6 +12,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -245,8 +246,29 @@ + } + + static void ++write_xkb_layout_state(struct wlr_keyboard *keyboard) ++{ ++ const char *path = getenv("CAGE_XKB_STATE_FILE"); ++ if (path == NULL || path[0] == '\0' || keyboard->xkb_state == NULL) { ++ return; ++ } ++ ++ FILE *state_file = fopen(path, "w"); ++ if (state_file == NULL) { ++ return; ++ } ++ ++ xkb_layout_index_t layout = ++ xkb_state_serialize_layout(keyboard->xkb_state, XKB_STATE_LAYOUT_EFFECTIVE); ++ fprintf(state_file, "%u\n", (unsigned int)layout); ++ fclose(state_file); ++} ++ ++static void + handle_modifier_event(struct wlr_keyboard *keyboard, struct cg_seat *seat) + { ++ write_xkb_layout_state(keyboard); ++ + wlr_seat_set_keyboard(seat->seat, keyboard); + wlr_seat_keyboard_notify_modifiers(seat->seat, &keyboard->modifiers); + +@@ -371,6 +393,8 @@ + wl_signal_add(&cg_group->wlr_group->keyboard.events.modifiers, &cg_group->modifiers); + cg_group->modifiers.notify = handle_keyboard_group_modifiers; + ++ write_xkb_layout_state(&cg_group->wlr_group->keyboard); ++ + return; + + cleanup: diff --git a/hosts/writter-deck/home.nix b/hosts/writter-deck/home.nix index 333de8d..60cebec 100644 --- a/hosts/writter-deck/home.nix +++ b/hosts/writter-deck/home.nix @@ -8,12 +8,39 @@ let mainFont = "Berkeley Mono Nerd Font Mono"; fontSize = 14; + + # Cage has no IPC for querying its active XKB group. This deck-only build + # writes that group to CAGE_XKB_STATE_FILE for the tmux indicator below. + cageWithLayoutState = pkgs.cage.overrideAttrs (oldAttrs: { + patches = (oldAttrs.patches or [ ]) ++ [ ./cage-xkb-state.patch ]; + }); + + keyboardLayout = pkgs.writeShellApplication { + name = "keyboard-layout"; + runtimeInputs = [ pkgs.coreutils ]; + text = '' + runtime_dir="''${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" + state_file="''${CAGE_XKB_STATE_FILE:-$runtime_dir/writter-deck-keyboard-layout}" + layout=0 + + if [[ -r "$state_file" ]]; then + IFS= read -r layout < "$state_file" || true + fi + + case "$layout" in + 0) printf 'US' ;; + 1) printf 'PT' ;; + *) printf '?' ;; + esac + ''; + }; in { imports = [ ../../modules/home-manager/oh-my-posh ../../modules/home-manager/zshrc ../../modules/home-manager/bat + ../../modules/home-manager/cedilla ../../modules/home-manager/opencode ../../modules/home-manager/nvim ../../modules/home-manager/pi @@ -40,6 +67,18 @@ in }; tmux = { enable = true; + extraConfig = '' + # Cage does not expose the XKB group through Wayland. The deck-only + # Cage patch updates the state file consumed by this status segment. + set -g status-interval 1 + set -ag status-right "#[fg=#89b4fa] KBD:#(${keyboardLayout}/bin/keyboard-layout)" + ''; + }; + cedilla = { + enable = true; + # Foot/libxkbcommon handles ~/.XCompose directly; the deck has no NixOS + # fcitx5 service at /run/current-system/sw. + startFcitx5 = false; }; oh-my-posh.enable = true; pi.enable = true; @@ -50,7 +89,8 @@ in }; home.packages = with pkgs; [ - cage + cageWithLayoutState + keyboardLayout foot wlr-randr git @@ -134,7 +174,12 @@ in export CAGE_RUNNING=1 export WLR_RENDERER=pixman export XDG_RUNTIME_DIR=''${XDG_RUNTIME_DIR:-/run/user/$(id -u)} - exec cage -- foot + export XKB_DEFAULT_LAYOUT="us,us" + export XKB_DEFAULT_VARIANT=",intl" + export XKB_DEFAULT_OPTIONS="grp:alt_shift_toggle" + export CAGE_XKB_STATE_FILE="$XDG_RUNTIME_DIR/writter-deck-keyboard-layout" + rm -f "$CAGE_XKB_STATE_FILE" + exec ${cageWithLayoutState}/bin/cage -- ${pkgs.foot}/bin/foot fi ''; }; diff --git a/modules/home-manager/cedilla/default.nix b/modules/home-manager/cedilla/default.nix index 783cc12..03bf34f 100644 --- a/modules/home-manager/cedilla/default.nix +++ b/modules/home-manager/cedilla/default.nix @@ -1,8 +1,16 @@ { lib, config, ... }: { + options.custom.cedilla = { + enable = lib.mkEnableOption "enable cedilla - apply Compose configuration for cedilla"; - options.custom = { - cedilla.enable = lib.mkEnableOption "enable cedilla - apply Compose configuration for cedilla"; + startFcitx5 = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Start the NixOS fcitx5 user service. Disable this when only the Compose + rules are needed, for example on a non-NixOS Wayland host. + ''; + }; }; config = lib.mkIf config.custom.cedilla.enable { @@ -13,7 +21,7 @@ : "Ç" Ccedilla ''; - systemd.user.services.fcitx5 = { + systemd.user.services.fcitx5 = lib.mkIf config.custom.cedilla.startFcitx5 { Unit = { Description = "Fcitx5 input method"; PartOf = [ "graphical-session.target" ];