diff --git a/engine/src/bamboo.rs b/engine/src/bamboo.rs index 7af2938..b96fbb0 100644 --- a/engine/src/bamboo.rs +++ b/engine/src/bamboo.rs @@ -528,4 +528,36 @@ mod tests { assert_eq!(process(InputMethod::Telex, "chafo"), "chào"); assert_eq!(process(InputMethod::Vni, "chao2"), "chào"); } + +#[test] +fn test_telex_tuaan() { + let mut e = crate::bamboo::BambooEngine::new(crate::input_method::InputMethod::Telex); + let mut out = String::new(); + for ch in "Tuaans".chars() { + if let Some(o) = e.process_key(ch) { out = o; } + } + assert_eq!(out, "Tuấn", "Expected Tuấn, got {}", out); +} + +#[test] +fn test_telex_nguyeenx() { + let mut e = crate::bamboo::BambooEngine::new(crate::input_method::InputMethod::Telex); + let mut out = String::new(); + for ch in "nguyeenx".chars() { + if let Some(o) = e.process_key(ch) { out = o; } + } + assert_eq!(out, "nguyễn", "Expected nguyễn, got {}", out); +} + +#[test] +fn test_telex_gios() { + let mut e = crate::bamboo::BambooEngine::new(crate::input_method::InputMethod::Telex); + let mut out = String::new(); + for ch in "gios".chars() { + if let Some(o) = e.process_key(ch) { out = o; } + } + assert_eq!(out, "gió", "Expected gió, got {}", out); +} + + } diff --git a/packaging/appimage/build-appimage.sh b/packaging/appimage/build-appimage.sh index f60b364..061bbc2 100644 --- a/packaging/appimage/build-appimage.sh +++ b/packaging/appimage/build-appimage.sh @@ -197,6 +197,30 @@ cat > "$APPDIR/AppRun" << 'EOF' #!/bin/sh HERE="$(dirname "$(readlink -f "${0}")")" +# Handle --update flag: download latest AppImage from GitHub +if [ "$1" = "--update" ]; then + echo "Viet+ Self-Updater" + RELEASE_URL="https://github.com/vndangkhoa/vietc/releases/latest/download/Viet+-x86_64.AppImage" + TEMP="/tmp/Viet+-update.AppImage" + echo "Downloading latest release..." + if command -v curl >/dev/null 2>&1; then + curl -L -o "$TEMP" "$RELEASE_URL" 2>/dev/null + elif command -v wget >/dev/null 2>&1; then + wget -q -O "$TEMP" "$RELEASE_URL" 2>/dev/null + else + echo "ERROR: curl or wget required for updates" >&2 + exit 1 + fi + if [ -s "$TEMP" ]; then + chmod +x "$TEMP" + mv "$TEMP" "$(readlink -f "${0}")" + echo "Updated! Restart the AppImage." + else + echo "ERROR: Download failed" >&2 + fi + exit 0 +fi + # Export our bin dir on PATH so child processes can find sibling binaries export PATH="$HERE/usr/bin:$PATH" diff --git a/protocol/src/uinput_monitor.rs b/protocol/src/uinput_monitor.rs index 646ec44..d6d4d2f 100644 --- a/protocol/src/uinput_monitor.rs +++ b/protocol/src/uinput_monitor.rs @@ -380,10 +380,14 @@ impl UinputInjector { } } - // Trailing ASCII via uinput (spaces, punctuation) - for ch in ascii_tail.chars() { - if let Some(kc) = char_to_linux_keycode(ch) { - self.send_key_stroke(kc, false); + // Trailing ASCII via uinput (spaces, punctuation). + // Small delay lets the clipboard paste finish before trailing chars arrive. + if !ascii_tail.is_empty() { + std::thread::sleep(std::time::Duration::from_millis(15)); + for ch in ascii_tail.chars() { + if let Some(kc) = char_to_linux_keycode(ch) { + self.send_key_stroke(kc, false); + } } }