From bfa919f62330c3b18a16ff1a0e829b2263fc8f7e Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Mon, 17 Aug 2026 11:53:40 +0900 Subject: [PATCH] ibus: name the address file as libibus does under Wayland libibus looks for the file under WAYLAND_DISPLAY when a session has one, DISPLAY only otherwise; strans always used DISPLAY, so in a Wayland session it wrote -unix-0 while every IBus client looked for -unix-wayland-0 and found nothing. The machine id now comes from D-Bus's copy first, as libibus reads it, and a host with neither file gets libibus's own "machine-id" rather than a daemon that dies. --- README.md | 3 ++- ibus.c | 47 ++++++++++++++++++++++++++++------------------- tests/ibus_test.c | 3 +++ 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index a54d5d4..6367473 100644 --- a/README.md +++ b/README.md @@ -147,7 +147,8 @@ caller's standard error. A service supervisor should instead run `XDG_RUNTIME_DIR` and `DISPLAY`: the GTK module finds the daemon at `$XDG_RUNTIME_DIR/strans.sock` (else `/tmp/strans.UID`), and IBus clients through the address file libibus expects under `~/.config/ibus/bus/`, -which strans writes as `ibus-daemon` would. +which strans writes as `ibus-daemon` would, named after `WAYLAND_DISPLAY` +when there is one and `DISPLAY` otherwise. The build does not copy or install the daemon or its data. `./strans DIR` opens `hira.map`, `kata.map`, `telex.map`, `kanji.dict`, `emoji.dict`, and diff --git a/ibus.c b/ibus.c index 1181cbf..ae04ed3 100644 --- a/ibus.c +++ b/ibus.c @@ -113,52 +113,63 @@ machineidfiles(char *buf, int sz, char **path, int npath) buf[0] = '\0'; } +/* libibus reads the D-Bus file first and calls it "machine-id" if neither is there. */ static void machineid(char *buf, int sz) { char *path[] = { - "/etc/machine-id", "/var/lib/dbus/machine-id", + "/etc/machine-id", }; machineidfiles(buf, sz, path, nelem(path)); + if(buf[0] == '\0') + snprintf(buf, sz, "machine-id"); } +static void +copyfield(char *dst, int sz, char *src, int n) +{ + if(n >= sz) + n = sz - 1; + memcpy(dst, src, n); + dst[n] = '\0'; +} + +/* + * The display libibus names the file after: the whole WAYLAND_DISPLAY, + * else DISPLAY's host and number, else unix and 0. + */ static void xdisplay(char *host, int hsz, char *num, int nsz) { char *d, *colon, *dot, *p; - int n; - strncpy(host, "unix", hsz); - host[hsz-1] = '\0'; - strncpy(num, "0", nsz); - num[nsz-1] = '\0'; + copyfield(host, hsz, "unix", 4); + copyfield(num, nsz, "0", 1); + d = getenv("WAYLAND_DISPLAY"); + if(d != nil && d[0] != '\0'){ + copyfield(num, nsz, d, strlen(d)); + return; + } d = getenv("DISPLAY"); if(d == nil || d[0] == '\0') return; colon = strchr(d, ':'); if(colon == nil) return; - if(colon > d){ - n = colon - d; - if(n >= hsz) n = hsz - 1; - memcpy(host, d, n); - host[n] = '\0'; - } + if(colon > d) + copyfield(host, hsz, d, colon - d); p = colon + 1; dot = strchr(p, '.'); - n = dot ? dot - p : (int)strlen(p); - if(n >= nsz) n = nsz - 1; - memcpy(num, p, n); - num[n] = '\0'; + copyfield(num, nsz, p, dot ? dot - p : (int)strlen(p)); } /* The IBus address file lives where libibus looks: config/ibus/bus/. */ static int buildaddrpath(char *buf, int sz) { - char mid[64], host[64], num[8], dir[512]; + char mid[64], host[64], num[64], dir[512]; char *cfg, *home, *explicit, *p; int n; @@ -168,8 +179,6 @@ buildaddrpath(char *buf, int sz) return explicit[0] == '\0' || n < 0 || n >= sz ? -1 : 0; } machineid(mid, sizeof(mid)); - if(mid[0] == '\0') - return -1; xdisplay(host, sizeof(host), num, sizeof(num)); cfg = getenv("XDG_CONFIG_HOME"); if(cfg != nil && cfg[0] != '\0') diff --git a/tests/ibus_test.c b/tests/ibus_test.c index ae64ae0..8aa6bc5 100644 --- a/tests/ibus_test.c +++ b/tests/ibus_test.c @@ -52,6 +52,9 @@ ibus_machine_id_fallback(struct ct *t) path[1] = fallback; machineidfiles(got, sizeof got, path, nelem(path)); CT_EQ_STR(t, "fallback-machine-id", got); + path[1] = primary; + machineidfiles(got, sizeof got, path, nelem(path)); + CT_EQ_STR(t, "", got); old = getenv("IBUS_ADDRESS_FILE"); saved = old == nil ? nil : strdup(old);