x11: Move window construction to ::constructed()
authorBenjamin Otte <otte@redhat.com>
Fri, 21 Apr 2023 18:36:07 +0000 (20:36 +0200)
committerBenjamin Otte <otte@redhat.com>
Wed, 26 Apr 2023 19:03:34 +0000 (21:03 +0200)
gdk/x11/gdksurface-x11.c

index b190b8ff34abe88235080ebfef8873801cde70c3..5488b3fd7b358cdd6e615b0576ecbd964873f20e 100644 (file)
@@ -777,133 +777,18 @@ gdk_x11_surface_end_frame (GdkSurface *surface)
  * X11 specific implementations of generic functions *
  *****************************************************/
 
-static void
-gdk_x11_surface_finalize (GObject *object)
-{
-  GdkX11Surface *impl;
-
-  g_return_if_fail (GDK_IS_X11_SURFACE (object));
-
-  impl = GDK_X11_SURFACE (object);
-
-  if (impl->toplevel->in_frame)
-    unhook_surface_changed (GDK_SURFACE (impl));
-
-  g_signal_handlers_disconnect_by_func (GDK_SURFACE (impl),
-                                        gdk_x11_toplevel_state_callback,
-                                        NULL);
-  g_signal_handlers_disconnect_by_func (GDK_SURFACE (impl),
-                                        gdk_x11_toplevel_event_callback,
-                                        NULL);
-
-  _gdk_x11_surface_grab_check_destroy (GDK_SURFACE (impl));
-
-  if (!GDK_SURFACE_DESTROYED (impl))
-    {
-      GdkDisplay *display = GDK_SURFACE_DISPLAY (GDK_SURFACE (impl));
-
-      _gdk_x11_display_remove_window (display, impl->xid);
-      if (impl->toplevel && impl->toplevel->focus_window)
-        _gdk_x11_display_remove_window (display, impl->toplevel->focus_window);
-    }
-
-  g_clear_pointer (&impl->surface_is_on_monitor, g_list_free);
-  g_clear_handle_id (&impl->compute_size_source_id, g_source_remove);
-  g_clear_pointer (&impl->toplevel_layout, gdk_toplevel_layout_unref);
-
-  g_free (impl->toplevel);
-
-  if (impl->cursor)
-    g_object_unref (impl->cursor);
-
-  G_OBJECT_CLASS (gdk_x11_surface_parent_class)->finalize (object);
-}
-
-typedef struct {
-  GdkDisplay *display;
-  Pixmap pixmap;
-} FreePixmapData;
-
-static void
-free_pixmap (gpointer datap)
-{
-  FreePixmapData *data = datap;
-
-  if (!gdk_display_is_closed (data->display))
-    {
-      XFreePixmap (GDK_DISPLAY_XDISPLAY (data->display),
-                   data->pixmap);
-    }
-
-  g_object_unref (data->display);
-  g_free (data);
-}
-
-static void
-attach_free_pixmap_handler (cairo_surface_t *surface,
-                            GdkDisplay      *display,
-                            Pixmap           pixmap)
-{
-  static const cairo_user_data_key_t key;
-  FreePixmapData *data;
-  
-  data = g_new (FreePixmapData, 1);
-  data->display = g_object_ref (display);
-  data->pixmap = pixmap;
-
-  cairo_surface_set_user_data (surface, &key, data, free_pixmap);
-}
-
-/* Cairo does not guarantee we get an xlib surface if we call
- * cairo_surface_create_similar(). In some cases however, we must use a
- * pixmap or bitmap in the X11 API.
- * These functions ensure an Xlib surface.
- */
-cairo_surface_t *
-_gdk_x11_display_create_bitmap_surface (GdkDisplay *display,
-                                        int         width,
-                                        int         height)
-{
-  cairo_surface_t *surface;
-  Pixmap pixmap;
-
-  pixmap = XCreatePixmap (GDK_DISPLAY_XDISPLAY (display),
-                          GDK_SCREEN_XROOTWIN (GDK_X11_DISPLAY (display)->screen),
-                          width, height, 1);
-  surface = cairo_xlib_surface_create_for_bitmap (GDK_DISPLAY_XDISPLAY (display),
-                                                  pixmap,
-                                                  GDK_X11_SCREEN (GDK_X11_DISPLAY (display)->screen)->xscreen,
-                                                  width, height);
-  attach_free_pixmap_handler (surface, display, pixmap);
-
-  return surface;
-}
-
-/* Create a surface backed with a pixmap without alpha on the same screen as surface */
-static cairo_surface_t *
-gdk_x11_surface_create_pixmap_surface (GdkSurface *surface,
-                                      int        width,
-                                      int        height)
+static const char *
+get_default_title (void)
 {
-  GdkDisplay *display;
-  Display *dpy;
-  cairo_surface_t *cairo_surface;
-  Pixmap pixmap;
-
-  display = gdk_surface_get_display (surface);
-  dpy = GDK_DISPLAY_XDISPLAY (display);
+  const char *title;
 
-  pixmap = XCreatePixmap (dpy,
-                          GDK_SURFACE_XID (surface),
-                          width, height,
-                          DefaultDepth (dpy, DefaultScreen (dpy)));
-  cairo_surface = cairo_xlib_surface_create (dpy,
-                                       pixmap,
-                                       DefaultVisual (dpy, DefaultScreen (dpy)),
-                                       width, height);
-  attach_free_pixmap_handler (cairo_surface, display, pixmap);
+  title = g_get_application_name ();
+  if (!title)
+    title = g_get_prgname ();
+  if (!title)
+    title = "";
 
-  return cairo_surface;
+  return title;
 }
 
 static void
