wayland-surface: disconnect signals on destroy
Otherwise signal handlers will be called on garbage https://bugzilla.gnome.org/show_bug.cgi?id=756548
This commit is contained in:
parent
f2afa7aa6c
commit
a4f763ac3b
@ -933,22 +933,26 @@ set_surface_is_on_output (MetaWaylandSurface *surface,
|
|||||||
MetaWaylandOutput *wayland_output,
|
MetaWaylandOutput *wayland_output,
|
||||||
gboolean is_on_output)
|
gboolean is_on_output)
|
||||||
{
|
{
|
||||||
gboolean was_on_output = g_hash_table_contains (surface->outputs,
|
gpointer orig_id;
|
||||||
wayland_output);
|
gboolean was_on_output = g_hash_table_lookup_extended (surface->outputs_to_destroy_notify_id,
|
||||||
|
wayland_output,
|
||||||
|
NULL, &orig_id);
|
||||||
|
|
||||||
if (!was_on_output && is_on_output)
|
if (!was_on_output && is_on_output)
|
||||||
{
|
{
|
||||||
g_signal_connect (wayland_output, "output-destroyed",
|
gulong id;
|
||||||
G_CALLBACK (surface_handle_output_destroy),
|
|
||||||
surface);
|
id = g_signal_connect (wayland_output, "output-destroyed",
|
||||||
g_hash_table_add (surface->outputs, wayland_output);
|
G_CALLBACK (surface_handle_output_destroy),
|
||||||
|
surface);
|
||||||
|
g_hash_table_insert (surface->outputs_to_destroy_notify_id, wayland_output,
|
||||||
|
GSIZE_TO_POINTER ((gsize)id));
|
||||||
surface_entered_output (surface, wayland_output);
|
surface_entered_output (surface, wayland_output);
|
||||||
}
|
}
|
||||||
else if (was_on_output && !is_on_output)
|
else if (was_on_output && !is_on_output)
|
||||||
{
|
{
|
||||||
g_hash_table_remove (surface->outputs, wayland_output);
|
g_hash_table_remove (surface->outputs_to_destroy_notify_id, wayland_output);
|
||||||
g_signal_handlers_disconnect_by_func (
|
g_signal_handler_disconnect (wayland_output, (gulong) GPOINTER_TO_SIZE (orig_id));
|
||||||
wayland_output, (gpointer)surface_handle_output_destroy, surface);
|
|
||||||
surface_left_output (surface, wayland_output);
|
surface_left_output (surface, wayland_output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -986,6 +990,12 @@ update_surface_output_state (gpointer key, gpointer value, gpointer user_data)
|
|||||||
set_surface_is_on_output (surface, wayland_output, is_on_output);
|
set_surface_is_on_output (surface, wayland_output, is_on_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
surface_output_disconnect_signal (gpointer key, gpointer value, gpointer user_data)
|
||||||
|
{
|
||||||
|
g_signal_handler_disconnect (key, (gulong) GPOINTER_TO_SIZE (value));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_wayland_surface_update_outputs (MetaWaylandSurface *surface)
|
meta_wayland_surface_update_outputs (MetaWaylandSurface *surface)
|
||||||
{
|
{
|
||||||
@ -1036,7 +1046,8 @@ wl_surface_destructor (struct wl_resource *resource)
|
|||||||
|
|
||||||
meta_wayland_compositor_destroy_frame_callbacks (compositor, surface);
|
meta_wayland_compositor_destroy_frame_callbacks (compositor, surface);
|
||||||
|
|
||||||
g_hash_table_unref (surface->outputs);
|
g_hash_table_foreach (surface->outputs_to_destroy_notify_id, surface_output_disconnect_signal, surface);
|
||||||
|
g_hash_table_unref (surface->outputs_to_destroy_notify_id);
|
||||||
|
|
||||||
wl_list_for_each_safe (cb, next, &surface->pending_frame_callback_list, link)
|
wl_list_for_each_safe (cb, next, &surface->pending_frame_callback_list, link)
|
||||||
wl_resource_destroy (cb->resource);
|
wl_resource_destroy (cb->resource);
|
||||||
@ -1081,7 +1092,7 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
|
|||||||
|
|
||||||
sync_drag_dest_funcs (surface);
|
sync_drag_dest_funcs (surface);
|
||||||
|
|
||||||
surface->outputs = g_hash_table_new (NULL, NULL);
|
surface->outputs_to_destroy_notify_id = g_hash_table_new (NULL, NULL);
|
||||||
|
|
||||||
pending_state_init (&surface->pending);
|
pending_state_init (&surface->pending);
|
||||||
return surface;
|
return surface;
|
||||||
|
@ -147,7 +147,7 @@ struct _MetaWaylandSurface
|
|||||||
int scale;
|
int scale;
|
||||||
int32_t offset_x, offset_y;
|
int32_t offset_x, offset_y;
|
||||||
GList *subsurfaces;
|
GList *subsurfaces;
|
||||||
GHashTable *outputs;
|
GHashTable *outputs_to_destroy_notify_id;
|
||||||
|
|
||||||
/* List of pending frame callbacks that needs to stay queued longer than one
|
/* List of pending frame callbacks that needs to stay queued longer than one
|
||||||
* commit sequence, such as when it has not yet been assigned a role.
|
* commit sequence, such as when it has not yet been assigned a role.
|
||||||
|
Loading…
Reference in New Issue
Block a user