diff --git a/docs/reference/gtk/migrating-3to4.md b/docs/reference/gtk/migrating-3to4.md index 0ffe95a8b5..3779465b35 100644 --- a/docs/reference/gtk/migrating-3to4.md +++ b/docs/reference/gtk/migrating-3to4.md @@ -133,7 +133,7 @@ or `gtk_style_context_get_color()` only accept the context's current state for their state argument. You should update all callers to pass the current state. -### Stop using `gdk_pixbuf_get_from_window()` and `gdk_cairo_set_source_surface()` +### Stop using `gdk_pixbuf_get_from_window()` and `gdk_cairo_set_source_window()` These functions are not supported in GTK 4. Instead, either use backend-specific APIs, or render your widgets using @@ -243,6 +243,10 @@ in GTK 3, you can prepare for the switch by using `gtk_widget_destroy()` only on toplevel windows, and replace all other uses with `gtk_container_remove()` or `g_object_unref()`. +### Stop using the GtkWidget.destroy vfunc + +Instead of implementing GtkWidget.destroy, you can implement GObject.dispose. + ### Reduce the use of generic container APIs GTK 4 removes `gtk_container_add()` and `gtk_container_remove()`. While there diff --git a/gtk/gtkselectionfiltermodel.c b/gtk/gtkselectionfiltermodel.c index 46cde1e965..398b88bc30 100644 --- a/gtk/gtkselectionfiltermodel.c +++ b/gtk/gtkselectionfiltermodel.c @@ -64,10 +64,10 @@ gtk_selection_filter_model_get_n_items (GListModel *list) { GtkSelectionFilterModel *self = GTK_SELECTION_FILTER_MODEL (list); - if (self->selection) - return gtk_bitset_get_size (self->selection); + if (!self->selection) + return 0; - return 0; + return gtk_bitset_get_size (self->selection); } static gpointer @@ -76,6 +76,12 @@ gtk_selection_filter_model_get_item (GListModel *list, { GtkSelectionFilterModel *self = GTK_SELECTION_FILTER_MODEL (list); + if (!self->selection) + return NULL; + + if (position >= gtk_bitset_get_size (self->selection)) + return NULL; + position = gtk_bitset_get_nth (self->selection, position); return g_list_model_get_item (G_LIST_MODEL (self->model), position); diff --git a/testsuite/gtk/filterlistmodel.c b/testsuite/gtk/filterlistmodel.c index fbcae6b3ad..cd109c2e0b 100644 --- a/testsuite/gtk/filterlistmodel.c +++ b/testsuite/gtk/filterlistmodel.c @@ -376,6 +376,35 @@ test_incremental (void) g_object_unref (filter); } +static void +test_empty (void) +{ + GtkFilterListModel *filter; + GListStore *store; + GtkFilter *f; + + filter = gtk_filter_list_model_new (NULL, NULL); + + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (filter)), ==, 0); + g_assert_null (g_list_model_get_item (G_LIST_MODEL (filter), 11)); + + store = g_list_store_new (G_TYPE_OBJECT); + gtk_filter_list_model_set_model (filter, G_LIST_MODEL (store)); + g_object_unref (store); + + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (filter)), ==, 0); + g_assert_null (g_list_model_get_item (G_LIST_MODEL (filter), 11)); + + f = GTK_FILTER (gtk_every_filter_new ()); + gtk_filter_list_model_set_filter (filter, f); + g_object_unref (f); + + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (filter)), ==, 0); + g_assert_null (g_list_model_get_item (G_LIST_MODEL (filter), 11)); + + g_object_unref (filter); +} + int main (int argc, char *argv[]) { @@ -389,6 +418,7 @@ main (int argc, char *argv[]) g_test_add_func ("/filterlistmodel/empty_set_filter", test_empty_set_filter); g_test_add_func ("/filterlistmodel/change_filter", test_change_filter); g_test_add_func ("/filterlistmodel/incremental", test_incremental); + g_test_add_func ("/filterlistmodel/empty", test_empty); return g_test_run (); } diff --git a/testsuite/gtk/multiselection.c b/testsuite/gtk/multiselection.c index bdc896073b..7117efb4e7 100644 --- a/testsuite/gtk/multiselection.c +++ b/testsuite/gtk/multiselection.c @@ -681,6 +681,47 @@ test_set_model (void) g_object_unref (selection); } +static void +test_empty (void) +{ + GtkMultiSelection *selection; + GListStore *store; + + selection = gtk_multi_selection_new (NULL); + + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (selection)), ==, 0); + g_assert_null (g_list_model_get_item (G_LIST_MODEL (selection), 11)); + + store = g_list_store_new (G_TYPE_OBJECT); + gtk_multi_selection_set_model (selection, G_LIST_MODEL (store)); + g_object_unref (store); + + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (selection)), ==, 0); + g_assert_null (g_list_model_get_item (G_LIST_MODEL (selection), 11)); + + g_object_unref (selection); +} + +static void +test_empty_filter (void) +{ + GtkStringList *stringlist; + GtkMultiSelection *selection; + GtkSelectionFilterModel *selection_filter; + + stringlist = gtk_string_list_new (NULL); + gtk_string_list_append (stringlist, "first item"); + + selection = gtk_multi_selection_new (G_LIST_MODEL (stringlist)); + selection_filter = gtk_selection_filter_model_new (GTK_SELECTION_MODEL (selection)); + + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (selection_filter)), ==, 0); + g_assert_null (g_list_model_get_item (G_LIST_MODEL (selection_filter), 11)); + + g_object_unref (selection_filter); + g_object_unref (selection); +} + int main (int argc, char *argv[]) { @@ -703,6 +744,8 @@ main (int argc, char *argv[]) g_test_add_func ("/multiselection/set_selection", test_set_selection); g_test_add_func ("/multiselection/selection-filter", test_selection_filter); g_test_add_func ("/multiselection/set-model", test_set_model); + g_test_add_func ("/multiselection/empty", test_empty); + g_test_add_func ("/multiselection/selection-filter/empty", test_empty_filter); return g_test_run (); } diff --git a/testsuite/gtk/singleselection.c b/testsuite/gtk/singleselection.c index 88283c36fc..bb6462cd97 100644 --- a/testsuite/gtk/singleselection.c +++ b/testsuite/gtk/singleselection.c @@ -706,6 +706,27 @@ test_set_model (void) g_object_unref (selection); } +static void +test_empty (void) +{ + GtkSingleSelection *selection; + GListStore *store; + + selection = gtk_single_selection_new (NULL); + + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (selection)), ==, 0); + g_assert_null (g_list_model_get_item (G_LIST_MODEL (selection), 11)); + + store = g_list_store_new (G_TYPE_OBJECT); + gtk_single_selection_set_model (selection, G_LIST_MODEL (store)); + g_object_unref (store); + + g_assert_cmpuint (g_list_model_get_n_items (G_LIST_MODEL (selection)), ==, 0); + g_assert_null (g_list_model_get_item (G_LIST_MODEL (selection), 11)); + + g_object_unref (selection); +} + int main (int argc, char *argv[]) { @@ -726,6 +747,7 @@ main (int argc, char *argv[]) g_test_add_func ("/singleselection/query-range", test_query_range); g_test_add_func ("/singleselection/changes", test_changes); g_test_add_func ("/singleselection/set-model", test_set_model); + g_test_add_func ("/singleselection/empty", test_empty); return g_test_run (); }