[sushi] Switch to using ExternalWindow class for external parenting



commit 286a75274cd2d991f308af58365ade93d144f9d4
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Tue Jul 2 11:14:57 2019 -0700

    Switch to using ExternalWindow class for external parenting
    
    The code is lifted from xdg-desktop-portal-gtk. This will allow
    us to parent the window to an external Nautilus window even under
    Wayland.

 meson.build                           |   2 +
 src/libsushi/externalwindow-wayland.c | 118 ++++++++++++++++++++++++
 src/libsushi/externalwindow-wayland.h |  34 +++++++
 src/libsushi/externalwindow-x11.c     | 136 ++++++++++++++++++++++++++++
 src/libsushi/externalwindow-x11.h     |  35 ++++++++
 src/libsushi/externalwindow.c         | 163 ++++++++++++++++++++++++++++++++++
 src/libsushi/externalwindow.h         |  54 +++++++++++
 src/libsushi/meson.build              |  15 ++++
 src/libsushi/sushi-utils.c            |  30 +++----
 src/libsushi/sushi-utils.h            |   4 +-
 src/ui/main.js                        |   1 -
 src/ui/mainWindow.js                  |   9 +-
 12 files changed, 577 insertions(+), 24 deletions(-)
---
diff --git a/meson.build b/meson.build
index 49f0b3f..d098e2d 100644
--- a/meson.build
+++ b/meson.build
@@ -17,6 +17,8 @@ gstreamer_audio_dep = dependency('gstreamer-audio-1.0')
 gstreamer_tag_dep = dependency('gstreamer-tag-1.0')
 gstreamer_video_dep = dependency('gstreamer-video-1.0')
 gtk_dep = dependency('gtk+-3.0', version: '>=3.13.2')
+gtk_x11_dep = dependency('gtk+-x11-3.0', required: false)
+gtk_wayland_dep = dependency('gtk+-wayland-3.0', version: '>= 3.21.5', required: false)
 gtksourceview_dep = dependency('gtksourceview-4', version: '>=4.0.3')
 harfbuzz_dep = dependency('harfbuzz', version: '>=0.9.9')
 musicbrainz_dep = dependency('libmusicbrainz5')
