ipc: a modifier keysym is no key

Shift, Control, and their kin were mapped to special keys that the
engine then had a range and a check to ignore, and the GTK module made a
round trip to the daemon for each press.  ipckeysym maps them to key 0,
which was already the "no key" every frontend and the engine skip;
Kmodfirst, Kmodlast, and ismodkey go.
This commit is contained in:
2026-08-17 10:56:03 +09:00
parent 46bb8b1d46
commit 33023d7f51
8 changed files with 17 additions and 22 deletions

8
ipc.c
View File

@@ -165,15 +165,17 @@ ipcconnect(void)
/* /*
* Engine key for an X keysym and its Unicode value: printable characters * Engine key for an X keysym and its Unicode value: printable characters
* as themselves, the function keysyms 0xff00-0xffff as Kspec+offset. * as themselves, the function keysyms 0xff00-0xffff as Kspec+offset, and
* The keypad keys and Shift+Tab (ISO_Left_Tab) fold onto their plain * no key at all for a modifier. The keypad keys and Shift+Tab
* counterparts. * (ISO_Left_Tab) fold onto their plain counterparts.
*/ */
uint32_t uint32_t
ipckeysym(uint32_t sym, uint32_t unicode) ipckeysym(uint32_t sym, uint32_t unicode)
{ {
if(unicode >= ' ' && unicode != 0x7f) if(unicode >= ' ' && unicode != 0x7f)
return unicode; return unicode;
if(sym >= 0xffe1 && sym <= 0xffee)
return 0;
switch(sym){ switch(sym){
case 0xfe20: case 0xfe20:
case 0xff89: case 0xff89:

2
ipc.h
View File

@@ -45,8 +45,6 @@ enum
Khenkan = Kspec|0x23, Khenkan = Kspec|0x23,
Kkana = Kspec|0x27, Kkana = Kspec|0x27,
Kzenkaku = Kspec|0x2a, Kzenkaku = Kspec|0x2a,
Kmodfirst = Kspec|0xe1,
Kmodlast = Kspec|0xee,
/* X core modifier bits; GDK and IBus also flag Super at bit 26. */ /* X core modifier bits; GDK and IBus also flag Super at bit 26. */
Mshift = 1<<0, Mshift = 1<<0,

View File

@@ -516,17 +516,11 @@ kokey(Rune c, u32int mod)
return c; return c;
} }
static int /* Modifier presses and unmapped keys, key 0, never engage the engine. */
ismodkey(u32int ks)
{
return ks >= Kmodfirst && ks <= Kmodlast;
}
/* Modifier presses and unmapped keys never engage the engine. */
int int
keymeaningful(u32int ks) keymeaningful(u32int ks)
{ {
return ks != 0 && !ismodkey(ks); return ks != 0;
} }
static void static void

View File

@@ -252,7 +252,7 @@ engine_active_owner_lifecycle(struct ct *t)
CT_EQ_PTR(t, nil, activeowner); CT_EQ_PTR(t, nil, activeowner);
CT_EQ_INT(t, 0, im.pre.n); CT_EQ_INT(t, 0, im.pre.n);
CT_EQ_INT(t, 0, im.raw.n); CT_EQ_INT(t, 0, im.raw.n);
ownerrequest(&c, Keypress, Kmodfirst, 0); ownerrequest(&c, Keypress, 0, 0);
CT_EQ_PTR(t, nil, activeowner); CT_EQ_PTR(t, nil, activeowner);
res = ownerrequest(&c, Keypress, 'k', 0); res = ownerrequest(&c, Keypress, 'k', 0);
CT_EQ_PTR(t, &c, activeowner); CT_EQ_PTR(t, &c, activeowner);
@@ -1646,7 +1646,7 @@ engine_emoji_preedit_languages(struct ct *t)
im.l = getlang(LangJP); im.l = getlang(LangJP);
sclear(&com); sclear(&com);
if(typekeys(t, "ka", &com)){ if(typekeys(t, "ka", &com)){
CT_CHECK(t, !keystroke(Kmodfirst+2, 0, &com)); CT_CHECK(t, !keystroke(0, 0, &com));
impre(&im, &shown); impre(&im, &shown);
checkstr(t, "modifier preserves Japanese", "", &shown); checkstr(t, "modifier preserves Japanese", "", &shown);
CT_CHECK(t, keystroke('E', Mctrl, &com)); CT_CHECK(t, keystroke('E', Mctrl, &com));
@@ -1665,7 +1665,7 @@ engine_emoji_preedit_languages(struct ct *t)
CT_CHECK(t, keystroke('E', Mctrl, &com)); CT_CHECK(t, keystroke('E', Mctrl, &com));
CT_EQ_INT(t, LangJP, im.l->lang); CT_EQ_INT(t, LangJP, im.l->lang);
CT_CHECK(t, keystroke('a', 0, &com)); CT_CHECK(t, keystroke('a', 0, &com));
CT_CHECK(t, !keystroke(Kmodfirst+2, 0, &com)); CT_CHECK(t, !keystroke(0, 0, &com));
CT_CHECK(t, search.lang); CT_CHECK(t, search.lang);
checkstr(t, "modifier preserves search", "a", &search.text); checkstr(t, "modifier preserves search", "a", &search.text);
CT_CHECK(t, !keystroke('P', Mctrl|Mshift, &com)); CT_CHECK(t, !keystroke('P', Mctrl|Mshift, &com));
@@ -2108,7 +2108,7 @@ engine_randomized_stress(struct ct *t)
res = ownerrequestat(owner, Keycaret, 0, 0, &pos); res = ownerrequestat(owner, Keycaret, 0, 0, &pos);
else if(op == 24) else if(op == 24)
res = ownerrequest(owner, Keypress, res = ownerrequest(owner, Keypress,
Kmodfirst + ((rnd >> 20) & 7), 0); 0, 0);
else if(op == 25) else if(op == 25)
res = ownerrequestat(owner, Keypress, 'p', Mctrl, &pos); res = ownerrequestat(owner, Keypress, 'p', Mctrl, &pos);
else if(op == 26) else if(op == 26)

View File

@@ -161,7 +161,7 @@ tryclient(char *path, int64_t deadline, int *client)
fd = connectsocket(path, deadline); fd = connectsocket(path, deadline);
if(fd < 0) if(fd < 0)
return errno == ETIMEDOUT ? -1 : 0; return errno == ETIMEDOUT ? -1 : 0;
if(!sendkey(fd, 1, 0, Kmodfirst)){ if(!sendkey(fd, 1, 0, 0)){
close(fd); close(fd);
return 0; return 0;
} }
@@ -208,7 +208,7 @@ overflowrejected(char *path)
fd = connectsocket(path, deadline); fd = connectsocket(path, deadline);
if(fd < 0) if(fd < 0)
return fail("overflow connect: %s", strerror(errno)); return fail("overflow connect: %s", strerror(errno));
if(!sendkey(fd, 1, 0, Kmodfirst)){ if(!sendkey(fd, 1, 0, 0)){
close(fd); close(fd);
return 1; return 1;
} }
@@ -286,7 +286,7 @@ runcapacity(char *path)
fail("connect capacity client %d: %s", i, strerror(errno)); fail("connect capacity client %d: %s", i, strerror(errno));
goto out; goto out;
} }
if(!requestkey(client[i], 1, 0, Kmodfirst, 0, "", "", if(!requestkey(client[i], 1, 0, 0, 0, "", "",
"capacity modifier")) "capacity modifier"))
goto out; goto out;
} }

