summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2018-08-27 08:37:16 +0200
committerBenjamin Otte <otte@redhat.com>2018-09-16 18:50:17 +0200
commit63e5b827eddc2f208886b004ab97363edaf2bde9 (patch)
tree496bf0d57cae1d50c3d70e98b7f4c51b2bd1fb07
parent573c63973abb30d99fc953037f8b303f5b4f3387 (diff)
downloadgtk+-63e5b827eddc2f208886b004ab97363edaf2bde9.tar.gz
window: Add gtk_window_get_toplevels()
This one returns a list of all toplevel windows.
-rw-r--r--docs/reference/gtk/gtk4-sections.txt1
-rw-r--r--gtk/gtkwidget.c3
-rw-r--r--gtk/gtkwindow.c55
-rw-r--r--gtk/gtkwindow.h2
4 files changed, 55 insertions, 6 deletions
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index dda37387e0..dbb179d3b1 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -4500,6 +4500,7 @@ gtk_window_set_destroy_with_parent
gtk_window_set_display
gtk_window_is_active
gtk_window_is_maximized
+gtk_window_get_toplevels
gtk_window_list_toplevels
gtk_window_add_mnemonic
gtk_window_remove_mnemonic
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 7699887c7f..a6c56292d9 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -3109,6 +3109,9 @@ gtk_widget_unparent (GtkWidget *widget)
_gtk_widget_update_parent_muxer (widget);
+ if (old_parent->priv->children_observer)
+ gtk_list_list_model_item_removed (old_parent->priv->children_observer, old_prev_sibling);
+
if (toplevel)
{
_gtk_widget_propagate_hierarchy_changed (widget, toplevel);
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 48620575d7..e2cc8525f6 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -520,7 +520,7 @@ static void gtk_window_style_updated (GtkWidget *widget);
static void gtk_surface_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state);
-static GSList *toplevel_list = NULL;
+static GListStore *toplevel_list = NULL;
static guint window_signals[LAST_SIGNAL] = { 0 };
static GList *default_icon_list = NULL;
static gchar *default_icon_name = NULL;
@@ -785,6 +785,9 @@ gtk_window_class_init (GtkWindowClass *klass)
quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
quark_gtk_buildable_accels = g_quark_from_static_string ("gtk-window-buildable-accels");
+ if (toplevel_list == NULL)
+ toplevel_list = g_list_store_new (GTK_TYPE_WIDGET);
+
gobject_class->constructed = gtk_window_constructed;
gobject_class->dispose = gtk_window_dispose;
gobject_class->finalize = gtk_window_finalize;
@@ -1911,7 +1914,6 @@ gtk_window_init (GtkWindow *window)
g_object_ref_sink (window);
priv->has_user_ref_count = TRUE;
- toplevel_list = g_slist_prepend (toplevel_list, window);
gtk_window_update_debugging ();
#ifdef GDK_WINDOWING_X11
@@ -2001,6 +2003,9 @@ gtk_window_constructed (GObject *object)
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->bubble_drag_gesture),
GTK_PHASE_BUBBLE);
}
+
+ g_list_store_append (toplevel_list, window);
+ g_object_unref (window);
}
static void
@@ -3272,6 +3277,26 @@ gtk_window_get_modal (GtkWindow *window)
}
/**
+ * gtk_window_get_toplevels:
+ *
+ * Returns a list of all existing toplevel windows.
+ *
+ * If you want to iterate through the list and perform actions involving
+ * callbacks that might destroy the widgets or add new ones, be aware that
+ * the list of toplevels will change and emit the "items-changed" signal.
+ *
+ * Returns: (element-type GtkWidget) (transfer none): the list of toplevel widgets
+ */
+GListModel *
+gtk_window_get_toplevels (void)
+{
+ if (toplevel_list == NULL)
+ toplevel_list = g_list_store_new (GTK_TYPE_WIDGET);
+
+ return G_LIST_MODEL (toplevel_list);
+}
+
+/**
* gtk_window_list_toplevels:
*
* Returns a list of all existing toplevel windows. The widgets
@@ -3286,11 +3311,18 @@ gtk_window_get_modal (GtkWindow *window)
GList*
gtk_window_list_toplevels (void)
{
+ GListModel *toplevels;
GList *list = NULL;
- GSList *slist;
+ guint i;
- for (slist = toplevel_list; slist; slist = slist->next)
- list = g_list_prepend (list, slist->data);
+ toplevels = gtk_window_get_toplevels ();
+
+ for (i = 0; i < g_list_model_get_n_items (toplevels); i++)
+ {
+ gpointer item = g_list_model_get_item (toplevels, i);
+ list = g_list_prepend (list, item);
+ g_object_unref (item);
+ }
return list;
}
@@ -5868,10 +5900,21 @@ gtk_window_destroy (GtkWidget *widget)
{
GtkWindow *window = GTK_WINDOW (widget);
GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
+ guint i;
gtk_window_release_application (window);
- toplevel_list = g_slist_remove (toplevel_list, window);
+ for (i = 0; i < g_list_model_get_n_items (G_LIST_MODEL (toplevel_list)); i++)
+ {
+ gpointer item = g_list_model_get_item (G_LIST_MODEL (toplevel_list), i);
+ if (item == window)
+ {
+ g_list_store_remove (toplevel_list, i);
+ break;
+ }
+ else
+ g_object_unref (item);
+ }
gtk_window_update_debugging ();
if (priv->transient_parent)
diff --git a/gtk/gtkwindow.h b/gtk/gtkwindow.h
index 96c0e75267..35143ab700 100644
--- a/gtk/gtkwindow.h
+++ b/gtk/gtkwindow.h
@@ -315,6 +315,8 @@ void gtk_window_set_modal (GtkWindow *window,
GDK_AVAILABLE_IN_ALL
gboolean gtk_window_get_modal (GtkWindow *window);
GDK_AVAILABLE_IN_ALL
+GListModel *gtk_window_get_toplevels (void);
+GDK_AVAILABLE_IN_ALL
GList* gtk_window_list_toplevels (void);
GDK_AVAILABLE_IN_ALL
void gtk_window_set_has_user_ref_count (GtkWindow *window,