@@ -925,20 +810,6 @@ set_wm_protocols (GdkSurface *surface)
   XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_SURFACE_XID (surface), protocols, n);
 }
 
-static const char *
-get_default_title (void)
-{
-  const char *title;
-
-  title = g_get_application_name ();
-  if (!title)
-    title = g_get_prgname ();
-  if (!title)
-    title = "";
-
-  return title;
-}
-
 static void
 check_leader_window_title (GdkDisplay *display)
 {
@@ -1027,8 +898,7 @@ ensure_sync_counter (GdkSurface *surface)
 }
 
 static void
-setup_toplevel_window (GdkSurface    *surface,
-                      GdkX11Screen *x11_screen)
+setup_toplevel_window (GdkSurface *surface)
 {
   GdkToplevelX11 *toplevel = _gdk_x11_surface_get_toplevel (surface);
   GdkX11Surface *impl = GDK_X11_SURFACE (surface);
@@ -1044,11 +914,11 @@ setup_toplevel_window (GdkSurface    *surface,
    * press events so they don't get sent to child surfaces.
    */
   toplevel->focus_window = create_focus_window (display, xid);
-  _gdk_x11_display_add_window (x11_screen->display,
+  _gdk_x11_display_add_window (display,
                                &toplevel->focus_window,
                                surface);
 
-  check_leader_window_title (x11_screen->display);
+  check_leader_window_title (display);
 
   /* FIXME: Is there any point in doing this? Do any WM's pay
    * attention to PSize, and even if they do, is this the
@@ -1068,28 +938,28 @@ setup_toplevel_window (GdkSurface    *surface,
       /* if sandboxed, we're likely in a pid namespace and would only confuse the wm with this */
       long pid = getpid ();
       XChangeProperty (xdisplay, xid,
-                       gdk_x11_get_xatom_by_name_for_display (x11_screen->display, "_NET_WM_PID"),
+                       gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PID"),
                        XA_CARDINAL, 32,
                        PropModeReplace,
                        (guchar *)&pid, 1);
     }
 
-  leader_window = GDK_X11_DISPLAY (x11_screen->display)->leader_window;
+  leader_window = GDK_X11_DISPLAY (display)->leader_window;
   if (!leader_window)
     leader_window = xid;
   XChangeProperty (xdisplay, xid, 
-                  gdk_x11_get_xatom_by_name_for_display (x11_screen->display, "WM_CLIENT_LEADER"),
+                  gdk_x11_get_xatom_by_name_for_display (display, "WM_CLIENT_LEADER"),
                   XA_WINDOW, 32, PropModeReplace,
                   (guchar *) &leader_window, 1);
 
   if (toplevel->focus_window != None)
     XChangeProperty (xdisplay, xid, 
-                     gdk_x11_get_xatom_by_name_for_display (x11_screen->display, "_NET_WM_USER_TIME_WINDOW"),
+                     gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_USER_TIME_WINDOW"),
                      XA_WINDOW, 32, PropModeReplace,
                      (guchar *) &toplevel->focus_window, 1);
 
-  if (GDK_X11_DISPLAY (x11_screen->display)->user_time != 0)
-    gdk_x11_surface_set_user_time (surface, GDK_X11_DISPLAY (x11_screen->display)->user_time);
+  if (GDK_X11_DISPLAY (display)->user_time != 0)
+    gdk_x11_surface_set_user_time (surface, GDK_X11_DISPLAY (display)->user_time);
 
   ensure_sync_counter (surface);
 
@@ -1193,6 +1063,179 @@ typedef enum
 
 static void gdk_x11_surface_set_title (GdkSurface *surface,
                                        const char *title);
+static void
+gdk_x11_surface_constructed (GObject *object)
+{
+  GdkX11Surface *self = GDK_X11_SURFACE (object);
+  GdkSurface *surface = GDK_SURFACE (self);
+  GdkDisplay *display = gdk_surface_get_display (surface);
+  GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
+  XClassHint *class_hint;
+
+  g_assert (self->xid);
+
+  g_object_ref (surface);
+  _gdk_x11_display_add_window (display, &self->xid, surface);
+
+  self->surface_scale = display_x11->screen->surface_scale;
+
+  gdk_surface_set_egl_native_window (surface, (void *) self->xid);
+
+  gdk_x11_surface_set_title (surface, get_default_title ());
+
+  class_hint = XAllocClassHint ();
+  class_hint->res_name = (char *) g_get_prgname ();
+  if (display_x11->program_class)
+    class_hint->res_class = (char *) display_x11->program_class;
+  else
+    class_hint->res_class = class_hint->res_name;
+  XSetClassHint (GDK_DISPLAY_XDISPLAY (display), self->xid, class_hint);
+  XFree (class_hint);
+
+  setup_toplevel_window (surface);
+
+  gdk_x11_event_source_select_events ((GdkEventSource *) display_x11->event_source,
+                                      GDK_SURFACE_XID (surface), GDK_ALL_EVENTS_MASK,
+                                      StructureNotifyMask | PropertyChangeMask);
+
+  _gdk_x11_surface_register_dnd (surface);
+
+  connect_frame_clock (surface);
+
+  gdk_surface_freeze_updates (surface);
+
+  G_OBJECT_CLASS (gdk_x11_surface_parent_class)->constructed (object);
+}
+
+static void
+gdk_x11_surface_finalize (GObject *object)
+{
+  GdkX11Surface *impl;
+
+  g_return_if_fail (GDK_IS_X11_SURFACE (object));
+
+  impl = GDK_X11_SURFACE (object);
+
+  if (impl->toplevel->in_frame)
+    unhook_surface_changed (GDK_SURFACE (impl));
+
+  g_signal_handlers_disconnect_by_func (GDK_SURFACE (impl),
+                                        gdk_x11_toplevel_state_callback,
+                                        NULL);
+  g_signal_handlers_disconnect_by_func (GDK_SURFACE (impl),
+                                        gdk_x11_toplevel_event_callback,
+                                        NULL);
+
+  _gdk_x11_surface_grab_check_destroy (GDK_SURFACE (impl));
+
+  if (!GDK_SURFACE_DESTROYED (impl))
+    {
+      GdkDisplay *display = GDK_SURFACE_DISPLAY (GDK_SURFACE (impl));
+
+      _gdk_x11_display_remove_window (display, impl->xid);
+      if (impl->toplevel && impl->toplevel->focus_window)
+        _gdk_x11_display_remove_window (display, impl->toplevel->focus_window);
+    }
+
+  g_clear_pointer (&impl->surface_is_on_monitor, g_list_free);
+  g_clear_handle_id (&impl->compute_size_source_id, g_source_remove);
+  g_clear_pointer (&impl->toplevel_layout, gdk_toplevel_layout_unref);
+
+  g_free (impl->toplevel);
+
+  if (impl->cursor)
+    g_object_unref (impl->cursor);
+
+  G_OBJECT_CLASS (gdk_x11_surface_parent_class)->finalize (object);
+}
+
+typedef struct {
+  GdkDisplay *display;
+  Pixmap pixmap;
+} FreePixmapData;
+
+static void
+free_pixmap (gpointer datap)
+{
+  FreePixmapData *data = datap;
+
+  if (!gdk_display_is_closed (data->display))
+    {
+      XFreePixmap (GDK_DISPLAY_XDISPLAY (data->display),
+                   data->pixmap);
+    }
+
+  g_object_unref (data->display);
+  g_free (data);
+}
+
+static void
+attach_free_pixmap_handler (cairo_surface_t *surface,
+                            GdkDisplay      *display,
+                            Pixmap           pixmap)
+{
+  static const cairo_user_data_key_t key;
+  FreePixmapData *data;
+  
+  data = g_new (FreePixmapData, 1);
+  data->display = g_object_ref (display);
+  data->pixmap = pixmap;
+
+  cairo_surface_set_user_data (surface, &key, data, free_pixmap);
+}
+
+/* Cairo does not guarantee we get an xlib surface if we call
+ * cairo_surface_create_similar(). In some cases however, we must use a
+ * pixmap or bitmap in the X11 API.
+ * These functions ensure an Xlib surface.
+ */
+cairo_surface_t *
+_gdk_x11_display_create_bitmap_surface (GdkDisplay *display,
+                                        int         width,
+                                        int         height)
+{
+  cairo_surface_t *surface;
+  Pixmap pixmap;
+
+  pixmap = XCreatePixmap (GDK_DISPLAY_XDISPLAY (display),
+                          GDK_SCREEN_XROOTWIN (GDK_X11_DISPLAY (display)->screen),
+                          width, height, 1);
+  surface = cairo_xlib_surface_create_for_bitmap (GDK_DISPLAY_XDISPLAY (display),
+                                                  pixmap,
+                                                  GDK_X11_SCREEN (GDK_X11_DISPLAY (display)->screen)->xscreen,
+                                                  width, height);
+  attach_free_pixmap_handler (surface, display, pixmap);
+
+  return surface;
+}
+
+/* Create a surface backed with a pixmap without alpha on the same screen as surface */
+static cairo_surface_t *
+gdk_x11_surface_create_pixmap_surface (GdkSurface *surface,
+                                      int        width,
+                                      int        height)
+{
+  GdkDisplay *display;
+  Display *dpy;
+  cairo_surface_t *cairo_surface;
+  Pixmap pixmap;
+
+  display = gdk_surface_get_display (surface);
+  dpy = GDK_DISPLAY_XDISPLAY (display);
+
+  pixmap = XCreatePixmap (dpy,
+                          GDK_SURFACE_XID (surface),
+                          width, height,
+                          DefaultDepth (dpy, DefaultScreen (dpy)));
+  cairo_surface = cairo_xlib_surface_create (dpy,
+                                       pixmap,
+                                       DefaultVisual (dpy, DefaultScreen (dpy)),
+                                       width, height);
+  attach_free_pixmap_handler (cairo_surface, display, pixmap);
+
+  return cairo_surface;
+}
+
 static void gdk_x11_surface_set_type_hint (GdkSurface        *surface,
                                            GdkSurfaceTypeHint hint);
 
@@ -1203,20 +1246,6 @@ gdk_x11_display_create_surface (GdkDisplay     *display,
 {
   GdkSurface *surface;
   GdkFrameClock *frame_clock;
-  GdkX11Surface *impl;
-  GdkX11Screen *x11_screen;
-  GdkX11Display *display_x11;
-
-  Window xparent;
-  Display *xdisplay;
-
-  XSetWindowAttributes xattributes;
-  long xattributes_mask;
-  XClassHint *class_hint;
-
-  display_x11 = GDK_X11_DISPLAY (display);
-  x11_screen = GDK_X11_SCREEN (display_x11->screen);
-  xparent = GDK_SCREEN_XROOTWIN (x11_screen);
 
   if (parent)
     frame_clock = g_object_ref (gdk_surface_get_frame_clock (parent));
@@ -1251,78 +1280,6 @@ gdk_x11_display_create_surface (GdkDisplay     *display,
 
   g_object_unref (frame_clock);
 
-  impl = GDK_X11_SURFACE (surface);
-  impl->surface_scale = x11_screen->surface_scale;
-
-  xdisplay = x11_screen->xdisplay;
-
-  xattributes_mask = 0;
-
-  impl->override_redirect = FALSE;
-
-  xattributes.background_pixmap = None;
-  xattributes_mask |= CWBackPixmap;
-
-  xattributes.border_pixel = BlackPixel (xdisplay, x11_screen->screen_num);
-  xattributes_mask |= CWBorderPixel;
-
-  xattributes.bit_gravity = NorthWestGravity;
-  xattributes_mask |= CWBitGravity;
-
-  xattributes.colormap = gdk_x11_display_get_window_colormap (display_x11);
-  xattributes_mask |= CWColormap;
-
-  if (surface_type == GDK_SURFACE_DRAG ||
-      surface_type == GDK_SURFACE_POPUP)
-    {
-      xattributes.save_under = True;
-      xattributes.override_redirect = True;
-      xattributes.cursor = None;
-      xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
-
-      impl->override_redirect = TRUE;
-    }
-
-  impl->xid = XCreateWindow (xdisplay, xparent,
-                             0, 0, 1, 1,
-                             0,
-                             gdk_x11_display_get_window_depth (display_x11),
-                             InputOutput,
-                             gdk_x11_display_get_window_visual (display_x11),
-                             xattributes_mask, &xattributes);
-
-  g_object_ref (surface);
-  _gdk_x11_display_add_window (x11_screen->display, &impl->xid, surface);
-
-  gdk_surface_set_egl_native_window (surface, (void *) impl->xid);
-
-  gdk_x11_surface_set_title (surface, get_default_title ());
-  if (surface_type == GDK_SURFACE_TOPLEVEL)
-    gdk_x11_surface_set_type_hint (surface, GDK_SURFACE_TYPE_HINT_NORMAL);
-  else if (surface_type == GDK_SURFACE_POPUP)
-    gdk_x11_surface_set_type_hint (surface, GDK_SURFACE_TYPE_HINT_MENU);
-
-  class_hint = XAllocClassHint ();
-  class_hint->res_name = (char *) g_get_prgname ();
-  if (display_x11->program_class)
-    class_hint->res_class = (char *) display_x11->program_class;
-  else
-    class_hint->res_class = class_hint->res_name;
-  XSetClassHint (xdisplay, impl->xid, class_hint);
-  XFree (class_hint);
-
-  setup_toplevel_window (surface, x11_screen);
-
-  gdk_x11_event_source_select_events ((GdkEventSource *) display_x11->event_source,
-                                      GDK_SURFACE_XID (surface), GDK_ALL_EVENTS_MASK,
-                                      StructureNotifyMask | PropertyChangeMask);
-
-  _gdk_x11_surface_register_dnd (surface);
-
-  connect_frame_clock (surface);
-
-  gdk_surface_freeze_updates (surface);
-
   return surface;
 }
 
@@ -2263,7 +2220,7 @@ gdk_x11_surface_focus (GdkSurface *surface,
 
 static void
 gdk_x11_surface_set_type_hint (GdkSurface        *surface,
-                             GdkSurfaceTypeHint hint)
+                               GdkSurfaceTypeHint hint)
 {
   GdkDisplay *display;
   Atom atom;
@@ -4841,6 +4798,7 @@ gdk_x11_surface_class_init (GdkX11SurfaceClass *klass)
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GdkSurfaceClass *impl_class = GDK_SURFACE_CLASS (klass);
   
+  object_class->constructed = gdk_x11_surface_constructed;
   object_class->finalize = gdk_x11_surface_finalize;
   
   impl_class->hide = gdk_x11_surface_hide;
@@ -4859,6 +4817,39 @@ gdk_x11_surface_class_init (GdkX11SurfaceClass *klass)
   impl_class->compute_size = gdk_x11_surface_compute_size;
 }
 
+static void
+gdk_x11_surface_create_window (GdkX11Surface        *self,
+                               XSetWindowAttributes *xattributes,
+                               long                  xattributes_mask)
+{
+  GdkDisplay *display = gdk_surface_get_display (GDK_SURFACE (self));
+  GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
+
+  g_assert (self->xid == 0);
+
+  xattributes->background_pixmap = None;
+  xattributes_mask |= CWBackPixmap;
+
+  xattributes->border_pixel = BlackPixel (GDK_DISPLAY_XDISPLAY (display),
+                                          display_x11->screen->screen_num);
+  xattributes_mask |= CWBorderPixel;
+
+  xattributes->bit_gravity = NorthWestGravity;
+  xattributes_mask |= CWBitGravity;
+
+  xattributes->colormap = gdk_x11_display_get_window_colormap (display_x11);
+  xattributes_mask |= CWColormap;
+
+  self->xid = XCreateWindow (GDK_DISPLAY_XDISPLAY (display),
+                             display_x11->screen->xroot_window,
+                             0, 0, 1, 1,
+                             0,
+                             gdk_x11_display_get_window_depth (display_x11),
+                             InputOutput,
+                             gdk_x11_display_get_window_visual (display_x11),
+                             xattributes_mask, xattributes);
+}
+
 #define LAST_PROP 1
 
 typedef struct {
@@ -4880,6 +4871,27 @@ gdk_x11_popup_init (GdkX11Popup *popup)
 {
 }
 
+static void
+gdk_x11_popup_constructed (GObject *object)
+{
+  GdkX11Surface *x11_surface = GDK_X11_SURFACE (object);
+  GdkSurface *surface = GDK_SURFACE (x11_surface);
+  XSetWindowAttributes xattributes;
+  long xattributes_mask;
+
+  xattributes.save_under = True;
+  xattributes.override_redirect = True;
+  xattributes_mask = CWSaveUnder | CWOverrideRedirect;
+
+  gdk_x11_surface_create_window (x11_surface, &xattributes, xattributes_mask);
+
+  x11_surface->override_redirect = TRUE;
+
+  G_OBJECT_CLASS (gdk_x11_popup_parent_class)->constructed (object);
+
+  gdk_x11_surface_set_type_hint (surface, GDK_SURFACE_TYPE_HINT_MENU);
+}
+
 static void
 gdk_x11_popup_get_property (GObject    *object,
                             guint       prop_id,
@@ -4930,12 +4942,12 @@ gdk_x11_popup_set_property (GObject      *object,
     }
 }
 
-
 static void
 gdk_x11_popup_class_init (GdkX11PopupClass *class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (class);
 
+  object_class->constructed = gdk_x11_popup_constructed;
   object_class->get_property = gdk_x11_popup_get_property;
   object_class->set_property = gdk_x11_popup_set_property;
 
@@ -4995,6 +5007,24 @@ static void
 gdk_x11_toplevel_init (GdkX11Toplevel *toplevel)
 {
 }
+
+static void
+gdk_x11_toplevel_constructed (GObject *object)
+{
+  GdkX11Surface *x11_surface = GDK_X11_SURFACE (object);
+  GdkSurface *surface = GDK_SURFACE (x11_surface);
+  XSetWindowAttributes xattributes;
+  long xattributes_mask;
+
+  xattributes_mask = 0;
+
+  gdk_x11_surface_create_window (x11_surface, &xattributes, xattributes_mask);
+
+  G_OBJECT_CLASS (gdk_x11_toplevel_parent_class)->constructed (object);
+
+  gdk_x11_surface_set_type_hint (surface, GDK_SURFACE_TYPE_HINT_NORMAL);
+}
+
 static void
 gdk_x11_toplevel_set_property (GObject      *object,
                                guint         prop_id,
@@ -5124,6 +5154,7 @@ gdk_x11_toplevel_class_init (GdkX11ToplevelClass *class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (class);
 
+  object_class->constructed = gdk_x11_toplevel_constructed;
   object_class->get_property = gdk_x11_toplevel_get_property;
   object_class->set_property = gdk_x11_toplevel_set_property;
 
@@ -5369,6 +5400,24 @@ G_DEFINE_TYPE_WITH_CODE (GdkX11DragSurface, gdk_x11_drag_surface, GDK_TYPE_X11_S
                          G_IMPLEMENT_INTERFACE (GDK_TYPE_DRAG_SURFACE,
                                                 gdk_x11_drag_surface_iface_init))
 
+static void
+gdk_x11_drag_surface_constructed (GObject *object)
+{
+  GdkX11Surface *x11_surface = GDK_X11_SURFACE (object);
+  XSetWindowAttributes xattributes;
+  long xattributes_mask;
+
+  xattributes.save_under = True;
+  xattributes.override_redirect = True;
+  xattributes_mask = CWSaveUnder | CWOverrideRedirect;
+
+  gdk_x11_surface_create_window (x11_surface, &xattributes, xattributes_mask);
+
+  x11_surface->override_redirect = TRUE;
+
+  G_OBJECT_CLASS (gdk_x11_drag_surface_parent_class)->constructed (object);
+}
+
 static void
 gdk_x11_drag_surface_init (GdkX11DragSurface *surface)
 {
@@ -5377,6 +5426,9 @@ gdk_x11_drag_surface_init (GdkX11DragSurface *surface)
 static void
 gdk_x11_drag_surface_class_init (GdkX11DragSurfaceClass *class)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->constructed = gdk_x11_drag_surface_constructed;
 }
 
 static gboolean