Reset master to testing content
This commit is contained in:
1 parent
0f2587b719
commit
42afa2a56c
1483 files changed
+145308
-938069
No files matched your search
@@ -0,0 +1,162 @@
|
||||
// Copyright (c) 2026 Storm Dragon
|
||||
// Authors: Storm Dragon, Angus Kola
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static gboolean armed;
|
||||
static unsigned childQueries;
|
||||
static gboolean slowRanges;
|
||||
static gint largestRange;
|
||||
static GHashTable *measuredRanges;
|
||||
static guint repeatedRanges;
|
||||
static gboolean lineGeometryOnly;
|
||||
static gboolean missingGlyph;
|
||||
static GtkWidget *reviewScroller;
|
||||
static AtkObject *brokenSubtree;
|
||||
static gint (*originalChildCount)(AtkObject *);
|
||||
static void (*originalRangeExtents)(AtkText *, gint, gint, AtkCoordType, AtkTextRectangle *);
|
||||
|
||||
static void range_extents(AtkText *text, gint start, gint end, AtkCoordType coordinates, AtkTextRectangle *rectangle) {
|
||||
if (missingGlyph && start == 5 && end == 6) {
|
||||
memset(rectangle, 0, sizeof(*rectangle));
|
||||
return;
|
||||
}
|
||||
if (lineGeometryOnly && end - start == 1) {
|
||||
memset(rectangle, 0, sizeof(*rectangle));
|
||||
return;
|
||||
}
|
||||
if (slowRanges) {
|
||||
largestRange = MAX(largestRange, end - start);
|
||||
guint64 key = ((guint64)(guint32)start << 32) | (guint32)end;
|
||||
if (g_hash_table_contains(measuredRanges, &key)) repeatedRanges++;
|
||||
else {
|
||||
guint64 *stored = g_new(guint64, 1);
|
||||
*stored = key;
|
||||
g_hash_table_add(measuredRanges, stored);
|
||||
}
|
||||
if (end - start > 128) g_usleep(1200000);
|
||||
}
|
||||
originalRangeExtents(text, start, end, coordinates, rectangle);
|
||||
}
|
||||
|
||||
static gint count_children(AtkObject *object) {
|
||||
(void)object;
|
||||
if (armed) {
|
||||
childQueries++;
|
||||
// The initial cache already reports this label as a leaf. A redundant
|
||||
// property query models the temporarily unresponsive live cell.
|
||||
g_usleep(1200000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gint subtree_child_count(AtkObject *object) {
|
||||
if (object == brokenSubtree && armed) return -1;
|
||||
return originalChildCount(object);
|
||||
}
|
||||
|
||||
static gboolean command_ready(GIOChannel *channel, GIOCondition condition, gpointer label) {
|
||||
if (condition & G_IO_HUP) {
|
||||
gtk_main_quit();
|
||||
return FALSE;
|
||||
}
|
||||
gchar *line = NULL;
|
||||
if (g_io_channel_read_line(channel, &line, NULL, NULL, NULL) != G_IO_STATUS_NORMAL)
|
||||
return TRUE;
|
||||
if (g_str_has_prefix(line, "arm")) {
|
||||
armed = TRUE;
|
||||
puts("armed");
|
||||
} else if (g_str_has_prefix(line, "count")) {
|
||||
printf("count %u\n", childQueries);
|
||||
} else if (g_str_has_prefix(line, "measure")) {
|
||||
slowRanges = TRUE;
|
||||
g_hash_table_remove_all(measuredRanges);
|
||||
repeatedRanges = 0;
|
||||
puts("measuring");
|
||||
} else if (g_str_has_prefix(line, "repeated")) {
|
||||
printf("repeated %u\n", repeatedRanges);
|
||||
} else if (g_str_has_prefix(line, "largest")) {
|
||||
printf("largest %d\n", largestRange);
|
||||
} else if (g_str_has_prefix(line, "scroll")) {
|
||||
GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(reviewScroller));
|
||||
gtk_adjustment_set_value(adjustment, gtk_adjustment_get_upper(adjustment) * 0.75);
|
||||
while (gtk_events_pending()) gtk_main_iteration();
|
||||
puts("scrolled");
|
||||
} else if (g_str_has_prefix(line, "change")) {
|
||||
armed = FALSE;
|
||||
gtk_label_set_text(GTK_LABEL(label), "Changed review text");
|
||||
puts("changed");
|
||||
}
|
||||
g_free(line);
|
||||
fflush(stdout);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
gboolean boundsMode = argc > 1 && strcmp(argv[1], "bounds") == 0;
|
||||
gboolean clippedMode = argc > 1 && strcmp(argv[1], "clipped") == 0;
|
||||
gboolean longMode = argc > 1 && strcmp(argv[1], "long") == 0;
|
||||
gboolean linesMode = argc > 1 && strcmp(argv[1], "lines") == 0;
|
||||
gboolean childrenMode = argc > 1 && strcmp(argv[1], "children") == 0;
|
||||
gboolean glyphsMode = argc > 1 && strcmp(argv[1], "glyphs") == 0;
|
||||
lineGeometryOnly = linesMode;
|
||||
missingGlyph = glyphsMode;
|
||||
gtk_init(&argc, &argv);
|
||||
measuredRanges = g_hash_table_new_full(g_int64_hash, g_int64_equal, g_free, NULL);
|
||||
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title(GTK_WINDOW(window), "Review cache probe");
|
||||
gtk_window_set_default_size(GTK_WINDOW(window), 300, 100);
|
||||
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
|
||||
GtkWidget *label = gtk_label_new("Cached review text");
|
||||
// This fixture has one label. Replace its class vfunc before the bridge
|
||||
// builds the initial cache, then arm the delay explicitly over stdin.
|
||||
if (!childrenMode)
|
||||
ATK_OBJECT_GET_CLASS(gtk_widget_get_accessible(label))->get_n_children = count_children;
|
||||
if (childrenMode) {
|
||||
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
|
||||
GtkWidget *panel = gtk_event_box_new();
|
||||
brokenSubtree = gtk_widget_get_accessible(panel);
|
||||
atk_object_set_name(brokenSubtree, "Broken subtree");
|
||||
originalChildCount = ATK_OBJECT_GET_CLASS(brokenSubtree)->get_n_children;
|
||||
ATK_OBJECT_GET_CLASS(brokenSubtree)->get_n_children = subtree_child_count;
|
||||
gtk_container_add(GTK_CONTAINER(panel), gtk_label_new("Subtree text"));
|
||||
gtk_container_add(GTK_CONTAINER(box), label);
|
||||
gtk_container_add(GTK_CONTAINER(box), panel);
|
||||
gtk_container_add(GTK_CONTAINER(window), box);
|
||||
} else if (boundsMode || clippedMode || longMode || linesMode || glyphsMode) {
|
||||
gchar *content = g_strnfill(linesMode ? 101000 : longMode ? 100001 : clippedMode ? 2020 : 3424, 'x');
|
||||
if (longMode) content[100000] = '\n';
|
||||
if (linesMode) {
|
||||
for (int row = 0; row < 1000; row++) content[row * 101 + 100] = '\n';
|
||||
gtk_window_set_default_size(GTK_WINDOW(window), 1000, 100);
|
||||
}
|
||||
if (clippedMode) {
|
||||
for (int row = 0; row < 20; row++) content[row * 101 + 100] = '\n';
|
||||
gtk_window_set_default_size(GTK_WINDOW(window), 300, 450);
|
||||
}
|
||||
gtk_label_set_text(GTK_LABEL(label), content);
|
||||
g_free(content);
|
||||
gtk_label_set_xalign(GTK_LABEL(label), 0);
|
||||
AtkObject *accessible = gtk_widget_get_accessible(label);
|
||||
atk_object_set_name(accessible, "Long review label");
|
||||
originalRangeExtents = ATK_TEXT_GET_IFACE(accessible)->get_range_extents;
|
||||
if (originalRangeExtents == NULL) g_error("fixture needs native GTK range extents");
|
||||
ATK_TEXT_GET_IFACE(accessible)->get_range_extents = range_extents;
|
||||
GtkWidget *scroller = gtk_scrolled_window_new(NULL, NULL);
|
||||
reviewScroller = scroller;
|
||||
gtk_container_add(GTK_CONTAINER(scroller), label);
|
||||
gtk_container_add(GTK_CONTAINER(window), scroller);
|
||||
} else {
|
||||
gtk_container_add(GTK_CONTAINER(window), label);
|
||||
}
|
||||
GIOChannel *input = g_io_channel_unix_new(0);
|
||||
g_io_add_watch(input, G_IO_IN | G_IO_HUP, command_ready, label);
|
||||
gtk_widget_show_all(window);
|
||||
gtk_main();
|
||||
g_io_channel_unref(input);
|
||||
g_hash_table_unref(measuredRanges);
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user