diff --git a/pressure-vessel-test-ui b/pressure-vessel-test-ui
index 3f5a18b3790cf30a6bf322d76bfcc388c6ddc202..d5ad026abed536a60205fecb8c2a724bd571bb70 100755
--- a/pressure-vessel-test-ui
+++ b/pressure-vessel-test-ui
@@ -493,9 +493,12 @@ class Gui:
             argv.append(os.path.join(id, 'files'))
 
         if self.host_graphics_check.get_active():
-            argv.append('--with-host-graphics')
+            if os.path.isdir('/run/host'):
+                argv.append('--graphics-provider=/run/host')
+            else:
+                argv.append('--graphics-provider=/')
         else:
-            argv.append('--without-host-graphics')
+            argv.append('--graphics-provider=')
 
         if self.copy_runtime_into_check.get_active():
             os.makedirs(self.var_path, mode=0o755, exist_ok=True)
diff --git a/src/runtime.c b/src/runtime.c
index dcf451f02ec4cd9d908c18f907832286ec8fca47..6fd755a806a1626fd536601779d2142283ce5d80 100644
--- a/src/runtime.c
+++ b/src/runtime.c
@@ -66,12 +66,16 @@ struct _PvRuntime
   gchar *runtime_usr;           /* either runtime_files or that + "/usr" */
   gchar *runtime_files_on_host;
   const gchar *adverb_in_container;
+  gchar *provider_in_current_namespace;
+  gchar *provider_in_host_namespace;
+  gchar *provider_in_container_namespace;
+  const gchar *host_in_current_namespace;
 
   PvRuntimeFlags flags;
   int mutable_parent_fd;
   int mutable_sysroot_fd;
-  gboolean any_libc_from_host;
-  gboolean all_libc_from_host;
+  gboolean any_libc_from_provider;
+  gboolean all_libc_from_provider;
   gboolean runtime_is_just_usr;
 };
 
@@ -85,6 +89,8 @@ enum {
   PROP_BUBBLEWRAP,
   PROP_FLAGS,
   PROP_MUTABLE_PARENT,
+  PROP_PROVIDER_IN_CURRENT_NAMESPACE,
+  PROP_PROVIDER_IN_CONTAINER_NAMESPACE,
   PROP_SOURCE_FILES,
   PROP_TOOLS_DIRECTORY,
   N_PROPERTIES
@@ -100,7 +106,8 @@ G_DEFINE_TYPE_WITH_CODE (PvRuntime, pv_runtime, G_TYPE_OBJECT,
                                                 pv_runtime_initable_iface_init))
 
 /*
- * Return whether @path is likely to be visible in /run/host.
+ * Return whether @path is likely to be visible in the provider mount point
+ * (e.g. /run/host).
  * This needs to be kept approximately in sync with pv_bwrap_bind_usr()
  * and Flatpak's --filesystem=host-os special keyword.
  *
@@ -108,7 +115,7 @@ G_DEFINE_TYPE_WITH_CODE (PvRuntime, pv_runtime, G_TYPE_OBJECT,
  * that /etc/ld.so.cache, etc., are not shared.
  */
 static gboolean
