engine: the Japanese keyboard's own keys; keypad arrows move through candidates

半角/全角, ひらがな/カタカナ, 変換, and 無変換 committed the reading and did
nothing, like any function key.  They now stand for what a Japanese
keyboard means by them: toggling Japanese and English, switching kana
modes, converting (or turning Japanese on), and turning it off; the
Korean keys became a switch of the same shape.  The keypad's arrows
and page keys, with NumLock off, fold onto the plain ones as its Enter
and Tab already did.
This commit is contained in:
2026-08-17 01:29:07 +09:00
parent 1c8d9fac07
commit 97a838eda1
6 changed files with 53 additions and 9 deletions

View File

@@ -17,7 +17,9 @@ Vietnamese Telex is also available as a compatibility mode.
| `Ctrl+H` | One-shot Hanja search |
A Korean keyboard's 한/영 key toggles Korean and English, and its 한자 key
is `Ctrl+H`. Only a plain `Ctrl` chord is a strans key: with `Shift`, `Alt`,
is `Ctrl+H`; a Japanese keyboard's 半角/全角 toggles Japanese and English,
ひらがな/カタカナ switches between the two kana modes, 変換 turns Japanese on
and then converts like `Space`, and 無変換 turns it off. Only a plain `Ctrl` chord is a strans key: with `Shift`, `Alt`,
or `Super` held it commits what is pending and goes to the application, so
`Ctrl+Shift+V` still pastes.

11
ipc.c
View File

@@ -166,7 +166,8 @@ ipcconnect(void)
/*
* Engine key for an X keysym and its Unicode value: printable characters
* as themselves, the function keysyms 0xff00-0xffff as Kspec+offset.
* The keypad and Shift+Tab (ISO_Left_Tab) variants fold onto Enter and Tab.
* The keypad keys and Shift+Tab (ISO_Left_Tab) fold onto their plain
* counterparts.
*/
uint32_t
ipckeysym(uint32_t sym, uint32_t unicode)
@@ -179,6 +180,14 @@ ipckeysym(uint32_t sym, uint32_t unicode)
return Ktab;
case 0xff8d:
return Kret;
case 0xff97:
return Kup;
case 0xff99:
return Kdown;
case 0xff9a:
return Kpgup;
case 0xff9b:
return Kpgdown;
}
if(sym >= 0xff00 && sym <= 0xffff)
return Kspec + (sym - 0xff00);

4
ipc.h
View File

@@ -41,6 +41,10 @@ enum
Kpgdown = Kspec|0x56,
Khangul = Kspec|0x31,
Khanja = Kspec|0x34,
Kmuhenkan = Kspec|0x22,
Khenkan = Kspec|0x23,
Kkana = Kspec|0x27,
Kzenkaku = Kspec|0x2a,
Kmodfirst = Kspec|0xe1,
Kmodlast = Kspec|0xee,

View File

@@ -765,13 +765,23 @@ transition(u32int ks, u32int mod, Str *com)
ks = kokey(ks, mod);
else if(isjp(&im))
ks = lower(ks); /* romaji is case-blind, Caps Lock included */
/* The Korean keyboard's 한/영 and 한자 keys are Ctrl+S or Ctrl+T, and Ctrl+H. */
if(ks == Khangul){
ks = im.l->lang == LangKO ? 't' : 's';
mod = Mctrl;
}else if(ks == Khanja){
ks = 'h';
mod = Mctrl;
/* The Korean and Japanese keyboards' own keys, as the Ctrl chords
* and Space they stand for. */
switch(ks){
case Khangul: ks = im.l->lang == LangKO ? 't' : 's'; mod = Mctrl; break;
case Khanja: ks = 'h'; mod = Mctrl; break;
case Kzenkaku: ks = isjp(&im) ? 't' : 'n'; mod = Mctrl; break;
case Kkana: ks = im.l->lang == LangJP ? 'k' : 'n'; mod = Mctrl; break;
case Khenkan:
if(isjp(&im)){
ks = ' ';
mod &= Mshift;
}else{
ks = 'n';
mod = Mctrl;
}
break;
case Kmuhenkan: ks = 't'; mod = Mctrl; break;
}
if(search.lang)
return searchkey(ks, mod, com);

View File

@@ -1965,6 +1965,24 @@ engine_hanja_input_languages(struct ct *t)
CT_EQ_INT(t, LangEN, im.l->lang);
CT_CHECK(t, keystroke(Khangul, 0, &com));
CT_EQ_INT(t, LangKO, im.l->lang);
CT_CHECK(t, keystroke(Kzenkaku, 0, &com));
CT_EQ_INT(t, LangJP, im.l->lang);
CT_CHECK(t, keystroke(Kkana, 0, &com));
CT_EQ_INT(t, LangJPK, im.l->lang);
CT_CHECK(t, keystroke(Kkana, 0, &com));
CT_EQ_INT(t, LangJP, im.l->lang);
CT_CHECK(t, keystroke(Kzenkaku, 0, &com));
CT_EQ_INT(t, LangEN, im.l->lang);
CT_CHECK(t, keystroke(Khenkan, 0, &com));
CT_EQ_INT(t, LangJP, im.l->lang);
sclear(&com);
if(typekeys(t, "ka", &com)){
CT_CHECK(t, keystroke(Khenkan, 0, &com));
CT_EQ_INT(t, 0, im.sel);
CT_CHECK(t, keystroke(Kmuhenkan, 0, &com));
checkstr(t, "無変換 commits", "", &com);
CT_EQ_INT(t, LangEN, im.l->lang);
}
}
init();

View File

@@ -55,6 +55,7 @@ ipc_masks_modifiers(struct ct *t)
CT_EQ_UINT(t, Kret, ipckeysym(0xff0d, '\r'));
CT_EQ_UINT(t, Kret, ipckeysym(0xff8d, '\r')); /* KP_Enter */
CT_EQ_UINT(t, Ktab, ipckeysym(0xfe20, 0)); /* ISO_Left_Tab */
CT_EQ_UINT(t, Kdown, ipckeysym(0xff99, 0)); /* KP_Down */
CT_EQ_UINT(t, Kback, ipckeysym(0xff08, 8));
CT_EQ_UINT(t, Kspec + 0xff, ipckeysym(0xffff, 0x7f)); /* Delete */
CT_EQ_UINT(t, 0x1f642, ipckeysym(0x101f642, 0x1f642));