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 <machine-id>-unix-0 while every IBus client looked for
<machine-id>-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.
This commit is contained in:
2026-08-17 11:53:40 +09:00
parent 5a6f352d72
commit bfa919f623
3 changed files with 33 additions and 20 deletions

View File

@@ -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

47
ibus.c
View File

@@ -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')

View File

@@ -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);