harden ipc and frontend recovery

This commit is contained in:
2026-08-11 19:34:47 +09:00
parent 4bfb659b6d
commit 9dc116a035
14 changed files with 495 additions and 245 deletions

View File

@@ -25,55 +25,40 @@ static struct xkb_state *xkbst;
static int active;
static int pending;
static u32int imserial;
static Channel *replyc;
static void
sendkey(u32int ks, u32int mod, char *com, int csz, char *pre, int psz,
int *eaten)
sendkey(u32int ks, u32int mod, Keyres *res)
{
Keyreq kr;
int p[2];
uchar hdr[2];
uchar pl;
int n;
*eaten = 0;
com[0] = '\0';
pre[0] = '\0';
if(pipe(p) < 0)
return;
kr.fd = p[1];
kr.ks = ks;
kr.mod = mod;
kr.want = 1;
kr.reply = replyc;
chansend(keyc, &kr);
if(read(p[0], hdr, 2) != 2)
goto out;
*eaten = hdr[0];
n = hdr[1];
if(n > 0 && n < csz){
if(read(p[0], com, n) != n)
goto out;
com[n] = '\0';
}
if(read(p[0], &pl, 1) != 1)
goto out;
if(pl > 0 && pl < psz){
if(read(p[0], pre, pl) != pl)
goto out;
pre[pl] = '\0';
}
out:
close(p[0]);
close(p[1]);
chanrecv(replyc, res);
}
static void
sendreset(void)
{
char com[64], pre[256];
int eaten;
Keyres res;
sendkey(Kesc, 0, com, sizeof(com), pre, sizeof(pre), &eaten);
sendkey(Kesc, 0, &res);
}
static u32int
kget(xkb_keysym_t ks)
{
u32int c;
c = xkb_keysym_to_utf32(ks);
if(c >= ' ' && c != 0x7f)
return c;
if(ks >= 0xff00 && ks <= 0xffff)
return Kspec + (ks - 0xff00);
return c;
}
static u32int
@@ -104,29 +89,32 @@ kpress(uint32_t time, uint32_t keycode, uint32_t state)
{
xkb_keysym_t ks;
u32int k, mod;
char com[64], pre[256];
int eaten, plen;
Keyres res;
char commit[Maxutf], preedit[Maxutf];
int plen;
if(state != WL_KEYBOARD_KEY_STATE_PRESSED || xkbst == nil){
zwp_virtual_keyboard_v1_key(vk, time, keycode, state);
return;
}
ks = xkb_state_key_get_one_sym(xkbst, keycode + 8);
k = ks >= 0xff00 ? Kspec + (ks - 0xff00) : xkb_keysym_to_utf32(ks);
k = kget(ks);
if(k == 0){
zwp_virtual_keyboard_v1_key(vk, time, keycode, state);
return;
}
mod = mget();
sendkey(k, mod, com, sizeof(com), pre, sizeof(pre), &eaten);
if(com[0] != '\0'){
zwp_input_method_v2_commit_string(im, com);
sendkey(k, mod, &res);
stoutf(&res.commit, commit, sizeof commit);
stoutf(&res.preedit, preedit, sizeof preedit);
if(commit[0] != '\0'){
zwp_input_method_v2_commit_string(im, commit);
zwp_input_method_v2_commit(im, imserial);
}
plen = strlen(pre);
zwp_input_method_v2_set_preedit_string(im, pre, plen, plen);
plen = strlen(preedit);
zwp_input_method_v2_set_preedit_string(im, preedit, plen, plen);
zwp_input_method_v2_commit(im, imserial);
if(!eaten)
if(!res.eaten)
zwp_virtual_keyboard_v1_key(vk, time, keycode, state);
}
@@ -158,6 +146,7 @@ kg_keymap(void *data, struct zwp_input_method_keyboard_grab_v2 *g,
munmap(s, size);
}
zwp_virtual_keyboard_v1_keymap(vk, format, fd, size);
close(fd);
}
static void
@@ -215,14 +204,6 @@ im_deactivate(void *data, struct zwp_input_method_v2 *m)
(void)data;
(void)m;
pending = 0;
if(active){
active = 0;
sendreset();
if(grab != nil){
zwp_input_method_keyboard_grab_v2_release(grab);
grab = nil;
}
}
}
static void
@@ -266,6 +247,13 @@ im_done(void *data, struct zwp_input_method_v2 *m)
if(grab != nil)
zwp_input_method_keyboard_grab_v2_add_listener(grab,
&grab_listener, nil);
}else if(!pending && active){
active = 0;
sendreset();
if(grab != nil){
zwp_input_method_keyboard_grab_v2_release(grab);
grab = nil;
}
}
}
@@ -292,9 +280,9 @@ reg_global(void *data, struct wl_registry *r, uint32_t name,
const char *iface, uint32_t version)
{
(void)data;
(void)version;
if(strcmp(iface, wl_seat_interface.name) == 0)
seat = wl_registry_bind(r, name, &wl_seat_interface, 5);
seat = wl_registry_bind(r, name, &wl_seat_interface,
version < 5 ? version : 5);
else if(strcmp(iface, zwp_input_method_manager_v2_interface.name) == 0)
immgr = wl_registry_bind(r, name,
&zwp_input_method_manager_v2_interface, 1);
@@ -345,6 +333,9 @@ waylandthread(void *_)
im = zwp_input_method_manager_v2_get_input_method(immgr, seat);
zwp_input_method_v2_add_listener(im, &im_listener, nil);
vk = zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(vkmgr, seat);
replyc = chancreate(sizeof(Keyres), 0);
while(wl_display_dispatch(dpy) != -1)
;
chanfree(replyc);
replyc = nil;
}