summaryrefslogtreecommitdiff
path: root/tests/x11
diff options
context:
space:
mode:
Diffstat (limited to 'tests/x11')
-rw-r--r--tests/x11/test_input.c32
-rw-r--r--tests/x11/test_state.c55
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;