Merge branch 'wip/otte/for-main' into 'main'
inspector: Don't randomly emit application signals See merge request GNOME/gtk!5834
This commit is contained in:
@@ -41,6 +41,9 @@ struct _GtkListListModel
|
||||
gpointer (* get_item) (gpointer, gpointer);
|
||||
gpointer data;
|
||||
GDestroyNotify notify;
|
||||
|
||||
guint cache_pos;
|
||||
gpointer cache_item;
|
||||
};
|
||||
|
||||
struct _GtkListListModelClass
|
||||
@@ -72,6 +75,18 @@ gtk_list_list_model_get_n_items (GListModel *list)
|
||||
return self->n_items;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_list_list_model_cache_is_valid (GtkListListModel *self)
|
||||
{
|
||||
return self->cache_item != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_list_list_model_invalidate_cache (GtkListListModel *self)
|
||||
{
|
||||
self->cache_item = NULL;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
gtk_list_list_model_get_item (GListModel *list,
|
||||
guint position)
|
||||
@@ -79,31 +94,50 @@ gtk_list_list_model_get_item (GListModel *list,
|
||||
GtkListListModel *self = GTK_LIST_LIST_MODEL (list);
|
||||
gpointer result;
|
||||
guint i;
|
||||
guint start, end;
|
||||
|
||||
if (position >= self->n_items)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else if (self->get_last &&
|
||||
position >= self->n_items / 2)
|
||||
{
|
||||
result = self->get_last (self->data);
|
||||
return NULL;
|
||||
|
||||
for (i = self->n_items - 1; i > position; i--)
|
||||
start = 0;
|
||||
end = self->n_items;
|
||||
if (gtk_list_list_model_cache_is_valid (self))
|
||||
{
|
||||
if (self->cache_pos <= position)
|
||||
start = self->cache_pos;
|
||||
else
|
||||
end = self->cache_pos;
|
||||
}
|
||||
|
||||
if (self->get_last &&
|
||||
position > (start + end) / 2)
|
||||
{
|
||||
if (end == self->cache_pos && gtk_list_list_model_cache_is_valid (self))
|
||||
result = self->get_previous (self->cache_item, self->data);
|
||||
else
|
||||
result = self->get_last (self->data);
|
||||
|
||||
for (i = end - 1; i > position; i--)
|
||||
{
|
||||
result = self->get_previous (result, self->data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = self->get_first (self->data);
|
||||
if (start == self->cache_pos && gtk_list_list_model_cache_is_valid (self))
|
||||
result = self->cache_item;
|
||||
else
|
||||
result = self->get_first (self->data);
|
||||
|
||||
for (i = 0; i < position; i++)
|
||||
for (i = start; i < position; i++)
|
||||
{
|
||||
result = self->get_next (result, self->data);
|
||||
}
|
||||
}
|
||||
|
||||
self->cache_item = result;
|
||||
self->cache_pos = position;
|
||||
|
||||
return self->get_item (result, self->data);
|
||||
}
|
||||
|
||||
@@ -275,7 +309,9 @@ gtk_list_list_model_item_added_at (GtkListListModel *self,
|
||||
g_return_if_fail (GTK_IS_LIST_LIST_MODEL (self));
|
||||
g_return_if_fail (position <= self->n_items);
|
||||
|
||||
self->n_items += 1;
|
||||
self->n_items++;
|
||||
if (position <= self->cache_pos)
|
||||
self->cache_pos++;
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 0, 1);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
|
||||
@@ -327,6 +363,12 @@ gtk_list_list_model_item_moved (GtkListListModel *self,
|
||||
|
||||
min = MIN (position, previous_position);
|
||||
max = MAX (position, previous_position) + 1;
|
||||
|
||||
if (self->cache_item == item)
|
||||
self->cache_pos = position;
|
||||
else if (self->cache_pos >= min && self->cache_pos < max)
|
||||
self->cache_pos += (self->cache_pos > position ? 1 : -1);
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), min, max - min, max - min);
|
||||
}
|
||||
|
||||
@@ -338,6 +380,10 @@ gtk_list_list_model_item_removed_at (GtkListListModel *self,
|
||||
g_return_if_fail (position < self->n_items);
|
||||
|
||||
self->n_items -= 1;
|
||||
if (position == self->cache_pos)
|
||||
gtk_list_list_model_invalidate_cache (self);
|
||||
else if (position < self->cache_pos)
|
||||
self->cache_pos--;
|
||||
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), position, 1, 0);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_N_ITEMS]);
|
||||
@@ -358,6 +404,8 @@ gtk_list_list_model_clear (GtkListListModel *self)
|
||||
self->n_items = 0;
|
||||
self->notify = NULL;
|
||||
|
||||
gtk_list_list_model_invalidate_cache (self);
|
||||
|
||||
if (n_items > 0)
|
||||
{
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), 0, n_items, 0);
|
||||
|
||||
@@ -38,6 +38,7 @@ struct _GtkInspectorActionEditor
|
||||
gboolean enabled;
|
||||
const GVariantType *parameter_type;
|
||||
GVariantType *state_type;
|
||||
GVariant *state;
|
||||
GtkWidget *activate_button;
|
||||
GtkWidget *parameter_entry;
|
||||
GtkWidget *state_entry;
|
||||
@@ -101,6 +102,11 @@ state_changed (GtkWidget *editor,
|
||||
return;
|
||||
|
||||
g_variant_ref_sink (value);
|
||||
if (g_variant_equal (value, r->state))
|
||||
{
|
||||
g_variant_unref (value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (G_IS_ACTION_GROUP (r->owner))
|
||||
g_action_group_change_action_state (G_ACTION_GROUP (r->owner), r->name, value);
|
||||
@@ -147,35 +153,35 @@ gtk_inspector_action_editor_init (GtkInspectorActionEditor *r)
|
||||
static void
|
||||
update_widgets (GtkInspectorActionEditor *r)
|
||||
{
|
||||
GVariant *state;
|
||||
g_clear_pointer (&r->state, g_variant_unref);
|
||||
|
||||
if (G_IS_ACTION_GROUP (r->owner))
|
||||
{
|
||||
if (!g_action_group_query_action (G_ACTION_GROUP (r->owner), r->name,
|
||||
&r->enabled, &r->parameter_type, NULL, NULL,
|
||||
&state))
|
||||
&r->state))
|
||||
{
|
||||
r->enabled = FALSE;
|
||||
r->parameter_type = NULL;
|
||||
state = NULL;
|
||||
r->state = NULL;
|
||||
}
|
||||
}
|
||||
else if (GTK_IS_ACTION_MUXER (r->owner))
|
||||
{
|
||||
if (!gtk_action_muxer_query_action (GTK_ACTION_MUXER (r->owner), r->name,
|
||||
&r->enabled, &r->parameter_type, NULL, NULL,
|
||||
&state))
|
||||
&r->state))
|
||||
{
|
||||
r->enabled = FALSE;
|
||||
r->parameter_type = NULL;
|
||||
state = NULL;
|
||||
r->state = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
r->enabled = FALSE;
|
||||
r->parameter_type = NULL;
|
||||
state = NULL;
|
||||
r->state = NULL;
|
||||
}
|
||||
|
||||
gtk_widget_set_sensitive (r->activate_button, r->enabled);
|
||||
@@ -184,15 +190,13 @@ update_widgets (GtkInspectorActionEditor *r)
|
||||
if (r->parameter_type)
|
||||
gtk_inspector_variant_editor_set_type (r->parameter_entry, r->parameter_type);
|
||||
|
||||
gtk_widget_set_visible (r->state_editor, state != NULL);
|
||||
if (state)
|
||||
gtk_widget_set_visible (r->state_editor, r->state != NULL);
|
||||
if (r->state)
|
||||
{
|
||||
if (r->state_type)
|
||||
g_variant_type_free (r->state_type);
|
||||
r->state_type = g_variant_type_copy (g_variant_get_type (state));
|
||||
gtk_inspector_variant_editor_set_value (r->state_entry, state);
|
||||
|
||||
g_variant_unref (state);
|
||||
r->state_type = g_variant_type_copy (g_variant_get_type (r->state));
|
||||
gtk_inspector_variant_editor_set_value (r->state_entry, r->state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,6 +211,7 @@ dispose (GObject *object)
|
||||
|
||||
g_clear_pointer (&r->name, g_free);
|
||||
g_clear_pointer (&r->state_type, g_variant_type_free);
|
||||
g_clear_pointer (&r->state, g_variant_unref);
|
||||
|
||||
G_OBJECT_CLASS (gtk_inspector_action_editor_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ free_changes (gpointer data)
|
||||
}
|
||||
|
||||
static void
|
||||
test_list_list_model (void)
|
||||
test_change (void)
|
||||
{
|
||||
GtkWidget *box;
|
||||
GListModel *model;
|
||||
@@ -111,6 +111,87 @@ test_list_list_model (void)
|
||||
g_object_unref (box);
|
||||
}
|
||||
|
||||
static void
|
||||
test_exhaustive (void)
|
||||
{
|
||||
GtkBox *box;
|
||||
GListModel *model, *compare;
|
||||
guint i;
|
||||
|
||||
box = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0));
|
||||
g_object_ref_sink (box);
|
||||
|
||||
model = gtk_widget_observe_children (GTK_WIDGET (box));
|
||||
compare = G_LIST_MODEL (g_list_store_new (GTK_TYPE_WIDGET));
|
||||
|
||||
for (i = 0; i < 500; i++)
|
||||
{
|
||||
switch (g_test_rand_int_range (0, 4))
|
||||
{
|
||||
case 0:
|
||||
/* compare */
|
||||
g_assert_cmpint (g_list_model_get_n_items (model), ==, g_list_model_get_n_items (compare));
|
||||
if (g_list_model_get_n_items (compare) > 0)
|
||||
{
|
||||
guint n = g_list_model_get_n_items (compare);
|
||||
guint step = n == 1 ? 1 : g_test_rand_int_range (1, n);
|
||||
guint j = 0;
|
||||
do
|
||||
{
|
||||
gpointer o1 = g_list_model_get_item (model, j);
|
||||
gpointer o2 = g_list_model_get_item (compare, j);
|
||||
g_assert_cmphex (GPOINTER_TO_SIZE (o1), ==, GPOINTER_TO_SIZE (o2));
|
||||
g_object_unref (o1);
|
||||
g_object_unref (o2);
|
||||
j = (j + step) % n;
|
||||
}
|
||||
while (j != 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* remove a widget */
|
||||
if (g_list_model_get_n_items (compare) > 0)
|
||||
{
|
||||
guint position = g_test_rand_int_range (0, g_list_model_get_n_items (compare));
|
||||
GtkWidget *child = g_list_model_get_item (compare, position);
|
||||
gtk_box_remove (box, child);
|
||||
g_list_store_remove (G_LIST_STORE (compare), position);
|
||||
g_object_unref (child);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* add a widget */
|
||||
{
|
||||
guint position = g_test_rand_int_range (0, g_list_model_get_n_items (compare) + 1);
|
||||
GtkWidget *child = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
|
||||
GtkWidget *sibling;
|
||||
if (position == 0)
|
||||
sibling = NULL;
|
||||
else
|
||||
sibling = g_list_model_get_item (compare, position - 1);
|
||||
gtk_box_insert_child_after (box, child, sibling);
|
||||
g_list_store_insert (G_LIST_STORE (compare), position, child);
|
||||
g_clear_object (&sibling);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* move a widget (FIXME) */
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (compare);
|
||||
g_object_unref (box);
|
||||
g_object_unref (model);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@@ -120,7 +201,8 @@ main (int argc, char *argv[])
|
||||
|
||||
changes_quark = g_quark_from_static_string ("What did I see? Can I believe what I saw?");
|
||||
|
||||
g_test_add_func ("/listlistmodel/change", test_list_list_model);
|
||||
g_test_add_func ("/listlistmodel/change", test_change);
|
||||
g_test_add_func ("/listlistmodel/exhaustive", test_exhaustive);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user