diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
index c9596870a..f09e4c99d 100644
--- a/src/backends/meta-backend-private.h
+++ b/src/backends/meta-backend-private.h
@@ -137,6 +137,10 @@ struct _MetaBackendClass
                                    MetaPointerConstraint *constraint);
 
   gboolean (* is_headless) (MetaBackend *backend);
+
+  void (* pause) (MetaBackend *backend);
+
+  void (* resume) (MetaBackend *backend);
 };
 
 void meta_backend_destroy (MetaBackend *backend);
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 184736e64..5eb94f902 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -630,6 +630,24 @@ meta_backend_real_is_headless (MetaBackend *backend)
   return FALSE;
 }
 
+static void
+meta_backend_real_pause (MetaBackend *backend)
+{
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+  meta_renderer_pause (priv->renderer);
+}
+
+static void
+meta_backend_real_resume (MetaBackend *backend)
+{
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+  ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
+
+  meta_renderer_resume (priv->renderer);
+  clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
+}
+
 void
 meta_backend_freeze_keyboard (MetaBackend *backend,
                               uint32_t     timestamp)
@@ -863,6 +881,8 @@ meta_backend_class_init (MetaBackendClass *klass)
   klass->is_lid_closed = meta_backend_real_is_lid_closed;
   klass->create_cursor_tracker = meta_backend_real_create_cursor_tracker;
   klass->is_headless = meta_backend_real_is_headless;
+  klass->pause = meta_backend_real_pause;
+  klass->resume = meta_backend_real_resume;
 
   obj_props[PROP_CONTEXT] =
     g_param_spec_object ("context", NULL, NULL,
@@ -927,14 +947,59 @@ meta_backend_class_init (MetaBackendClass *klass)
                   G_TYPE_NONE, 0);
 }
 
+static void
+meta_backend_pause (MetaBackend *backend)
+{
+  COGL_TRACE_BEGIN_SCOPED (MetaBackendPause,
+                           "Meta::Backend::pause()");
+
+  META_BACKEND_GET_CLASS (backend)->pause (backend);
+}
+
+static void
+meta_backend_resume (MetaBackend *backend)
+{
+  COGL_TRACE_BEGIN_SCOPED (MetaBackendResume,
+                           "Meta::Backend::resume()");
+
+  META_BACKEND_GET_CLASS (backend)->resume (backend);
+}
+
+static void
+on_session_active_changed (MetaLauncher *launcher,
+                           GParamSpec   *pspec,
+                           MetaBackend  *backend)
+{
+  gboolean active = meta_launcher_is_session_active (launcher);
+
+  if (active)
+    meta_backend_resume (backend);
+  else
+    meta_backend_pause (backend);
+}
+
 static gboolean
 meta_backend_create_launcher (MetaBackend   *backend,
                               MetaLauncher **launcher_out,
                               GError       **error)
 {
-  return META_BACKEND_GET_CLASS (backend)->create_launcher (backend,
-                                                            launcher_out,
-                                                            error);
+  g_autoptr (MetaLauncher) launcher = NULL;
+  gboolean ret;
+
+  ret = META_BACKEND_GET_CLASS (backend)->create_launcher (backend,
+                                                           &launcher,
+                                                           error);
+
+  if (launcher)
+    {
+      g_signal_connect_object (launcher, "notify::session-active",
+                               G_CALLBACK (on_session_active_changed),
+                               backend,
+                               G_CONNECT_DEFAULT);
+    }
+
+  *launcher_out = g_steal_pointer (&launcher);
+  return ret;
 }
 
 static MetaMonitorManager *
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
index 2e4996afc..9565b7c92 100644
--- a/src/backends/native/meta-backend-native.c
+++ b/src/backends/native/meta-backend-native.c
@@ -100,9 +100,9 @@ G_DEFINE_TYPE_WITH_PRIVATE (MetaBackendNative,
                             meta_backend_native,
                             META_TYPE_BACKEND)
 
-static void meta_backend_native_resume (MetaBackendNative *native);
+static void meta_backend_native_resume (MetaBackend *backend);
 
-static void meta_backend_native_pause (MetaBackendNative *native);
+static void meta_backend_native_pause (MetaBackend *backend);
 
 static void
 meta_backend_native_dispose (GObject *object)
@@ -737,17 +737,6 @@ on_started (MetaContext *context,
   meta_seat_native_start (META_SEAT_NATIVE (seat));
 }
 
