diff options
Diffstat (limited to 'tests/x11')
| -rw-r--r-- | tests/x11/test_input.c | 32 | ||||
| -rw-r--r-- | tests/x11/test_state.c | 55 |
2 files changed, 87 insertions, 0 deletions
diff --git a/tests/x11/test_input.c b/tests/x11/test_input.c index bbcbf45..95943d1 100644 --- a/tests/x11/test_input.c +++ b/tests/x11/test_input.c @@ -65,6 +65,37 @@ static void check_selection_encoding(struct x11_display *d, struct x11_surface * } } +/* Own the XSETTINGS selection with one Net/DoubleClickTime value. */ +static void check_double_click(struct x11_display *d) +{ + /* No settings owner and no portal: the default applies. */ + unsetenv("DBUS_SESSION_BUS_ADDRESS"); + unsetenv("XDG_RUNTIME_DIR"); + assert(yasl_display_double_click_ms(&d->base) == YASL_DOUBLE_CLICK_MS_DEFAULT); + + char name[32]; + snprintf(name, sizeof(name), "_XSETTINGS_S%d", d->screen); + Atom selection = XInternAtom(d->native, name, False); + Atom property = XInternAtom(d->native, "_XSETTINGS_SETTINGS", False); + Window owner = XCreateSimpleWindow(d->native, DefaultRootWindow(d->native), + 0, 0, 1, 1, 0, 0, 0); + XSetSelectionOwner(d->native, selection, owner, CurrentTime); + static const unsigned char blob[] = { + LSBFirst, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 19, 0, 'N', 'e', 't', '/', 'D', 'o', 'u', 'b', 'l', 'e', + 'C', 'l', 'i', 'c', 'k', 'T', 'i', 'm', 'e', 0, 0, 0, 0, 0, + 250, 0, 0, 0, + }; + XChangeProperty(d->native, owner, property, property, 8, PropModeReplace, + blob, sizeof(blob)); + XSync(d->native, False); + assert(yasl_display_double_click_ms(&d->base) == 250); + + XDestroyWindow(d->native, owner); + XSync(d->native, False); + assert(yasl_display_double_click_ms(&d->base) == YASL_DOUBLE_CLICK_MS_DEFAULT); +} + int main(void) { struct yasl_display_spec ds = {.backend = YASL_BACKEND_X11}; @@ -117,6 +148,7 @@ int main(void) XFree(saved); s->ic = saved_ic; check_selection_encoding(d, s); + check_double_click(d); /* Test CSD interactive actions, window menu, and IME caret */ assert(yasl_display_caps(base) & YASL_CAP_CSD); diff --git a/tests/x11/test_state.c b/tests/x11/test_state.c index abdda95..abc0851 100644 --- a/tests/x11/test_state.c +++ b/tests/x11/test_state.c @@ -36,8 +36,63 @@ static void state_changed(struct yasl_surface *surface, uint32_t state, void *ud notifications++; } +/* Build an XSETTINGS blob in either byte order. */ +struct blob { + unsigned char bytes[256]; + size_t len; + bool msb; +}; + +static void put(struct blob *b, uint32_t v, int size) +{ + for (int i = 0; i < size; i++) + b->bytes[b->len++] = (unsigned char)(v >> (8 * (b->msb ? size - 1 - i : i))); +} + +static void put_name(struct blob *b, unsigned type, const char *name) +{ + size_t n = strlen(name); + b->bytes[b->len++] = (unsigned char)type; + b->bytes[b->len++] = 0; + put(b, (uint32_t)n, 2); + memcpy(b->bytes + b->len, name, n); + b->len += (n + 3) & ~(size_t)3; + put(b, 7, 4); /* Last-change serial. */ +} + +static void test_xsettings(void) +{ + for (int order = 0; order < 2; order++) { + struct blob b = {.msb = order == 1}; + b.bytes[0] = b.msb ? MSBFirst : LSBFirst; + b.len = 4; + put(&b, 1, 4); + put(&b, 4, 4); + put_name(&b, 1, "Net/ThemeName"); + put(&b, 5, 4); + memcpy(b.bytes + b.len, "Adwai", 5); + b.len += 8; + put_name(&b, 2, "Net/Color"); + put(&b, 0x1111, 2); put(&b, 0x2222, 2); put(&b, 0x3333, 2); put(&b, 0xffff, 2); + put_name(&b, 0, "Net/DoubleClickTimeX"); + put(&b, 999, 4); + put_name(&b, 0, "Net/DoubleClickTime"); + put(&b, 250, 4); + + int32_t ms = 0; + assert(xsettings_int(b.bytes, b.len, "Net/DoubleClickTime", &ms) && ms == 250); + assert(!xsettings_int(b.bytes, b.len, "Net/DoubleClick", &ms)); + /* A string with that name is not an integer setting. */ + assert(!xsettings_int(b.bytes, b.len, "Net/ThemeName", &ms)); + /* The value is last, so any truncation fails cleanly. */ + for (size_t len = 0; len < b.len; len++) + assert(!xsettings_int(b.bytes, len, "Net/DoubleClickTime", &ms)); + } +} + int main(void) { + test_xsettings(); struct x11_display display = {.base.ops = &yasl_x11_backend, .net_state = 10, .fullscreen = 20, .maximized_h = 21, .maximized_v = 22}; display.native = (Display *)&display; |
