diff --git a/meson.build b/meson.build
index 6ec758167..03d61737b 100644
--- a/meson.build
+++ b/meson.build
@@ -15,7 +15,7 @@ libmutter_api_version = '@0@'.format(api_version)
# generic version requirements
fribidi_req = '>= 1.0.0'
-glib_req = '>= 2.53.2'
+glib_req = '>= 2.56'
gi_req = '>= 0.9.5'
gtk3_req = '>= 3.19.8'
gdk_pixbuf_req = '>= 2.0'
diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h
index 821f1dff0..dc384d36f 100644
--- a/src/compositor/compositor-private.h
+++ b/src/compositor/compositor-private.h
@@ -13,6 +13,8 @@
struct _MetaCompositor
{
+ GObject parent;
+
MetaDisplay *display;
guint pre_paint_func_id;
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index cbb0ab6df..0a762452f 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -86,6 +86,8 @@
#include "wayland/meta-wayland-private.h"
#endif
+G_DEFINE_TYPE (MetaCompositor, meta_compositor, G_TYPE_OBJECT)
+
static void
on_presented (ClutterStage *stage,
CoglFrameEvent event,
@@ -135,33 +137,8 @@ meta_switch_workspace_completed (MetaCompositor *compositor)
void
meta_compositor_destroy (MetaCompositor *compositor)
{
- g_signal_handler_disconnect (compositor->stage,
- compositor->stage_after_paint_id);
- g_signal_handler_disconnect (compositor->stage,
- compositor->stage_presented_id);
-
- compositor->stage_after_paint_id = 0;
- compositor->stage_presented_id = 0;
- compositor->stage = NULL;
-
- clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
- clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
-
- if (compositor->top_window_actor)
- {
- g_signal_handler_disconnect (compositor->top_window_actor,
- compositor->top_window_actor_destroy_id);
- compositor->top_window_actor = NULL;
- compositor->top_window_actor_destroy_id = 0;
- }
-
- g_clear_pointer (&compositor->window_group, clutter_actor_destroy);
- g_clear_pointer (&compositor->top_window_group, clutter_actor_destroy);
- g_clear_pointer (&compositor->feedback_group, clutter_actor_destroy);
- g_clear_pointer (&compositor->windows, g_list_free);
-
- if (compositor->have_x11_sync_object)
- meta_sync_ring_destroy ();
+ g_object_run_dispose (G_OBJECT (compositor));
+ g_object_unref (compositor);
}
static void
@@ -1309,12 +1286,20 @@ on_shadow_factory_changed (MetaShadowFactory *factory,
MetaCompositor *
meta_compositor_new (MetaDisplay *display)
{
- MetaBackend *backend = meta_get_backend ();
- ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
MetaCompositor *compositor;
- compositor = g_new0 (MetaCompositor, 1);
+ compositor = g_object_new (META_TYPE_COMPOSITOR, NULL);
compositor->display = display;
+
+ return compositor;
+}
+
+static void
+meta_compositor_init (MetaCompositor *compositor)
+{
+ MetaBackend *backend = meta_get_backend ();
+ ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
+
compositor->context = clutter_backend->cogl_context;
g_signal_connect (meta_shadow_factory_get_default (),
@@ -1332,7 +1317,59 @@ meta_compositor_new (MetaDisplay *display)
meta_post_paint_func,
compositor,
NULL);
- return compositor;
+}
+
+static void
+meta_compositor_dispose (GObject *object)
+{
+ MetaCompositor *compositor = META_COMPOSITOR (object);
+
+ if (compositor->stage)
+ {
+ g_signal_handler_disconnect (compositor->stage,
+ compositor->stage_after_paint_id);
+ g_signal_handler_disconnect (compositor->stage,
+ compositor->stage_presented_id);
+
+ compositor->stage_after_paint_id = 0;
+ compositor->stage_presented_id = 0;
+ compositor->stage = NULL;
+ }
+
+ g_clear_handle_id (&compositor->pre_paint_func_id,
+ clutter_threads_remove_repaint_func);
+ g_clear_handle_id (&compositor->post_paint_func_id,
+ clutter_threads_remove_repaint_func);
+
+ if (compositor->top_window_actor)
+ {
+ g_signal_handlers_disconnect_by_func (compositor->top_window_actor,
+ on_top_window_actor_destroyed,
+ compositor);
+ compositor->top_window_actor = NULL;
+ compositor->top_window_actor_destroy_id = 0;
+ }
+
+ g_clear_pointer (&compositor->window_group, clutter_actor_destroy);
+ g_clear_pointer (&compositor->top_window_group, clutter_actor_destroy);
+ g_clear_pointer (&compositor->feedback_group, clutter_actor_destroy);
+ g_clear_pointer (&compositor->windows, g_list_free);
+
+ if (compositor->have_x11_sync_object)
+ {
+ meta_sync_ring_destroy ();
+ compositor->have_x11_sync_object = FALSE;
+ }
+
+ G_OBJECT_CLASS (meta_compositor_parent_class)->dispose (object);
+}
+
+static void
+meta_compositor_class_init (MetaCompositorClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = meta_compositor_dispose;
}
/**
diff --git a/src/meta/compositor.h b/src/meta/compositor.h
index 43dcc2b19..d97ddf20a 100644
--- a/src/meta/compositor.h
+++ b/src/meta/compositor.h
@@ -28,6 +28,10 @@
#include
#include
+#define META_TYPE_COMPOSITOR (meta_compositor_get_type ())
+META_EXPORT
+G_DECLARE_FINAL_TYPE (MetaCompositor, meta_compositor, META, COMPOSITOR, GObject)
+
/**
* MetaCompEffect:
* @META_COMP_EFFECT_CREATE: The window is newly created