-static void
-on_session_active_changed (MetaLauncher      *launcher,
-                           GParamSpec        *pspec,
-                           MetaBackendNative *native)
-{
-  if (meta_launcher_is_session_active (launcher))
-    meta_backend_native_resume (native);
-  else
-    meta_backend_native_pause (native);
-}
-
 static gboolean
 meta_backend_native_create_launcher (MetaBackend   *backend,
                                      MetaLauncher **launcher_out,
@@ -795,10 +784,6 @@ meta_backend_native_create_launcher (MetaBackend   *backend,
       return FALSE;
     }
 
-  g_signal_connect (launcher, "notify::session-active",
-                    G_CALLBACK (on_session_active_changed),
-                    native);
-
   *launcher_out = g_steal_pointer (&launcher);
   return TRUE;
 }
@@ -895,6 +880,9 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
 
   backend_class->is_headless = meta_backend_native_is_headless;
 
+  backend_class->pause = meta_backend_native_pause;
+  backend_class->resume = meta_backend_native_resume;
+
   obj_props[PROP_MODE] =
     g_param_spec_enum ("mode", NULL, NULL,
                        META_TYPE_BACKEND_NATIVE_MODE,
@@ -969,11 +957,11 @@ meta_backend_native_activate_vt (MetaBackendNative  *backend_native,
 }
 
 static void
-meta_backend_native_pause (MetaBackendNative *backend_native)
+meta_backend_native_pause (MetaBackend *backend)
 {
+  MetaBackendNative *native = META_BACKEND_NATIVE (backend);
   MetaBackendNativePrivate *priv =
-    meta_backend_native_get_instance_private (backend_native);
-  MetaBackend *backend = META_BACKEND (backend_native);
+    meta_backend_native_get_instance_private (native);
   MetaMonitorManager *monitor_manager =
     meta_backend_get_monitor_manager (backend);
   MetaMonitorManagerNative *monitor_manager_native =
@@ -981,25 +969,20 @@ meta_backend_native_pause (MetaBackendNative *backend_native)
   ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
   MetaSeatNative *seat =
     META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
-  MetaRenderer *renderer = meta_backend_get_renderer (backend);
-
-  COGL_TRACE_BEGIN_SCOPED (MetaBackendNativePause,
-                           "Meta::BackendNative::pause()");
 
   meta_seat_native_release_devices (seat);
-  meta_renderer_pause (renderer);
   meta_udev_pause (priv->udev);
-
   meta_monitor_manager_native_pause (monitor_manager_native);
+
+  META_BACKEND_CLASS (meta_backend_native_parent_class)->pause (backend);
 }
 
 static void
-meta_backend_native_resume (MetaBackendNative *native)
+meta_backend_native_resume (MetaBackend *backend)
 {
+  MetaBackendNative *native = META_BACKEND_NATIVE (backend);
   MetaBackendNativePrivate *priv =
     meta_backend_native_get_instance_private (native);
-  MetaBackend *backend = META_BACKEND (native);
-  ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
   MetaMonitorManager *monitor_manager =
     meta_backend_get_monitor_manager (backend);
   MetaMonitorManagerNative *monitor_manager_native =
@@ -1007,26 +990,20 @@ meta_backend_native_resume (MetaBackendNative *native)
   ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
   MetaSeatNative *seat =
     META_SEAT_NATIVE (clutter_backend_get_default_seat (clutter_backend));
-  MetaRenderer *renderer = meta_backend_get_renderer (backend);
-  MetaIdleManager *idle_manager;
-  MetaInputSettings *input_settings;
+  MetaIdleManager *idle_manager = meta_backend_get_idle_manager (backend);
+  MetaInputSettings *input_settings = meta_backend_get_input_settings (backend);
 
-  COGL_TRACE_BEGIN_SCOPED (MetaBackendNativeResume,
-                           "Meta::BackendNative::resume()");
+  META_BACKEND_CLASS (meta_backend_native_parent_class)->resume (backend);
 
   meta_monitor_manager_native_resume (monitor_manager_native);
   meta_udev_resume (priv->udev);
   meta_kms_resume (priv->kms);
 
   meta_seat_native_reclaim_devices (seat);
-  meta_renderer_resume (renderer);
-
-  clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
 
   idle_manager = meta_backend_get_idle_manager (backend);
   meta_idle_manager_reset_idle_time (idle_manager);
 
-  input_settings = meta_backend_get_input_settings (backend);
   meta_input_settings_maybe_restore_numlock_state (input_settings);
 
   clutter_seat_ensure_a11y_state (CLUTTER_SEAT (seat));