diff --git a/config/fcitx5/config b/config/fcitx5/config index 7ef67e6d..b7111d4f 100644 --- a/config/fcitx5/config +++ b/config/fcitx5/config @@ -9,7 +9,9 @@ [Hotkey/DeactivateKeys] 0=Muhenkan +# A lone Shift leaves an engine like Pinyin for Latin input and returns to it. [Hotkey/AltTriggerKeys] +0=Shift_L [Hotkey/EnumerateGroupForwardKeys] diff --git a/default/input-methods/configure.py b/default/input-methods/configure.py index deb6cd6f..e84d63cb 100644 --- a/default/input-methods/configure.py +++ b/default/input-methods/configure.py @@ -108,7 +108,6 @@ def defaults(config_home, fresh=False): stock_lists = { "Hotkey/ActivateKeys": {"0": "Hangul_Hanja"}, "Hotkey/DeactivateKeys": {"0": "Hangul_Romaja"}, - "Hotkey/AltTriggerKeys": {"0": "Shift_L"}, "Hotkey/EnumerateGroupForwardKeys": {"0": "Super+space"}, "Hotkey/EnumerateGroupBackwardKeys": {"0": "Super+Shift+space"}, "TriggerKey": {"0": "Super+grave", "1": "Super+semicolon"}, diff --git a/manual/34-keyboard-mouse-trackpad.md b/manual/34-keyboard-mouse-trackpad.md index 919e47d8..48a2d2ab 100644 --- a/manual/34-keyboard-mouse-trackpad.md +++ b/manual/34-keyboard-mouse-trackpad.md @@ -61,7 +61,7 @@ On Dell XPS laptops with a haptic touchpad, you can also set the click strength Select Japanese, Korean, Chinese (Simplified, Pinyin), or Chinese (Traditional, Zhuyin) when the installer asks for your keyboard. Omarchy configures the keyboard and matching input engine automatically, including during offline first-boot setup. Japanese uses Mozc, Korean uses standard two-set Hangul, Simplified Chinese uses Pinyin, and Traditional Chinese uses Chewing's standard Zhuyin arrangement. Japanese (US keyboard) provides Mozc with a US keyboard layout. -Typing starts in Latin mode. Press `Super + I` to cycle through configured input methods, and `Super + Shift + I` to cycle back. On Japanese keyboards, 全角/半角 toggles input, 変換 turns it on, and 無変換 turns it off. On a Korean keyboard layout, dedicated 한/영 and 한자 keys switch Hangul and convert to Hanja. `Ctrl + Space` stays available for Tmux and Herdr; `Shift + CapsLock` stays the compose key. +Typing starts in Latin mode. Press `Super + I` to cycle through configured input methods, and `Super + Shift + I` to cycle back. Tap `Shift` on its own to step out of an input method like Pinyin into Latin letters, and tap it again to go back, the way Sogou, Microsoft Pinyin, and macOS work; `Shift` plus a letter still types a capital. On Japanese keyboards, 全角/半角 toggles input, 変換 turns it on, and 無変換 turns it off. On a Korean keyboard layout, dedicated 한/영 and 한자 keys switch Hangul and convert to Hanja. `Ctrl + Space` stays available for Tmux and Herdr; `Shift + CapsLock` stays the compose key. The keyboard indicator appears on the right of the bar when you have multiple keyboard layouts or input methods. Click it to switch input languages; Japanese displays あ for hiragana. For Japanese character choices, switch to Japanese, type a word such as `nihongo`, then press Space twice. Press Enter to accept your choice. If you also have multiple keyboard layouts, right-click the indicator to cycle those. diff --git a/migrations/1791676907.sh b/migrations/1791676907.sh new file mode 100644 index 00000000..b00d4a36 --- /dev/null +++ b/migrations/1791676907.sh @@ -0,0 +1,10 @@ +echo "Let a lone Shift switch out of an input method and back" + +# An earlier migration wrote this list empty. Fill only that empty list: a +# missing one already falls back to Fcitx's Shift_L, and a filled one is the +# user's choice. +config="${XDG_CONFIG_HOME:-$HOME/.config}/fcitx5/config" +if [[ -f $config ]] && awk '/^\[Hotkey\/AltTriggerKeys\]$/ { in_list = 1; found = 1; next } /^\[/ { in_list = 0 } in_list && /=/ { filled = 1 } END { exit !(found && !filled) }' "$config"; then + sed -i --follow-symlinks '/^\[Hotkey\/AltTriggerKeys\]$/a 0=Shift_L' "$config" + busctl --user call org.fcitx.Fcitx5 /controller org.fcitx.Fcitx.Controller1 ReloadConfig 2>/dev/null || true +fi diff --git a/test/shell.d/input-method-checks.py b/test/shell.d/input-method-checks.py index 6cb6381f..5d7d82e4 100644 --- a/test/shell.d/input-method-checks.py +++ b/test/shell.d/input-method-checks.py @@ -66,6 +66,7 @@ class InputMethodTest(unittest.TestCase): self.assertEqual(keys["Behavior"]["ActiveByDefault"], "False") self.assertNotIn("Control+space", keys["Hotkey/TriggerKeys"].values()) self.assertEqual(set(keys["Hotkey/TriggerKeys"].values()), {"Zenkaku_Hankaku", "Hangul"}) + self.assertEqual(keys["Hotkey/AltTriggerKeys"], {"0": "Shift_L"}) def test_vconsole_variants_quotes_and_japanese_without_preference(self): self.preference.unlink() diff --git a/test/shell.d/shift-switch-migration-test.sh b/test/shell.d/shift-switch-migration-test.sh new file mode 100755 index 00000000..5098831c --- /dev/null +++ b/test/shell.d/shift-switch-migration-test.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +set -euo pipefail + +source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" + +migration="$ROOT/migrations/1791676907.sh" +test_dir=$(mktemp -d) +trap 'rm -rf "$test_dir"' EXIT +mkdir -p "$test_dir/bin" +export CALL_LOG="$test_dir/calls" + +# A live Fcitx is asked to reload; never reach the real session bus. +cat >"$test_dir/bin/busctl" <<'SH' +#!/bin/bash +printf 'busctl %s\n' "$*" >>"$CALL_LOG" +SH +chmod +x "$test_dir/bin/busctl" + +# Runs the migration twice, as a retried update would. The caller's own +# XDG_CONFIG_HOME would point at the developer's real config, so it is cleared +# unless a case sets MIGRATION_XDG_CONFIG_HOME. +migrate() { + local home=$1 + for run in 1 2; do + env -u XDG_CONFIG_HOME ${MIGRATION_XDG_CONFIG_HOME:+XDG_CONFIG_HOME="$MIGRATION_XDG_CONFIG_HOME"} \ + HOME="$home" PATH="$test_dir/bin:$PATH" bash -euo pipefail "$migration" >/dev/null + done +} + +fresh_home() { + rm -rf "$test_dir/home" "$CALL_LOG" + mkdir -p "$test_dir/home/.config/fcitx5" + printf '%s' "$1" >"$test_dir/home/.config/fcitx5/config" +} + +fresh_home $'[Hotkey/TriggerKeys]\n0=Hangul\n\n[Hotkey/AltTriggerKeys]\n\n[Behavior]\nActiveByDefault=False\n' +migrate "$test_dir/home" +[[ $(<"$test_dir/home/.config/fcitx5/config") == $'[Hotkey/TriggerKeys]\n0=Hangul\n\n[Hotkey/AltTriggerKeys]\n0=Shift_L\n\n[Behavior]\nActiveByDefault=False' ]] || + fail "an empty list gets Shift_L once" "$(<"$test_dir/home/.config/fcitx5/config")" +[[ $(grep -c ReloadConfig "$CALL_LOG") == 1 ]] || fail "Fcitx reloads only when the list changes" "$(cat "$CALL_LOG")" +pass "an empty list gets Shift_L once, and Fcitx reloads once" + +fresh_home $'[Hotkey/AltTriggerKeys]\n0=Shift_R\n' +migrate "$test_dir/home" +[[ $(<"$test_dir/home/.config/fcitx5/config") == $'[Hotkey/AltTriggerKeys]\n0=Shift_R' && ! -e $CALL_LOG ]] || + fail "a chosen key is kept" "$(<"$test_dir/home/.config/fcitx5/config")" +pass "a list the user filled is kept" + +fresh_home $'[Behavior]\nActiveByDefault=False\n' +migrate "$test_dir/home" +[[ $(<"$test_dir/home/.config/fcitx5/config") == $'[Behavior]\nActiveByDefault=False' ]] || + fail "a missing list keeps Fcitx's own Shift_L default" "$(<"$test_dir/home/.config/fcitx5/config")" +rm -rf "$test_dir/home" +mkdir -p "$test_dir/home" +migrate "$test_dir/home" +[[ ! -e $test_dir/home/.config/fcitx5/config ]] || fail "no Fcitx config is created" +pass "a missing list or config is left to Fcitx's default" + +fresh_home "" +mkdir -p "$test_dir/dotfiles" +printf '[Hotkey/AltTriggerKeys]\n\n' >"$test_dir/dotfiles/fcitx5-config" +ln -sf "$test_dir/dotfiles/fcitx5-config" "$test_dir/home/.config/fcitx5/config" +migrate "$test_dir/home" +[[ -L $test_dir/home/.config/fcitx5/config && $(grep -c '^0=Shift_L$' "$test_dir/dotfiles/fcitx5-config") == 1 ]] || + fail "a symlinked config stays linked and its target is updated" "$(ls -l "$test_dir/home/.config/fcitx5/config"; cat "$test_dir/dotfiles/fcitx5-config")" +pass "a symlinked config stays linked and its target is updated" + +rm -rf "$test_dir/home" "$test_dir/xdg" +mkdir -p "$test_dir/home" "$test_dir/xdg/fcitx5" +printf '[Hotkey/AltTriggerKeys]\n' >"$test_dir/xdg/fcitx5/config" +MIGRATION_XDG_CONFIG_HOME="$test_dir/xdg" migrate "$test_dir/home" +[[ $(<"$test_dir/xdg/fcitx5/config") == $'[Hotkey/AltTriggerKeys]\n0=Shift_L' ]] || + fail "XDG_CONFIG_HOME is followed" "$(<"$test_dir/xdg/fcitx5/config")" +pass "the config under XDG_CONFIG_HOME is the one repaired"