diff --git a/src/libsushi/externalwindow-wayland.c b/src/libsushi/externalwindow-wayland.c
new file mode 100644
index 0000000..077ac24
--- /dev/null
+++ b/src/libsushi/externalwindow-wayland.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright © 2016 Red Hat, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *       Jonas Ådahl <jadahl redhat com>
+ */
+
+#include "config.h"
+
+#include <gdk/gdk.h>
+#include <gdk/gdkwayland.h>
+
+#include "externalwindow-wayland.h"
+
+static GdkDisplay *wayland_display;
+
+struct _ExternalWindowWayland
+{
+  ExternalWindow parent;
+
+  char *handle_str;
+};
+
+struct _ExternalWindowWaylandClass
+{
+  ExternalWindowClass parent_class;
+};
+
+G_DEFINE_TYPE (ExternalWindowWayland, external_window_wayland,
+               EXTERNAL_TYPE_WINDOW)
+
+static GdkDisplay *
+get_wayland_display (void)
+{
+  if (wayland_display)
+    return wayland_display;
+
+  gdk_set_allowed_backends ("wayland");
+  wayland_display = gdk_display_open (NULL);
+  gdk_set_allowed_backends (NULL);
+  if (!wayland_display)
+    g_warning ("Failed to open Wayland display");
+
+  return wayland_display;
+}
+
+ExternalWindowWayland *
+external_window_wayland_new (const char *handle_str)
+{
+  ExternalWindowWayland *external_window_wayland;
+  GdkDisplay *display;
+
+  display = get_wayland_display ();
+  if (!display)
+    {
+      g_warning ("No Wayland display connection, ignoring Wayland parent");
+      return NULL;
+    }
+
+  external_window_wayland = g_object_new (EXTERNAL_TYPE_WINDOW_WAYLAND,
+                                          "display", display,
+                                          NULL);
+  external_window_wayland->handle_str = g_strdup (handle_str);
+
+  return external_window_wayland;
+}
+
+static void
+external_window_wayland_set_parent_of (ExternalWindow *external_window,
+                                       GdkWindow      *child_window)
+{
+  ExternalWindowWayland *external_window_wayland =
+    EXTERNAL_WINDOW_WAYLAND (external_window);
+  char *handle_str = external_window_wayland->handle_str;
+
+  if (!gdk_wayland_window_set_transient_for_exported (child_window, handle_str))
+    g_warning ("Failed to set portal window transient for external parent");
+}
+
+static void
+external_window_wayland_dispose (GObject *object)
+{
+  ExternalWindowWayland *external_window_wayland =
+    EXTERNAL_WINDOW_WAYLAND (object);
+
+  g_free (external_window_wayland->handle_str);
+
+  G_OBJECT_CLASS (external_window_wayland_parent_class)->dispose (object);
+}
+
+static void
+external_window_wayland_init (ExternalWindowWayland *external_window_wayland)
+{
+}
+
+static void
+external_window_wayland_class_init (ExternalWindowWaylandClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  ExternalWindowClass *external_window_class = EXTERNAL_WINDOW_CLASS (klass);
+
+  object_class->dispose = external_window_wayland_dispose;
+
+  external_window_class->set_parent_of = external_window_wayland_set_parent_of;
+}
diff --git a/src/libsushi/externalwindow-wayland.h b/src/libsushi/externalwindow-wayland.h
new file mode 100644
index 0000000..ede29ef
--- /dev/null
+++ b/src/libsushi/externalwindow-wayland.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2016 Red Hat, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *       Jonas Ådahl <jadahl redhat com>
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+#include "externalwindow.h"
+
+#define EXTERNAL_TYPE_WINDOW_WAYLAND (external_window_wayland_get_type ())
+#define EXTERNAL_WINDOW_WAYLAND(object) (G_TYPE_CHECK_INSTANCE_CAST (object, EXTERNAL_TYPE_WINDOW_WAYLAND, 
ExternalWindowWayland))
+
+typedef struct _ExternalWindowWayland ExternalWindowWayland;
+typedef struct _ExternalWindowWaylandClass ExternalWindowWaylandClass;
+
+GType external_window_wayland_get_type (void);
+ExternalWindowWayland *external_window_wayland_new (const char *handle_str);
diff --git a/src/libsushi/externalwindow-x11.c b/src/libsushi/externalwindow-x11.c
new file mode 100644
index 0000000..75de557
--- /dev/null
+++ b/src/libsushi/externalwindow-x11.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright © 2016 Red Hat, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *       Jonas Ådahl <jadahl redhat com>
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdk.h>
+#include <stdlib.h>
+
+#include "externalwindow-x11.h"
+
+
+static GdkDisplay *x11_display;
+
+struct _ExternalWindowX11
+{
+  ExternalWindow parent;
+
+  GdkWindow *foreign_gdk_window;
+};
+
+struct _ExternalWindowX11Class
+{
+  ExternalWindowClass parent_class;
+};
+
+G_DEFINE_TYPE (ExternalWindowX11, external_window_x11,
+               EXTERNAL_TYPE_WINDOW)
+
+static GdkDisplay *
+get_x11_display (void)
+{
+  if (x11_display)
+    return x11_display;
+
+  gdk_set_allowed_backends ("x11");
+  x11_display = gdk_display_open (NULL);
+  gdk_set_allowed_backends (NULL);
+  if (!x11_display)
+    g_warning ("Failed to open X11 display");
+
+  return x11_display;
+}
+
+ExternalWindowX11 *
+external_window_x11_new (const char *handle_str)
+{
+  ExternalWindowX11 *external_window_x11;
+  GdkDisplay *display;
+  int xid;
+  GdkWindow *foreign_gdk_window;
+
+  display = get_x11_display ();
+  if (!display)
+    {
+      g_warning ("No X display connection, ignoring X11 parent");
+      return NULL;
+    }
+
+  errno = 0;
+  xid = strtol (handle_str, NULL, 16);
+  if (errno != 0)
+    {
+      g_warning ("Failed to reference external X11 window, invalid XID %s", handle_str);
+      return NULL;
+    }
+
+  foreign_gdk_window = gdk_x11_window_foreign_new_for_display (display, xid);
+  if (!foreign_gdk_window)
+    {
+      g_warning ("Failed to create foreign window for XID %d", xid);
+      return NULL;
+    }
+
+  external_window_x11 = g_object_new (EXTERNAL_TYPE_WINDOW_X11,
+                                      "display", display,
+                                      NULL);
+  external_window_x11->foreign_gdk_window = foreign_gdk_window;
+
+  return external_window_x11;
+}
+
+static void
+external_window_x11_set_parent_of (ExternalWindow *external_window,
+                                   GdkWindow      *child_window)
+{
+  ExternalWindowX11 *external_window_x11 =
+    EXTERNAL_WINDOW_X11 (external_window);
+
+  gdk_window_set_transient_for (child_window,
+                                external_window_x11->foreign_gdk_window);
+}
+
+static void
+external_window_x11_dispose (GObject *object)
+{
+  ExternalWindowX11 *external_window_x11 = EXTERNAL_WINDOW_X11 (object);
+
+  g_clear_object (&external_window_x11->foreign_gdk_window);
+
+  G_OBJECT_CLASS (external_window_x11_parent_class)->dispose (object);
+}
+
+static void
+external_window_x11_init (ExternalWindowX11 *external_window_x11)
+{
+}
+
+static void
+external_window_x11_class_init (ExternalWindowX11Class *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  ExternalWindowClass *external_window_class = EXTERNAL_WINDOW_CLASS (klass);
+
+  object_class->dispose = external_window_x11_dispose;
+
+  external_window_class->set_parent_of = external_window_x11_set_parent_of;
+}
diff --git a/src/libsushi/externalwindow-x11.h b/src/libsushi/externalwindow-x11.h
new file mode 100644
index 0000000..d380a3d
--- /dev/null
+++ b/src/libsushi/externalwindow-x11.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2016 Red Hat, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *       Jonas Ådahl <jadahl redhat com>
+ */
+
+#pragma once
+
+#include <glib-object.h>
+
+#include "externalwindow.h"
+
+
+#define EXTERNAL_TYPE_WINDOW_X11 (external_window_x11_get_type ())
+#define EXTERNAL_WINDOW_X11(object) (G_TYPE_CHECK_INSTANCE_CAST (object, EXTERNAL_TYPE_WINDOW_X11, 
ExternalWindowX11))
+
+typedef struct _ExternalWindowX11 ExternalWindowX11;
+typedef struct _ExternalWindowX11Class ExternalWindowX11Class;
+
+GType external_window_get_type (void);
+ExternalWindowX11 *external_window_x11_new (const char *handle_str);
diff --git a/src/libsushi/externalwindow.c b/src/libsushi/externalwindow.c
new file mode 100644
index 0000000..9b81670
--- /dev/null
+++ b/src/libsushi/externalwindow.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright © 2016 Red Hat, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *       Jonas Ådahl <jadahl redhat com>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "externalwindow.h"
+#ifdef HAVE_GTK_X11
+#include "externalwindow-x11.h"
+#endif
+#ifdef HAVE_GTK_WAYLAND
+#include "externalwindow-wayland.h"
+#endif
+
+enum
+{
+  PROP_0,
+
+  PROP_DISPLAY,
+};
+
+typedef struct _ExternalWindowPrivate
+{
+  GdkDisplay *display;
+} ExternalWindowPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (ExternalWindow, external_window, G_TYPE_OBJECT)
+
+ExternalWindow *
+create_external_window_from_handle (const char *handle_str)
+{
+#ifdef HAVE_GTK_X11
+    {
+      const char x11_prefix[] = "x11:";
+      if (g_str_has_prefix (handle_str, x11_prefix))
+        {
+          ExternalWindowX11 *external_window_x11;
+          const char *x11_handle_str = handle_str + strlen (x11_prefix);
+
+          external_window_x11 = external_window_x11_new (x11_handle_str);
+          return EXTERNAL_WINDOW (external_window_x11);
+        }
+    }
+#endif
+#ifdef HAVE_GTK_WAYLAND
+    {
+      const char wayland_prefix[] = "wayland:";
+      if (g_str_has_prefix (handle_str, wayland_prefix))
+        {
+          ExternalWindowWayland *external_window_wayland;
+          const char *wayland_handle_str = handle_str + strlen (wayland_prefix);
+
+          external_window_wayland =
+            external_window_wayland_new (wayland_handle_str);
+          return EXTERNAL_WINDOW (external_window_wayland);
+        }
+    }
+#endif
+
+  g_warning ("Unhandled parent window type %s\n", handle_str);
+  return NULL;
+}
+
+void
+external_window_set_parent_of (ExternalWindow *external_window,
+                               GdkWindow      *child_window)
+{
+  EXTERNAL_WINDOW_GET_CLASS (external_window)->set_parent_of (external_window,
+                                                              child_window);
+}
+
+GdkDisplay *
+external_window_get_display (ExternalWindow *external_window)
+{
+  ExternalWindowPrivate *priv =
+    external_window_get_instance_private (external_window);
+
+  return priv->display;
+}
+
+static void
+external_window_set_property (GObject      *object,
+                              guint         prop_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
+{
+  ExternalWindow *external_window = EXTERNAL_WINDOW (object);
+  ExternalWindowPrivate *priv =
+    external_window_get_instance_private (external_window);
+
+  switch (prop_id)
+    {
+    case PROP_DISPLAY:
+      g_set_object (&priv->display, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+external_window_get_property (GObject    *object,
+                              guint       prop_id,
+                              GValue     *value,
+                              GParamSpec *pspec)
+{
+  ExternalWindow *external_window = EXTERNAL_WINDOW (object);
+  ExternalWindowPrivate *priv =
+    external_window_get_instance_private (external_window);
+
+  switch (prop_id)
+    {
+    case PROP_DISPLAY:
+      g_value_set_object (value, priv->display);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+external_window_init (ExternalWindow *external_window)
+{
+}
+
+static void
+external_window_class_init (ExternalWindowClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->get_property = external_window_get_property;
+  object_class->set_property = external_window_set_property;
+
+  g_object_class_install_property (object_class,
+                                   PROP_DISPLAY,
+                                   g_param_spec_object ("display",
+                                                        "GdkDisplay",
+                                                        "The GdkDisplay instance",
+                                                        GDK_TYPE_DISPLAY,
+                                                        G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT_ONLY |
+                                                        G_PARAM_STATIC_STRINGS));
+}
diff --git a/src/libsushi/externalwindow.h b/src/libsushi/externalwindow.h
new file mode 100644
index 0000000..8282fc2
--- /dev/null
+++ b/src/libsushi/externalwindow.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright © 2016 Red Hat, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *       Jonas Ådahl <jadahl redhat com>
+ */
+
+#pragma once
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+
+#define EXTERNAL_TYPE_WINDOW (external_window_get_type ())
+#define EXTERNAL_WINDOW(object) (G_TYPE_CHECK_INSTANCE_CAST (object, EXTERNAL_TYPE_WINDOW, ExternalWindow))
+#define EXTERNAL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST (klass, EXTERNAL_TYPE_WINDOW, 
ExternalWindowClass))
+#define EXTERNAL_WINDOW_GET_CLASS(klass) (G_TYPE_INSTANCE_GET_CLASS (klass, EXTERNAL_TYPE_WINDOW, 
ExternalWindowClass))
+
+typedef struct _ExternalWindow ExternalWindow;
+typedef struct _ExternalWindowClass ExternalWindowClass;
+
+struct _ExternalWindow
+{
+  GObject parent_instance;
+};
+
+struct _ExternalWindowClass
+{
+  GObjectClass parent_class;
+
+  void (*set_parent_of) (ExternalWindow *external_window,
+                         GdkWindow      *child_window);
+};
+
+GType external_window_get_type (void);
+ExternalWindow *create_external_window_from_handle (const char *handle_str);
+
+void external_window_set_parent_of (ExternalWindow *external_window,
+                                    GdkWindow      *child_window);
+
+GdkDisplay *external_window_get_display (ExternalWindow *external_window);
diff --git a/src/libsushi/meson.build b/src/libsushi/meson.build
index d43ee21..4f15335 100644
--- a/src/libsushi/meson.build
+++ b/src/libsushi/meson.build
@@ -1,3 +1,17 @@
+config_data = configuration_data()
+config_data.set10('HAVE_GTK_X11', gtk_x11_dep.found())
+config_data.set10('HAVE_GTK_WAYLAND', gtk_wayland_dep.found())
+configure_file(output: 'config.h', configuration: config_data)
+
+externalwindow_sources = [
+  'externalwindow.c',
+  'externalwindow.h',
+  'externalwindow-wayland.c',
+  'externalwindow-wayland.h',
+  'externalwindow-x11.c',
+  'externalwindow-x11.h',
+]
+
 libsushi_deps = [
   epoxy_dep,
   evince_document_dep,
@@ -35,6 +49,7 @@ libsushi = shared_library(
   'sushi-1.0',
   dependencies: libsushi_deps,
   sources: [
+    externalwindow_sources,
     libsushi_sources,
     libsushi_resource
   ],
diff --git a/src/libsushi/sushi-utils.c b/src/libsushi/sushi-utils.c
index 81f690d..89e5c94 100644
--- a/src/libsushi/sushi-utils.c
+++ b/src/libsushi/sushi-utils.c
@@ -33,23 +33,21 @@
 #include <gdk/gdkx.h>
 #endif
 
-/**
- * sushi_create_foreign_window:
- * @xid:
- *
- * Returns: (transfer full): a #GdkWindow
- */
-GdkWindow *
-sushi_create_foreign_window (guint xid)
+#include "externalwindow.h"
+
+void
+sushi_window_set_child_of_external (GtkWindow *window,
+                                    const char *handle)
 {
-  GdkWindow *retval = NULL;
+  ExternalWindow *external_window = create_external_window_from_handle (handle);
 
-#ifdef GDK_WINDOWING_X11
-  if (GDK_IS_X11_DISPLAY (gdk_display_get_default ()))
-    retval = gdk_x11_window_foreign_new_for_display (gdk_display_get_default (), xid);
-#endif
+  if (!external_window)
+    return;
 
-  return retval;
+  gtk_widget_realize (GTK_WIDGET (window));
+  external_window_set_parent_of (external_window,
+                                 gtk_widget_get_window (GTK_WIDGET (window)));
+  g_object_unref (external_window);
 }
 
 /**
@@ -160,12 +158,14 @@ libreoffice_missing (GTask *task)
   GtkWidget *widget = GTK_WIDGET (gtk_application_get_active_window (GTK_APPLICATION (app)));
   GDBusConnection *connection = g_application_get_dbus_connection (app);
   guint xid = 0;
-  GdkWindow *gdk_window;
   const gchar *libreoffice_path[2];
 
+#ifdef GDK_WINDOWING_X11
+  GdkWindow *gdk_window;
   gdk_window = gtk_widget_get_window (widget);
   if (gdk_window != NULL)
     xid = GDK_WINDOW_XID (gdk_window);
+#endif
 
   libreoffice_path[0] = "/usr/bin/libreoffice";
   libreoffice_path[1] = NULL;
diff --git a/src/libsushi/sushi-utils.h b/src/libsushi/sushi-utils.h
index 83f7ea0..b36ff2b 100644
--- a/src/libsushi/sushi-utils.h
+++ b/src/libsushi/sushi-utils.h
@@ -34,7 +34,6 @@
 
 G_BEGIN_DECLS
 
-GdkWindow *    sushi_create_foreign_window (guint xid);
 gchar **       sushi_query_supported_document_types (void);
 
 EvDocument *   sushi_get_evince_document_from_job (EvJob   *job,
@@ -56,6 +55,9 @@ gchar *        sushi_get_asin_for_track_finish (GAsyncResult *result,
 GdkPixbuf *    sushi_pixbuf_from_gst_sample (GstSample *sample,
                                              GError   **error);
 
+void           sushi_window_set_child_of_external (GtkWindow *window,
+                                                   const char *handle);
+
 G_END_DECLS
 
 #endif /* __SUSHI_UTILS_H__ */
diff --git a/src/ui/main.js b/src/ui/main.js
index 5fbd5bf..b0cb7de 100644
--- a/src/ui/main.js
+++ b/src/ui/main.js
@@ -29,7 +29,6 @@ pkg.require({
     EvinceView: '3.0',
     Gdk: '3.0',
     GdkPixbuf: '2.0',
-    GdkX11: '3.0',
     Gio: '2.0',
     GLib: '2.0',
     GObject: '2.0',
diff --git a/src/ui/mainWindow.js b/src/ui/mainWindow.js
index 66e3b26..e495290 100644
--- a/src/ui/mainWindow.js
+++ b/src/ui/mainWindow.js
@@ -328,13 +328,8 @@ var MainWindow = GObject.registerClass(class MainWindow extends Gtk.Window {
      ************************ public methods **********************************
      **************************************************************************/
     setParent(xid) {
-        this._parent = Sushi.create_foreign_window(xid);
-        this.realize();
-        if (this._parent)
-            this.get_window().set_transient_for(this._parent);
-
-        if (this.get_window().move_to_current_desktop)
-            this.get_window().move_to_current_desktop();
+        let handle = 'x11:%d'.format(xid);
+        Sushi.window_set_child_of_external(this, handle);
     }
 
     setFile(file) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]