[gtk+/wip/carlosg/event-delivery: 104/104] gtk: Make GtkPointerFocus refcounted
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/carlosg/event-delivery: 104/104] gtk: Make GtkPointerFocus refcounted
- Date: Thu, 25 May 2017 14:48:51 +0000 (UTC)
commit b894c350080f5686a7c8bb7107001373da097b5f
Author: Carlos Garnacho <carlosg gnome org>
Date: Thu May 25 16:00:40 2017 +0200
gtk: Make GtkPointerFocus refcounted
In order to make it really sure the GtkPointerFocus is valid while being
removed from a GtkWindow.
gtk/gtkpointerfocus.c | 21 +++++++++++++++++----
gtk/gtkpointerfocusprivate.h | 4 +++-
gtk/gtkwindow.c | 20 ++++++++++++++++----
3 files changed, 36 insertions(+), 9 deletions(-)
---
diff --git a/gtk/gtkpointerfocus.c b/gtk/gtkpointerfocus.c
index 3a4026d..cb484b8 100644
--- a/gtk/gtkpointerfocus.c
+++ b/gtk/gtkpointerfocus.c
@@ -39,6 +39,7 @@ gtk_pointer_focus_new (GtkWindow *toplevel,
GtkPointerFocus *focus;
focus = g_new0 (GtkPointerFocus, 1);
+ focus->ref_count = 1;
focus->toplevel = toplevel;
focus->device = device;
focus->sequence = sequence;
@@ -48,12 +49,24 @@ gtk_pointer_focus_new (GtkWindow *toplevel,
return focus;
}
+GtkPointerFocus *
+gtk_pointer_focus_ref (GtkPointerFocus *focus)
+{
+ focus->ref_count++;
+ return focus;
+}
+
void
-gtk_pointer_focus_free (GtkPointerFocus *focus)
+gtk_pointer_focus_unref (GtkPointerFocus *focus)
{
- gtk_pointer_focus_set_target (focus, NULL);
- gtk_pointer_focus_set_implicit_grab (focus, NULL);
- g_free (focus);
+ focus->ref_count--;
+
+ if (focus->ref_count == 0)
+ {
+ gtk_pointer_focus_set_target (focus, NULL);
+ gtk_pointer_focus_set_implicit_grab (focus, NULL);
+ g_free (focus);
+ }
}
void
diff --git a/gtk/gtkpointerfocusprivate.h b/gtk/gtkpointerfocusprivate.h
index 5d5be95..c7ffd90 100644
--- a/gtk/gtkpointerfocusprivate.h
+++ b/gtk/gtkpointerfocusprivate.h
@@ -24,6 +24,7 @@ typedef struct _GtkPointerFocus GtkPointerFocus;
struct _GtkPointerFocus
{
+ gint ref_count;
GdkDevice *device;
GdkEventSequence *sequence;
GtkWindow *toplevel;
@@ -38,7 +39,8 @@ GtkPointerFocus * gtk_pointer_focus_new (GtkWindow *toplevel,
GdkEventSequence *sequence,
gdouble x,
gdouble y);
-void gtk_pointer_focus_free (GtkPointerFocus *focus);
+GtkPointerFocus * gtk_pointer_focus_ref (GtkPointerFocus *focus);
+void gtk_pointer_focus_unref (GtkPointerFocus *focus);
void gtk_pointer_focus_set_coordinates (GtkPointerFocus *focus,
gdouble x,
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 0304673..8e71100 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -1689,9 +1689,9 @@ device_removed_cb (GdkSeat *seat,
if (focus->device == device)
{
- gtk_pointer_focus_free (focus);
window->priv->foci =
g_list_delete_link (window->priv->foci, cur);
+ gtk_pointer_focus_unref (focus);
}
}
}
@@ -11275,7 +11275,7 @@ gtk_window_add_pointer_focus (GtkWindow *window,
{
GtkWindowPrivate *priv = window->priv;
- priv->foci = g_list_prepend (priv->foci, focus);
+ priv->foci = g_list_prepend (priv->foci, gtk_pointer_focus_ref (focus));
}
static void
@@ -11283,8 +11283,14 @@ gtk_window_remove_pointer_focus (GtkWindow *window,
GtkPointerFocus *focus)
{
GtkWindowPrivate *priv = window->priv;
+ GList *pos;
+
+ pos = g_list_find (priv->foci, focus);
+ if (!pos)
+ return;
priv->foci = g_list_remove (priv->foci, focus);
+ gtk_pointer_focus_unref (focus);
}
static GtkPointerFocus *
@@ -11351,6 +11357,8 @@ gtk_window_update_pointer_focus (GtkWindow *window,
focus = gtk_window_lookup_pointer_focus (window, device, sequence);
if (focus)
{
+ gtk_pointer_focus_ref (focus);
+
if (target)
{
gtk_pointer_focus_set_target (focus, target);
@@ -11359,8 +11367,9 @@ gtk_window_update_pointer_focus (GtkWindow *window,
else
{
gtk_window_remove_pointer_focus (window, focus);
- gtk_pointer_focus_free (focus);
}
+
+ gtk_pointer_focus_unref (focus);
}
else if (target)
{
@@ -11383,17 +11392,20 @@ gtk_window_update_pointer_focus_on_state_change (GtkWindow *window,
focus = cur->data;
l = cur->next;
+ gtk_pointer_focus_ref (focus);
+
if (GTK_WIDGET (focus->toplevel) == widget)
{
/* Unmapping the toplevel, remove pointer focus */
gtk_window_remove_pointer_focus (window, focus);
- gtk_pointer_focus_free (focus);
}
else if (focus->target == widget ||
gtk_widget_is_ancestor (focus->target, widget))
{
gtk_pointer_focus_repick_target (focus);
}
+
+ gtk_pointer_focus_unref (focus);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]