-path_visible_in_run_host (const char *path)
+path_visible_in_provider_namespace (const char *path)
 {
   while (path[0] == '/')
     path++;
@@ -159,7 +166,7 @@ typedef struct
   const char *tuple;
   gchar *capsule_capture_libs_basename;
   gchar *capsule_capture_libs;
-  gchar *libdir_on_host;
+  gchar *libdir_in_current_namespace;
   gchar *libdir_in_container;
   const char *libqual;
   gchar *ld_so;
@@ -185,13 +192,15 @@ runtime_architecture_init (RuntimeArchitecture *self,
   self->capsule_capture_libs = g_build_filename (runtime->tools_dir,
                                                  self->capsule_capture_libs_basename,
                                                  NULL);
-  self->libdir_on_host = g_build_filename (runtime->overrides, "lib",
-                                           self->tuple, NULL);
+  self->libdir_in_current_namespace = g_build_filename (runtime->overrides, "lib",
+                                                        self->tuple, NULL);
   self->libdir_in_container = g_build_filename (runtime->overrides_in_container,
                                                 "lib", self->tuple, NULL);
 
   /* This has the side-effect of testing whether we can run binaries
-   * for this architecture on the host system. */
+   * for this architecture on the current environment. We
+   * assume that this is the same as whether we can run them
+   * on the host, if different. */
   argv[0] = self->capsule_capture_libs;
   self->ld_so = pv_capture_output (argv, NULL);
 
@@ -211,7 +220,7 @@ runtime_architecture_check_valid (RuntimeArchitecture *self)
   g_return_val_if_fail (self->tuple == multiarch_tuples[self->multiarch_index], FALSE);
   g_return_val_if_fail (self->capsule_capture_libs_basename != NULL, FALSE);
   g_return_val_if_fail (self->capsule_capture_libs != NULL, FALSE);
-  g_return_val_if_fail (self->libdir_on_host != NULL, FALSE);
+  g_return_val_if_fail (self->libdir_in_current_namespace != NULL, FALSE);
   g_return_val_if_fail (self->libdir_in_container != NULL, FALSE);
   g_return_val_if_fail (self->libqual == libquals[self->multiarch_index], FALSE);
   g_return_val_if_fail (self->ld_so != NULL, FALSE);
@@ -226,7 +235,7 @@ runtime_architecture_clear (RuntimeArchitecture *self)
   self->libqual = NULL;
   g_clear_pointer (&self->capsule_capture_libs_basename, g_free);
   g_clear_pointer (&self->capsule_capture_libs, g_free);
-  g_clear_pointer (&self->libdir_on_host, g_free);
+  g_clear_pointer (&self->libdir_in_current_namespace, g_free);
   g_clear_pointer (&self->libdir_in_container, g_free);
   g_clear_pointer (&self->ld_so, g_free);
 }
@@ -234,17 +243,17 @@ runtime_architecture_clear (RuntimeArchitecture *self)
 G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (RuntimeArchitecture,
                                   runtime_architecture_clear)
 
-static gboolean pv_runtime_use_host_graphics_stack (PvRuntime *self,
-                                                    FlatpakBwrap *bwrap,
-                                                    GError **error);
+static gboolean pv_runtime_use_provider_graphics_stack (PvRuntime *self,
+                                                        FlatpakBwrap *bwrap,
+                                                        GError **error);
 static void pv_runtime_set_search_paths (PvRuntime *self,
                                          FlatpakBwrap *bwrap);
 
 static void
 pv_runtime_init (PvRuntime *self)
 {
-  self->any_libc_from_host = FALSE;
-  self->all_libc_from_host = FALSE;
+  self->any_libc_from_provider = FALSE;
+  self->all_libc_from_provider = FALSE;
   self->mutable_parent_fd = -1;
   self->mutable_sysroot_fd = -1;
 }
@@ -271,6 +280,14 @@ pv_runtime_get_property (GObject *object,
         g_value_set_string (value, self->mutable_parent);
         break;
 
+      case PROP_PROVIDER_IN_CURRENT_NAMESPACE:
+        g_value_set_string (value, self->provider_in_current_namespace);
+        break;
+
+      case PROP_PROVIDER_IN_CONTAINER_NAMESPACE:
+        g_value_set_string (value, self->provider_in_container_namespace);
+        break;
+
       case PROP_SOURCE_FILES:
         g_value_set_string (value, self->source_files);
         break;
@@ -324,6 +341,18 @@ pv_runtime_set_property (GObject *object,
 
         break;
 
+      case PROP_PROVIDER_IN_CURRENT_NAMESPACE:
+        /* Construct-only */
+        g_return_if_fail (self->provider_in_current_namespace == NULL);
+        self->provider_in_current_namespace = g_value_dup_string (value);
+        break;
+
+      case PROP_PROVIDER_IN_CONTAINER_NAMESPACE:
+        /* Construct-only */
+        g_return_if_fail (self->provider_in_container_namespace == NULL);
+        self->provider_in_container_namespace = g_value_dup_string (value);
+        break;
+
       case PROP_SOURCE_FILES:
         /* Construct-only */
         g_return_if_fail (self->source_files == NULL);
@@ -362,6 +391,8 @@ pv_runtime_constructed (GObject *object)
   G_OBJECT_CLASS (pv_runtime_parent_class)->constructed (object);
 
   g_return_if_fail (self->bubblewrap != NULL);
+  g_return_if_fail (self->provider_in_current_namespace != NULL);
+  g_return_if_fail (self->provider_in_container_namespace != NULL);
   g_return_if_fail (self->source_files != NULL);
   g_return_if_fail (self->tools_dir != NULL);
 }
@@ -677,7 +708,9 @@ pv_runtime_initable_init (GInitable *initable,
   g_return_val_if_fail (PV_IS_RUNTIME (self), FALSE);
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
-  if (!g_file_test (self->bubblewrap, G_FILE_TEST_IS_EXECUTABLE))
+  /* If we are in Flatpak container we don't expect to have a working bwrap */
+  if (!g_file_test ("/.flatpak-info", G_FILE_TEST_IS_REGULAR)
+      && !g_file_test (self->bubblewrap, G_FILE_TEST_IS_EXECUTABLE))
     {
       return glnx_throw (error, "\"%s\" is not executable",
                          self->bubblewrap);
@@ -742,8 +775,8 @@ pv_runtime_initable_init (GInitable *initable,
       self->runtime_files = self->source_files;
     }
 
-  //TODO This will be used in the future.
-  self->runtime_files_on_host = g_strdup (self->runtime_files);
+  self->runtime_files_on_host = pv_current_namespace_path_to_host_path (self->runtime_files);
+
   g_mkdir (self->overrides, 0700);
 
   self->runtime_usr = g_build_filename (self->runtime_files, "usr", NULL);
@@ -768,6 +801,18 @@ pv_runtime_initable_init (GInitable *initable,
   if (!g_file_test (self->libcapsule_knowledge, G_FILE_TEST_EXISTS))
     g_clear_pointer (&self->libcapsule_knowledge, g_free);
 
+  /* Path that, when resolved in the host namespace, points to the provider */
+  self->provider_in_host_namespace =
+    pv_current_namespace_path_to_host_path (self->provider_in_current_namespace);
+
+  /* If we are in a Flatpak environment we expect to have the host system
+   * mounted in `/run/host`. Otherwise we assume that the host system, in the
+   * current namespace, is the root. */
+  if (g_file_test ("/.flatpak-info", G_FILE_TEST_IS_REGULAR))
+    self->host_in_current_namespace = "/run/host";
+  else
+    self->host_in_current_namespace = "/";
+
   return TRUE;
 }
 
@@ -803,6 +848,9 @@ pv_runtime_finalize (GObject *object)
   g_free (self->mutable_parent);
   glnx_close_fd (&self->mutable_sysroot_fd);
   g_free (self->mutable_sysroot);
+  g_free (self->provider_in_current_namespace);
+  g_free (self->provider_in_host_namespace);
+  g_free (self->provider_in_container_namespace);
   g_free (self->runtime_files_on_host);
   g_free (self->runtime_usr);
   g_free (self->source_files);
@@ -846,17 +894,35 @@ pv_runtime_class_init (PvRuntimeClass *cls)
                          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
                           G_PARAM_STATIC_STRINGS));
 
+  properties[PROP_PROVIDER_IN_CURRENT_NAMESPACE] =
+    g_param_spec_string ("provider-in-current-namespace",
+                         "Provider in current namespace",
+                         ("Path that, when resolved in the current namespace, "
+                          "points to the provider"),
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+
+  properties[PROP_PROVIDER_IN_CONTAINER_NAMESPACE] =
+    g_param_spec_string ("provider-in-container-namespace",
+                         "Provider in container namespace",
+                         ("Path to a directory in which the provider will be "
+                          "accessible from inside the container"),
+                         NULL,
+                         (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+
   properties[PROP_SOURCE_FILES] =
     g_param_spec_string ("source-files", "Source files",
                          ("Path to read-only runtime files (merged-/usr "
-                          "or sysroot) on host system"),
+                          "or sysroot) in current namespace"),
                          NULL,
                          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
                           G_PARAM_STATIC_STRINGS));
 
   properties[PROP_TOOLS_DIRECTORY] =
     g_param_spec_string ("tools-directory", "Tools directory",
-                         "Path to pressure-vessel/bin on host system",
+                         "Path to pressure-vessel/bin in current namespace",
                          NULL,
                          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
                           G_PARAM_STATIC_STRINGS));
@@ -869,6 +935,8 @@ pv_runtime_new (const char *source_files,
                 const char *mutable_parent,
                 const char *bubblewrap,
                 const char *tools_dir,
+                const char *provider_in_current_namespace,
+                const char *provider_in_container_namespace,
                 PvRuntimeFlags flags,
                 GError **error)
 {
@@ -884,6 +952,10 @@ pv_runtime_new (const char *source_files,
                          "mutable-parent", mutable_parent,
                          "source-files", source_files,
                          "tools-directory", tools_dir,
+                         "provider-in-current-namespace",
+                           provider_in_current_namespace,
+                         "provider-in-container-namespace",
+                           provider_in_container_namespace == NULL ? "/run/host" : provider_in_container_namespace,
                          "flags", flags,
                          NULL);
 }
@@ -1047,8 +1119,9 @@ pv_runtime_get_capsule_capture_libs (PvRuntime *self,
   flatpak_bwrap_add_args (ret,
                           arch->capsule_capture_libs,
                           "--container", self->container_access,
-                          "--link-target", "/run/host",
-                          "--provider", "/",
+                          "--link-target", self->provider_in_container_namespace,
+                          "--provider",
+                            self->provider_in_current_namespace,
                           NULL);
 
   if (self->libcapsule_knowledge)
@@ -1067,9 +1140,17 @@ try_bind_dri (PvRuntime *self,
               GError **error)
 {
   g_autofree gchar *dri = g_build_filename (libdir, "dri", NULL);
+  g_autofree gchar *dri_in_current_namespace = g_build_filename (
+                                                self->provider_in_container_namespace,
+                                                dri,
+                                                NULL);
   g_autofree gchar *s2tc = g_build_filename (libdir, "libtxc_dxtn.so", NULL);
+  g_autofree gchar *s2tc_in_current_namespace = g_build_filename (
+                                                  self->provider_in_container_namespace,
+                                                  s2tc,
+                                                  NULL);
 
-  if (g_file_test (dri, G_FILE_TEST_IS_DIR))
+  if (g_file_test (dri_in_current_namespace, G_FILE_TEST_IS_DIR))
     {
       g_autoptr(FlatpakBwrap) temp_bwrap = NULL;
       g_autofree gchar *expr = NULL;
@@ -1085,7 +1166,7 @@ try_bind_dri (PvRuntime *self,
 
       temp_bwrap = pv_runtime_get_capsule_capture_libs (self, arch);
       flatpak_bwrap_add_args (temp_bwrap,
-                              "--dest", arch->libdir_on_host,
+                              "--dest", arch->libdir_in_current_namespace,
                               expr,
                               NULL);
       flatpak_bwrap_finish (temp_bwrap);
@@ -1095,7 +1176,7 @@ try_bind_dri (PvRuntime *self,
 
       g_clear_pointer (&temp_bwrap, flatpak_bwrap_free);
 
-      dir = g_dir_open (dri, 0, error);
+      dir = g_dir_open (dri_in_current_namespace, 0, error);
 
       if (dir == NULL)
         return FALSE;
@@ -1104,9 +1185,9 @@ try_bind_dri (PvRuntime *self,
            member != NULL;
            member = g_dir_read_name (dir))
         {
-          g_autofree gchar *target = g_build_filename ("/run/host", dri,
-                                                      member, NULL);
-          g_autofree gchar *dest = g_build_filename (arch->libdir_on_host,
+          g_autofree gchar *target = g_build_filename (self->provider_in_container_namespace,
+                                                       dri, member, NULL);
+          g_autofree gchar *dest = g_build_filename (arch->libdir_in_current_namespace,
                                                      "dri", member, NULL);
 
           g_debug ("Creating symbolic link \"%s\" -> \"%s\" for \"%s\" DRI driver",
@@ -1125,7 +1206,7 @@ try_bind_dri (PvRuntime *self,
         }
     }
 
-  if (g_file_test (s2tc, G_FILE_TEST_EXISTS))
+  if (g_file_test (s2tc_in_current_namespace, G_FILE_TEST_EXISTS))
     {
       g_autoptr(FlatpakBwrap) temp_bwrap = NULL;
       g_autofree gchar *expr = NULL;
@@ -1138,7 +1219,7 @@ try_bind_dri (PvRuntime *self,
 
       temp_bwrap = pv_runtime_get_capsule_capture_libs (self, arch);
       flatpak_bwrap_add_args (temp_bwrap,
-                              "--dest", arch->libdir_on_host,
+                              "--dest", arch->libdir_in_current_namespace,
                               expr,
                               NULL);
       flatpak_bwrap_finish (temp_bwrap);
@@ -1227,7 +1308,7 @@ bind_icd (PvRuntime *self,
           GError **error)
 {
   static const char options[] = "if-exists:if-same-abi";
-  g_autofree gchar *on_host = NULL;
+  g_autofree gchar *in_current_namespace = NULL;
   g_autofree gchar *pattern = NULL;
   g_autofree gchar *dependency_pattern = NULL;
   g_autofree gchar *seq_str = NULL;
@@ -1257,17 +1338,19 @@ bind_icd (PvRuntime *self,
       if (sequence_number != G_MAXSIZE)
         {
           seq_str = g_strdup_printf ("%" G_GSIZE_FORMAT, sequence_number);
-          on_host = g_build_filename (arch->libdir_on_host, subdir, seq_str, NULL);
+          in_current_namespace = g_build_filename (arch->libdir_in_current_namespace,
+                                                   subdir, seq_str, NULL);
         }
       else
         {
-          on_host = g_build_filename (arch->libdir_on_host, subdir, NULL);
+          in_current_namespace = g_build_filename (arch->libdir_in_current_namespace,
+                                                   subdir, NULL);
         }
 
-      g_debug ("Ensuring %s exists", on_host);
+      g_debug ("Ensuring %s exists", in_current_namespace);
 
-      if (g_mkdir_with_parents (on_host, 0700) != 0)
-        return glnx_throw_errno_prefix (error, "Unable to create %s", on_host);
+      if (g_mkdir_with_parents (in_current_namespace, 0700) != 0)
+        return glnx_throw_errno_prefix (error, "Unable to create %s", in_current_namespace);
     }
   else
     {
@@ -1288,7 +1371,7 @@ bind_icd (PvRuntime *self,
   temp_bwrap = pv_runtime_get_capsule_capture_libs (self, arch);
   flatpak_bwrap_add_args (temp_bwrap,
                           "--dest",
-                            on_host == NULL ? arch->libdir_on_host : on_host,
+                            in_current_namespace == NULL ? arch->libdir_in_current_namespace : in_current_namespace,
                           pattern,
                           NULL);
   flatpak_bwrap_finish (temp_bwrap);
@@ -1298,13 +1381,13 @@ bind_icd (PvRuntime *self,
 
   g_clear_pointer (&temp_bwrap, flatpak_bwrap_free);
 
-  if (on_host != NULL)
+  if (in_current_namespace != NULL)
     {
       /* Try to remove the directory we created. If it succeeds, then we
        * can optimize slightly by not capturing the dependencies: there's
        * no point, because we know we didn't create a symlink to the ICD
        * itself. (It must have been nonexistent or for a different ABI.) */
-      if (g_rmdir (on_host) == 0)
+      if (g_rmdir (in_current_namespace) == 0)
         {
           details->kinds[multiarch_index] = ICD_KIND_NONEXISTENT;
           return TRUE;
@@ -1313,7 +1396,7 @@ bind_icd (PvRuntime *self,
 
   temp_bwrap = pv_runtime_get_capsule_capture_libs (self, arch);
   flatpak_bwrap_add_args (temp_bwrap,
-                          "--dest", arch->libdir_on_host,
+                          "--dest", arch->libdir_in_current_namespace,
                           dependency_pattern,
                           NULL);
   flatpak_bwrap_finish (temp_bwrap);
@@ -1325,7 +1408,7 @@ bind_icd (PvRuntime *self,
 
   if (details->kinds[multiarch_index] == ICD_KIND_ABSOLUTE)
     {
-      g_assert (on_host != NULL);
+      g_assert (in_current_namespace != NULL);
       details->paths_in_container[multiarch_index] = g_build_filename (arch->libdir_in_container,
                                                                        subdir,
                                                                        seq_str ? seq_str : "",
@@ -1407,20 +1490,33 @@ bind_runtime (PvRuntime *self,
                           NULL);
 
   /* https://github.com/flatpak/flatpak/pull/3733 */
-  if (g_file_test ("/etc/os-release", G_FILE_TEST_EXISTS))
+  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/os-release",
+                               G_FILE_TEST_EXISTS))
     flatpak_bwrap_add_args (bwrap,
                             "--ro-bind", "/etc/os-release",
                             "/run/host/os-release",
                             NULL);
-  else if (g_file_test ("/usr/lib/os-release", G_FILE_TEST_EXISTS))
+  else if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/usr/lib/os-release",
+                               G_FILE_TEST_EXISTS))
     flatpak_bwrap_add_args (bwrap,
                             "--ro-bind", "/usr/lib/os-release",
                             "/run/host/os-release",
                             NULL);
 
-  if (!pv_bwrap_bind_usr (bwrap, "/", "/", "/run/host", error))
+  if (!pv_bwrap_bind_usr (bwrap, "/", self->host_in_current_namespace, "/run/host", error))
     return FALSE;
 
+  if (g_strcmp0 (self->provider_in_host_namespace, "/") != 0
+      || g_strcmp0 (self->provider_in_container_namespace, "/run/host") != 0)
+    {
+      if (!pv_bwrap_bind_usr (bwrap,
+                              self->provider_in_host_namespace,
+                              self->provider_in_current_namespace,
+                              self->provider_in_container_namespace,
+                              error))
+        return FALSE;
+    }
+
   for (i = 0; i < G_N_ELEMENTS (bind_mutable); i++)
     {
       g_autofree gchar *path = g_build_filename (self->runtime_files,
@@ -1452,13 +1548,24 @@ bind_runtime (PvRuntime *self,
           target = glnx_readlinkat_malloc (-1, full, NULL, NULL);
 
           if (target != NULL)
-            flatpak_bwrap_add_args (bwrap, "--symlink", target, dest, NULL);
+            {
+              flatpak_bwrap_add_args (bwrap, "--symlink", target, dest, NULL);
+            }
           else
-            flatpak_bwrap_add_args (bwrap, "--ro-bind", full, dest, NULL);
+            {
+              /* We will run bwrap in the host system, so translate the path
+               * if necessary */
+              g_autofree gchar *on_host = pv_current_namespace_path_to_host_path (full);
+              flatpak_bwrap_add_args (bwrap, "--ro-bind", on_host, dest, NULL);
+            }
         }
     }
 
-  if (g_file_test ("/etc/machine-id", G_FILE_TEST_EXISTS))
+  /* If we are in a Flatpak environment, we need to test if these files are
+   * available in the host, and not in the current environment, because we will
+   * run bwrap in the host system */
+  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/machine-id",
+                               G_FILE_TEST_EXISTS))
     {
       flatpak_bwrap_add_args (bwrap,
                               "--ro-bind", "/etc/machine-id", "/etc/machine-id",
@@ -1466,7 +1573,11 @@ bind_runtime (PvRuntime *self,
                               "/var/lib/dbus/machine-id",
                               NULL);
     }
-  else if (g_file_test ("/var/lib/dbus/machine-id", G_FILE_TEST_EXISTS))
+  /* We leave this for completeness but in practice we do not expect to have
+   * access to the "/var" host directory because Flatpak usually just binds
+   * the host's "etc" and "usr". */
+  else if (pv_file_test_in_sysroot (self->host_in_current_namespace,
+                                    "/var/lib/dbus/machine-id", G_FILE_TEST_EXISTS))
     {
       flatpak_bwrap_add_args (bwrap,
                               "--ro-bind", "/var/lib/dbus/machine-id",
@@ -1476,33 +1587,41 @@ bind_runtime (PvRuntime *self,
                               NULL);
     }
 
-  if (g_file_test ("/etc/resolv.conf", G_FILE_TEST_EXISTS))
+  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/resolv.conf",
+                               G_FILE_TEST_EXISTS))
     flatpak_bwrap_add_args (bwrap,
                             "--ro-bind", "/etc/resolv.conf", "/etc/resolv.conf",
                             NULL);
-  if (g_file_test ("/etc/host.conf", G_FILE_TEST_EXISTS))
+
+  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/host.conf",
+                               G_FILE_TEST_EXISTS))
     flatpak_bwrap_add_args (bwrap,
                             "--ro-bind", "/etc/host.conf", "/etc/host.conf",
                             NULL);
-  if (g_file_test ("/etc/hosts", G_FILE_TEST_EXISTS))
+
+  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/hosts",
+                               G_FILE_TEST_EXISTS))
     flatpak_bwrap_add_args (bwrap,
                             "--ro-bind", "/etc/hosts", "/etc/hosts",
                             NULL);
 
   /* TODO: Synthesize a passwd with only the user and nobody,
    * like Flatpak does? */
-  if (g_file_test ("/etc/passwd", G_FILE_TEST_EXISTS))
+  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/passwd",
+                               G_FILE_TEST_EXISTS))
     flatpak_bwrap_add_args (bwrap,
                             "--ro-bind", "/etc/passwd", "/etc/passwd",
                             NULL);
-  if (g_file_test ("/etc/group", G_FILE_TEST_EXISTS))
+
+  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/group",
+                               G_FILE_TEST_EXISTS))
     flatpak_bwrap_add_args (bwrap,
                             "--ro-bind", "/etc/group", "/etc/group",
                             NULL);
 
-  if (self->flags & PV_RUNTIME_FLAGS_HOST_GRAPHICS_STACK)
+  if (self->flags & PV_RUNTIME_FLAGS_PROVIDER_GRAPHICS_STACK)
     {
-      if (!pv_runtime_use_host_graphics_stack (self, bwrap, error))
+      if (!pv_runtime_use_provider_graphics_stack (self, bwrap, error))
         return FALSE;
     }
 
@@ -1520,14 +1639,17 @@ bind_runtime (PvRuntime *self,
    * non-existing targets), in which case we don't want to attempt to create
    * bogus symlinks or bind mounts, as that will cause flatpak run to fail.
    */
-  if (g_file_test ("/etc/localtime", G_FILE_TEST_EXISTS))
+  if (pv_file_test_in_sysroot (self->host_in_current_namespace, "/etc/localtime",
+                               G_FILE_TEST_EXISTS))
     {
       g_autofree char *target = NULL;
       gboolean is_reachable = FALSE;
       g_autofree char *tz = flatpak_get_timezone ();
       g_autofree char *timezone_content = g_strdup_printf ("%s\n", tz);
+      g_autofree char *localtime_in_current_namespace =
+        g_build_filename (self->host_in_current_namespace, "/etc/localtime", NULL);
 
-      target = glnx_readlinkat_malloc (-1, "/etc/localtime", NULL, NULL);
+      target = glnx_readlinkat_malloc (-1, localtime_in_current_namespace, NULL, NULL);
 
       if (target != NULL)
         {
@@ -1565,34 +1687,36 @@ bind_runtime (PvRuntime *self,
 
 typedef enum
 {
-  TAKE_FROM_HOST_FLAGS_IF_DIR = (1 << 0),
-  TAKE_FROM_HOST_FLAGS_IF_EXISTS = (1 << 1),
-  TAKE_FROM_HOST_FLAGS_IF_CONTAINER_COMPATIBLE = (1 << 2),
-  TAKE_FROM_HOST_FLAGS_COPY_FALLBACK = (1 << 3),
-  TAKE_FROM_HOST_FLAGS_NONE = 0
-} TakeFromHostFlags;
+  TAKE_FROM_PROVIDER_FLAGS_IF_DIR = (1 << 0),
+  TAKE_FROM_PROVIDER_FLAGS_IF_EXISTS = (1 << 1),
+  TAKE_FROM_PROVIDER_FLAGS_IF_CONTAINER_COMPATIBLE = (1 << 2),
+  TAKE_FROM_PROVIDER_FLAGS_COPY_FALLBACK = (1 << 3),
+  TAKE_FROM_PROVIDER_FLAGS_NONE = 0
+} TakeFromProviderFlags;
 
 static gboolean
-pv_runtime_take_from_host (PvRuntime *self,
-                           FlatpakBwrap *bwrap,
-                           const char *source_in_host,
-                           const char *dest_in_container,
-                           TakeFromHostFlags flags,
-                           GError **error)
+pv_runtime_take_from_provider (PvRuntime *self,
+                               FlatpakBwrap *bwrap,
+                               const char *source_in_provider,
+                               const char *dest_in_container,
+                               TakeFromProviderFlags flags,
+                               GError **error)
 {
   g_return_val_if_fail (PV_IS_RUNTIME (self), FALSE);
   g_return_val_if_fail (!pv_bwrap_was_finished (bwrap), FALSE);
   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
-  if (flags & TAKE_FROM_HOST_FLAGS_IF_DIR)
+  if (flags & TAKE_FROM_PROVIDER_FLAGS_IF_DIR)
     {
-      if (!g_file_test (source_in_host, G_FILE_TEST_IS_DIR))
+      if (!pv_file_test_in_sysroot (self->provider_in_current_namespace,
+                                    source_in_provider, G_FILE_TEST_IS_DIR))
         return TRUE;
     }
 
-  if (flags & TAKE_FROM_HOST_FLAGS_IF_EXISTS)
+  if (flags & TAKE_FROM_PROVIDER_FLAGS_IF_EXISTS)
     {
-      if (!g_file_test (source_in_host, G_FILE_TEST_EXISTS))
+      if (!pv_file_test_in_sysroot (self->provider_in_current_namespace,
+                                    source_in_provider, G_FILE_TEST_EXISTS))
         return TRUE;
     }
 
@@ -1621,24 +1745,48 @@ pv_runtime_take_from_host (PvRuntime *self,
 
       /* If it isn't in /usr, /lib, etc., then the symlink will be
        * dangling and this probably isn't going to work. */
-      if (!path_visible_in_run_host (source_in_host))
+      if (!path_visible_in_provider_namespace (source_in_provider))
         {
-          if (flags & TAKE_FROM_HOST_FLAGS_COPY_FALLBACK)
+          if (flags & TAKE_FROM_PROVIDER_FLAGS_COPY_FALLBACK)
             {
-              return glnx_file_copy_at (AT_FDCWD, source_in_host, NULL,
+              glnx_autofd int file_fd = -1;
+              glnx_autofd int sysroot_fd = -1;
+              struct stat stat_buf;
+
+              if (!glnx_opendirat (-1, self->provider_in_current_namespace,
+                                   FALSE, &sysroot_fd, error))
+                return FALSE;
+
+              file_fd = pv_resolve_in_sysroot (sysroot_fd, source_in_provider,
+                                               PV_RESOLVE_FLAGS_READABLE,
+                                               NULL, error);
+              if (file_fd < 0)
+                return FALSE;
+
+              if (fstat (file_fd, &stat_buf) != 0)
+                {
+                  return glnx_throw_errno_prefix (error,
+                                                  "An error occurred using fstat for %s",
+                                                  source_in_provider);
+                }
+
+              g_autofree gchar *proc_fd = g_strdup_printf ("/proc/self/fd/%d", file_fd);
+
+
+              return glnx_file_copy_at (AT_FDCWD, proc_fd, &stat_buf,
                                         parent_dirfd, base,
                                         GLNX_FILE_COPY_OVERWRITE,
                                         NULL, error);
             }
           else
             {
-              g_warning ("\"%s\" is unlikely to appear in /run/host",
-                         source_in_host);
+              g_warning ("\"%s\" is unlikely to appear in \"%s\"",
+                         source_in_provider, self->provider_in_container_namespace);
               /* ... but try it anyway, it can't hurt */
             }
         }
 
-      target = g_build_filename ("/run/host", source_in_host, NULL);
+      target = g_build_filename (self->provider_in_container_namespace, source_in_provider, NULL);
 
       if (TEMP_FAILURE_RETRY (symlinkat (target, parent_dirfd, base)) != 0)
         return glnx_throw_errno_prefix (error,
@@ -1651,7 +1799,7 @@ pv_runtime_take_from_host (PvRuntime *self,
       /* We can't edit the runtime in-place, so tell bubblewrap to mount
        * a new version over the top */
 
-      if (flags & TAKE_FROM_HOST_FLAGS_IF_CONTAINER_COMPATIBLE)
+      if (flags & TAKE_FROM_PROVIDER_FLAGS_IF_CONTAINER_COMPATIBLE)
         {
           g_autofree gchar *dest = NULL;
 
@@ -1664,13 +1812,13 @@ pv_runtime_take_from_host (PvRuntime *self,
                                      dest_in_container,
                                      NULL);
 
-          if (g_file_test (source_in_host, G_FILE_TEST_IS_DIR))
+          if (g_file_test (source_in_provider, G_FILE_TEST_IS_DIR))
             {
               if (!g_file_test (dest, G_FILE_TEST_IS_DIR))
                 {
                   g_warning ("Not mounting \"%s\" over non-directory file or "
                              "nonexistent path \"%s\"",
-                             source_in_host, dest);
+                             source_in_provider, dest);
                   return TRUE;
                 }
             }
@@ -1681,14 +1829,14 @@ pv_runtime_take_from_host (PvRuntime *self,
                 {
                   g_warning ("Not mounting \"%s\" over directory or "
                              "nonexistent path \"%s\"",
-                             source_in_host, dest);
+                             source_in_provider, dest);
                   return TRUE;
                 }
             }
         }
 
       flatpak_bwrap_add_args (bwrap,
-                              "--ro-bind", source_in_host, dest_in_container,
+                              "--ro-bind", source_in_provider, dest_in_container,
                               NULL);
     }
 
@@ -1807,7 +1955,7 @@ pv_runtime_remove_overridden_libraries (PvRuntime *self,
             {
               g_autofree gchar *soname_link = NULL;
 
-              soname_link = g_build_filename (arch->libdir_on_host,
+              soname_link = g_build_filename (arch->libdir_in_current_namespace,
                                               dent->d_name, NULL);
 
               /* If we found libfoo.so.1 in the container, and libfoo.so.1
@@ -1828,7 +1976,7 @@ pv_runtime_remove_overridden_libraries (PvRuntime *self,
             {
               g_autofree gchar *soname_link = NULL;
 
-              soname_link = g_build_filename (arch->libdir_on_host,
+              soname_link = g_build_filename (arch->libdir_in_current_namespace,
                                               glnx_basename (target),
                                               NULL);
 
@@ -1875,8 +2023,8 @@ pv_runtime_remove_overridden_libraries (PvRuntime *self,
             {
               g_autofree gchar *soname_link = NULL;
 
-              soname_link = g_build_filename (arch->libdir_on_host, soname,
-                                              NULL);
+              soname_link = g_build_filename (arch->libdir_in_current_namespace,
+                                              soname, NULL);
 
               if (g_file_test (soname_link, G_FILE_TEST_IS_SYMLINK))
                 {
@@ -1930,24 +2078,35 @@ out:
 }
 
 static gboolean
-pv_runtime_take_ld_so_from_host (PvRuntime *self,
-                                 RuntimeArchitecture *arch,
-                                 const gchar *ld_so_in_runtime,
-                                 FlatpakBwrap *bwrap,
-                                 GError **error)
+pv_runtime_take_ld_so_from_provider (PvRuntime *self,
+                                     RuntimeArchitecture *arch,
+                                     const gchar *ld_so_in_runtime,
+                                     FlatpakBwrap *bwrap,
+                                     GError **error)
 {
-  g_autofree gchar *ld_so_in_host = NULL;
+  glnx_autofd int path_fd = -1;
+  glnx_autofd int provider_fd = -1;
+  g_autofree gchar *ld_so_relative_to_provider = NULL;
+  g_autofree gchar *ld_so_in_provider = NULL;
+
+  g_debug ("Making provider's ld.so visible in container");
 
-  g_debug ("Making host ld.so visible in container");
+  if (!glnx_opendirat (-1, self->provider_in_current_namespace, FALSE, &provider_fd, error))
+    return FALSE;
 
-  ld_so_in_host = realpath (arch->ld_so, NULL);
+  path_fd = pv_resolve_in_sysroot (provider_fd,
+                                   arch->ld_so, PV_RESOLVE_FLAGS_READABLE,
+                                   &ld_so_relative_to_provider, error);
 
-  if (ld_so_in_host == NULL)
+  if (path_fd < 0)
     return glnx_throw_errno_prefix (error,
-                                    "Unable to determine host path to %s",
+                                    "Unable to determine provider path to %s",
                                     arch->ld_so);
 
-  g_debug ("Host path: %s -> %s", arch->ld_so, ld_so_in_host);
+  ld_so_in_provider = g_build_filename (self->provider_in_host_namespace,
+                                        ld_so_relative_to_provider, NULL);
+
+  g_debug ("Provider path: %s -> %s", arch->ld_so, ld_so_relative_to_provider);
   /* Might be either absolute, or relative to the root */
   g_debug ("Container path: %s -> %s", arch->ld_so, ld_so_in_runtime);
 
@@ -1958,9 +2117,9 @@ pv_runtime_take_ld_so_from_host (PvRuntime *self,
    * having to dereference a long chain of symlinks every time we run
    * an executable. */
   if (self->mutable_sysroot != NULL &&
-      !pv_runtime_take_from_host (self, bwrap, ld_so_in_host,
-                                  arch->ld_so, TAKE_FROM_HOST_FLAGS_NONE,
-                                  error))
+      !pv_runtime_take_from_provider (self, bwrap, ld_so_in_provider,
+                                      arch->ld_so,
+                                      TAKE_FROM_PROVIDER_FLAGS_NONE, error))
     return FALSE;
 
   /* If we don't have a mutable sysroot, we cannot replace symlinks,
@@ -1977,15 +2136,48 @@ pv_runtime_take_ld_so_from_host (PvRuntime *self,
    * non-standard path), that's pretty much a disaster, because it will
    * just crash. However, all of those (chains of) non-standard symlinks
    * will end up pointing to ld_so_in_runtime. */
-  return pv_runtime_take_from_host (self, bwrap, ld_so_in_host,
-                                    ld_so_in_runtime,
-                                    TAKE_FROM_HOST_FLAGS_NONE, error);
+  return pv_runtime_take_from_provider (self, bwrap, ld_so_in_provider,
+                                        ld_so_in_runtime,
+                                        TAKE_FROM_PROVIDER_FLAGS_NONE, error);
+}
+
+static gchar *
+pv_runtime_search_in_path_and_bin (PvRuntime *self,
+                                   const gchar *program_name)
+{
+  const gchar * const common_bin_dirs[] =
+  {
+    "/usr/bin",
+    "/bin",
+    "/usr/sbin",
+    "/sbin",
+    NULL
+  };
+
+  if (g_strcmp0 (self->host_in_current_namespace, "/") == 0)
+    {
+      gchar *found_path = g_find_program_in_path (program_name);
+      if (found_path != NULL)
+        return found_path;
+    }
+
+  for (gsize i = 0; i < G_N_ELEMENTS (common_bin_dirs) - 1; i++)
+    {
+      g_autofree gchar *test_path = g_build_filename (common_bin_dirs[i],
+                                                      program_name,
+                                                      NULL);
+      if (pv_file_test_in_sysroot (self->host_in_current_namespace,
+                                   test_path, G_FILE_TEST_IS_EXECUTABLE))
+        return g_steal_pointer (&test_path);
+    }
+
+  return NULL;
 }
 
 static gboolean
-pv_runtime_use_host_graphics_stack (PvRuntime *self,
-                                    FlatpakBwrap *bwrap,
-                                    GError **error)
+pv_runtime_use_provider_graphics_stack (PvRuntime *self,
+                                        FlatpakBwrap *bwrap,
+                                        GError **error)
 {
   gsize i, j;
   g_autoptr(GString) dri_path = g_string_new ("");
@@ -2006,14 +2198,22 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
   guint n_egl_icds;
   guint n_vulkan_icds;
   const GList *icd_iter;
-  gboolean all_libdrm_from_host = TRUE;
-  g_autoptr(GHashTable) libdrm_data_from_host = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                                                       g_free, NULL);
-  g_autoptr(GHashTable) gconv_from_host = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                                                 g_free, NULL);
-  g_autofree gchar *best_libdrm_data_from_host = NULL;
+  gboolean all_libdrm_from_provider = TRUE;
+  g_autoptr(GHashTable) libdrm_data_in_provider = g_hash_table_new_full (g_str_hash,
+                                                                         g_str_equal,
+                                                                         g_free, NULL);
+  g_autoptr(GHashTable) gconv_in_provider = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                                                     g_free, NULL);
+  g_autofree gchar *best_libdrm_data_in_provider = NULL;
   GHashTableIter iter;
   const gchar *gconv_path;
+  g_autofree gchar *provider_in_container_namespace_guarded = NULL;
+  if (g_str_has_suffix (self->provider_in_container_namespace, "/"))
+    provider_in_container_namespace_guarded =
+      g_strdup (self->provider_in_container_namespace);
+  else
+    provider_in_container_namespace_guarded =
+      g_strdup_printf ("%s/", self->provider_in_container_namespace);
 
   g_return_val_if_fail (PV_IS_RUNTIME (self), FALSE);
   g_return_val_if_fail (!pv_bwrap_was_finished (bwrap), FALSE);
@@ -2022,7 +2222,9 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
   if (!pv_runtime_provide_container_access (self, error))
     return FALSE;
 
-  g_debug ("Enumerating EGL ICDs on host system...");
+  srt_system_info_set_sysroot (system_info, self->provider_in_current_namespace);
+
+  g_debug ("Enumerating EGL ICDs on provider system...");
   egl_icds = srt_system_info_list_egl_icds (system_info, multiarch_tuples);
   n_egl_icds = g_list_length (egl_icds);
 
@@ -2051,7 +2253,7 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
       g_ptr_array_add (egl_icd_details, icd_details_new (icd));
     }
 
-  g_debug ("Enumerating Vulkan ICDs on host system...");
+  g_debug ("Enumerating Vulkan ICDs on provider system...");
   vulkan_icds = srt_system_info_list_vulkan_icds (system_info,
                                                   multiarch_tuples);
   n_vulkan_icds = g_list_length (vulkan_icds);
@@ -2081,9 +2283,9 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
       g_ptr_array_add (vulkan_icd_details, icd_details_new (icd));
     }
 
-  /* We set this FALSE later if we decide not to use the host libc for
-   * some architecture. */
-  self->all_libc_from_host = TRUE;
+  /* We set this FALSE later if we decide not to use the provider libc
+   * for some architecture. */
+  self->all_libc_from_provider = TRUE;
 
   g_assert (multiarch_tuples[G_N_ELEMENTS (multiarch_tuples) - 1] == NULL);
 
@@ -2098,7 +2300,7 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
         {
           g_auto(GStrv) dirs = NULL;
           g_autoptr(FlatpakBwrap) temp_bwrap = NULL;
-          g_autofree gchar *this_dri_path_on_host = g_build_filename (arch->libdir_on_host,
+          g_autofree gchar *this_dri_path_on_host = g_build_filename (arch->libdir_in_current_namespace,
                                                                       "dri", NULL);
           g_autofree gchar *this_dri_path_in_container = g_build_filename (arch->libdir_in_container,
                                                                            "dri", NULL);
@@ -2140,9 +2342,9 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
                 return FALSE;
 
               if (!pv_bwrap_bind_usr (temp_bwrap,
-                                      "/",
-                                      "/",
-                                      "/run/host",
+                                      self->provider_in_host_namespace,
+                                      self->provider_in_current_namespace,
+                                      self->provider_in_container_namespace,
                                       error))
                 return FALSE;
 
@@ -2172,14 +2374,14 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
 
           pv_search_path_append (dri_path, this_dri_path_in_container);
 
-          g_mkdir_with_parents (arch->libdir_on_host, 0755);
+          g_mkdir_with_parents (arch->libdir_in_current_namespace, 0755);
           g_mkdir_with_parents (this_dri_path_on_host, 0755);
 
-          g_debug ("Collecting graphics drivers from host system...");
+          g_debug ("Collecting graphics drivers from provider system...");
 
           temp_bwrap = pv_runtime_get_capsule_capture_libs (self, arch);
           flatpak_bwrap_add_args (temp_bwrap,
-                                  "--dest", arch->libdir_on_host,
+                                  "--dest", arch->libdir_in_current_namespace,
                                   /* Mesa GLX, etc. */
                                   "gl:",
                                   /* Vulkan */
@@ -2323,17 +2525,17 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
               !pv_runtime_remove_overridden_libraries (self, arch, error))
             return FALSE;
 
-          libc = g_build_filename (arch->libdir_on_host, "libc.so.6", NULL);
+          libc = g_build_filename (arch->libdir_in_current_namespace, "libc.so.6", NULL);
 
-          /* If we are going to use the host system's libc6 (likely)
+          /* If we are going to use the provider's libc6 (likely)
            * then we have to use its ld.so too. */
           if (g_file_test (libc, G_FILE_TEST_IS_SYMLINK))
             {
               g_autofree char *libc_target = NULL;
 
-              if (!pv_runtime_take_ld_so_from_host (self, arch,
-                                                    ld_so_in_runtime,
-                                                    bwrap, error))
+              if (!pv_runtime_take_ld_so_from_provider (self, arch,
+                                                        ld_so_in_runtime,
+                                                        bwrap, error))
                 return FALSE;
 
               /* Collect miscellaneous libraries that libc might dlopen.
@@ -2341,7 +2543,7 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
               g_assert (temp_bwrap == NULL);
               temp_bwrap = pv_runtime_get_capsule_capture_libs (self, arch);
               flatpak_bwrap_add_args (temp_bwrap,
-                                      "--dest", arch->libdir_on_host,
+                                      "--dest", arch->libdir_in_current_namespace,
                                       "if-exists:libidn2.so.0",
                                       NULL);
               flatpak_bwrap_finish (temp_bwrap);
@@ -2355,13 +2557,15 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
               if (libc_target != NULL)
                 {
                   g_autofree gchar *dir = NULL;
-                  g_autofree gchar *gconv_dir_in_host = NULL;
+                  g_autofree gchar *gconv_dir_in_provider = NULL;
                   gboolean found = FALSE;
 
                   dir = g_path_get_dirname (libc_target);
 
-                  if (g_str_has_prefix (dir, "/run/host/"))
-                    memmove (dir, dir + strlen ("/run/host"), strlen (dir) - strlen ("/run/host") + 1);
+                  if (g_str_has_prefix (dir, provider_in_container_namespace_guarded))
+                    memmove (dir,
+                             dir + strlen (self->provider_in_container_namespace),
+                             strlen (dir) - strlen (self->provider_in_container_namespace) + 1);
 
                   /* We are assuming that in the glibc "Makeconfig", $(libdir) was the same as
                    * $(slibdir) (this is the upstream default) or the same as "/usr$(slibdir)"
@@ -2373,11 +2577,12 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
                   if (g_str_has_prefix (dir, "/usr/"))
                     memmove (dir, dir + strlen ("/usr"), strlen (dir) - strlen ("/usr") + 1);
 
-                  gconv_dir_in_host = g_build_filename ("/usr", dir, "gconv", NULL);
+                  gconv_dir_in_provider = g_build_filename ("/usr", dir, "gconv", NULL);
 
-                  if (g_file_test (gconv_dir_in_host, G_FILE_TEST_IS_DIR))
+                  if (pv_file_test_in_sysroot (self->provider_in_current_namespace,
+                                               gconv_dir_in_provider, G_FILE_TEST_IS_DIR))
                     {
-                      g_hash_table_add (gconv_from_host, g_steal_pointer (&gconv_dir_in_host));
+                      g_hash_table_add (gconv_in_provider, g_steal_pointer (&gconv_dir_in_provider));
                       found = TRUE;
                     }
 
@@ -2401,12 +2606,13 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
                           *slash = '\0';
                         }
 
-                      g_clear_pointer (&gconv_dir_in_host, g_free);
-                      gconv_dir_in_host = g_build_filename ("/usr", dir, "gconv", NULL);
+                      g_clear_pointer (&gconv_dir_in_provider, g_free);
+                      gconv_dir_in_provider = g_build_filename ("/usr", dir, "gconv", NULL);
 
-                      if (g_file_test (gconv_dir_in_host, G_FILE_TEST_IS_DIR))
+                      if (pv_file_test_in_sysroot (self->provider_in_current_namespace,
+                                                   gconv_dir_in_provider, G_FILE_TEST_IS_DIR))
                         {
-                          g_hash_table_add (gconv_from_host, g_steal_pointer (&gconv_dir_in_host));
+                          g_hash_table_add (gconv_in_provider, g_steal_pointer (&gconv_dir_in_provider));
                           found = TRUE;
                         }
                     }
@@ -2414,19 +2620,19 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
                   if (!found)
                     {
                       g_debug ("We were expecting to have the gconv modules directory in the "
-                               "host to be located in \"%s/gconv\", but instead it is missing",
+                               "provider to be located in \"%s/gconv\", but instead it is missing",
                                dir);
                     }
                 }
 
-              self->any_libc_from_host = TRUE;
+              self->any_libc_from_provider = TRUE;
             }
           else
             {
-              self->all_libc_from_host = FALSE;
+              self->all_libc_from_provider = FALSE;
             }
 
-          libdrm = g_build_filename (arch->libdir_on_host, "libdrm.so.2", NULL);
+          libdrm = g_build_filename (arch->libdir_in_current_namespace, "libdrm.so.2", NULL);
 
           /* If we have libdrm.so.2 in overrides we also want to mount
            * ${prefix}/share/libdrm from the host. ${prefix} is derived from
@@ -2440,7 +2646,7 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
                 {
                   g_autofree gchar *dir = NULL;
                   g_autofree gchar *lib_multiarch = NULL;
-                  g_autofree gchar *libdrm_dir_in_host = NULL;
+                  g_autofree gchar *libdrm_dir_in_provider = NULL;
 
                   dir = g_path_get_dirname (target);
 
@@ -2454,27 +2660,32 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
                   else if (g_str_has_suffix (dir, "/lib"))
                     dir[strlen (dir) - strlen ("/lib")] = '\0';
 
-                  if (g_str_has_prefix (dir, "/run/host"))
-                    memmove (dir, dir + strlen ("/run/host"), strlen (dir) - strlen ("/run/host") + 1);
+                  if (g_str_has_prefix (dir, provider_in_container_namespace_guarded))
+                    memmove (dir,
+                             dir + strlen (self->provider_in_container_namespace),
+                             strlen (dir) - strlen (self->provider_in_container_namespace) + 1);
 
-                  libdrm_dir_in_host = g_build_filename (dir, "share", "libdrm", NULL);
+                  libdrm_dir_in_provider = g_build_filename (dir, "share", "libdrm", NULL);
 
-                  if (g_file_test (libdrm_dir_in_host, G_FILE_TEST_IS_DIR))
+                  if (pv_file_test_in_sysroot (self->provider_in_current_namespace,
+                                               libdrm_dir_in_provider, G_FILE_TEST_IS_DIR))
                     {
-                      g_hash_table_add (libdrm_data_from_host, g_steal_pointer (&libdrm_dir_in_host));
+                      g_hash_table_add (libdrm_data_in_provider,
+                                        g_steal_pointer (&libdrm_dir_in_provider));
                     }
                   else
                     {
-                      g_debug ("We were expecting to have the libdrm directory in the host "
-                               "to be located in \"%s\", but instead it is missing",
-                               libdrm_dir_in_host);
+                      g_debug ("We were expecting to have the libdrm directory "
+                               "in the provider to be located in "
+                               "\"%s/share/libdrm\", but instead it is missing",
+                               dir);
                     }
                 }
             }
           else
             {
               /* For at least a single architecture, libdrm is newer in the container */
-              all_libdrm_from_host = FALSE;
+              all_libdrm_from_provider = FALSE;
             }
 
           /* Order matters: drivers from a later entry will overwrite
@@ -2520,103 +2731,95 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
       return FALSE;
     }
 
-  if (self->any_libc_from_host && !self->all_libc_from_host)
+  if (self->any_libc_from_provider && !self->all_libc_from_provider)
     {
       /*
        * This shouldn't happen. It would mean that there exist at least
        * two architectures (let's say aaa and bbb) for which we have:
-       * host libc6:aaa < container libc6 < host libc6:bbb
+       * provider libc6:aaa < container libc6 < provider libc6:bbb
        * (we know that the container's libc6:aaa and libc6:bbb are
        * constrained to be the same version because that's how multiarch
        * works).
        *
-       * If the host system locales work OK with both the aaa and bbb
+       * If the provider system locales work OK with both the aaa and bbb
        * versions, let's assume they will also work with the intermediate
        * version from the container...
        */
-      g_warning ("Using glibc from host system for some but not all "
-                 "architectures! Arbitrarily using host locales.");
+      g_warning ("Using glibc from provider system for some but not all "
+                 "architectures! Arbitrarily using provider locales.");
     }
 
-  if (self->any_libc_from_host)
+  if (self->any_libc_from_provider)
     {
-      g_debug ("Making host locale data visible in container");
+      g_debug ("Making provider locale data visible in container");
 
-      if (!pv_runtime_take_from_host (self, bwrap,
-                                      "/usr/lib/locale",
-                                      "/usr/lib/locale",
-                                      TAKE_FROM_HOST_FLAGS_IF_EXISTS,
-                                      error))
+      if (!pv_runtime_take_from_provider (self, bwrap,
+                                          "/usr/lib/locale",
+                                          "/usr/lib/locale",
+                                          TAKE_FROM_PROVIDER_FLAGS_IF_EXISTS,
+                                          error))
         return FALSE;
 
-      if (!pv_runtime_take_from_host (self, bwrap,
-                                      "/usr/share/i18n",
-                                      "/usr/share/i18n",
-                                      TAKE_FROM_HOST_FLAGS_IF_EXISTS,
-                                      error))
+      if (!pv_runtime_take_from_provider (self, bwrap,
+                                          "/usr/share/i18n",
+                                          "/usr/share/i18n",
+                                          TAKE_FROM_PROVIDER_FLAGS_IF_EXISTS,
+                                          error))
         return FALSE;
 
-      localedef = g_find_program_in_path ("localedef");
+      localedef = pv_runtime_search_in_path_and_bin (self, "localedef");
 
       if (localedef == NULL)
         {
-          g_warning ("Cannot find localedef in PATH");
+          g_warning ("Cannot find localedef");
         }
-      else if (!pv_runtime_take_from_host (self, bwrap, localedef,
-                                           "/usr/bin/localedef",
-                                           TAKE_FROM_HOST_FLAGS_IF_CONTAINER_COMPATIBLE,
-                                           error))
+      else if (!pv_runtime_take_from_provider (self, bwrap, localedef,
+                                               "/usr/bin/localedef",
+                                               TAKE_FROM_PROVIDER_FLAGS_IF_CONTAINER_COMPATIBLE,
+                                               error))
         {
           return FALSE;
         }
 
-      locale = g_find_program_in_path ("locale");
+      locale = pv_runtime_search_in_path_and_bin (self, "locale");
 
       if (locale == NULL)
         {
-          g_warning ("Cannot find locale in PATH");
+          g_warning ("Cannot find locale");
         }
-      else if (!pv_runtime_take_from_host (self, bwrap, locale,
-                                           "/usr/bin/locale",
-                                           TAKE_FROM_HOST_FLAGS_IF_CONTAINER_COMPATIBLE,
-                                           error))
+      else if (!pv_runtime_take_from_provider (self, bwrap, locale,
+                                               "/usr/bin/locale",
+                                               TAKE_FROM_PROVIDER_FLAGS_IF_CONTAINER_COMPATIBLE,
+                                               error))
         {
           return FALSE;
         }
 
-      ldconfig = g_find_program_in_path ("ldconfig");
-
-      if (ldconfig == NULL
-          && g_file_test ("/sbin/ldconfig", G_FILE_TEST_IS_EXECUTABLE))
-        ldconfig = g_strdup ("/sbin/ldconfig");
-
-      if (ldconfig == NULL
-          && g_file_test ("/usr/sbin/ldconfig", G_FILE_TEST_IS_EXECUTABLE))
-        ldconfig = g_strdup ("/usr/sbin/ldconfig");
+      ldconfig = pv_runtime_search_in_path_and_bin (self, "ldconfig");
 
       if (ldconfig == NULL)
         {
-          g_warning ("Cannot find ldconfig in PATH, /sbin or /usr/sbin");
+          g_warning ("Cannot find ldconfig");
         }
-      else if (!pv_runtime_take_from_host (self, bwrap,
-                                           ldconfig,
-                                           "/sbin/ldconfig",
-                                           TAKE_FROM_HOST_FLAGS_NONE,
-                                           error))
+      else if (!pv_runtime_take_from_provider (self, bwrap,
+                                               ldconfig,
+                                               "/sbin/ldconfig",
+                                               TAKE_FROM_PROVIDER_FLAGS_NONE,
+                                               error))
         {
           return FALSE;
         }
 
-      g_debug ("Making host gconv modules visible in container");
+      g_debug ("Making provider gconv modules visible in container");
 
-      g_hash_table_iter_init (&iter, gconv_from_host);
+      g_hash_table_iter_init (&iter, gconv_in_provider);
       while (g_hash_table_iter_next (&iter, (gpointer *)&gconv_path, NULL))
         {
-          if (!pv_runtime_take_from_host (self, bwrap,
-                                          gconv_path,
-                                          gconv_path,
-                                          TAKE_FROM_HOST_FLAGS_IF_DIR,
-                                          error))
+          if (!pv_runtime_take_from_provider (self, bwrap,
+                                              gconv_path,
+                                              gconv_path,
+                                              TAKE_FROM_PROVIDER_FLAGS_IF_DIR,
+                                              error))
             return FALSE;
         }
     }
@@ -2626,36 +2829,38 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
       g_debug ("Using included gconv modules from container");
     }
 
-  if (g_hash_table_size (libdrm_data_from_host) > 0 && !all_libdrm_from_host)
+  if (g_hash_table_size (libdrm_data_in_provider) > 0 && !all_libdrm_from_provider)
     {
-      /* See the explanation in the similar "any_libc_from_host && !all_libc_from_host"
-       * case, above */
-      g_warning ("Using libdrm.so.2 from host system for some but not all "
-                 "architectures! Will take /usr/share/libdrm from host.");
+      /* See the explanation in the similar
+       * "any_libc_from_provider && !all_libc_from_provider" case, above */
+      g_warning ("Using libdrm.so.2 from provider system for some but not all "
+                 "architectures! Will take /usr/share/libdrm from provider.");
     }
 
-  if (g_hash_table_size (libdrm_data_from_host) == 1)
+  if (g_hash_table_size (libdrm_data_in_provider) == 1)
     {
-      best_libdrm_data_from_host = g_strdup (pv_hash_table_get_arbitrary_key (libdrm_data_from_host));
+      best_libdrm_data_in_provider = g_strdup (
+        pv_hash_table_get_arbitrary_key (libdrm_data_in_provider));
     }
-  else if (g_hash_table_size (libdrm_data_from_host) > 1)
+  else if (g_hash_table_size (libdrm_data_in_provider) > 1)
     {
-      g_warning ("Found more than one possible libdrm data directory from host");
+      g_warning ("Found more than one possible libdrm data directory from provider");
       /* Prioritize "/usr/share/libdrm" if available. Otherwise randomly pick
        * the first directory in the hash table */
-      if (g_hash_table_contains (libdrm_data_from_host, "/usr/share/libdrm"))
-        best_libdrm_data_from_host = g_strdup ("/usr/share/libdrm");
+      if (g_hash_table_contains (libdrm_data_in_provider, "/usr/share/libdrm"))
+        best_libdrm_data_in_provider = g_strdup ("/usr/share/libdrm");
       else
-        best_libdrm_data_from_host = g_strdup (pv_hash_table_get_arbitrary_key (libdrm_data_from_host));
+        best_libdrm_data_in_provider = g_strdup (
+          pv_hash_table_get_arbitrary_key (libdrm_data_in_provider));
     }
 
-  if (best_libdrm_data_from_host != NULL)
+  if (best_libdrm_data_in_provider != NULL)
     {
-      if (!pv_runtime_take_from_host (self, bwrap,
-                                      best_libdrm_data_from_host,
-                                      "/usr/share/libdrm",
-                                      TAKE_FROM_HOST_FLAGS_IF_CONTAINER_COMPATIBLE,
-                                      error))
+      if (!pv_runtime_take_from_provider (self, bwrap,
+                                          best_libdrm_data_in_provider,
+                                          "/usr/share/libdrm",
+                                          TAKE_FROM_PROVIDER_FLAGS_IF_CONTAINER_COMPATIBLE,
+                                          error))
         return FALSE;
     }
 
@@ -2674,7 +2879,7 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
     {
       IcdDetails *details = g_ptr_array_index (egl_icd_details, j);
       SrtEglIcd *icd = SRT_EGL_ICD (details->icd);
-      gboolean need_host_json = FALSE;
+      gboolean need_provider_json = FALSE;
 
       if (!srt_egl_icd_check_error (icd, NULL))
         continue;
@@ -2712,11 +2917,11 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
             }
           else if (details->kinds[i] == ICD_KIND_SONAME)
             {
-              need_host_json = TRUE;
+              need_provider_json = TRUE;
             }
         }
 
-      if (need_host_json)
+      if (need_provider_json)
         {
           g_autofree gchar *json_in_container = NULL;
           g_autofree gchar *json_base = NULL;
@@ -2728,11 +2933,11 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
                                                 "egl_vendor.d",
                                                 json_base, NULL);
 
-          if (!pv_runtime_take_from_host (self, bwrap,
-                                          json_on_host,
-                                          json_in_container,
-                                          TAKE_FROM_HOST_FLAGS_COPY_FALLBACK,
-                                          error))
+          if (!pv_runtime_take_from_provider (self, bwrap,
+                                              json_on_host,
+                                              json_in_container,
+                                              TAKE_FROM_PROVIDER_FLAGS_COPY_FALLBACK,
+                                              error))
             return FALSE;
 
           pv_search_path_append (egl_path, json_in_container);
@@ -2754,7 +2959,7 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
     {
       IcdDetails *details = g_ptr_array_index (vulkan_icd_details, j);
       SrtVulkanIcd *icd = SRT_VULKAN_ICD (details->icd);
-      gboolean need_host_json = FALSE;
+      gboolean need_provider_json = FALSE;
 
       if (!srt_vulkan_icd_check_error (icd, NULL))
         continue;
@@ -2791,11 +2996,11 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
             }
           else if (details->kinds[i] == ICD_KIND_SONAME)
             {
-              need_host_json = TRUE;
+              need_provider_json = TRUE;
             }
         }
 
-      if (need_host_json)
+      if (need_provider_json)
         {
           g_autofree gchar *json_in_container = NULL;
           g_autofree gchar *json_base = NULL;
@@ -2806,11 +3011,11 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
                                                 "share", "vulkan", "icd.d",
                                                 json_base, NULL);
 
-          if (!pv_runtime_take_from_host (self, bwrap,
-                                          json_on_host,
-                                          json_in_container,
-                                          TAKE_FROM_HOST_FLAGS_COPY_FALLBACK,
-                                          error))
+          if (!pv_runtime_take_from_provider (self, bwrap,
+                                              json_on_host,
+                                              json_in_container,
+                                              TAKE_FROM_PROVIDER_FLAGS_COPY_FALLBACK,
+                                              error))
             return FALSE;
 
           pv_search_path_append (vulkan_path, json_in_container);
@@ -2905,25 +3110,27 @@ pv_runtime_use_host_graphics_stack (PvRuntime *self,
     NULL
   };
 
-  g_autofree gchar *i386_libdir_on_host = g_build_filename (self->overrides, "lib",
-                                                            "i386-linux-gnu",
-                                                            NULL);
+  g_autofree gchar *i386_libdir_in_current_namespace = g_build_filename (self->overrides,
+                                                                         "lib",
+                                                                         "i386-linux-gnu",
+                                                                         NULL);
 
   for (i = 0; i < G_N_ELEMENTS (extra_multiarch_tuples) - 1; i++)
     {
-      g_autofree gchar *extra_libdir_on_host = g_build_filename (self->overrides, "lib",
-                                                                 extra_multiarch_tuples[i],
-                                                                 NULL);
+      g_autofree gchar *extra_libdir_in_current_namespace = g_build_filename (self->overrides,
+                                                                              "lib",
+                                                                              extra_multiarch_tuples[i],
+                                                                              NULL);
 
-      if (!g_file_test (extra_libdir_on_host, G_FILE_TEST_EXISTS) &&
-          g_file_test (i386_libdir_on_host, G_FILE_TEST_IS_DIR))
+      if (!g_file_test (extra_libdir_in_current_namespace, G_FILE_TEST_EXISTS) &&
+          g_file_test (i386_libdir_in_current_namespace, G_FILE_TEST_IS_DIR))
         {
-          g_unlink (extra_libdir_on_host);
+          g_unlink (extra_libdir_in_current_namespace);
 
-          if (symlink ("i386-linux-gnu", extra_libdir_on_host) != 0)
+          if (symlink ("i386-linux-gnu", extra_libdir_in_current_namespace) != 0)
             return glnx_throw_errno_prefix (error,
                                             "Unable to create symlink %s -> i386-linux-gnu",
-                                            extra_libdir_on_host);
+                                            extra_libdir_in_current_namespace);
         }
     }
 
@@ -2990,9 +3197,11 @@ pv_runtime_bind (PvRuntime *self,
     }
   else
     {
+      g_autofree gchar *pressure_vessel_prefix_in_host_namespace =
+        pv_current_namespace_path_to_host_path (pressure_vessel_prefix);
       flatpak_bwrap_add_args (bwrap,
                               "--ro-bind",
-                              pressure_vessel_prefix,
+                              pressure_vessel_prefix_in_host_namespace,
                               "/run/pressure-vessel/pv-from-host",
                               NULL);
       self->adverb_in_container = "/run/pressure-vessel/pv-from-host/bin/pressure-vessel-adverb";
diff --git a/src/runtime.h b/src/runtime.h
index c3d9cdbf0377d975906dd9ffb445aac6e3f8031f..a2412ac0d122cde05e7950b9fbd16f03190ba0b0 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -31,7 +31,7 @@
 
 /**
  * PvRuntimeFlags:
- * @PV_RUNTIME_FLAGS_HOST_GRAPHICS_STACK: Use host system graphics stack
+ * @PV_RUNTIME_FLAGS_PROVIDER_GRAPHICS_STACK: Use provider graphics stack
  * @PV_RUNTIME_FLAGS_GENERATE_LOCALES: Generate missing locales
  * @PV_RUNTIME_FLAGS_GC_RUNTIMES: Garbage-collect old temporary runtimes
  * @PV_RUNTIME_FLAGS_NONE: None of the above
@@ -40,7 +40,7 @@
  */
 typedef enum
 {
-  PV_RUNTIME_FLAGS_HOST_GRAPHICS_STACK = (1 << 0),
+  PV_RUNTIME_FLAGS_PROVIDER_GRAPHICS_STACK = (1 << 0),
   PV_RUNTIME_FLAGS_GENERATE_LOCALES = (1 << 1),
   PV_RUNTIME_FLAGS_GC_RUNTIMES = (1 << 2),
   PV_RUNTIME_FLAGS_VERBOSE = (1 << 3),
@@ -48,7 +48,7 @@ typedef enum
 } PvRuntimeFlags;
 
 #define PV_RUNTIME_FLAGS_MASK \
-  (PV_RUNTIME_FLAGS_HOST_GRAPHICS_STACK \
+  (PV_RUNTIME_FLAGS_PROVIDER_GRAPHICS_STACK \
    | PV_RUNTIME_FLAGS_GENERATE_LOCALES \
    | PV_RUNTIME_FLAGS_GC_RUNTIMES \
    | PV_RUNTIME_FLAGS_VERBOSE \
@@ -69,6 +69,8 @@ PvRuntime *pv_runtime_new (const char *source_files,
                            const char *mutable_parent,
                            const char *bubblewrap,
                            const char *tools_dir,
+                           const char *provider_in_current_namespace,
+                           const char *provider_in_container_namespace,
                            PvRuntimeFlags flags,
                            GError **error);
 
diff --git a/src/utils.c b/src/utils.c
index 0ca0fa46d7816cd6180d3bfe6299e833a04be534..da973cc005cf1cc021ec30b28b90cb0b9fbcabdf 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -929,6 +929,67 @@ pv_terminate_all_child_processes (GTimeSpan wait_period,
   return TRUE;
 }
 
+/**
+ * pv_current_namespace_path_to_host_path:
+ * @current_env_path: a path in the current environment
+ *
+ * Returns: (transfer full): The @current_env_path converted to the host
+ *  system, or a copy of @current_env_path if we are not in a Flatpak
+ *  environment or it's unknown how to convert the given path.
+ */
+gchar *
+pv_current_namespace_path_to_host_path (const gchar *current_env_path)
+{
+  gchar *path_on_host = NULL;
+  g_autofree gchar *home_env_guarded = NULL;
+  const gchar *home_env = g_getenv ("HOME");
+
+  g_return_val_if_fail (g_path_is_absolute (current_env_path),
+                        g_strdup (current_env_path));
+
+  if (home_env == NULL)
+    home_env = g_get_home_dir ();
+
+  if (home_env != NULL)
+    {
+      /* Avoid the edge case where e.g. current_env_path is
+       * '/home/melanie/Games' and home_env is '/home/me' */
+      if (g_str_has_suffix (home_env, "/"))
+        home_env_guarded = g_strdup (home_env);
+      else
+        home_env_guarded = g_strdup_printf ("%s/", home_env);
+    }
+
+  if (g_file_test ("/.flatpak-info", G_FILE_TEST_IS_REGULAR))
+    {
+      /* If we are inside a Flatpak container, usually, the home
+       * folder is '${HOME}/.var/app/${FLATPAK_ID}' on the host system */
+      if (home_env != NULL
+          && g_str_has_prefix (current_env_path, home_env_guarded))
+        {
+          path_on_host = g_build_filename (home_env,
+                                           ".var",
+                                           "app",
+                                           g_getenv ("FLATPAK_ID"),
+                                           current_env_path + strlen (home_env),
+                                           NULL);
+        }
+
+      /* In a Flatpak container, usually, '/run/host' is the root of the
+       * host system */
+      if (g_str_has_prefix (current_env_path, "/run/host/"))
+        path_on_host = g_strdup (current_env_path + strlen ("/run/host"));
+      else if (g_strcmp0 (current_env_path, "/run/host") == 0)
+        path_on_host = g_strdup ("/");
+    }
+  /* Either we are not in a Flatpak container or it's not obvious how the
+   * container to host translation should happen. Just keep the same path. */
+  if (path_on_host == NULL)
+    path_on_host = g_strdup (current_env_path);
+
+  return path_on_host;
+}
+
 /**
  * pv_file_test_in_sysroot:
  * @sysroot: (type filename): A path used as the root
diff --git a/src/utils.h b/src/utils.h
index 811c0cb39f41b5842b87db6c244591d9ff843d9d..a7e17b775818446a0c0806b323cca76466e46d16 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -74,6 +74,8 @@ gboolean pv_terminate_all_child_processes (GTimeSpan wait_period,
                                            GTimeSpan grace_period,
                                            GError **error);
 
+gchar *pv_current_namespace_path_to_host_path (const gchar *current_env_path);
+
 gboolean pv_file_test_in_sysroot (const char *sysroot,
                                   const char *filename,
                                   GFileTest test);
diff --git a/src/wrap.c b/src/wrap.c
index 69a9dff51ecb0e0f0628c6ce984fc279cb38a9ac..525b545bcfd010c74c339f526b43dbc80ce8251a 100644
--- a/src/wrap.c
+++ b/src/wrap.c
@@ -365,7 +365,8 @@ static gboolean opt_gc_runtimes = TRUE;
 static gboolean opt_generate_locales = TRUE;
 static char *opt_home = NULL;
 static gboolean opt_host_fallback = FALSE;
-static gboolean opt_host_graphics = TRUE;
+static char *opt_graphics_provider = NULL;
+static char *graphics_provider_mount_point = NULL;
 static gboolean opt_only_prepare = FALSE;
 static gboolean opt_remove_game_overlay = FALSE;
 static PvShell opt_shell = PV_SHELL_NONE;
@@ -539,6 +540,38 @@ opt_share_home_cb (const gchar *option_name,
   return TRUE;
 }
 
+static gboolean
+opt_with_host_graphics_cb (const gchar *option_name,
+                           const gchar *value,
+                           gpointer data,
+                           GError **error)
+{
+  /* This is the old way to get the graphics from the host system */
+  if (g_strcmp0 (option_name, "--with-host-graphics") == 0)
+    {
+      if (g_file_test ("/run/host", G_FILE_TEST_IS_DIR))
+        opt_graphics_provider = g_strdup ("/run/host");
+      else
+        opt_graphics_provider = g_strdup ("/");
+    }
+  /* This is the old way to avoid using graphics from the host */
+  else if (g_strcmp0 (option_name, "--without-host-graphics") == 0)
+    {
+      opt_graphics_provider = g_strdup ("");
+    }
+  else
+    {
+      g_return_val_if_reached (FALSE);
+    }
+
+  g_warning ("\"--with-host-graphics\" and \"--without-host-graphics\" have "
+             "been deprecated and could be removed in future releases. Please use "
+             "use \"--graphics-provider=/\", \"--graphics-provider=/run/host\" or "
+             "\"--graphics-provider=\" instead.");
+
+  return TRUE;
+}
+
 static GOptionEntry options[] =
 {
   { "batch", '\0',
@@ -597,6 +630,14 @@ static GOptionEntry options[] =
     G_OPTION_FLAG_NONE, G_OPTION_ARG_CALLBACK, &opt_host_ld_preload_cb,
     "Add MODULE from the host system to LD_PRELOAD when executing COMMAND.",
     "MODULE" },
+  { "graphics-provider", '\0',
+    G_OPTION_FLAG_NONE, G_OPTION_ARG_FILENAME, &opt_graphics_provider,
+    "If using --runtime, use PATH as the graphics provider. "
+    "The path is assumed to be relative to the current namespace, "
+    "and will be adjusted for use on the host system if pressure-vessel "
+    "is run in a container. The empty string means use the graphics "
+    "stack from container."
+    "[Default: $PRESSURE_VESSEL_GRAPHICS_PROVIDER or '/run/host' or '/']", "PATH" },
   { "remove-game-overlay", '\0',
     G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_remove_game_overlay,
     "Disable the Steam Overlay. "
@@ -610,7 +651,7 @@ static GOptionEntry options[] =
   { "runtime", '\0',
     G_OPTION_FLAG_NONE, G_OPTION_ARG_FILENAME, &opt_runtime,
     "Mount the given sysroot or merged /usr in the container, and augment "
-    "it with the host system's graphics stack. The empty string "
+    "it with the provider's graphics stack. The empty string "
     "means don't use a runtime. [Default: $PRESSURE_VESSEL_RUNTIME or '']",
     "RUNTIME" },
   { "runtime-base", '\0',
@@ -698,13 +739,14 @@ static GOptionEntry options[] =
     G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &opt_version_only,
     "Print version number (no other information) and exit.", NULL },
   { "with-host-graphics", '\0',
-    G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &opt_host_graphics,
-    "If using --runtime, use the host graphics stack (default)", NULL },
+    G_OPTION_FLAG_NO_ARG | G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK,
+    opt_with_host_graphics_cb,
+    "Deprecated alias for \"--graphics-provider=/\" or "
+    "\"--graphics-provider=/run/host\"", NULL },
   { "without-host-graphics", '\0',
-    G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_host_graphics,
-    "If using --runtime, don't use the host graphics stack. "
-    "This is likely to result in software rendering or a crash.",
-    NULL },
+    G_OPTION_FLAG_NO_ARG | G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_CALLBACK,
+    opt_with_host_graphics_cb,
+    "Deprecated alias for \"--graphics-provider=\"", NULL },
   { "write-bwrap-arguments", '\0',
     G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_FILENAME, &opt_write_bwrap,
     "Write the final bwrap arguments, as null terminated strings, to the "
@@ -763,6 +805,7 @@ main (int argc,
   g_autoptr(GString) adjusted_ld_preload = g_string_new ("");
   g_autofree gchar *cwd_p = NULL;
   g_autofree gchar *cwd_l = NULL;
+  g_autofree gchar *cwd_p_host = NULL;
   const gchar *home;
   g_autofree gchar *bwrap_help = NULL;
   g_autofree gchar *tools_dir = NULL;
@@ -811,8 +854,7 @@ main (int argc,
   opt_share_home = tristate_environment ("PRESSURE_VESSEL_SHARE_HOME");
   opt_gc_runtimes = pv_boolean_environment ("PRESSURE_VESSEL_GC_RUNTIMES", TRUE);
   opt_generate_locales = pv_boolean_environment ("PRESSURE_VESSEL_GENERATE_LOCALES", TRUE);
-  opt_host_graphics = pv_boolean_environment ("PRESSURE_VESSEL_HOST_GRAPHICS",
-                                              TRUE);
+
   opt_share_pid = pv_boolean_environment ("PRESSURE_VESSEL_SHARE_PID", TRUE);
   opt_verbose = pv_boolean_environment ("PRESSURE_VESSEL_VERBOSE", FALSE);
 
@@ -856,6 +898,33 @@ main (int argc,
       && opt_copy_runtime_into[0] == '\0')
     opt_copy_runtime_into = NULL;
 
+  if (opt_graphics_provider == NULL)
+    opt_graphics_provider = g_strdup (g_getenv ("PRESSURE_VESSEL_GRAPHICS_PROVIDER"));
+
+  if (opt_graphics_provider == NULL)
+    {
+      /* Also check the deprecated 'PRESSURE_VESSEL_HOST_GRAPHICS' */
+      if (!pv_boolean_environment ("PRESSURE_VESSEL_HOST_GRAPHICS", TRUE))
+        opt_graphics_provider = g_strdup ("");
+      else if (g_file_test ("/run/host", G_FILE_TEST_IS_DIR))
+        opt_graphics_provider = g_strdup ("/run/host");
+      else
+        opt_graphics_provider = g_strdup ("/");
+    }
+
+  g_assert (opt_graphics_provider != NULL);
+  if (opt_graphics_provider[0] != '\0' && opt_graphics_provider[0] != '/')
+    {
+      g_printerr ("%s: --graphics-provider path must be absolute, not \"%s\"\n",
+                  g_get_prgname (), opt_graphics_provider);
+      goto out;
+    }
+
+  if (g_strcmp0 (opt_graphics_provider, "/") == 0)
+    graphics_provider_mount_point = g_strdup ("/run/host");
+  else
+    graphics_provider_mount_point = g_strdup ("/run/gfx");
+
   if (opt_version_only)
     {
       g_print ("%s\n", VERSION);
@@ -1205,8 +1274,8 @@ main (int argc,
       if (opt_generate_locales)
         flags |= PV_RUNTIME_FLAGS_GENERATE_LOCALES;
 
-      if (opt_host_graphics)
-        flags |= PV_RUNTIME_FLAGS_HOST_GRAPHICS_STACK;
+      if (opt_graphics_provider != NULL && opt_graphics_provider[0] != '\0')
+        flags |= PV_RUNTIME_FLAGS_PROVIDER_GRAPHICS_STACK;
 
       if (opt_verbose)
         flags |= PV_RUNTIME_FLAGS_VERBOSE;
@@ -1217,6 +1286,8 @@ main (int argc,
                                 opt_copy_runtime_into,
                                 bwrap_executable,
                                 tools_dir,
+                                opt_graphics_provider,
+                                graphics_provider_mount_point,
                                 flags,
                                 error);
 
@@ -1365,6 +1436,8 @@ main (int argc,
    * run) is available. Some games write here. */
   g_debug ("Making current working directory available...");
 
+  cwd_p_host = pv_current_namespace_path_to_host_path (cwd_p);
+
   if (pv_is_same_file (home, cwd_p))
     {
       g_debug ("Not making physical working directory \"%s\" available to "
@@ -1374,7 +1447,7 @@ main (int argc,
   else
     {
       flatpak_bwrap_add_args (bwrap,
-                              "--bind", cwd_p, cwd_p,
+                              "--bind", cwd_p_host, cwd_p_host,
                               NULL);
     }
 
@@ -1384,14 +1457,31 @@ main (int argc,
   if (runtime != NULL)
     {
       flatpak_run_add_wayland_args (bwrap);
-      flatpak_run_add_x11_args (bwrap, TRUE);
+
+      /* When in a Flatpak container the "DISPLAY" env is equal to ":99.0",
+       * but it might be different on the host system. As a workaround we simply
+       * bind the whole "/tmp/.X11-unix" directory and unset the container
+       * "DISPLAY" env.
+       */
+      if (g_file_test ("/.flatpak-info", G_FILE_TEST_IS_REGULAR))
+        {
+          flatpak_bwrap_add_args (bwrap,
+                                  "--ro-bind", "/tmp/.X11-unix", "/tmp/.X11-unix",
+                                  NULL);
+          flatpak_bwrap_unset_env (bwrap, "DISPLAY");
+        }
+      else
+        {
+          flatpak_run_add_x11_args (bwrap, TRUE);
+        }
+
       flatpak_run_add_pulseaudio_args (bwrap);
       flatpak_run_add_session_dbus_args (bwrap);
       flatpak_run_add_system_dbus_args (bwrap);
     }
 
   flatpak_bwrap_add_args (bwrap,
-                          "--chdir", cwd_p,
+                          "--chdir", cwd_p_host,
                           "--unsetenv", "PWD",
                           NULL);