View File

@@ -60,6 +60,7 @@ ipc_masks_modifiers(struct ct *t)
CT_EQ_UINT(t, Kspec + 0xff, ipckeysym(0xffff, 0x7f)); /* Delete */ CT_EQ_UINT(t, Kspec + 0xff, ipckeysym(0xffff, 0x7f)); /* Delete */
CT_EQ_UINT(t, 0x1f642, ipckeysym(0x101f642, 0x1f642)); CT_EQ_UINT(t, 0x1f642, ipckeysym(0x101f642, 0x1f642));
CT_EQ_UINT(t, 0, ipckeysym(0xfe03, 0)); /* ISO_Level3_Shift */ CT_EQ_UINT(t, 0, ipckeysym(0xfe03, 0)); /* ISO_Level3_Shift */
CT_EQ_UINT(t, 0, ipckeysym(0xffe1, 0)); /* Shift_L */
CT_EQ_UINT(t, Mshift|Mctrl, ipcmod(Mshift|Mctrl|(1<<1)|(1<<4))); CT_EQ_UINT(t, Mshift|Mctrl, ipcmod(Mshift|Mctrl|(1<<1)|(1<<4)));
CT_EQ_UINT(t, Msuper, ipcmod(1<<6)); CT_EQ_UINT(t, Msuper, ipcmod(1<<6));
CT_EQ_UINT(t, Msuper, ipcmod(1<<26)); CT_EQ_UINT(t, Msuper, ipcmod(1<<26));

View File

@@ -691,5 +691,5 @@ ipcprobe(int fd, char *where)
{ {
unsigned char empty[] = {0, 0, 0, 0, 0}; unsigned char empty[] = {0, 0, 0, 0, 0};
return ipcrequest(fd, 0, Kmodfirst, empty, sizeof empty, where); return ipcrequest(fd, 0, 0, empty, sizeof empty, where);
} }

View File

@@ -287,7 +287,7 @@ server_connection_ownership(struct ct *t)
CT_CHECK(t, readreply(t, &a, 1, "", preedit)); CT_CHECK(t, readreply(t, &a, 1, "", preedit));
CT_EQ_STR(t, "", preedit); CT_EQ_STR(t, "", preedit);
CT_EQ_PTR(t, bowner, testengineowner()); CT_EQ_PTR(t, bowner, testengineowner());
if(!sendkey(t, &b, 1, 0, Kmodfirst)) if(!sendkey(t, &b, 1, 0, 0))
goto cleanup; goto cleanup;
req = nextrequest(t, &f.pump, Keypress); req = nextrequest(t, &f.pump, Keypress);
allowrequest(&f.pump); allowrequest(&f.pump);