mirror of
https://github.com/qingjian-team/qingjian.git
synced 2026-11-06 16:13:55 +00:00
GNOME 默认的输入法框架是 IBus:加一个 IBus 前端(纯 Rust,与 Fcitx5 插件共用同一个 Server),安装脚本按机器上有哪个框架装对应的前端(--frontend auto/fcitx5/ibus/both),可选把 Server 装成随登录启动的 systemd 用户服务。 协议类型搬进 qingjian_platform::protocol::linux,两个前端共用。GNOME Wayland 上组句中按应用快捷键时先把拼音上屏到原来的框。 合并 main 时保留 #351 的 --fcitx4(单独一支,不与 --frontend 同用)。
88 lines
2.9 KiB
Rust
88 lines
2.9 KiB
Rust
//! 共享长度前缀协议的内存回环。
|
|
use qingjian_platform::protocol::{
|
|
ClientMessage, KeyEvent, KeyModifiers, PROTOCOL_VERSION, ServerMessage, SessionId,
|
|
read_message, write_message,
|
|
};
|
|
use std::io::Cursor;
|
|
|
|
#[test]
|
|
fn client_key_round_trips_with_length_prefix() {
|
|
let message = ClientMessage::Key {
|
|
session: SessionId(42),
|
|
event: KeyEvent::new(u32::from(b'N'), Some('n'), KeyModifiers::default()),
|
|
};
|
|
let mut bytes = Vec::new();
|
|
write_message(&mut bytes, &message).unwrap();
|
|
assert_eq!(
|
|
u32::from_le_bytes(bytes[..4].try_into().unwrap()) as usize,
|
|
bytes.len() - 4
|
|
);
|
|
let decoded = read_message::<_, ClientMessage>(&mut Cursor::new(bytes)).unwrap();
|
|
assert_eq!(decoded, Some(message));
|
|
}
|
|
|
|
#[test]
|
|
fn open_session_carries_protocol_and_close_is_replyless() {
|
|
let open = ClientMessage::OpenSession {
|
|
session: SessionId(1),
|
|
app: Some("gedit".into()),
|
|
protocol: PROTOCOL_VERSION,
|
|
};
|
|
let close = ClientMessage::CloseSession {
|
|
session: SessionId(1),
|
|
};
|
|
let mut bytes = Vec::new();
|
|
write_message(&mut bytes, &open).unwrap();
|
|
write_message(&mut bytes, &close).unwrap();
|
|
let mut cursor = Cursor::new(bytes);
|
|
assert_eq!(
|
|
read_message::<_, ClientMessage>(&mut cursor).unwrap(),
|
|
Some(open)
|
|
);
|
|
assert_eq!(
|
|
read_message::<_, ClientMessage>(&mut cursor).unwrap(),
|
|
Some(close)
|
|
);
|
|
let response = ServerMessage::Committed {
|
|
session: SessionId(1),
|
|
text: Some("你好".into()),
|
|
};
|
|
let mut out = Vec::new();
|
|
write_message(&mut out, &response).unwrap();
|
|
assert_eq!(
|
|
read_message::<_, ServerMessage>(&mut Cursor::new(out)).unwrap(),
|
|
Some(response)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn linux_display_identity_round_trips_without_changing_shared_protocol() {
|
|
let identity = qingjian_platform::protocol::linux::DisplayIdentity {
|
|
generation: 7,
|
|
context: "001122".into(),
|
|
revision: 13,
|
|
};
|
|
let ack = qingjian_platform::protocol::linux::DisplayAcknowledged {
|
|
session: SessionId(2),
|
|
identity: identity.clone(),
|
|
senses: vec![(0, 1), (3, 0)],
|
|
};
|
|
let value = serde_json::to_value(&ack).unwrap();
|
|
let decoded: qingjian_platform::protocol::linux::DisplayAcknowledged =
|
|
serde_json::from_value(value).unwrap();
|
|
assert_eq!(decoded.identity, identity);
|
|
assert_eq!(decoded.senses, vec![(0, 1), (3, 0)]);
|
|
}
|
|
|
|
/// Fcitx5 插件的 OpenSession 把协议版本写死在 C++ 里;Server 要求完全一致,升版本时两边得一起改。
|
|
#[test]
|
|
fn fcitx5_plugin_opens_sessions_with_the_current_protocol() {
|
|
let plugin = concat!(env!("CARGO_MANIFEST_DIR"), "/../fcitx5/src/qingjian.cpp");
|
|
let source = std::fs::read_to_string(plugin).unwrap();
|
|
let expected = format!("{{\"protocol\", {PROTOCOL_VERSION}}}");
|
|
assert!(
|
|
source.contains(&expected),
|
|
"qingjian.cpp 的 OpenSession 应写 {expected}"
|
|
);
|
|
}
|