[gtk/wip/matthiasc/popup5: 77/152] Get rid of GdkSurfaceImpl



commit c397fa724e85541bef023bebb482f7c3904b3ddd
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Apr 22 01:14:46 2019 +0000

    Get rid of GdkSurfaceImpl
    
    We don't need the complicated wrapper system anymore,
    since client-side windows are gone. This commit moves
    all the vfuncs to GtkSurfaceClass, and changes the
    backends to just derive their surface implementation
    from GdkSurface.

 gdk/broadway/gdkdevice-broadway.c  |   4 +-
 gdk/broadway/gdkdisplay-broadway.c |   9 +-
 gdk/broadway/gdkdnd-broadway.c     |   4 +-
 gdk/broadway/gdkeventsource.c      |   2 +-
 gdk/broadway/gdkprivate-broadway.h |  12 +-
 gdk/broadway/gdksurface-broadway.c | 291 +++++++++----------
 gdk/broadway/gdksurface-broadway.h |  25 +-
 gdk/gdkdisplay.c                   |  31 +-
 gdk/gdkdisplayprivate.h            |  22 +-
 gdk/gdkinternals.h                 |  75 +----
 gdk/gdksurface.c                   | 577 ++++++++++++++++++++++++-------------
 gdk/gdksurface.h                   |  15 -
 gdk/gdksurfaceimpl.c               | 312 --------------------
 gdk/gdksurfaceimpl.h               | 212 --------------
 gdk/gdksurfaceprivate.h            | 174 +++++++++--
 gdk/meson.build                    |   1 -
 gdk/wayland/gdkdevice-wayland.c    |   4 +-
 gdk/wayland/gdkdisplay-wayland.c   |   5 +-
 gdk/wayland/gdkglcontext-wayland.c |   9 +-
 gdk/wayland/gdkprivate-wayland.h   |  12 +-
 gdk/wayland/gdksurface-wayland.c   | 412 ++++++++++++--------------
 gdk/x11/gdkcairocontext-x11.c      |   1 +
 gdk/x11/gdkdevice-xi2.c            |   6 +-
 gdk/x11/gdkdevicemanager-xi2.c     |   4 +-
 gdk/x11/gdkdisplay-x11.c           |  16 +-
 gdk/x11/gdkdrag-x11.c              |  17 +-
 gdk/x11/gdkdrop-x11.c              |   4 +-
 gdk/x11/gdkglcontext-x11.c         |  10 +-
 gdk/x11/gdkprivate-x11.h           |  14 +-
 gdk/x11/gdksurface-x11.c           | 264 +++++++++--------
 gdk/x11/gdksurface-x11.h           |  36 +--
 31 files changed, 1109 insertions(+), 1471 deletions(-)
---
diff --git a/gdk/broadway/gdkdevice-broadway.c b/gdk/broadway/gdkdevice-broadway.c
index 6b3621d7d8..801b021c56 100644
--- a/gdk/broadway/gdkdevice-broadway.c
+++ b/gdk/broadway/gdkdevice-broadway.c
@@ -20,7 +20,7 @@
 
 #include "gdkdevice-broadway.h"
 
-#include "gdksurface.h"
+#include "gdksurfaceprivate.h"
 #include "gdkprivate-broadway.h"
 
 static gboolean gdk_broadway_device_get_history (GdkDevice      *device,
@@ -251,7 +251,7 @@ gdk_broadway_device_grab (GdkDevice    *device,
     {
       /* Device is a pointer */
       return _gdk_broadway_server_grab_pointer (broadway_display->server,
-                                                GDK_SURFACE_IMPL_BROADWAY (surface->impl)->id,
+                                                GDK_BROADWAY_SURFACE (surface)->id,
                                                 owner_events,
                                                 event_mask,
                                                 time_);
diff --git a/gdk/broadway/gdkdisplay-broadway.c b/gdk/broadway/gdkdisplay-broadway.c
index e3ba560f88..c9ffa25d27 100644
--- a/gdk/broadway/gdkdisplay-broadway.c
+++ b/gdk/broadway/gdkdisplay-broadway.c
@@ -95,10 +95,10 @@ _gdk_broadway_display_size_changed (GdkDisplay                      *display,
   toplevels =  broadway_display->toplevels;
   for (l = toplevels; l != NULL; l = l->next)
     {
-      GdkSurfaceImplBroadway *toplevel_impl = l->data;
+      GdkBroadwaySurface *toplevel = l->data;
 
-      if (toplevel_impl->maximized)
-        gdk_surface_move_resize (toplevel_impl->wrapper, 0, 0, msg->width, msg->height);
+      if (toplevel->maximized)
+        gdk_surface_move_resize (GDK_SURFACE (toplevel), 0, 0, msg->width, msg->height);
     }
 }
 
@@ -420,7 +420,6 @@ gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
   object_class->dispose = gdk_broadway_display_dispose;
   object_class->finalize = gdk_broadway_display_finalize;
 
-  display_class->surface_type = GDK_TYPE_BROADWAY_SURFACE;
   display_class->cairo_context_type = GDK_TYPE_BROADWAY_CAIRO_CONTEXT;
 
   display_class->get_name = gdk_broadway_display_get_name;
@@ -435,7 +434,7 @@ gdk_broadway_display_class_init (GdkBroadwayDisplayClass * class)
 
   display_class->get_next_serial = gdk_broadway_display_get_next_serial;
   display_class->notify_startup_complete = gdk_broadway_display_notify_startup_complete;
-  display_class->create_surface_impl = _gdk_broadway_display_create_surface_impl;
+  display_class->create_surface = _gdk_broadway_display_create_surface;
   display_class->get_keymap = _gdk_broadway_display_get_keymap;
   display_class->text_property_to_utf8_list = _gdk_broadway_display_text_property_to_utf8_list;
   display_class->utf8_to_string_target = _gdk_broadway_display_utf8_to_string_target;
diff --git a/gdk/broadway/gdkdnd-broadway.c b/gdk/broadway/gdkdnd-broadway.c
index 461998f339..67438adcfc 100644
--- a/gdk/broadway/gdkdnd-broadway.c
+++ b/gdk/broadway/gdkdnd-broadway.c
@@ -26,7 +26,7 @@
 
 #include "gdkdragprivate.h"
 
-#include "gdkinternals.h"
+#include "gdksurfaceprivate.h"
 #include "gdkproperty.h"
 #include "gdkprivate-broadway.h"
 #include "gdkinternals.h"
@@ -94,7 +94,7 @@ _gdk_broadway_surface_drag_begin (GdkSurface         *surface,
   GdkDrag *new_context;
 
   g_return_val_if_fail (surface != NULL, NULL);
-  g_return_val_if_fail (GDK_SURFACE_IS_BROADWAY (surface), NULL);
+  g_return_val_if_fail (GDK_IS_BROADWAY_SURFACE (surface), NULL);
 
   new_context = g_object_new (GDK_TYPE_BROADWAY_DRAG,
                               "device", device,
diff --git a/gdk/broadway/gdkeventsource.c b/gdk/broadway/gdkeventsource.c
index f0672bd8c4..506740fa16 100644
--- a/gdk/broadway/gdkeventsource.c
+++ b/gdk/broadway/gdkeventsource.c
@@ -20,7 +20,7 @@
 #include "gdkeventsource.h"
 #include "gdkseat.h"
 
-#include "gdkinternals.h"
+#include "gdksurfaceprivate.h"
 #include "gdkframeclockprivate.h"
 
 #include <stdlib.h>
diff --git a/gdk/broadway/gdkprivate-broadway.h b/gdk/broadway/gdkprivate-broadway.h
index 5987c2c454..784947c00f 100644
--- a/gdk/broadway/gdkprivate-broadway.h
+++ b/gdk/broadway/gdkprivate-broadway.h
@@ -101,9 +101,13 @@ void _gdk_broadway_display_get_default_cursor_size (GdkDisplay *display,
 void _gdk_broadway_display_get_maximal_cursor_size (GdkDisplay *display,
                                                     guint       *width,
                                                     guint       *height);
-void       _gdk_broadway_display_create_surface_impl    (GdkDisplay    *display,
-                                                         GdkSurface     *surface,
-                                                         GdkSurface     *real_parent);
+GdkSurface * _gdk_broadway_display_create_surface (GdkDisplay     *display,
+                                                   GdkSurfaceType  surface_type,
+                                                   GdkSurface     *parent,
+                                                   int             x,
+                                                   int             y,
+                                                   int             width,
+                                                   int             height);
 gint _gdk_broadway_display_text_property_to_utf8_list (GdkDisplay    *display,
                                                        GdkAtom        encoding,
                                                        gint           format,
@@ -125,6 +129,4 @@ void _gdk_broadway_surface_resize_surface        (GdkSurface *surface);
 void _gdk_broadway_cursor_update_theme (GdkCursor *cursor);
 void _gdk_broadway_cursor_display_finalize (GdkDisplay *display);
 
-#define GDK_SURFACE_IS_BROADWAY(win)   (GDK_IS_SURFACE_IMPL_BROADWAY (((GdkSurface *)win)->impl))
-
 #endif /* __GDK_PRIVATE_BROADWAY_H__ */
diff --git a/gdk/broadway/gdksurface-broadway.c b/gdk/broadway/gdksurface-broadway.c
index dcb6a9eb42..67e8de7e4b 100644
--- a/gdk/broadway/gdksurface-broadway.c
+++ b/gdk/broadway/gdksurface-broadway.c
@@ -29,50 +29,26 @@
 
 #include "gdkbroadwaydisplay.h"
 #include "gdkdisplay.h"
-#include "gdksurface.h"
-#include "gdksurfaceimpl.h"
+#include "gdksurfaceprivate.h"
 #include "gdkdisplay-broadway.h"
 #include "gdkprivate-broadway.h"
 #include "gdkinternals.h"
 #include "gdkdeviceprivate.h"
 #include "gdkeventsource.h"
-#include <gdk/gdktextureprivate.h>
-#include <gdk/gdkframeclockprivate.h>
+#include "gdktextureprivate.h"
+#include "gdkframeclockidleprivate.h"
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 
 /* Forward declarations */
-static void        gdk_surface_impl_broadway_finalize   (GObject            *object);
+static void        gdk_broadway_surface_finalize   (GObject            *object);
 
 #define SURFACE_IS_TOPLEVEL(surface)  TRUE
 
-struct _GdkBroadwaySurface {
-  GdkSurface parent;
-};
-
-struct _GdkBroadwaySurfaceClass {
-  GdkSurfaceClass parent_class;
-};
-
 G_DEFINE_TYPE (GdkBroadwaySurface, gdk_broadway_surface, GDK_TYPE_SURFACE)
 
-static void
-gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *broadway_surface_class)
-{
-}
-
-static void
-gdk_broadway_surface_init (GdkBroadwaySurface *broadway_surface)
-{
-}
-
-G_DEFINE_TYPE (GdkSurfaceImplBroadway,
-               gdk_surface_impl_broadway,
-               GDK_TYPE_SURFACE_IMPL)
-
-
 /* We need to flush in an idle rather than AFTER_PAINT, as the clock
    is frozen during e.g. surface resizes so the paint will not happen
    and the surface resize request is never flushed. */
@@ -83,26 +59,23 @@ queue_flush (GdkSurface *surface)
 }
 
 static void
-gdk_surface_impl_broadway_init (GdkSurfaceImplBroadway *impl)
+gdk_broadway_surface_init (GdkBroadwaySurface *impl)
 {
 }
 
 static void
-gdk_surface_impl_broadway_finalize (GObject *object)
+gdk_broadway_surface_finalize (GObject *object)
 {
-  GdkSurface *wrapper;
-  GdkSurfaceImplBroadway *impl;
+  GdkBroadwaySurface *impl;
   GdkBroadwayDisplay *broadway_display;
 
-  g_return_if_fail (GDK_IS_SURFACE_IMPL_BROADWAY (object));
-
-  impl = GDK_SURFACE_IMPL_BROADWAY (object);
+  g_return_if_fail (GDK_IS_BROADWAY_SURFACE (object));
 
-  wrapper = impl->wrapper;
+  impl = GDK_BROADWAY_SURFACE (object);
 
-  _gdk_broadway_surface_grab_check_destroy (wrapper);
+  _gdk_broadway_surface_grab_check_destroy (GDK_SURFACE (impl));
 
-  broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (impl->wrapper));
+  broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (GDK_SURFACE (impl)));
 
   g_hash_table_remove (broadway_display->id_ht, GINT_TO_POINTER(impl->id));
 
@@ -111,7 +84,7 @@ gdk_surface_impl_broadway_finalize (GObject *object)
 
   broadway_display->toplevels = g_list_remove (broadway_display->toplevels, impl);
 
-  G_OBJECT_CLASS (gdk_surface_impl_broadway_parent_class)->finalize (object);
+  G_OBJECT_CLASS (gdk_broadway_surface_parent_class)->finalize (object);
 }
 
 static gboolean
@@ -124,10 +97,10 @@ thaw_clock_cb (GdkFrameClock *clock)
 
 void
 _gdk_broadway_roundtrip_notify (GdkSurface  *surface,
-                                guint32 tag,
-                                gboolean local_reply)
+                                guint32      tag,
+                                gboolean     local_reply)
 {
-  GdkSurfaceImplBroadway *impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
+  GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
   GdkFrameClock *clock = gdk_surface_get_frame_clock (surface);
   GdkFrameTimings *timings;
 
@@ -160,10 +133,10 @@ _gdk_broadway_roundtrip_notify (GdkSurface  *surface,
 
 static void
 on_frame_clock_after_paint (GdkFrameClock *clock,
-                            GdkSurface     *surface)
+                            GdkSurface    *surface)
 {
   GdkDisplay *display = gdk_surface_get_display (surface);
-  GdkSurfaceImplBroadway *impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
+  GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
   GdkBroadwayDisplay *broadway_display;
 
   impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
@@ -178,7 +151,7 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
 
 static void
 on_frame_clock_before_paint (GdkFrameClock *clock,
-                             GdkSurface     *surface)
+                             GdkSurface    *surface)
 {
   GdkFrameTimings *timings = gdk_frame_clock_get_current_timings (clock);
   gint64 presentation_time;
@@ -203,29 +176,46 @@ on_frame_clock_before_paint (GdkFrameClock *clock,
 static void
 connect_frame_clock (GdkSurface *surface)
 {
-  if (SURFACE_IS_TOPLEVEL (surface))
-    {
-      GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
+  GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
 
-      g_signal_connect (frame_clock, "before-paint",
-                        G_CALLBACK (on_frame_clock_before_paint), surface);
-      g_signal_connect (frame_clock, "after-paint",
-                        G_CALLBACK (on_frame_clock_after_paint), surface);
-    }
+  g_signal_connect (frame_clock, "before-paint",
+                    G_CALLBACK (on_frame_clock_before_paint), surface);
+  g_signal_connect (frame_clock, "after-paint",
+                    G_CALLBACK (on_frame_clock_after_paint), surface);
 }
 
-void
-_gdk_broadway_display_create_surface_impl (GdkDisplay     *display,
-                                           GdkSurface     *surface,
-                                           GdkSurface     *real_parent)
+GdkSurface *
+_gdk_broadway_display_create_surface (GdkDisplay     *display,
+                                      GdkSurfaceType  surface_type,
+                                      GdkSurface     *parent,
+                                      int             x,
+                                      int             y,
+                                      int             width,
+                                      int             height)
 {
-  GdkSurfaceImplBroadway *impl;
   GdkBroadwayDisplay *broadway_display;
+  GdkFrameClock *frame_clock;
+  GdkSurface *surface;
+  GdkBroadwaySurface *impl;
+
+  frame_clock = _gdk_frame_clock_idle_new ();
+
+  surface = g_object_new (GDK_TYPE_BROADWAY_SURFACE,
+                          "display", display,
+                          "frame-clock", frame_clock,
+                          NULL);
+
+  g_object_unref (frame_clock);
+
+  surface->surface_type = surface_type;
+  surface->x = x;
+  surface->y = y;
+  surface->width = width;
+  surface->height = height;
 
   broadway_display = GDK_BROADWAY_DISPLAY (display);
 
-  impl = g_object_new (GDK_TYPE_SURFACE_IMPL_BROADWAY, NULL);
-  surface->impl = (GdkSurfaceImpl *)impl;
+  impl = GDK_BROADWAY_SURFACE (surface);
   impl->id = _gdk_broadway_server_new_surface (broadway_display->server,
                                                surface->x,
                                                surface->y,
@@ -233,7 +223,6 @@ _gdk_broadway_display_create_surface_impl (GdkDisplay     *display,
                                                surface->height,
                                                surface->surface_type == GDK_SURFACE_TEMP);
   g_hash_table_insert (broadway_display->id_ht, GINT_TO_POINTER(impl->id), surface);
-  impl->wrapper = surface;
 
   g_assert (surface->surface_type == GDK_SURFACE_TOPLEVEL ||
             surface->surface_type == GDK_SURFACE_TEMP);
@@ -241,15 +230,15 @@ _gdk_broadway_display_create_surface_impl (GdkDisplay     *display,
   broadway_display->toplevels = g_list_prepend (broadway_display->toplevels, impl);
 
   connect_frame_clock (surface);
+
+  return surface;
 }
 
 static cairo_surface_t *
-gdk_surface_broadway_ref_cairo_surface (GdkSurface *surface)
+gdk_broadway_surface_ref_cairo_surface (GdkSurface *surface)
 {
-  GdkSurfaceImplBroadway *impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
-
-  if (GDK_IS_SURFACE_IMPL_BROADWAY (surface) &&
-      GDK_SURFACE_DESTROYED (impl->wrapper))
+  if (GDK_IS_BROADWAY_SURFACE (surface) &&
+      GDK_SURFACE_DESTROYED (surface))
     return NULL;
 
   return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1);
@@ -257,14 +246,14 @@ gdk_surface_broadway_ref_cairo_surface (GdkSurface *surface)
 
 static void
 _gdk_broadway_surface_destroy (GdkSurface *surface,
-                               gboolean   foreign_destroy)
+                               gboolean    foreign_destroy)
 {
-  GdkSurfaceImplBroadway *impl;
+  GdkBroadwaySurface *impl;
   GdkBroadwayDisplay *broadway_display;
 
   g_return_if_fail (GDK_IS_SURFACE (surface));
 
-  impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
+  impl = GDK_BROADWAY_SURFACE (surface);
 
   if (impl->node_data)
     g_array_unref (impl->node_data);
@@ -282,15 +271,15 @@ _gdk_broadway_surface_destroy (GdkSurface *surface,
 
 void
 gdk_broadway_surface_set_nodes (GdkSurface *surface,
-                                GArray *nodes,
-                                GPtrArray *node_textures)
+                                GArray     *nodes,
+                                GPtrArray  *node_textures)
 {
-  GdkSurfaceImplBroadway *impl;
+  GdkBroadwaySurface *impl;
   GdkBroadwayDisplay *broadway_display;
 
   g_return_if_fail (GDK_IS_SURFACE (surface));
 
-  impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
+  impl = GDK_BROADWAY_SURFACE (surface);
 
   broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
 
@@ -321,13 +310,13 @@ gdk_broadway_surface_destroy_notify (GdkSurface *surface)
 }
 
 static void
-gdk_surface_broadway_show (GdkSurface *surface,
-                           gboolean already_mapped)
+gdk_broadway_surface_show (GdkSurface *surface,
+                           gboolean    already_mapped)
 {
-  GdkSurfaceImplBroadway *impl;
+  GdkBroadwaySurface *impl;
   GdkBroadwayDisplay *broadway_display;
 
-  impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
+  impl = GDK_BROADWAY_SURFACE (surface);
   impl->visible = TRUE;
 
   /* FIXME: update state ? */
@@ -339,12 +328,12 @@ gdk_surface_broadway_show (GdkSurface *surface,
 }
 
 static void
-gdk_surface_broadway_hide (GdkSurface *surface)
+gdk_broadway_surface_hide (GdkSurface *surface)
 {
-  GdkSurfaceImplBroadway *impl;
+  GdkBroadwaySurface *impl;
   GdkBroadwayDisplay *broadway_display;
 
-  impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
+  impl = GDK_BROADWAY_SURFACE (surface);
   impl->visible = FALSE;
 
   /* FIXME: update state ? */
@@ -361,20 +350,20 @@ gdk_surface_broadway_hide (GdkSurface *surface)
 }
 
 static void
-gdk_surface_broadway_withdraw (GdkSurface *surface)
+gdk_broadway_surface_withdraw (GdkSurface *surface)
 {
-  gdk_surface_broadway_hide (surface);
+  gdk_broadway_surface_hide (surface);
 }
 
 static void
-gdk_surface_broadway_move_resize (GdkSurface *surface,
+gdk_broadway_surface_move_resize (GdkSurface *surface,
                                   gboolean   with_move,
                                   gint       x,
                                   gint       y,
                                   gint       width,
                                   gint       height)
 {
-  GdkSurfaceImplBroadway *impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
+  GdkBroadwaySurface *impl = GDK_BROADWAY_SURFACE (surface);
   GdkBroadwayDisplay *broadway_display;
   gboolean size_changed;
 
@@ -418,19 +407,19 @@ gdk_surface_broadway_move_resize (GdkSurface *surface,
 }
 
 static void
-gdk_surface_broadway_raise (GdkSurface *surface)
+gdk_broadway_surface_raise (GdkSurface *surface)
 {
 }
 
 static void
-gdk_surface_broadway_restack_toplevel (GdkSurface *surface,
+gdk_broadway_surface_restack_toplevel (GdkSurface *surface,
                                        GdkSurface *sibling,
                                        gboolean   above)
 {
 }
 
 static void
-gdk_surface_broadway_lower (GdkSurface *surface)
+gdk_broadway_surface_lower (GdkSurface *surface)
 {
 }
 
@@ -439,7 +428,7 @@ static void
 gdk_broadway_surface_focus (GdkSurface *surface,
                             guint32    timestamp)
 {
-  GdkSurfaceImplBroadway *impl;
+  GdkBroadwaySurface *impl;
   GdkBroadwayDisplay *broadway_display;
 
   g_return_if_fail (GDK_IS_SURFACE (surface));
@@ -448,7 +437,7 @@ gdk_broadway_surface_focus (GdkSurface *surface,
       !surface->accept_focus)
     return;
 
-  impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
+  impl = GDK_BROADWAY_SURFACE (surface);
   broadway_display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
   _gdk_broadway_server_surface_focus (broadway_display->server,
                                       impl->id);
@@ -473,26 +462,26 @@ gdk_broadway_surface_set_modal_hint (GdkSurface *surface,
 }
 
 static void
-gdk_broadway_surface_set_geometry_hints (GdkSurface         *surface,
+gdk_broadway_surface_set_geometry_hints (GdkSurface        *surface,
                                          const GdkGeometry *geometry,
-                                         GdkSurfaceHints     geom_mask)
+                                         GdkSurfaceHints    geom_mask)
 {
-  GdkSurfaceImplBroadway *impl;
+  GdkBroadwaySurface *impl;
 
-  impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
+  impl = GDK_BROADWAY_SURFACE (surface);
 
   impl->geometry_hints = *geometry;
   impl->geometry_hints_mask = geom_mask;
 }
 
 static void
-gdk_broadway_surface_set_title (GdkSurface   *surface,
+gdk_broadway_surface_set_title (GdkSurface  *surface,
                                 const gchar *title)
 {
 }
 
 static void
-gdk_broadway_surface_set_startup_id (GdkSurface   *surface,
+gdk_broadway_surface_set_startup_id (GdkSurface  *surface,
                                      const gchar *startup_id)
 {
 }
@@ -502,66 +491,58 @@ gdk_broadway_surface_set_transient_for (GdkSurface *surface,
                                         GdkSurface *parent)
 {
   GdkBroadwayDisplay *display;
-  GdkSurfaceImplBroadway *impl;
+  GdkBroadwaySurface *impl;
   int parent_id;
 
-  impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
+  impl = GDK_BROADWAY_SURFACE (surface);
 
   parent_id = 0;
   if (parent)
-    parent_id = GDK_SURFACE_IMPL_BROADWAY (parent->impl)->id;
+    parent_id = GDK_BROADWAY_SURFACE (parent)->id;
 
   impl->transient_for = parent_id;
 
-  display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (impl->wrapper));
+  display = GDK_BROADWAY_DISPLAY (gdk_surface_get_display (surface));
   _gdk_broadway_server_surface_set_transient_for (display->server, impl->id, impl->transient_for);
 }
 
 static void
-gdk_surface_broadway_get_geometry (GdkSurface *surface,
-                                   gint      *x,
-                                   gint      *y,
-                                   gint      *width,
-                                   gint      *height)
+gdk_broadway_surface_get_geometry (GdkSurface *surface,
+                                   gint       *x,
+                                   gint       *y,
+                                   gint       *width,
+                                   gint       *height)
 {
-  GdkSurfaceImplBroadway *impl;
-
   g_return_if_fail (GDK_IS_SURFACE (surface));
 
-  impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
-
   /* TODO: These should really roundtrip to the client to get the current data */
 
   if (x)
-    *x = impl->wrapper->x;
+    *x = surface->x;
   if (y)
-    *y = impl->wrapper->y;
+    *y = surface->y;
   if (width)
-    *width = impl->wrapper->width;
+    *width = surface->width;
   if (height)
-    *height = impl->wrapper->height;
+    *height = surface->height;
 
 }
 
 static void
-gdk_surface_broadway_get_root_coords (GdkSurface *surface,
-                                      gint       x,
-                                      gint       y,
-                                      gint      *root_x,
-                                      gint      *root_y)
+gdk_broadway_surface_get_root_coords (GdkSurface *surface,
+                                      gint        x,
+                                      gint        y,
+                                      gint       *root_x,
+                                      gint       *root_y)
 {
-  GdkSurfaceImplBroadway *impl;
-
-  impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
-
   if (root_x)
-    *root_x = x + impl->wrapper->x;
+    *root_x = x + surface->x;
   if (root_y)
-    *root_y = y + impl->wrapper->y;
+    *root_y = y + surface->y;
 }
 
 static void
-gdk_broadway_surface_get_frame_extents (GdkSurface    *surface,
+gdk_broadway_surface_get_frame_extents (GdkSurface   *surface,
                                         GdkRectangle *rect)
 {
   g_return_if_fail (rect != NULL);
@@ -575,7 +556,7 @@ gdk_broadway_surface_get_frame_extents (GdkSurface    *surface,
 }
 
 static gboolean
-gdk_surface_broadway_get_device_state (GdkSurface       *surface,
+gdk_broadway_surface_get_device_state (GdkSurface      *surface,
                                        GdkDevice       *device,
                                        gdouble         *x,
                                        gdouble         *y,
@@ -596,7 +577,7 @@ gdk_surface_broadway_get_device_state (GdkSurface       *surface,
 }
 
 static void
-gdk_surface_broadway_input_shape_combine_region (GdkSurface       *surface,
+gdk_broadway_surface_input_shape_combine_region (GdkSurface       *surface,
                                                  const cairo_region_t *shape_region,
                                                  gint             offset_x,
                                                  gint             offset_y)
@@ -683,7 +664,7 @@ gdk_broadway_surface_unstick (GdkSurface *surface)
 static void
 gdk_broadway_surface_maximize (GdkSurface *surface)
 {
-  GdkSurfaceImplBroadway *impl;
+  GdkBroadwaySurface *impl;
   GdkDisplay *display;
   GdkMonitor *monitor;
   GdkRectangle geom;
@@ -692,7 +673,7 @@ gdk_broadway_surface_maximize (GdkSurface *surface)
       !SURFACE_IS_TOPLEVEL (surface))
     return;
 
-  impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
+  impl = GDK_BROADWAY_SURFACE (surface);
 
   if (impl->maximized)
     return;
@@ -718,13 +699,13 @@ gdk_broadway_surface_maximize (GdkSurface *surface)
 static void
 gdk_broadway_surface_unmaximize (GdkSurface *surface)
 {
-  GdkSurfaceImplBroadway *impl;
+  GdkBroadwaySurface *impl;
 
   if (GDK_SURFACE_DESTROYED (surface) ||
       !SURFACE_IS_TOPLEVEL (surface))
     return;
 
-  impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
+  impl = GDK_BROADWAY_SURFACE (surface);
 
   if (!impl->maximized)
     return;
@@ -1188,9 +1169,9 @@ gdk_broadway_surface_begin_resize_drag (GdkSurface     *surface,
                                         guint32        timestamp)
 {
   MoveResizeData *mv_resize;
-  GdkSurfaceImplBroadway *impl;
+  GdkBroadwaySurface *impl;
 
-  impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
+  impl = GDK_BROADWAY_SURFACE (surface);
 
   if (GDK_SURFACE_DESTROYED (surface) ||
       !SURFACE_IS_TOPLEVEL (surface))
@@ -1207,8 +1188,8 @@ gdk_broadway_surface_begin_resize_drag (GdkSurface     *surface,
   mv_resize->is_resize = TRUE;
   mv_resize->moveresize_button = button;
   mv_resize->resize_edge = edge;
-  mv_resize->moveresize_x = x  + impl->wrapper->x;
-  mv_resize->moveresize_y = y + impl->wrapper->y;
+  mv_resize->moveresize_x = x  + surface->x;
+  mv_resize->moveresize_y = y + surface->y;
   mv_resize->moveresize_surface = g_object_ref (surface);
 
   mv_resize->moveresize_orig_width = gdk_surface_get_width (surface);
@@ -1231,9 +1212,9 @@ gdk_broadway_surface_begin_move_drag (GdkSurface *surface,
                                       guint32    timestamp)
 {
   MoveResizeData *mv_resize;
-  GdkSurfaceImplBroadway *impl;
+  GdkBroadwaySurface *impl;
 
-  impl = GDK_SURFACE_IMPL_BROADWAY (surface->impl);
+  impl = GDK_BROADWAY_SURFACE (surface);
 
   if (GDK_SURFACE_DESTROYED (surface) ||
       !SURFACE_IS_TOPLEVEL (surface))
@@ -1249,8 +1230,8 @@ gdk_broadway_surface_begin_move_drag (GdkSurface *surface,
 
   mv_resize->is_resize = FALSE;
   mv_resize->moveresize_button = button;
-  mv_resize->moveresize_x = x + impl->wrapper->x;
-  mv_resize->moveresize_y = y + impl->wrapper->y;
+  mv_resize->moveresize_x = x + surface->x;
+  mv_resize->moveresize_y = y + surface->y;
   mv_resize->moveresize_surface = g_object_ref (surface);
 
   mv_resize->moveresize_orig_width = gdk_surface_get_width (surface);
@@ -1296,25 +1277,25 @@ gdk_broadway_get_last_seen_time (GdkSurface  *surface)
 }
 
 static void
-gdk_surface_impl_broadway_class_init (GdkSurfaceImplBroadwayClass *klass)
+gdk_broadway_surface_class_init (GdkBroadwaySurfaceClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  GdkSurfaceImplClass *impl_class = GDK_SURFACE_IMPL_CLASS (klass);
-
-  object_class->finalize = gdk_surface_impl_broadway_finalize;
-
-  impl_class->ref_cairo_surface = gdk_surface_broadway_ref_cairo_surface;
-  impl_class->show = gdk_surface_broadway_show;
-  impl_class->hide = gdk_surface_broadway_hide;
-  impl_class->withdraw = gdk_surface_broadway_withdraw;
-  impl_class->raise = gdk_surface_broadway_raise;
-  impl_class->lower = gdk_surface_broadway_lower;
-  impl_class->restack_toplevel = gdk_surface_broadway_restack_toplevel;
-  impl_class->move_resize = gdk_surface_broadway_move_resize;
-  impl_class->get_geometry = gdk_surface_broadway_get_geometry;
-  impl_class->get_root_coords = gdk_surface_broadway_get_root_coords;
-  impl_class->get_device_state = gdk_surface_broadway_get_device_state;
-  impl_class->input_shape_combine_region = gdk_surface_broadway_input_shape_combine_region;
+  GdkSurfaceClass *impl_class = GDK_SURFACE_CLASS (klass);
+
+  object_class->finalize = gdk_broadway_surface_finalize;
+
+  impl_class->ref_cairo_surface = gdk_broadway_surface_ref_cairo_surface;
+  impl_class->show = gdk_broadway_surface_show;
+  impl_class->hide = gdk_broadway_surface_hide;
+  impl_class->withdraw = gdk_broadway_surface_withdraw;
+  impl_class->raise = gdk_broadway_surface_raise;
+  impl_class->lower = gdk_broadway_surface_lower;
+  impl_class->restack_toplevel = gdk_broadway_surface_restack_toplevel;
+  impl_class->move_resize = gdk_broadway_surface_move_resize;
+  impl_class->get_geometry = gdk_broadway_surface_get_geometry;
+  impl_class->get_root_coords = gdk_broadway_surface_get_root_coords;
+  impl_class->get_device_state = gdk_broadway_surface_get_device_state;
+  impl_class->input_shape_combine_region = gdk_broadway_surface_input_shape_combine_region;
   impl_class->destroy = _gdk_broadway_surface_destroy;
   impl_class->beep = gdk_broadway_surface_beep;
 
diff --git a/gdk/broadway/gdksurface-broadway.h b/gdk/broadway/gdksurface-broadway.h
index 9be2da92df..a2c0b96cf7 100644
--- a/gdk/broadway/gdksurface-broadway.h
+++ b/gdk/broadway/gdksurface-broadway.h
@@ -25,28 +25,17 @@
 #ifndef __GDK_SURFACE_BROADWAY_H__
 #define __GDK_SURFACE_BROADWAY_H__
 
-#include <gdk/gdksurfaceimpl.h>
+#include <gdk/gdksurfaceprivate.h>
+#include "gdkbroadwaysurface.h"
 
 G_BEGIN_DECLS
 
-typedef struct _GdkSurfaceImplBroadway GdkSurfaceImplBroadway;
-typedef struct _GdkSurfaceImplBroadwayClass GdkSurfaceImplBroadwayClass;
-
 /* Surface implementation for Broadway
  */
 
-#define GDK_TYPE_SURFACE_IMPL_BROADWAY              (gdk_surface_impl_broadway_get_type ())
-#define GDK_SURFACE_IMPL_BROADWAY(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), 
GDK_TYPE_SURFACE_IMPL_BROADWAY, GdkSurfaceImplBroadway))
-#define GDK_SURFACE_IMPL_BROADWAY_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), 
GDK_TYPE_SURFACE_IMPL_BROADWAY, GdkSurfaceImplBroadwayClass))
-#define GDK_IS_SURFACE_IMPL_BROADWAY(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), 
GDK_TYPE_SURFACE_IMPL_BROADWAY))
-#define GDK_IS_SURFACE_IMPL_BROADWAY_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), 
GDK_TYPE_SURFACE_IMPL_BROADWAY))
-#define GDK_SURFACE_IMPL_BROADWAY_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), 
GDK_TYPE_SURFACE_IMPL_BROADWAY, GdkSurfaceImplBroadwayClass))
-
-struct _GdkSurfaceImplBroadway
+struct _GdkBroadwaySurface
 {
-  GdkSurfaceImpl parent_instance;
-
-  GdkSurface *wrapper;
+  GdkSurface parent_instance;
 
   GdkCursor *cursor;
 
@@ -73,12 +62,12 @@ struct _GdkSurfaceImplBroadway
   GPtrArray *node_data_textures;
 };
 
-struct _GdkSurfaceImplBroadwayClass
+struct _GdkBroadwaySurfaceClass
 {
-  GdkSurfaceImplClass parent_class;
+  GdkSurfaceClass parent_class;
 };
 
-GType gdk_surface_impl_broadway_get_type (void);
+GType gdk_surface_broadway_get_type (void);
 
 G_END_DECLS
 
diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c
index 1290b78d55..c657d66133 100644
--- a/gdk/gdkdisplay.c
+++ b/gdk/gdkdisplay.c
@@ -31,9 +31,9 @@
 #include "gdkdeviceprivate.h"
 #include "gdkdisplaymanagerprivate.h"
 #include "gdkevents.h"
-#include "gdksurfaceimpl.h"
 #include "gdkinternals.h"
 #include "gdkmonitorprivate.h"
+#include "gdkframeclockidleprivate.h"
 
 #include <math.h>
 #include <glib.h>
@@ -171,8 +171,6 @@ gdk_display_class_init (GdkDisplayClass *class)
   object_class->get_property = gdk_display_get_property;
 
   class->get_app_launch_context = gdk_display_real_get_app_launch_context;
-  class->surface_type = GDK_TYPE_SURFACE;
-
   class->opened = gdk_display_real_opened;
   class->make_default = gdk_display_real_make_default;
   class->event_data_copy = gdk_display_real_event_data_copy;
@@ -1324,22 +1322,19 @@ _gdk_display_event_data_free (GdkDisplay *display,
   GDK_DISPLAY_GET_CLASS (display)->event_data_free (display, event);
 }
 
-void
-gdk_display_create_surface_impl (GdkDisplay       *display,
-                                 GdkSurface       *surface,
-                                 GdkSurface       *real_parent)
-{
-  GDK_DISPLAY_GET_CLASS (display)->create_surface_impl (display,
-                                                        surface,
-                                                        real_parent);
-}
-
 GdkSurface *
-_gdk_display_create_surface (GdkDisplay *display)
-{
-  return g_object_new (GDK_DISPLAY_GET_CLASS (display)->surface_type,
-                       "display", display,
-                       NULL);
+gdk_display_create_surface (GdkDisplay     *display,
+                            GdkSurfaceType  surface_type,
+                            GdkSurface     *parent,
+                            int             x,
+                            int             y,
+                            int             width,
+                            int             height)
+{
+  return GDK_DISPLAY_GET_CLASS (display)->create_surface (display,
+                                                          surface_type,
+                                                          parent,
+                                                          x, y, width, height);
 }
 
 /**
diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h
index 496d023614..8c8b76a8bc 100644
--- a/gdk/gdkdisplayprivate.h
+++ b/gdk/gdkdisplayprivate.h
@@ -112,7 +112,6 @@ struct _GdkDisplayClass
 {
   GObjectClass parent_class;
 
-  GType surface_type;         /* type for native surfaces for this display, set in class_init */
   GType cairo_context_type;   /* type for GdkCairoContext, must be set */
   GType vk_context_type;      /* type for GdkVulkanContext, must be set if vk_extension_name != NULL */
   const char *vk_extension_name; /* Name of required windowing vulkan extension or %NULL (default) if Vulkan 
isn't supported */
@@ -141,9 +140,13 @@ struct _GdkDisplayClass
                                                  GdkEvent       *new_event);
   void                       (*event_data_free) (GdkDisplay     *display,
                                                  GdkEvent       *event);
-  void                       (*create_surface_impl) (GdkDisplay    *display,
-                                                     GdkSurface     *surface,
-                                                     GdkSurface     *real_parent);
+  GdkSurface *               (*create_surface) (GdkDisplay     *display,
+                                                GdkSurfaceType  surface_type,
+                                                GdkSurface     *parent,
+                                                int             x,
+                                                int             y,
+                                                int             width,
+                                                int             height);
 
   GdkKeymap *                (*get_keymap)         (GdkDisplay    *display);
 
@@ -228,10 +231,13 @@ void                _gdk_display_event_data_copy      (GdkDisplay       *display
                                                        GdkEvent         *new_event);
 void                _gdk_display_event_data_free      (GdkDisplay       *display,
                                                        GdkEvent         *event);
-void                gdk_display_create_surface_impl   (GdkDisplay       *display,
-                                                       GdkSurface        *surface,
-                                                       GdkSurface        *real_parent);
-GdkSurface *         _gdk_display_create_surface      (GdkDisplay       *display);
+GdkSurface *        gdk_display_create_surface        (GdkDisplay       *display,
+                                                       GdkSurfaceType    surface_type,
+                                                       GdkSurface       *parent,
+                                                       int               x,
+                                                       int               y,
+                                                       int               width,
+                                                       int               height);
 
 gboolean            gdk_display_make_gl_context_current  (GdkDisplay        *display,
                                                           GdkGLContext      *context);
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 17c914ce7a..1079bc7b32 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -28,9 +28,9 @@
 #define __GDK_INTERNALS_H__
 
 #include <gdk-pixbuf/gdk-pixbuf.h>
-#include "gdksurfaceimpl.h"
 #include "gdkdisplay.h"
 #include "gdkeventsprivate.h"
+#include "gdksurfaceprivate.h"
 #include "gdkenumtypes.h"
 #include "gdkdragprivate.h"
 
@@ -116,79 +116,6 @@ typedef enum
 
 typedef struct _GdkSurfacePaint GdkSurfacePaint;
 
-struct _GdkSurface
-{
-  GObject parent_instance;
-
-  GdkDisplay *display;
-
-  GdkSurfaceImpl *impl; /* window-system-specific delegate object */
-
-  GdkSurface *transient_for;
-
-  gpointer widget;
-
-  gint x;
-  gint y;
-
-  guint8 surface_type;
-
-  guint8 resize_count;
-
-  GdkGLContext *gl_paint_context;
-
-  cairo_region_t *update_area;
-  guint update_freeze_count;
-  /* This is the update_area that was in effect when the current expose
-     started. It may be smaller than the expose area if we'e painting
-     more than we have to, but it represents the "true" damage. */
-  cairo_region_t *active_update_area;
-
-  GdkSurfaceState old_state;
-  GdkSurfaceState state;
-
-  guint8 alpha;
-  guint8 fullscreen_mode;
-
-  guint modal_hint : 1;
-
-  guint destroyed : 2;
-
-  guint accept_focus : 1;
-  guint focus_on_map : 1;
-  guint support_multidevice : 1;
-  guint viewable : 1; /* mapped and all parents mapped */
-  guint in_update : 1;
-  guint frame_clock_events_paused : 1;
-
-  /* The GdkSurface that has the impl, ref:ed if another surface.
-   * This ref is required to keep the wrapper of the impl surface alive
-   * for as long as any GdkSurface references the impl. */
-  GdkSurface *impl_surface;
-
-  guint update_and_descendants_freeze_count;
-
-  gint width, height;
-  gint shadow_top;
-  gint shadow_left;
-  gint shadow_right;
-  gint shadow_bottom;
-
-  GdkCursor *cursor;
-  GHashTable *device_cursor;
-
-  cairo_region_t *input_shape;
-
-  GList *devices_inside;
-
-  GdkFrameClock *frame_clock; /* NULL to use from parent or default */
-
-  GSList *draw_contexts;
-  GdkDrawContext *paint_context;
-
-  cairo_region_t *opaque_region;
-};
-
 #define GDK_SURFACE_TYPE(d) ((((GdkSurface *)(d)))->surface_type)
 #define GDK_SURFACE_DESTROYED(d) (((GdkSurface *)(d))->destroyed)
 
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index 182df6864f..7f4f1c0a96 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -36,7 +36,6 @@
 #include "gdkdeviceprivate.h"
 #include "gdkframeclockidleprivate.h"
 #include "gdkmarshalers.h"
-#include "gdksurfaceimpl.h"
 #include "gdkglcontextprivate.h"
 #include "gdk-private.h"
 
@@ -152,6 +151,272 @@ print_region (cairo_region_t *region)
 }
 #endif
 
+static gboolean
+gdk_surface_real_beep (GdkSurface *surface)
+{
+  return FALSE;
+}
+
+static GdkDisplay *
+get_display_for_surface (GdkSurface *primary,
+                         GdkSurface *secondary)
+{
+  GdkDisplay *display = gdk_surface_get_display (primary);
+
+  if (display)
+    return display;
+
+  display = gdk_surface_get_display (secondary);
+
+  if (display)
+    return display;
+
+  g_warning ("no display for surface, using default");
+  return gdk_display_get_default ();
+}
+
+static GdkMonitor *
+get_monitor_for_rect (GdkDisplay         *display,
+                      const GdkRectangle *rect)
+{
+  gint biggest_area = G_MININT;
+  GdkMonitor *best_monitor = NULL;
+  GdkMonitor *monitor;
+  GdkRectangle workarea;
+  GdkRectangle intersection;
+  gint x;
+  gint y;
+  gint i;
+
+  for (i = 0; i < gdk_display_get_n_monitors (display); i++)
+    {
+      monitor = gdk_display_get_monitor (display, i);
+      gdk_monitor_get_workarea (monitor, &workarea);
+
+      if (gdk_rectangle_intersect (&workarea, rect, &intersection))
+        {
+          if (intersection.width * intersection.height > biggest_area)
+            {
+              biggest_area = intersection.width * intersection.height;
+              best_monitor = monitor;
+            }
+        }
+    }
+
+  if (best_monitor)
+    return best_monitor;
+
+  x = rect->x + rect->width / 2;
+  y = rect->y + rect->height / 2;
+
+  return gdk_display_get_monitor_at_point (display, x, y);
+}
+
+static gint
+get_anchor_x_sign (GdkGravity anchor)
+{
+  switch (anchor)
+    {
+    case GDK_GRAVITY_STATIC:
+    case GDK_GRAVITY_NORTH_WEST:
+    case GDK_GRAVITY_WEST:
+    case GDK_GRAVITY_SOUTH_WEST:
+      return -1;
+
+    default:
+    case GDK_GRAVITY_NORTH:
+    case GDK_GRAVITY_CENTER:
+    case GDK_GRAVITY_SOUTH:
+      return 0;
+
+    case GDK_GRAVITY_NORTH_EAST:
+    case GDK_GRAVITY_EAST:
+    case GDK_GRAVITY_SOUTH_EAST:
+      return 1;
+    }
+}
+
+static gint
+get_anchor_y_sign (GdkGravity anchor)
+{
+  switch (anchor)
+    {
+    case GDK_GRAVITY_STATIC:
+    case GDK_GRAVITY_NORTH_WEST:
+    case GDK_GRAVITY_NORTH:
+    case GDK_GRAVITY_NORTH_EAST:
+      return -1;
+
+    default:
+    case GDK_GRAVITY_WEST:
+    case GDK_GRAVITY_CENTER:
+    case GDK_GRAVITY_EAST:
+      return 0;
+
+    case GDK_GRAVITY_SOUTH_WEST:
+    case GDK_GRAVITY_SOUTH:
+    case GDK_GRAVITY_SOUTH_EAST:
+      return 1;
+    }
+}
+
+static gint
+maybe_flip_position (gint      bounds_pos,
+                     gint      bounds_size,
+                     gint      rect_pos,
+                     gint      rect_size,
+                     gint      surface_size,
+                     gint      rect_sign,
+                     gint      surface_sign,
+                     gint      offset,
+                     gboolean  flip,
+                     gboolean *flipped)
+{
+  gint primary;
+  gint secondary;
+
+  *flipped = FALSE;
+  primary = rect_pos + (1 + rect_sign) * rect_size / 2 + offset - (1 + surface_sign) * surface_size / 2;
+
+  if (!flip || (primary >= bounds_pos && primary + surface_size <= bounds_pos + bounds_size))
+    return primary;
+
+  *flipped = TRUE;
+  secondary = rect_pos + (1 - rect_sign) * rect_size / 2 - offset - (1 - surface_sign) * surface_size / 2;
+
+  if (secondary >= bounds_pos && secondary + surface_size <= bounds_pos + bounds_size)
+    return secondary;
+
+  *flipped = FALSE;
+  return primary;
+}
+
+static void
+gdk_surface_real_move_to_rect (GdkSurface         *surface,
+                               const GdkRectangle *rect,
+                               GdkGravity          rect_anchor,
+                               GdkGravity          surface_anchor,
+                               GdkAnchorHints      anchor_hints,
+                               gint                rect_anchor_dx,
+                               gint                rect_anchor_dy)
+{
+  GdkSurface *transient_for_toplevel;
+  GdkDisplay *display;
+  GdkMonitor *monitor;
+  GdkRectangle bounds;
+  GdkRectangle root_rect = *rect;
+  GdkRectangle flipped_rect;
+  GdkRectangle final_rect;
+  gboolean flipped_x;
+  gboolean flipped_y;
+
+  /*
+   * First translate the anchor rect to toplevel coordinates.
+   * This is needed because not all backends will be able to get
+   * root coordinates for non-toplevel surfaces.
+   */
+  transient_for_toplevel = surface->transient_for;
+
+  gdk_surface_get_root_coords (transient_for_toplevel,
+                              root_rect.x,
+                              root_rect.y,
+                              &root_rect.x,
+                              &root_rect.y);
+
+  display = get_display_for_surface (surface, surface->transient_for);
+  monitor = get_monitor_for_rect (display, &root_rect);
+  gdk_monitor_get_workarea (monitor, &bounds);
+
+  flipped_rect.width = surface->width - surface->shadow_left - surface->shadow_right;
+  flipped_rect.height = surface->height - surface->shadow_top - surface->shadow_bottom;
+  flipped_rect.x = maybe_flip_position (bounds.x,
+                                        bounds.width,
+                                        root_rect.x,
+                                        root_rect.width,
+                                        flipped_rect.width,
+                                        get_anchor_x_sign (rect_anchor),
+                                        get_anchor_x_sign (surface_anchor),
+                                        rect_anchor_dx,
+                                        anchor_hints & GDK_ANCHOR_FLIP_X,
+                                        &flipped_x);
+  flipped_rect.y = maybe_flip_position (bounds.y,
+                                        bounds.height,
+                                        root_rect.y,
+                                        root_rect.height,
+                                        flipped_rect.height,
+                                        get_anchor_y_sign (rect_anchor),
+                                        get_anchor_y_sign (surface_anchor),
+                                        rect_anchor_dy,
+                                        anchor_hints & GDK_ANCHOR_FLIP_Y,
+                                        &flipped_y);
+
+  final_rect = flipped_rect;
+
+  if (anchor_hints & GDK_ANCHOR_SLIDE_X)
+    {
+      if (final_rect.x + final_rect.width > bounds.x + bounds.width)
+        final_rect.x = bounds.x + bounds.width - final_rect.width;
+
+      if (final_rect.x < bounds.x)
+        final_rect.x = bounds.x;
+    }
+
+  if (anchor_hints & GDK_ANCHOR_SLIDE_Y)
+    {
+      if (final_rect.y + final_rect.height > bounds.y + bounds.height)
+        final_rect.y = bounds.y + bounds.height - final_rect.height;
+
+      if (final_rect.y < bounds.y)
+        final_rect.y = bounds.y;
+    }
+
+  if (anchor_hints & GDK_ANCHOR_RESIZE_X)
+    {
+      if (final_rect.x < bounds.x)
+        {
+          final_rect.width -= bounds.x - final_rect.x;
+          final_rect.x = bounds.x;
+        }
+
+      if (final_rect.x + final_rect.width > bounds.x + bounds.width)
+        final_rect.width = bounds.x + bounds.width - final_rect.x;
+    }
+
+  if (anchor_hints & GDK_ANCHOR_RESIZE_Y)
+    {
+      if (final_rect.y < bounds.y)
+        {
+          final_rect.height -= bounds.y - final_rect.y;
+          final_rect.y = bounds.y;
+        }
+
+      if (final_rect.y + final_rect.height > bounds.y + bounds.height)
+        final_rect.height = bounds.y + bounds.height - final_rect.y;
+    }
+
+  flipped_rect.x -= surface->shadow_left;
+  flipped_rect.y -= surface->shadow_top;
+  flipped_rect.width += surface->shadow_left + surface->shadow_right;
+  flipped_rect.height += surface->shadow_top + surface->shadow_bottom;
+
+  final_rect.x -= surface->shadow_left;
+  final_rect.y -= surface->shadow_top;
+  final_rect.width += surface->shadow_left + surface->shadow_right;
+  final_rect.height += surface->shadow_top + surface->shadow_bottom;
+
+  if (final_rect.width != surface->width || final_rect.height != surface->height)
+    gdk_surface_move_resize (surface, final_rect.x, final_rect.y, final_rect.width, final_rect.height);
+  else
+    gdk_surface_move (surface, final_rect.x, final_rect.y);
+
+  g_signal_emit_by_name (surface,
+                         "moved-to-rect",
+                         &flipped_rect,
+                         &final_rect,
+                         flipped_x,
+                         flipped_y);
+}
+
 static void
 gdk_surface_init (GdkSurface *surface)
 {
@@ -164,6 +429,10 @@ gdk_surface_init (GdkSurface *surface)
   surface->width = 1;
   surface->height = 1;
 
+  surface->accept_focus = TRUE;
+  surface->focus_on_map = TRUE;
+  surface->alpha = 255;
+
   surface->device_cursor = g_hash_table_new_full (NULL, NULL,
                                                  NULL, g_object_unref);
 }
@@ -177,7 +446,8 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
   object_class->set_property = gdk_surface_set_property;
   object_class->get_property = gdk_surface_get_property;
 
-  /* Properties */
+  klass->beep = gdk_surface_real_beep;
+  klass->move_to_rect = gdk_surface_real_move_to_rect;
 
   /**
    * GdkSurface:cursor:
@@ -355,18 +625,6 @@ gdk_surface_finalize (GObject *object)
       _gdk_surface_destroy (surface, FALSE);
     }
 
-  if (surface->impl)
-    {
-      g_object_unref (surface->impl);
-      surface->impl = NULL;
-    }
-
-  if (surface->impl_surface != surface)
-    {
-      g_object_unref (surface->impl_surface);
-      surface->impl_surface = NULL;
-    }
-
   if (surface->input_shape)
     cairo_region_destroy (surface->input_shape);
 
@@ -452,12 +710,6 @@ gdk_surface_get_property (GObject    *object,
     }
 }
 
-GdkSurface *
-gdk_surface_get_impl_surface (GdkSurface *surface)
-{
-  return surface->impl_surface;
-}
-
 void
 _gdk_surface_update_size (GdkSurface *surface)
 {
@@ -477,28 +729,14 @@ gdk_surface_new (GdkDisplay     *display,
                  int             height)
 {
   GdkSurface *surface;
-  GdkFrameClock *frame_clock;
-
-  surface = _gdk_display_create_surface (display);
-
-  surface->accept_focus = TRUE;
-  surface->focus_on_map = TRUE;
-  surface->alpha = 255;
-
-  surface->surface_type = surface_type;
-  surface->x = x;
-  surface->y = y;
-  surface->width = width;
-  surface->height = height;
-
-  frame_clock = g_object_new (GDK_TYPE_FRAME_CLOCK_IDLE, NULL);
-  gdk_surface_set_frame_clock (surface, frame_clock);
-  g_object_unref (frame_clock);
 
-  gdk_display_create_surface_impl (display, surface, parent);
-  surface->impl_surface = surface;
+  surface = gdk_display_create_surface (display,
+                                        surface_type,
+                                        parent,
+                                        x, y, width, height);
 
-  g_signal_connect (display, "seat-removed", G_CALLBACK (seat_removed_cb), surface);
+  g_signal_connect (display, "seat-removed",
+                    G_CALLBACK (seat_removed_cb), surface);
 
   return surface;
 }
@@ -621,7 +859,6 @@ static void
 _gdk_surface_destroy_hierarchy (GdkSurface *surface,
                                 gboolean   foreign_destroy)
 {
-  GdkSurfaceImplClass *impl_class;
   GdkDisplay *display;
 
   g_return_if_fail (GDK_IS_SURFACE (surface));
@@ -647,8 +884,7 @@ _gdk_surface_destroy_hierarchy (GdkSurface *surface,
 
   _gdk_surface_clear_update_area (surface);
 
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-  impl_class->destroy (surface, foreign_destroy);
+  GDK_SURFACE_GET_CLASS (surface)->destroy (surface, foreign_destroy);
 
   surface->state |= GDK_SURFACE_STATE_WITHDRAWN;
   surface->destroyed = TRUE;
@@ -852,40 +1088,37 @@ gdk_surface_get_paint_gl_context (GdkSurface  *surface,
       return NULL;
     }
 
-  if (surface->impl_surface->gl_paint_context == NULL)
+  if (surface->gl_paint_context == NULL)
     {
-      GdkSurfaceImplClass *impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
+      GdkSurfaceClass *class = GDK_SURFACE_GET_CLASS (surface);
 
-      if (impl_class->create_gl_context == NULL)
+      if (class->create_gl_context == NULL)
         {
           g_set_error_literal (error, GDK_GL_ERROR, GDK_GL_ERROR_NOT_AVAILABLE,
                                _("The current backend does not support OpenGL"));
           return NULL;
         }
 
-      surface->impl_surface->gl_paint_context =
-        impl_class->create_gl_context (surface->impl_surface,
-                                       TRUE,
-                                       NULL,
-                                       &internal_error);
+      surface->gl_paint_context =
+        class->create_gl_context (surface, TRUE, NULL, &internal_error);
     }
 
   if (internal_error != NULL)
     {
       g_propagate_error (error, internal_error);
-      g_clear_object (&(surface->impl_surface->gl_paint_context));
+      g_clear_object (&(surface->gl_paint_context));
       return NULL;
     }
 
-  gdk_gl_context_realize (surface->impl_surface->gl_paint_context, &internal_error);
+  gdk_gl_context_realize (surface->gl_paint_context, &internal_error);
   if (internal_error != NULL)
     {
       g_propagate_error (error, internal_error);
-      g_clear_object (&(surface->impl_surface->gl_paint_context));
+      g_clear_object (&(surface->gl_paint_context));
       return NULL;
     }
 
-  return surface->impl_surface->gl_paint_context;
+  return surface->gl_paint_context;
 }
 
 /**
@@ -918,10 +1151,10 @@ gdk_surface_create_gl_context (GdkSurface   *surface,
   if (paint_context == NULL)
     return NULL;
 
-  return GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->create_gl_context (surface->impl_surface,
-                                                                        FALSE,
-                                                                        paint_context,
-                                                                        error);
+  return GDK_SURFACE_GET_CLASS (surface)->create_gl_context (surface,
+                                                             FALSE,
+                                                             paint_context,
+                                                             error);
 }
 
 /**
@@ -1098,7 +1331,6 @@ gdk_surface_paint_on_clock (GdkFrameClock *clock,
   surface = GDK_SURFACE (data);
 
   g_return_if_fail (GDK_IS_SURFACE (surface));
-  g_return_if_fail (surface->impl_surface == surface);
 
   if (GDK_SURFACE_DESTROYED (surface))
     return;
@@ -1273,7 +1505,7 @@ gdk_surface_freeze_updates (GdkSurface *surface)
 {
   g_return_if_fail (GDK_IS_SURFACE (surface));
 
-  surface->impl_surface->update_freeze_count++;
+  surface->update_freeze_count++;
 }
 
 /**
@@ -1285,16 +1517,12 @@ gdk_surface_freeze_updates (GdkSurface *surface)
 void
 gdk_surface_thaw_updates (GdkSurface *surface)
 {
-  GdkSurface *impl_surface;
-
   g_return_if_fail (GDK_IS_SURFACE (surface));
 
-  impl_surface = gdk_surface_get_impl_surface (surface);
-
-  g_return_if_fail (impl_surface->update_freeze_count > 0);
+  g_return_if_fail (surface->update_freeze_count > 0);
 
-  if (--impl_surface->update_freeze_count == 0)
-    gdk_surface_schedule_update (impl_surface);
+  if (--surface->update_freeze_count == 0)
+    gdk_surface_schedule_update (surface);
 }
 
 void
@@ -1475,10 +1703,10 @@ gdk_surface_get_device_position (GdkSurface       *surface,
 
   tmp_x = tmp_y = 0;
   tmp_mask = 0;
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->get_device_state (surface,
-                                                                device,
-                                                                &tmp_x, &tmp_y,
-                                                                &tmp_mask);
+  GDK_SURFACE_GET_CLASS (surface)->get_device_state (surface,
+                                                     device,
+                                                     &tmp_x, &tmp_y,
+                                                     &tmp_mask);
 
   if (x)
     *x = tmp_x;
@@ -1491,10 +1719,7 @@ gdk_surface_get_device_position (GdkSurface       *surface,
 static void
 gdk_surface_raise_internal (GdkSurface *surface)
 {
-  GdkSurfaceImplClass *impl_class;
-
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-  impl_class->raise (surface);
+  GDK_SURFACE_GET_CLASS (surface)->raise (surface);
 }
 
 /* Returns TRUE If the native surface was mapped or unmapped */
@@ -1519,7 +1744,6 @@ _gdk_surface_update_viewable (GdkSurface *surface)
 static void
 gdk_surface_show_internal (GdkSurface *surface, gboolean raise)
 {
-  GdkSurfaceImplClass *impl_class;
   gboolean was_mapped;
   gboolean did_show;
 
@@ -1538,8 +1762,7 @@ gdk_surface_show_internal (GdkSurface *surface, gboolean raise)
 
   did_show = _gdk_surface_update_viewable (surface);
 
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-  impl_class->show (surface, !did_show ? was_mapped : TRUE);
+  GDK_SURFACE_GET_CLASS (surface)->show (surface, !did_show ? was_mapped : TRUE);
 
   if (!was_mapped)
     {
@@ -1592,10 +1815,7 @@ gdk_surface_raise (GdkSurface *surface)
 static void
 gdk_surface_lower_internal (GdkSurface *surface)
 {
-  GdkSurfaceImplClass *impl_class;
-
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-  impl_class->lower (surface);
+  GDK_SURFACE_GET_CLASS (surface)->lower (surface);
 }
 
 /**
@@ -1647,8 +1867,6 @@ gdk_surface_restack (GdkSurface     *surface,
                      GdkSurface     *sibling,
                      gboolean       above)
 {
-  GdkSurfaceImplClass *impl_class;
-
   g_return_if_fail (GDK_IS_SURFACE (surface));
   g_return_if_fail (sibling == NULL || GDK_IS_SURFACE (sibling));
 
@@ -1664,8 +1882,7 @@ gdk_surface_restack (GdkSurface     *surface,
       return;
     }
 
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-  impl_class->restack_toplevel (surface, sibling, above);
+  GDK_SURFACE_GET_CLASS (surface)->restack_toplevel (surface, sibling, above);
 }
 
 
@@ -1701,7 +1918,6 @@ gdk_surface_show (GdkSurface *surface)
 void
 gdk_surface_hide (GdkSurface *surface)
 {
-  GdkSurfaceImplClass *impl_class;
   gboolean was_mapped;
 
   g_return_if_fail (GDK_IS_SURFACE (surface));
@@ -1747,8 +1963,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
       g_list_free (devices);
     }
 
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-  impl_class->hide (surface);
+  GDK_SURFACE_GET_CLASS (surface)->hide (surface);
 }
 
 static void
@@ -1759,10 +1974,7 @@ gdk_surface_move_resize_toplevel (GdkSurface *surface,
                                   gint       width,
                                   gint       height)
 {
-  GdkSurfaceImplClass *impl_class;
-
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-  impl_class->move_resize (surface, with_move, x, y, width, height);
+  GDK_SURFACE_GET_CLASS (surface)->move_resize (surface, with_move, x, y, width, height);
 }
 
 
@@ -1890,20 +2102,17 @@ gdk_surface_move_to_rect (GdkSurface          *surface,
                           gint                rect_anchor_dx,
                           gint                rect_anchor_dy)
 {
-  GdkSurfaceImplClass *impl_class;
-
   g_return_if_fail (GDK_IS_SURFACE (surface));
   g_return_if_fail (surface->transient_for);
   g_return_if_fail (rect);
 
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-  impl_class->move_to_rect (surface,
-                            rect,
-                            rect_anchor,
-                            surface_anchor,
-                            anchor_hints,
-                            rect_anchor_dx,
-                            rect_anchor_dy);
+  GDK_SURFACE_GET_CLASS (surface)->move_to_rect (surface,
+                                                 rect,
+                                                 rect_anchor,
+                                                 surface_anchor,
+                                                 anchor_hints,
+                                                 rect_anchor_dx,
+                                                 rect_anchor_dy);
 }
 
 static void
@@ -2105,15 +2314,12 @@ gdk_surface_get_geometry (GdkSurface *surface,
                           gint      *width,
                           gint      *height)
 {
-  GdkSurfaceImplClass *impl_class;
-
   g_return_if_fail (GDK_IS_SURFACE (surface));
 
   if (GDK_SURFACE_DESTROYED (surface))
     return;
 
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-  impl_class->get_geometry (surface, x, y, width, height);
+  GDK_SURFACE_GET_CLASS (surface)->get_geometry (surface, x, y, width, height);
 }
 
 /**
@@ -2206,8 +2412,6 @@ gdk_surface_get_root_coords (GdkSurface *surface,
                              gint      *root_x,
                              gint      *root_y)
 {
-  GdkSurfaceImplClass *impl_class;
-
   g_return_if_fail (GDK_IS_SURFACE (surface));
 
   if (GDK_SURFACE_DESTROYED (surface))
@@ -2217,9 +2421,7 @@ gdk_surface_get_root_coords (GdkSurface *surface,
       return;
     }
   
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-  impl_class->get_root_coords (surface->impl_surface,
-                               x, y, root_x, root_y);
+  GDK_SURFACE_GET_CLASS (surface)->get_root_coords (surface, x, y, root_x, root_y);
 }
 
 /**
@@ -2252,8 +2454,6 @@ gdk_surface_input_shape_combine_region (GdkSurface       *surface,
                                         gint             offset_x,
                                         gint             offset_y)
 {
-  GdkSurfaceImplClass *impl_class;
-
   g_return_if_fail (GDK_IS_SURFACE (surface));
 
   if (GDK_SURFACE_DESTROYED (surface))
@@ -2270,8 +2470,7 @@ gdk_surface_input_shape_combine_region (GdkSurface       *surface,
   else
     surface->input_shape = NULL;
 
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-  impl_class->input_shape_combine_region (surface, surface->input_shape, 0, 0);
+  GDK_SURFACE_GET_CLASS (surface)->input_shape_combine_region (surface, surface->input_shape, 0, 0);
 }
 
 static void
@@ -2441,7 +2640,7 @@ gdk_surface_beep (GdkSurface *surface)
   if (GDK_SURFACE_DESTROYED (surface))
     return;
 
-  if (GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->beep (surface))
+  if (GDK_SURFACE_GET_CLASS (surface)->beep (surface))
     return;
 
   display = gdk_surface_get_display (surface);
@@ -2845,7 +3044,7 @@ void
 gdk_surface_focus (GdkSurface *surface,
                    guint32    timestamp)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->focus (surface, timestamp);
+  GDK_SURFACE_GET_CLASS (surface)->focus (surface, timestamp);
 }
 
 /**
@@ -2864,7 +3063,7 @@ void
 gdk_surface_set_type_hint (GdkSurface        *surface,
                            GdkSurfaceTypeHint hint)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_type_hint (surface, hint);
+  GDK_SURFACE_GET_CLASS (surface)->set_type_hint (surface, hint);
 }
 
 /**
@@ -2878,7 +3077,7 @@ gdk_surface_set_type_hint (GdkSurface        *surface,
 GdkSurfaceTypeHint
 gdk_surface_get_type_hint (GdkSurface *surface)
 {
-  return GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->get_type_hint (surface);
+  return GDK_SURFACE_GET_CLASS (surface)->get_type_hint (surface);
 }
 
 /**
@@ -2898,7 +3097,7 @@ void
 gdk_surface_set_modal_hint (GdkSurface *surface,
                             gboolean   modal)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_modal_hint (surface, modal);
+  GDK_SURFACE_GET_CLASS (surface)->set_modal_hint (surface, modal);
 }
 
 /**
@@ -2936,7 +3135,7 @@ gdk_surface_set_geometry_hints (GdkSurface         *surface,
 {
   g_return_if_fail (geometry != NULL || geom_mask == 0);
 
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_geometry_hints (surface, geometry, geom_mask);
+  GDK_SURFACE_GET_CLASS (surface)->set_geometry_hints (surface, geometry, geom_mask);
 }
 
 /**
@@ -2954,7 +3153,7 @@ void
 gdk_surface_set_title (GdkSurface   *surface,
                        const gchar *title)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_title (surface, title);
+  GDK_SURFACE_GET_CLASS (surface)->set_title (surface, title);
 }
 
 /**
@@ -2969,10 +3168,7 @@ void
 gdk_surface_set_startup_id (GdkSurface   *surface,
                             const gchar *startup_id)
 {
-  GdkSurfaceImplClass *klass = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-
-  if (klass->set_startup_id)
-    klass->set_startup_id (surface, startup_id);
+  GDK_SURFACE_GET_CLASS (surface)->set_startup_id (surface, startup_id);
 }
 
 /**
@@ -2994,7 +3190,7 @@ gdk_surface_set_transient_for (GdkSurface *surface,
 {
   surface->transient_for = parent;
 
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_transient_for (surface, parent);
+  GDK_SURFACE_GET_CLASS (surface)->set_transient_for (surface, parent);
 }
 
 /**
@@ -3012,7 +3208,7 @@ void
 gdk_surface_get_frame_extents (GdkSurface    *surface,
                                GdkRectangle *rect)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->get_frame_extents (surface, rect);
+  GDK_SURFACE_GET_CLASS (surface)->get_frame_extents (surface, rect);
 }
 
 /**
@@ -3030,7 +3226,7 @@ void
 gdk_surface_set_accept_focus (GdkSurface *surface,
                               gboolean accept_focus)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_accept_focus (surface, accept_focus);
+  GDK_SURFACE_GET_CLASS (surface)->set_accept_focus (surface, accept_focus);
 }
 
 /**
@@ -3051,7 +3247,7 @@ void
 gdk_surface_set_focus_on_map (GdkSurface *surface,
                               gboolean focus_on_map)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_focus_on_map (surface, focus_on_map);
+  GDK_SURFACE_GET_CLASS (surface)->set_focus_on_map (surface, focus_on_map);
 }
 
 /**
@@ -3074,7 +3270,7 @@ void
 gdk_surface_set_icon_list (GdkSurface *surface,
                            GList     *textures)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_icon_list (surface, textures);
+  GDK_SURFACE_GET_CLASS (surface)->set_icon_list (surface, textures);
 }
 
 /**
@@ -3099,7 +3295,7 @@ void
 gdk_surface_set_icon_name (GdkSurface   *surface,
                            const gchar *name)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_icon_name (surface, name);
+  GDK_SURFACE_GET_CLASS (surface)->set_icon_name (surface, name);
 }
 
 /**
@@ -3116,7 +3312,7 @@ gdk_surface_set_icon_name (GdkSurface   *surface,
 void
 gdk_surface_iconify (GdkSurface *surface)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->iconify (surface);
+  GDK_SURFACE_GET_CLASS (surface)->iconify (surface);
 }
 
 /**
@@ -3133,7 +3329,7 @@ gdk_surface_iconify (GdkSurface *surface)
 void
 gdk_surface_deiconify (GdkSurface *surface)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->deiconify (surface);
+  GDK_SURFACE_GET_CLASS (surface)->deiconify (surface);
 }
 
 /**
@@ -3154,7 +3350,7 @@ gdk_surface_deiconify (GdkSurface *surface)
 void
 gdk_surface_stick (GdkSurface *surface)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->stick (surface);
+  GDK_SURFACE_GET_CLASS (surface)->stick (surface);
 }
 
 /**
@@ -3168,7 +3364,7 @@ gdk_surface_stick (GdkSurface *surface)
 void
 gdk_surface_unstick (GdkSurface *surface)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->unstick (surface);
+  GDK_SURFACE_GET_CLASS (surface)->unstick (surface);
 }
 
 /**
@@ -3191,7 +3387,7 @@ gdk_surface_unstick (GdkSurface *surface)
 void
 gdk_surface_maximize (GdkSurface *surface)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->maximize (surface);
+  GDK_SURFACE_GET_CLASS (surface)->maximize (surface);
 }
 
 /**
@@ -3214,7 +3410,7 @@ gdk_surface_maximize (GdkSurface *surface)
 void
 gdk_surface_unmaximize (GdkSurface *surface)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->unmaximize (surface);
+  GDK_SURFACE_GET_CLASS (surface)->unmaximize (surface);
 }
 
 /**
@@ -3238,7 +3434,7 @@ gdk_surface_unmaximize (GdkSurface *surface)
 void
 gdk_surface_fullscreen (GdkSurface *surface)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->fullscreen (surface);
+  GDK_SURFACE_GET_CLASS (surface)->fullscreen (surface);
 }
 
 /**
@@ -3260,10 +3456,10 @@ gdk_surface_fullscreen_on_monitor (GdkSurface  *surface,
   g_return_if_fail (gdk_monitor_get_display (monitor) == gdk_surface_get_display (surface));
   g_return_if_fail (gdk_monitor_is_valid (monitor));
 
-  if (GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->fullscreen_on_monitor != NULL)
-    GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->fullscreen_on_monitor (surface, monitor);
+  if (GDK_SURFACE_GET_CLASS (surface)->fullscreen_on_monitor != NULL)
+    GDK_SURFACE_GET_CLASS (surface)->fullscreen_on_monitor (surface, monitor);
   else
-    GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->fullscreen (surface);
+    GDK_SURFACE_GET_CLASS (surface)->fullscreen (surface);
 }
 
 /**
@@ -3293,17 +3489,14 @@ void
 gdk_surface_set_fullscreen_mode (GdkSurface        *surface,
                                  GdkFullscreenMode mode)
 {
-  GdkSurfaceImplClass *impl_class;
-
   g_return_if_fail (GDK_IS_SURFACE (surface));
 
   if (surface->fullscreen_mode != mode)
     {
       surface->fullscreen_mode = mode;
 
-      impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-      if (impl_class->apply_fullscreen_mode != NULL)
-        impl_class->apply_fullscreen_mode (surface);
+      if (GDK_SURFACE_GET_CLASS (surface)->apply_fullscreen_mode != NULL)
+        GDK_SURFACE_GET_CLASS (surface)->apply_fullscreen_mode (surface);
     }
 }
 
@@ -3341,7 +3534,7 @@ gdk_surface_get_fullscreen_mode (GdkSurface *surface)
 void
 gdk_surface_unfullscreen (GdkSurface *surface)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->unfullscreen (surface);
+  GDK_SURFACE_GET_CLASS (surface)->unfullscreen (surface);
 }
 
 /**
@@ -3363,7 +3556,7 @@ void
 gdk_surface_set_keep_above (GdkSurface *surface,
                             gboolean   setting)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_keep_above (surface, setting);
+  GDK_SURFACE_GET_CLASS (surface)->set_keep_above (surface, setting);
 }
 
 /**
@@ -3385,7 +3578,7 @@ void
 gdk_surface_set_keep_below (GdkSurface *surface,
                             gboolean setting)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_keep_below (surface, setting);
+  GDK_SURFACE_GET_CLASS (surface)->set_keep_below (surface, setting);
 }
 
 /**
@@ -3413,7 +3606,7 @@ void
 gdk_surface_set_decorations (GdkSurface      *surface,
                              GdkWMDecoration decorations)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_decorations (surface, decorations);
+  GDK_SURFACE_GET_CLASS (surface)->set_decorations (surface, decorations);
 }
 
 /**
@@ -3430,7 +3623,7 @@ gboolean
 gdk_surface_get_decorations (GdkSurface       *surface,
                              GdkWMDecoration *decorations)
 {
-  return GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->get_decorations (surface, decorations);
+  return GDK_SURFACE_GET_CLASS (surface)->get_decorations (surface, decorations);
 }
 
 /**
@@ -3457,7 +3650,7 @@ void
 gdk_surface_set_functions (GdkSurface    *surface,
                            GdkWMFunction functions)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_functions (surface, functions);
+  GDK_SURFACE_GET_CLASS (surface)->set_functions (surface, functions);
 }
 
 /**
@@ -3482,7 +3675,7 @@ gdk_surface_begin_resize_drag_for_device (GdkSurface     *surface,
                                           gint            y,
                                           guint32         timestamp)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->begin_resize_drag (surface, edge, device, button, x, y, 
timestamp);
+  GDK_SURFACE_GET_CLASS (surface)->begin_resize_drag (surface, edge, device, button, x, y, timestamp);
 }
 
 /**
@@ -3536,8 +3729,8 @@ gdk_surface_begin_move_drag_for_device (GdkSurface *surface,
                                         gint        y,
                                         guint32     timestamp)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->begin_move_drag (surface,
-                                                               device, button, x, y, timestamp);
+  GDK_SURFACE_GET_CLASS (surface)->begin_move_drag (surface,
+                                                    device, button, x, y, timestamp);
 }
 
 /**
@@ -3603,7 +3796,7 @@ gdk_surface_set_opacity (GdkSurface *surface,
   if (surface->destroyed)
     return;
 
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_opacity (surface, opacity);
+  GDK_SURFACE_GET_CLASS (surface)->set_opacity (surface, opacity);
 }
 
 /* This function is called when the XWindow is really gone.
@@ -3611,7 +3804,7 @@ gdk_surface_set_opacity (GdkSurface *surface,
 void
 gdk_surface_destroy_notify (GdkSurface *surface)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->destroy_notify (surface);
+  GDK_SURFACE_GET_CLASS (surface)->destroy_notify (surface);
 }
 
 /**
@@ -3623,7 +3816,7 @@ gdk_surface_destroy_notify (GdkSurface *surface)
 void
 gdk_surface_register_dnd (GdkSurface *surface)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->register_dnd (surface);
+  GDK_SURFACE_GET_CLASS (surface)->register_dnd (surface);
 }
 
 /**
@@ -3655,7 +3848,7 @@ gdk_drag_begin (GdkSurface          *surface,
   g_return_val_if_fail (gdk_surface_get_display (surface) == gdk_device_get_display (device), NULL);
   g_return_val_if_fail (GDK_IS_CONTENT_PROVIDER (content), NULL);
 
-  return GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->drag_begin (surface, device, content, actions, dx, dy);
+  return GDK_SURFACE_GET_CLASS (surface)->drag_begin (surface, device, content, actions, dx, dy);
 }
 
 static void
@@ -3778,17 +3971,16 @@ gdk_surface_get_frame_clock (GdkSurface *surface)
 gint
 gdk_surface_get_scale_factor (GdkSurface *surface)
 {
-  GdkSurfaceImplClass *impl_class;
+  GdkSurfaceClass *class;
 
   g_return_val_if_fail (GDK_IS_SURFACE (surface), 1);
 
   if (GDK_SURFACE_DESTROYED (surface))
     return 1;
 
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-
-  if (impl_class->get_scale_factor)
-    return impl_class->get_scale_factor (surface);
+  class = GDK_SURFACE_GET_CLASS (surface);
+  if (class->get_scale_factor)
+    return class->get_scale_factor (surface);
 
   return 1;
 }
@@ -3801,20 +3993,17 @@ gdk_surface_get_unscaled_size (GdkSurface *surface,
                                int *unscaled_width,
                                int *unscaled_height)
 {
-  GdkSurfaceImplClass *impl_class;
+  GdkSurfaceClass *class;
   gint scale;
 
   g_return_if_fail (GDK_IS_SURFACE (surface));
 
-  if (surface->impl_surface == surface)
-    {
-      impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
+  class = GDK_SURFACE_GET_CLASS (surface);
 
-      if (impl_class->get_unscaled_size)
-        {
-          impl_class->get_unscaled_size (surface, unscaled_width, unscaled_height);
-          return;
-        }
+  if (class->get_unscaled_size)
+    {
+      class->get_unscaled_size (surface, unscaled_width, unscaled_height);
+      return;
     }
 
   scale = gdk_surface_get_scale_factor (surface);
@@ -3850,7 +4039,7 @@ void
 gdk_surface_set_opaque_region (GdkSurface      *surface,
                                cairo_region_t *region)
 {
-  GdkSurfaceImplClass *impl_class;
+  GdkSurfaceClass *class;
 
   g_return_if_fail (GDK_IS_SURFACE (surface));
   g_return_if_fail (!GDK_SURFACE_DESTROYED (surface));
@@ -3863,10 +4052,9 @@ gdk_surface_set_opaque_region (GdkSurface      *surface,
   if (region != NULL)
     surface->opaque_region = cairo_region_reference (region);
 
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-
-  if (impl_class->set_opaque_region)
-    impl_class->set_opaque_region (surface, region);
+  class = GDK_SURFACE_GET_CLASS (surface);
+  if (class->set_opaque_region)
+    class->set_opaque_region (surface, region);
 }
 
 /**
@@ -3894,7 +4082,7 @@ gdk_surface_set_shadow_width (GdkSurface *surface,
                               gint       top,
                               gint       bottom)
 {
-  GdkSurfaceImplClass *impl_class;
+  GdkSurfaceClass *class;
 
   g_return_if_fail (GDK_IS_SURFACE (surface));
   g_return_if_fail (!GDK_SURFACE_DESTROYED (surface));
@@ -3905,10 +4093,9 @@ gdk_surface_set_shadow_width (GdkSurface *surface,
   surface->shadow_right = right;
   surface->shadow_bottom = bottom;
 
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-
-  if (impl_class->set_shadow_width)
-    impl_class->set_shadow_width (surface, left, right, top, bottom);
+  class = GDK_SURFACE_GET_CLASS (surface);
+  if (class->set_shadow_width)
+    class->set_shadow_width (surface, left, right, top, bottom);
 }
 
 /**
@@ -3928,15 +4115,14 @@ gboolean
 gdk_surface_show_window_menu (GdkSurface *surface,
                               GdkEvent  *event)
 {
-  GdkSurfaceImplClass *impl_class;
+  GdkSurfaceClass *class;
 
   g_return_val_if_fail (GDK_IS_SURFACE (surface), FALSE);
   g_return_val_if_fail (!GDK_SURFACE_DESTROYED (surface), FALSE);
 
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-
-  if (impl_class->show_window_menu)
-    return impl_class->show_window_menu (surface, event);
+  class = GDK_SURFACE_GET_CLASS (surface);
+  if (class->show_window_menu)
+    return class->show_window_menu (surface, event);
   else
     return FALSE;
 }
@@ -3944,15 +4130,14 @@ gdk_surface_show_window_menu (GdkSurface *surface,
 gboolean
 gdk_surface_supports_edge_constraints (GdkSurface *surface)
 {
-  GdkSurfaceImplClass *impl_class;
+  GdkSurfaceClass *class;
 
   g_return_val_if_fail (GDK_IS_SURFACE (surface), FALSE);
   g_return_val_if_fail (!GDK_SURFACE_DESTROYED (surface), FALSE);
 
-  impl_class = GDK_SURFACE_IMPL_GET_CLASS (surface->impl);
-
-  if (impl_class->supports_edge_constraints)
-    return impl_class->supports_edge_constraints (surface);
+  class = GDK_SURFACE_GET_CLASS (surface);
+  if (class->supports_edge_constraints)
+    return class->supports_edge_constraints (surface);
   else
     return FALSE;
 }
diff --git a/gdk/gdksurface.h b/gdk/gdksurface.h
index 03bc5f02f3..f3ab38f851 100644
--- a/gdk/gdksurface.h
+++ b/gdk/gdksurface.h
@@ -411,21 +411,6 @@ typedef struct _GdkSurfaceClass GdkSurfaceClass;
 #define GDK_SURFACE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_SURFACE, GdkSurfaceClass))
 
 
-struct _GdkSurfaceClass
-{
-  GObjectClass      parent_class;
-
-  /* Padding for future expansion */
-  void (*_gdk_reserved1) (void);
-  void (*_gdk_reserved2) (void);
-  void (*_gdk_reserved3) (void);
-  void (*_gdk_reserved4) (void);
-  void (*_gdk_reserved5) (void);
-  void (*_gdk_reserved6) (void);
-  void (*_gdk_reserved7) (void);
-  void (*_gdk_reserved8) (void);
-};
-
 /* Surfaces
  */
 GDK_AVAILABLE_IN_ALL
diff --git a/gdk/gdksurfaceprivate.h b/gdk/gdksurfaceprivate.h
index 664ad7e2e9..f2855ae996 100644
--- a/gdk/gdksurfaceprivate.h
+++ b/gdk/gdksurfaceprivate.h
@@ -21,7 +21,6 @@
 #define __GDK_SURFACE_PRIVATE_H__
 
 #include <gdk-pixbuf/gdk-pixbuf.h>
-#include "gdksurfaceimpl.h"
 #include "gdkenumtypes.h"
 #include "gdksurface.h"
 
@@ -33,8 +32,6 @@ struct _GdkSurface
 
   GdkDisplay *display;
 
-  GdkSurfaceImpl *impl; /* window-system-specific delegate object */
-
   GdkSurface *transient_for;
 
   gpointer widget;
@@ -72,11 +69,6 @@ struct _GdkSurface
   guint in_update : 1;
   guint frame_clock_events_paused : 1;
 
-  /* The GdkSurface that has the impl, ref:ed if another surface.
-   * This ref is required to keep the wrapper of the impl surface alive
-   * for as long as any GdkSurface references the impl. */
-  GdkSurface *impl_surface;
-
   guint update_and_descendants_freeze_count;
 
   gint width, height;
@@ -102,17 +94,161 @@ struct _GdkSurface
 
 struct _GdkSurfaceClass
 {
-  GObjectClass      parent_class;
-
-  /* Padding for future expansion */
-  void (*_gdk_reserved1) (void);
-  void (*_gdk_reserved2) (void);
-  void (*_gdk_reserved3) (void);
-  void (*_gdk_reserved4) (void);
-  void (*_gdk_reserved5) (void);
-  void (*_gdk_reserved6) (void);
-  void (*_gdk_reserved7) (void);
-  void (*_gdk_reserved8) (void);
+  GObjectClass parent_class;
+
+  cairo_surface_t *
+               (* ref_cairo_surface)    (GdkSurface       *surface);
+
+  void         (* show)                 (GdkSurface       *surface,
+                                         gboolean         already_mapped);
+  void         (* hide)                 (GdkSurface       *surface);
+  void         (* withdraw)             (GdkSurface       *surface);
+  void         (* raise)                (GdkSurface       *surface);
+  void         (* lower)                (GdkSurface       *surface);
+  void         (* restack_toplevel)     (GdkSurface       *surface,
+                                         GdkSurface       *sibling,
+                                         gboolean        above);
+
+  void         (* move_resize)          (GdkSurface       *surface,
+                                         gboolean         with_move,
+                                         gint             x,
+                                         gint             y,
+                                         gint             width,
+                                         gint             height);
+  void         (* move_to_rect)         (GdkSurface       *surface,
+                                         const GdkRectangle *rect,
+                                         GdkGravity       rect_anchor,
+                                         GdkGravity       surface_anchor,
+                                         GdkAnchorHints   anchor_hints,
+                                         gint             rect_anchor_dx,
+                                         gint             rect_anchor_dy);
+
+  void         (* get_geometry)         (GdkSurface       *surface,
+                                         gint            *x,
+                                         gint            *y,
+                                         gint            *width,
+                                         gint            *height);
+  void         (* get_root_coords)      (GdkSurface       *surface,
+                                         gint             x,
+                                         gint             y,
+                                         gint            *root_x,
+                                         gint            *root_y);
+  gboolean     (* get_device_state)     (GdkSurface       *surface,
+                                         GdkDevice       *device,
+                                         gdouble         *x,
+                                         gdouble         *y,
+                                         GdkModifierType *mask);
+
+  void         (* input_shape_combine_region) (GdkSurface       *surface,
+                                               const cairo_region_t *shape_region,
+                                               gint             offset_x,
+                                               gint             offset_y);
+
+/* Called to do the windowing system specific part of gdk_surface_destroy(),
+ *
+ * surface: The window being destroyed
+ * foreign_destroy: If TRUE, the surface or a parent was destroyed by some
+ *     external agency. The surface has already been destroyed and no
+ *     windowing system calls should be made. (This may never happen
+ *     for some windowing systems.)
+ */
+  void         (* destroy)              (GdkSurface       *surface,
+                                         gboolean         foreign_destroy);
+
+
+  /* optional */
+  gboolean     (* beep)                 (GdkSurface       *surface);
+
+  void         (* focus)                (GdkSurface       *surface,
+                                         guint32          timestamp);
+  void         (* set_type_hint)        (GdkSurface       *surface,
+                                         GdkSurfaceTypeHint hint);
+  GdkSurfaceTypeHint (* get_type_hint)   (GdkSurface       *surface);
+  void         (* set_modal_hint)       (GdkSurface *surface,
+                                         gboolean   modal);
+  void         (* set_geometry_hints)   (GdkSurface         *surface,
+                                         const GdkGeometry *geometry,
+                                         GdkSurfaceHints     geom_mask);
+  void         (* set_title)            (GdkSurface   *surface,
+                                         const gchar *title);
+  void         (* set_startup_id)       (GdkSurface   *surface,
+                                         const gchar *startup_id);
+  void         (* set_transient_for)    (GdkSurface *surface,
+                                         GdkSurface *parent);
+  void         (* get_frame_extents)    (GdkSurface    *surface,
+                                         GdkRectangle *rect);
+  void         (* set_accept_focus)     (GdkSurface *surface,
+                                         gboolean accept_focus);
+  void         (* set_focus_on_map)     (GdkSurface *surface,
+                                         gboolean focus_on_map);
+  void         (* set_icon_list)        (GdkSurface *surface,
+                                         GList     *pixbufs);
+  void         (* set_icon_name)        (GdkSurface   *surface,
+                                         const gchar *name);
+  void         (* iconify)              (GdkSurface *surface);
+  void         (* deiconify)            (GdkSurface *surface);
+  void         (* stick)                (GdkSurface *surface);
+  void         (* unstick)              (GdkSurface *surface);
+  void         (* maximize)             (GdkSurface *surface);
+  void         (* unmaximize)           (GdkSurface *surface);
+  void         (* fullscreen)           (GdkSurface *surface);
+  void         (* fullscreen_on_monitor) (GdkSurface  *surface,
+                                          GdkMonitor *monitor);
+  void         (* apply_fullscreen_mode) (GdkSurface *surface);
+  void         (* unfullscreen)         (GdkSurface *surface);
+  void         (* set_keep_above)       (GdkSurface *surface,
+                                         gboolean   setting);
+  void         (* set_keep_below)       (GdkSurface *surface,
+                                         gboolean   setting);
+  void         (* set_decorations)      (GdkSurface      *surface,
+                                         GdkWMDecoration decorations);
+  gboolean     (* get_decorations)      (GdkSurface       *surface,
+                                         GdkWMDecoration *decorations);
+  void         (* set_functions)        (GdkSurface    *surface,
+                                         GdkWMFunction functions);
+  void         (* begin_resize_drag)    (GdkSurface     *surface,
+                                         GdkSurfaceEdge  edge,
+                                         GdkDevice     *device,
+                                         gint           button,
+                                         gint           root_x,
+                                         gint           root_y,
+                                         guint32        timestamp);
+  void         (* begin_move_drag)      (GdkSurface *surface,
+                                         GdkDevice     *device,
+                                         gint       button,
+                                         gint       root_x,
+                                         gint       root_y,
+                                         guint32    timestamp);
+  void         (* set_opacity)          (GdkSurface *surface,
+                                         gdouble    opacity);
+  void         (* destroy_notify)       (GdkSurface *surface);
+  void         (* register_dnd)         (GdkSurface *surface);
+  GdkDrag * (*drag_begin)               (GdkSurface        *surface,
+                                         GdkDevice        *device,
+                                         GdkContentProvider*content,
+                                         GdkDragAction     actions,
+                                         gint              dx,
+                                         gint              dy);
+
+  gint         (* get_scale_factor)       (GdkSurface      *surface);
+  void         (* get_unscaled_size)      (GdkSurface      *surface,
+                                           int            *unscaled_width,
+                                           int            *unscaled_height);
+
+  void         (* set_opaque_region)      (GdkSurface      *surface,
+                                           cairo_region_t *region);
+  void         (* set_shadow_width)       (GdkSurface      *surface,
+                                           gint            left,
+                                           gint            right,
+                                           gint            top,
+                                           gint            bottom);
+  gboolean     (* show_window_menu)       (GdkSurface      *surface,
+                                           GdkEvent       *event);
+  GdkGLContext *(*create_gl_context)      (GdkSurface      *surface,
+                                           gboolean        attached,
+                                           GdkGLContext   *share,
+                                           GError        **error);
+  gboolean     (* supports_edge_constraints)(GdkSurface    *surface);
 };
 
 void gdk_surface_set_state (GdkSurface      *surface,
diff --git a/gdk/meson.build b/gdk/meson.build
index 3c411c1fb9..7380961ccf 100644
--- a/gdk/meson.build
+++ b/gdk/meson.build
@@ -44,7 +44,6 @@ gdk_public_sources = files([
   'gdktexture.c',
   'gdkvulkancontext.c',
   'gdksurface.c',
-  'gdksurfaceimpl.c',
   'gdkprofiler.c'
 ])
 
diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c
index 46ca742c3b..d90d133321 100644
--- a/gdk/wayland/gdkdevice-wayland.c
+++ b/gdk/wayland/gdkdevice-wayland.c
@@ -22,8 +22,8 @@
 #include <errno.h>
 
 #include <string.h>
-#include <gdk/gdksurface.h>
-#include <gdk/gdktypes.h>
+#include "gdksurfaceprivate.h"
+#include "gdktypes.h"
 #include "gdkclipboard-wayland.h"
 #include "gdkclipboardprivate.h"
 #include "gdkprivate-wayland.h"
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index d721026d54..a5370ebeeb 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -39,7 +39,7 @@
 #include "gdkdisplay-wayland.h"
 #include "gdkmonitor-wayland.h"
 #include "gdkseat-wayland.h"
-#include "gdkinternals.h"
+#include "gdksurfaceprivate.h"
 #include "gdkdeviceprivate.h"
 #include "gdkkeysprivate.h"
 #include "gdkprivate-wayland.h"
@@ -1004,7 +1004,6 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
   object_class->dispose = gdk_wayland_display_dispose;
   object_class->finalize = gdk_wayland_display_finalize;
 
-  display_class->surface_type = gdk_wayland_surface_get_type ();
   display_class->cairo_context_type = GDK_TYPE_WAYLAND_CAIRO_CONTEXT;
 
 #ifdef GDK_RENDERING_VULKAN
@@ -1026,7 +1025,7 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
   display_class->get_next_serial = gdk_wayland_display_get_next_serial;
   display_class->get_startup_notification_id = gdk_wayland_display_get_startup_notification_id;
   display_class->notify_startup_complete = gdk_wayland_display_notify_startup_complete;
-  display_class->create_surface_impl = _gdk_wayland_display_create_surface_impl;
+  display_class->create_surface = _gdk_wayland_display_create_surface;
   display_class->get_keymap = _gdk_wayland_display_get_keymap;
   display_class->text_property_to_utf8_list = _gdk_wayland_display_text_property_to_utf8_list;
   display_class->utf8_to_string_target = _gdk_wayland_display_utf8_to_string_target;
diff --git a/gdk/wayland/gdkglcontext-wayland.c b/gdk/wayland/gdkglcontext-wayland.c
index 75c4acfd87..79751cb8fc 100644
--- a/gdk/wayland/gdkglcontext-wayland.c
+++ b/gdk/wayland/gdkglcontext-wayland.c
@@ -30,6 +30,7 @@
 #include "gdkprivate-wayland.h"
 
 #include "gdkinternals.h"
+#include "gdksurfaceprivate.h"
 
 #include "gdkintl.h"
 
@@ -176,7 +177,7 @@ gdk_wayland_gl_context_get_damage (GdkGLContext *context)
         shared = context;
       shared_wayland = GDK_WAYLAND_GL_CONTEXT (shared);
 
-      egl_surface = gdk_wayland_surface_get_egl_surface (surface->impl_surface,
+      egl_surface = gdk_wayland_surface_get_egl_surface (surface,
                                                         shared_wayland->egl_config);
       gdk_gl_context_make_current (shared);
       eglQuerySurface (display_wayland->egl_display, egl_surface,
@@ -228,7 +229,7 @@ gdk_wayland_gl_context_end_frame (GdkDrawContext *draw_context,
 
   gdk_gl_context_make_current (context);
 
-  egl_surface = gdk_wayland_surface_get_egl_surface (surface->impl_surface,
+  egl_surface = gdk_wayland_surface_get_egl_surface (surface,
                                                     context_wayland->egl_config);
 
   gdk_wayland_surface_sync (surface);
@@ -513,13 +514,13 @@ gdk_wayland_display_make_gl_context_current (GdkDisplay   *display,
   surface = gdk_gl_context_get_surface (context);
 
   if (context_wayland->is_attached || gdk_draw_context_is_in_frame (GDK_DRAW_CONTEXT (context)))
-    egl_surface = gdk_wayland_surface_get_egl_surface (surface->impl_surface, context_wayland->egl_config);
+    egl_surface = gdk_wayland_surface_get_egl_surface (surface, context_wayland->egl_config);
   else
     {
       if (display_wayland->have_egl_surfaceless_context)
        egl_surface = EGL_NO_SURFACE;
       else
-       egl_surface = gdk_wayland_surface_get_dummy_egl_surface (surface->impl_surface,
+       egl_surface = gdk_wayland_surface_get_dummy_egl_surface (surface,
                                                                context_wayland->egl_config);
     }
 
diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h
index ff4abf2146..e156208b29 100644
--- a/gdk/wayland/gdkprivate-wayland.h
+++ b/gdk/wayland/gdkprivate-wayland.h
@@ -44,8 +44,6 @@
 #define WL_SURFACE_HAS_BUFFER_SCALE 3
 #define WL_POINTER_HAS_FRAME 5
 
-#define GDK_SURFACE_IS_WAYLAND(win)    (GDK_IS_SURFACE_IMPL_WAYLAND (((GdkSurface *)win)->impl))
-
 GdkKeymap *_gdk_wayland_keymap_new (GdkDisplay *display);
 void       _gdk_wayland_keymap_update_from_fd (GdkKeymap *keymap,
                                                uint32_t   format,
@@ -116,9 +114,13 @@ void             gdk_wayland_drop_set_source_actions       (GdkDrop
 void             gdk_wayland_drop_set_action               (GdkDrop               *drop,
                                                             uint32_t               action);
 
-void _gdk_wayland_display_create_surface_impl (GdkDisplay     *display,
-                                               GdkSurface     *surface,
-                                               GdkSurface     *real_parent);
+GdkSurface * _gdk_wayland_display_create_surface (GdkDisplay *display,
+                                                  GdkSurfaceType surface_type,
+                                                  GdkSurface *parent,
+                                                  int         x,
+                                                  int         y,
+                                                  int         width,
+                                                  int         height);
 
 gint        _gdk_wayland_display_text_property_to_utf8_list (GdkDisplay    *display,
                                                              GdkAtom        encoding,
diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c
index d8f6e24fcd..bf167354c8 100644
--- a/gdk/wayland/gdksurface-wayland.c
+++ b/gdk/wayland/gdksurface-wayland.c
@@ -22,14 +22,13 @@
 
 #include "gdk.h"
 #include "gdkwayland.h"
+#include "gdkwaylandsurface.h"
 
-#include "gdksurface.h"
-#include "gdksurfaceimpl.h"
+#include "gdksurfaceprivate.h"
 #include "gdkdisplay-wayland.h"
 #include "gdkglcontext-wayland.h"
-#include "gdkframeclockprivate.h"
+#include "gdkframeclockidleprivate.h"
 #include "gdkprivate-wayland.h"
-#include "gdkinternals.h"
 #include "gdkdeviceprivate.h"
 #include "gdkprivate-wayland.h"
 #include "gdkmonitor-wayland.h"
@@ -53,41 +52,6 @@ static guint signals[LAST_SIGNAL];
 
 #define MAX_WL_BUFFER_SIZE (4083) /* 4096 minus header, string argument length and NUL byte */
 
-typedef struct _GdkWaylandSurface GdkWaylandSurface;
-typedef struct _GdkWaylandSurfaceClass GdkWaylandSurfaceClass;
-
-struct _GdkWaylandSurface
-{
-  GdkSurface parent;
-};
-
-struct _GdkWaylandSurfaceClass
-{
-  GdkSurfaceClass parent_class;
-};
-
-G_DEFINE_TYPE (GdkWaylandSurface, gdk_wayland_surface, GDK_TYPE_SURFACE)
-
-static void
-gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *wayland_surface_class)
-{
-}
-
-static void
-gdk_wayland_surface_init (GdkWaylandSurface *wayland_surface)
-{
-}
-
-#define GDK_TYPE_SURFACE_IMPL_WAYLAND              (_gdk_surface_impl_wayland_get_type ())
-#define GDK_SURFACE_IMPL_WAYLAND(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), 
GDK_TYPE_SURFACE_IMPL_WAYLAND, GdkSurfaceImplWayland))
-#define GDK_SURFACE_IMPL_WAYLAND_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), 
GDK_TYPE_SURFACE_IMPL_WAYLAND, GdkSurfaceImplWaylandClass))
-#define GDK_IS_SURFACE_IMPL_WAYLAND(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), 
GDK_TYPE_SURFACE_IMPL_WAYLAND))
-#define GDK_IS_SURFACE_IMPL_WAYLAND_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), 
GDK_TYPE_SURFACE_IMPL_WAYLAND))
-#define GDK_SURFACE_IMPL_WAYLAND_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), 
GDK_TYPE_SURFACE_IMPL_WAYLAND, GdkSurfaceImplWaylandClass))
-
-typedef struct _GdkSurfaceImplWayland GdkSurfaceImplWayland;
-typedef struct _GdkSurfaceImplWaylandClass GdkSurfaceImplWaylandClass;
-
 typedef enum _PositionMethod
 {
   POSITION_METHOD_NONE,
@@ -95,11 +59,9 @@ typedef enum _PositionMethod
   POSITION_METHOD_MOVE_TO_RECT
 } PositionMethod;
 
-struct _GdkSurfaceImplWayland
+struct _GdkWaylandSurface
 {
-  GdkSurfaceImpl parent_instance;
-
-  GdkSurface *wrapper;
+  GdkSurface parent_instance;
 
   struct {
     /* The wl_outputs that this surface currently touches */
@@ -203,9 +165,9 @@ struct _GdkSurfaceImplWayland
   GHashTable *shortcuts_inhibitors;
 };
 
-struct _GdkSurfaceImplWaylandClass
+struct _GdkWaylandSurfaceClass
 {
-  GdkSurfaceImplClass parent_class;
+  GdkSurfaceClass parent_class;
 };
 
 static void gdk_wayland_surface_maybe_configure (GdkSurface *surface,
@@ -234,17 +196,16 @@ static void calculate_moved_to_rect_result (GdkSurface    *surface,
 
 static gboolean gdk_wayland_surface_is_exported (GdkSurface *surface);
 
-GType _gdk_surface_impl_wayland_get_type (void);
-
-G_DEFINE_TYPE (GdkSurfaceImplWayland, _gdk_surface_impl_wayland, GDK_TYPE_SURFACE_IMPL)
+G_DEFINE_TYPE (GdkWaylandSurface, gdk_wayland_surface, GDK_TYPE_SURFACE)
 
 static void
-_gdk_surface_impl_wayland_init (GdkSurfaceImplWayland *impl)
+gdk_wayland_surface_init (GdkWaylandSurface *impl)
 {
   impl->scale = 1;
   impl->initial_fullscreen_output = NULL;
   impl->saved_width = -1;
   impl->saved_height = -1;
+  impl->shortcuts_inhibitors = g_hash_table_new (NULL, NULL);
 }
 
 static void
@@ -261,7 +222,7 @@ _gdk_wayland_screen_add_orphan_dialog (GdkSurface *surface)
 static void
 _gdk_wayland_surface_save_size (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (surface->state & (GDK_SURFACE_STATE_FULLSCREEN | GDK_SURFACE_STATE_MAXIMIZED))
     return;
@@ -273,7 +234,7 @@ _gdk_wayland_surface_save_size (GdkSurface *surface)
 static void
 _gdk_wayland_surface_clear_saved_size (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (surface->state & (GDK_SURFACE_STATE_FULLSCREEN | GDK_SURFACE_STATE_MAXIMIZED))
     return;
@@ -282,20 +243,13 @@ _gdk_wayland_surface_clear_saved_size (GdkSurface *surface)
   impl->saved_height = -1;
 }
 
-/*
- * gdk_wayland_surface_update_size:
- * @drawable: a #GdkDrawableImplWayland.
- *
- * Updates the state of the drawable (in particular the drawable's
- * cairo surface) when its size has changed.
- */
 static void
 gdk_wayland_surface_update_size (GdkSurface *surface,
                                  int32_t     width,
                                  int32_t     height,
                                  int         scale)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if ((surface->width == width) &&
       (surface->height == height) &&
@@ -378,7 +332,7 @@ frame_callback (void               *data,
                 uint32_t            time)
 {
   GdkSurface *surface = data;
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkWaylandDisplay *display_wayland =
     GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
   GdkFrameClock *clock = gdk_surface_get_frame_clock (surface);
@@ -468,7 +422,7 @@ on_frame_clock_before_paint (GdkFrameClock *clock,
 void
 gdk_wayland_surface_request_frame (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   struct wl_callback *callback;
   GdkFrameClock *clock;
 
@@ -487,7 +441,7 @@ static void
 on_frame_clock_after_paint (GdkFrameClock *clock,
                             GdkSurface    *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (impl->pending_commit)
     {
@@ -518,7 +472,7 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
 void
 gdk_wayland_surface_update_scale (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
   guint32 scale;
   GSList *l;
@@ -542,31 +496,46 @@ gdk_wayland_surface_update_scale (GdkSurface *surface)
 
 static void gdk_wayland_surface_create_surface (GdkSurface *surface);
 
-void
-_gdk_wayland_display_create_surface_impl (GdkDisplay     *display,
-                                          GdkSurface     *surface,
-                                          GdkSurface     *real_parent)
+GdkSurface *
+_gdk_wayland_display_create_surface (GdkDisplay     *display,
+                                     GdkSurfaceType  surface_type,
+                                     GdkSurface     *parent,
+                                     int             x,
+                                     int             y,
+                                     int             width,
+                                     int             height)
 {
   GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
-  GdkSurfaceImplWayland *impl;
+  GdkSurface *surface;
+  GdkWaylandSurface *impl;
   GdkFrameClock *frame_clock;
 
-  impl = g_object_new (GDK_TYPE_SURFACE_IMPL_WAYLAND, NULL);
-  surface->impl = GDK_SURFACE_IMPL (impl);
-  impl->wrapper = GDK_SURFACE (surface);
-  impl->shortcuts_inhibitors = g_hash_table_new (NULL, NULL);
+  frame_clock = _gdk_frame_clock_idle_new ();
+
+  surface = g_object_new (GDK_TYPE_WAYLAND_SURFACE,
+                          "display", display,
+                          "frame-clock", frame_clock,
+                          NULL);
+
+  impl = GDK_WAYLAND_SURFACE (surface);
 
-  if (surface->width > 65535)
+  if (width > 65535)
     {
       g_warning ("Native Surfaces wider than 65535 pixels are not supported");
-      surface->width = 65535;
+      width = 65535;
     }
-  if (surface->height > 65535)
+  if (height > 65535)
     {
       g_warning ("Native Surfaces taller than 65535 pixels are not supported");
-      surface->height = 65535;
+      height = 65535;
     }
 
+  surface->surface_type = surface_type;
+  surface->x = x;
+  surface->y = y;
+  surface->width = width;
+  surface->height = height;
+
   g_object_ref (surface);
 
   /* More likely to be right than just assuming 1 */
@@ -576,14 +545,17 @@ _gdk_wayland_display_create_surface_impl (GdkDisplay     *display,
 
   gdk_surface_set_title (surface, get_default_title ());
 
-  if (real_parent == NULL)
+  if (parent == NULL)
     display_wayland->toplevels = g_list_prepend (display_wayland->toplevels, surface);
 
   gdk_wayland_surface_create_surface (surface);
 
-  frame_clock = gdk_surface_get_frame_clock (surface);
   g_signal_connect (frame_clock, "before-paint", G_CALLBACK (on_frame_clock_before_paint), surface);
   g_signal_connect (frame_clock, "after-paint", G_CALLBACK (on_frame_clock_after_paint), surface);
+
+  g_object_unref (frame_clock);
+
+  return surface;
 }
 
 void
@@ -591,7 +563,7 @@ gdk_wayland_surface_attach_image (GdkSurface           *surface,
                                   cairo_surface_t      *cairo_surface,
                                   const cairo_region_t *damage)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkWaylandDisplay *display;
   cairo_rectangle_int_t rect;
   int i, n;
@@ -632,7 +604,7 @@ gdk_wayland_surface_sync (GdkSurface *surface)
 }
 
 static gboolean
-gdk_surface_impl_wayland_beep (GdkSurface *surface)
+gdk_wayland_surface_beep (GdkSurface *surface)
 {
   gdk_wayland_display_system_bell (gdk_surface_get_display (surface),
                                    surface);
@@ -641,14 +613,14 @@ gdk_surface_impl_wayland_beep (GdkSurface *surface)
 }
 
 static void
-gdk_surface_impl_wayland_finalize (GObject *object)
+gdk_wayland_surface_finalize (GObject *object)
 {
   GdkSurface *surface = GDK_SURFACE (object);
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
 
-  g_return_if_fail (GDK_IS_SURFACE_IMPL_WAYLAND (object));
+  g_return_if_fail (GDK_IS_WAYLAND_SURFACE (object));
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (object);
+  impl = GDK_WAYLAND_SURFACE (object);
 
   if (gdk_wayland_surface_is_exported (surface))
     gdk_wayland_surface_unexport_handle (surface);
@@ -666,7 +638,7 @@ gdk_surface_impl_wayland_finalize (GObject *object)
   g_clear_pointer (&impl->input_region, cairo_region_destroy);
   g_clear_pointer (&impl->shortcuts_inhibitors, g_hash_table_unref);
 
-  G_OBJECT_CLASS (_gdk_surface_impl_wayland_parent_class)->finalize (object);
+  G_OBJECT_CLASS (gdk_wayland_surface_parent_class)->finalize (object);
 }
 
 static void
@@ -694,7 +666,7 @@ gdk_wayland_surface_configure (GdkSurface *surface,
 static gboolean
 is_realized_shell_surface (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   return (impl->display_server.xdg_surface ||
           impl->display_server.zxdg_surface_v6);
@@ -703,7 +675,7 @@ is_realized_shell_surface (GdkSurface *surface)
 static gboolean
 is_realized_toplevel (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   return (impl->display_server.xdg_toplevel ||
           impl->display_server.zxdg_toplevel_v6);
@@ -712,7 +684,7 @@ is_realized_toplevel (GdkSurface *surface)
 static gboolean
 is_realized_popup (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   return (impl->display_server.xdg_popup ||
           impl->display_server.zxdg_popup_v6);
@@ -724,7 +696,7 @@ gdk_wayland_surface_maybe_configure (GdkSurface *surface,
                                      int         height,
                                      int         scale)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   gboolean is_xdg_popup;
   gboolean is_visible;
 
@@ -755,10 +727,10 @@ static void
 gdk_wayland_surface_sync_parent (GdkSurface *surface,
                                  GdkSurface *parent)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkWaylandDisplay *display_wayland =
     GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
-  GdkSurfaceImplWayland *impl_parent = NULL;
+  GdkWaylandSurface *impl_parent = NULL;
 
   g_assert (parent == NULL ||
             gdk_surface_get_display (surface) == gdk_surface_get_display (parent));
@@ -767,9 +739,9 @@ gdk_wayland_surface_sync_parent (GdkSurface *surface,
     return;
 
   if (impl->transient_for)
-    impl_parent = GDK_SURFACE_IMPL_WAYLAND (impl->transient_for->impl);
+    impl_parent = GDK_WAYLAND_SURFACE (impl->transient_for);
   else if (parent)
-    impl_parent = GDK_SURFACE_IMPL_WAYLAND (parent->impl);
+    impl_parent = GDK_WAYLAND_SURFACE (parent);
 
   /* XXX: Is this correct? */
   if (impl_parent && !impl_parent->display_server.wl_surface)
@@ -812,7 +784,7 @@ gdk_wayland_surface_sync_parent (GdkSurface *surface,
 static void
 gdk_wayland_surface_sync_parent_of_imported (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (!impl->display_server.wl_surface)
     return;
@@ -840,12 +812,12 @@ gdk_wayland_surface_update_dialogs (GdkSurface *surface)
   for (l = display_wayland->orphan_dialogs; l; l = l->next)
     {
       GdkSurface *w = l->data;
-      GdkSurfaceImplWayland *impl;
+      GdkWaylandSurface *impl;
 
-      if (!GDK_IS_SURFACE_IMPL_WAYLAND (w->impl))
+      if (!GDK_IS_WAYLAND_SURFACE (w))
         continue;
 
-      impl = GDK_SURFACE_IMPL_WAYLAND (w->impl);
+      impl = GDK_WAYLAND_SURFACE (w);
       if (w == surface)
        continue;
       if (impl->hint != GDK_SURFACE_TYPE_HINT_DIALOG)
@@ -861,7 +833,7 @@ gdk_wayland_surface_update_dialogs (GdkSurface *surface)
 static void
 gdk_wayland_surface_sync_title (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkWaylandDisplay *display_wayland =
     GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
 
@@ -890,7 +862,7 @@ static void
 gdk_wayland_surface_get_window_geometry (GdkSurface   *surface,
                                          GdkRectangle *geometry)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   *geometry = (GdkRectangle) {
     .x = impl->margin_left,
@@ -903,7 +875,7 @@ gdk_wayland_surface_get_window_geometry (GdkSurface   *surface,
 static void
 gdk_wayland_surface_sync_margin (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkWaylandDisplay *display_wayland =
     GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
   GdkRectangle geometry;
@@ -962,7 +934,7 @@ wl_region_from_cairo_region (GdkWaylandDisplay *display,
 static void
 gdk_wayland_surface_sync_opaque_region (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   struct wl_region *wl_region = NULL;
 
   if (!impl->display_server.wl_surface)
@@ -986,7 +958,7 @@ gdk_wayland_surface_sync_opaque_region (GdkSurface *surface)
 static void
 gdk_wayland_surface_sync_input_region (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   struct wl_region *wl_region = NULL;
 
   if (!impl->display_server.wl_surface)
@@ -1013,7 +985,7 @@ surface_enter (void              *data,
                struct wl_output  *output)
 {
   GdkSurface *surface = GDK_SURFACE (data);
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS,
             g_message ("surface enter, surface %p output %p", surface, output));
@@ -1029,7 +1001,7 @@ surface_leave (void              *data,
                struct wl_output  *output)
 {
   GdkSurface *surface = GDK_SURFACE (data);
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   GDK_DISPLAY_NOTE (gdk_surface_get_display (surface), EVENTS,
             g_message ("surface leave, surface %p output %p", surface, output));
@@ -1048,7 +1020,7 @@ static const struct wl_surface_listener surface_listener = {
 static void
 gdk_wayland_surface_create_surface (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
 
   impl->display_server.wl_surface = wl_compositor_create_surface (display_wayland->compositor);
@@ -1059,7 +1031,7 @@ static void
 gdk_wayland_surface_handle_configure (GdkSurface *surface,
                                       uint32_t    serial)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkWaylandDisplay *display_wayland =
     GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
   GdkSurfaceState new_state;
@@ -1167,7 +1139,7 @@ gdk_wayland_surface_handle_configure_toplevel (GdkSurface      *surface,
                                                int32_t          height,
                                                GdkSurfaceState  state)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   impl->pending.state |= state;
   impl->pending.width = width;
@@ -1262,7 +1234,7 @@ create_xdg_toplevel_resources (GdkSurface *surface)
 {
   GdkWaylandDisplay *display_wayland =
     GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   impl->display_server.xdg_surface =
     xdg_wm_base_get_xdg_surface (display_wayland->xdg_wm_base,
@@ -1349,7 +1321,7 @@ create_zxdg_toplevel_v6_resources (GdkSurface *surface)
 {
   GdkWaylandDisplay *display_wayland =
     GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   impl->display_server.zxdg_surface_v6 =
     zxdg_shell_v6_get_xdg_surface (display_wayland->zxdg_shell_v6,
@@ -1369,7 +1341,7 @@ static void
 gdk_wayland_surface_create_xdg_toplevel (GdkSurface *surface)
 {
   GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   const gchar *app_id;
 
   gdk_surface_freeze_updates (surface);
@@ -1449,7 +1421,7 @@ gdk_wayland_surface_handle_configure_popup (GdkSurface *surface,
                                             int32_t     width,
                                             int32_t     height)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkRectangle flipped_rect;
   GdkRectangle final_rect;
   gboolean flipped_x;
@@ -1669,7 +1641,7 @@ void
 gdk_wayland_surface_announce_csd (GdkSurface *surface)
 {
   GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   if (!display_wayland->server_decoration_manager)
     return;
   impl->display_server.server_decoration =
@@ -1685,7 +1657,7 @@ get_real_parent_and_translate (GdkSurface *surface,
                                gint       *x,
                                gint       *y)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkSurface *parent = impl->transient_for;
 
   return parent;
@@ -1727,7 +1699,7 @@ calculate_popup_rect (GdkSurface   *surface,
                       GdkGravity    surface_anchor,
                       GdkRectangle *out_rect)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkRectangle geometry;
   GdkRectangle anchor_rect;
   int x = 0, y = 0;
@@ -1900,7 +1872,7 @@ calculate_moved_to_rect_result (GdkSurface   *surface,
                                 gboolean     *flipped_x,
                                 gboolean     *flipped_y)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkSurface *parent;
   gint surface_x, surface_y;
   gint surface_width, surface_height;
@@ -1976,7 +1948,7 @@ calculate_moved_to_rect_result (GdkSurface   *surface,
 static gpointer
 create_dynamic_positioner (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkWaylandDisplay *display =
     GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
   GdkRectangle geometry;
@@ -2156,8 +2128,8 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface     *surface,
                                       GdkWaylandSeat *grab_input_seat)
 {
   GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
-  GdkSurfaceImplWayland *parent_impl = GDK_SURFACE_IMPL_WAYLAND (parent->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+  GdkWaylandSurface *parent_impl = GDK_WAYLAND_SURFACE (parent);
   gpointer positioner;
 
   if (!impl->display_server.wl_surface)
@@ -2263,8 +2235,8 @@ find_grab_input_seat (GdkSurface *surface,
                       GdkSurface *transient_for)
 {
   GdkSurface *attached_grab_surface;
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
-  GdkSurfaceImplWayland *tmp_impl;
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+  GdkWaylandSurface *tmp_impl;
 
   /* Use the device that was used for the grab as the device for
    * the popup surface setup - so this relies on GTK+ taking the
@@ -2282,14 +2254,14 @@ find_grab_input_seat (GdkSurface *surface,
   attached_grab_surface = g_object_get_data (G_OBJECT (surface), "gdk-attached-grab-surface");
   if (attached_grab_surface)
     {
-      tmp_impl = GDK_SURFACE_IMPL_WAYLAND (attached_grab_surface->impl);
+      tmp_impl = GDK_WAYLAND_SURFACE (attached_grab_surface);
       if (tmp_impl->grab_input_seat)
         return GDK_WAYLAND_SEAT (tmp_impl->grab_input_seat);
     }
 
   while (transient_for)
     {
-      tmp_impl = GDK_SURFACE_IMPL_WAYLAND (transient_for->impl);
+      tmp_impl = GDK_WAYLAND_SURFACE (transient_for);
 
       if (tmp_impl->grab_input_seat)
         return GDK_WAYLAND_SEAT (tmp_impl->grab_input_seat);
@@ -2303,7 +2275,7 @@ find_grab_input_seat (GdkSurface *surface,
 static gboolean
 should_be_mapped (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   /* Don't map crazy temp that GTK+ uses for internal X11 shenanigans. */
   if (surface->surface_type == GDK_SURFACE_TEMP && surface->x < 0 && surface->y < 0)
@@ -2318,7 +2290,7 @@ should_be_mapped (GdkSurface *surface)
 static gboolean
 should_map_as_popup (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   /* Ideally, popup would be temp surfaces with a parent and grab */
   if (GDK_SURFACE_TYPE (surface) == GDK_SURFACE_TEMP)
@@ -2362,7 +2334,7 @@ get_popup_parent (GdkSurface *surface)
 {
   while (surface)
     {
-      GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+      GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
       if (is_realized_popup (surface) || is_realized_toplevel (surface))
         return surface;
@@ -2376,7 +2348,7 @@ get_popup_parent (GdkSurface *surface)
 static void
 gdk_wayland_surface_map (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkSurface *transient_for = NULL;
 
   if (!should_be_mapped (surface))
@@ -2412,8 +2384,8 @@ gdk_wayland_surface_map (GdkSurface *surface)
                                    "gdk-attached-grab-surface");
               if (attached_grab_surface)
                 {
-                  GdkSurfaceImplWayland *attached_impl =
-                    GDK_SURFACE_IMPL_WAYLAND (attached_grab_surface->impl);
+                  GdkWaylandSurface *attached_impl =
+                    GDK_WAYLAND_SURFACE (attached_grab_surface);
                   grab_device = gdk_seat_get_pointer (attached_impl->grab_input_seat);
                   transient_for =
                     gdk_device_get_surface_at_position (grab_device, NULL, NULL);
@@ -2482,7 +2454,7 @@ static void
 gdk_wayland_surface_show (GdkSurface *surface,
                           gboolean    already_mapped)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (!impl->display_server.wl_surface)
     gdk_wayland_surface_create_surface (surface);
@@ -2500,7 +2472,7 @@ unmap_popups_for_surface (GdkSurface *surface)
   for (l = display_wayland->current_popups; l; l = l->next)
     {
        GdkSurface *popup = l->data;
-       GdkSurfaceImplWayland *popup_impl = GDK_SURFACE_IMPL_WAYLAND (popup->impl);
+       GdkWaylandSurface *popup_impl = GDK_WAYLAND_SURFACE (popup);
 
        if (popup_impl->popup_parent == surface)
          {
@@ -2516,7 +2488,7 @@ static void
 gdk_wayland_surface_hide_surface (GdkSurface *surface)
 {
   GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   unmap_popups_for_surface (surface);
 
@@ -2633,7 +2605,7 @@ gdk_wayland_surface_hide (GdkSurface *surface)
 }
 
 static void
-gdk_surface_wayland_withdraw (GdkSurface *surface)
+gdk_wayland_surface_withdraw (GdkSurface *surface)
 {
   if (!surface->destroyed)
     {
@@ -2647,31 +2619,31 @@ gdk_surface_wayland_withdraw (GdkSurface *surface)
 }
 
 static void
-gdk_surface_wayland_raise (GdkSurface *surface)
+gdk_wayland_surface_raise (GdkSurface *surface)
 {
 }
 
 static void
-gdk_surface_wayland_lower (GdkSurface *surface)
+gdk_wayland_surface_lower (GdkSurface *surface)
 {
 }
 
 static void
-gdk_surface_wayland_restack_toplevel (GdkSurface *surface,
+gdk_wayland_surface_restack_toplevel (GdkSurface *surface,
                                       GdkSurface *sibling,
                                       gboolean    above)
 {
 }
 
 static void
-gdk_surface_wayland_move_resize (GdkSurface *surface,
+gdk_wayland_surface_move_resize (GdkSurface *surface,
                                  gboolean    with_move,
                                  gint        x,
                                  gint        y,
                                  gint        width,
                                  gint        height)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (with_move)
     {
@@ -2706,7 +2678,7 @@ sanitize_anchor_rect (GdkSurface   *surface,
 }
 
 static void
-gdk_surface_wayland_move_to_rect (GdkSurface         *surface,
+gdk_wayland_surface_move_to_rect (GdkSurface         *surface,
                                   const GdkRectangle *rect,
                                   GdkGravity          rect_anchor,
                                   GdkGravity          surface_anchor,
@@ -2714,7 +2686,7 @@ gdk_surface_wayland_move_to_rect (GdkSurface         *surface,
                                   gint                rect_anchor_dx,
                                   gint                rect_anchor_dy)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   impl->pending_move_to_rect.rect = *rect;
   sanitize_anchor_rect (surface, &impl->pending_move_to_rect.rect);
@@ -2729,7 +2701,7 @@ gdk_surface_wayland_move_to_rect (GdkSurface         *surface,
 }
 
 static void
-gdk_surface_wayland_get_geometry (GdkSurface *surface,
+gdk_wayland_surface_get_geometry (GdkSurface *surface,
                                   gint       *x,
                                   gint       *y,
                                   gint       *width,
@@ -2749,7 +2721,7 @@ gdk_surface_wayland_get_geometry (GdkSurface *surface,
 }
 
 static void
-gdk_surface_wayland_get_root_coords (GdkSurface *surface,
+gdk_wayland_surface_get_root_coords (GdkSurface *surface,
                                      gint        x,
                                      gint        y,
                                      gint       *root_x,
@@ -2785,7 +2757,7 @@ gdk_surface_wayland_get_root_coords (GdkSurface *surface,
 }
 
 static gboolean
-gdk_surface_wayland_get_device_state (GdkSurface       *surface,
+gdk_wayland_surface_get_device_state (GdkSurface       *surface,
                                       GdkDevice        *device,
                                       gdouble          *x,
                                       gdouble          *y,
@@ -2812,12 +2784,12 @@ gdk_surface_wayland_get_device_state (GdkSurface       *surface,
 }
 
 static void
-gdk_surface_wayland_input_shape_combine_region (GdkSurface           *surface,
+gdk_wayland_surface_input_shape_combine_region (GdkSurface           *surface,
                                                 const cairo_region_t *shape_region,
                                                 gint                  offset_x,
                                                 gint                  offset_y)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (GDK_SURFACE_DESTROYED (surface))
     return;
@@ -2856,7 +2828,7 @@ static void
 gdk_wayland_surface_focus (GdkSurface *surface,
                            guint32     timestamp)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (!impl->display_server.gtk_surface)
     return;
@@ -2875,9 +2847,9 @@ static void
 gdk_wayland_surface_set_type_hint (GdkSurface         *surface,
                                    GdkSurfaceTypeHint  hint)
 {
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
 
   if (GDK_SURFACE_DESTROYED (surface))
     return;
@@ -2888,12 +2860,12 @@ gdk_wayland_surface_set_type_hint (GdkSurface         *surface,
 static GdkSurfaceTypeHint
 gdk_wayland_surface_get_type_hint (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
 
   if (GDK_SURFACE_DESTROYED (surface))
     return GDK_SURFACE_TYPE_HINT_NORMAL;
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
 
   return impl->hint;
 }
@@ -2904,7 +2876,7 @@ gtk_surface_configure (void                *data,
                        struct wl_array     *states)
 {
   GdkSurface *surface = GDK_SURFACE (data);
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkSurfaceState new_state = 0;
   uint32_t *p;
 
@@ -2946,7 +2918,7 @@ gtk_surface_configure_edges (void                *data,
                              struct wl_array     *edge_constraints)
 {
   GdkSurface *surface = GDK_SURFACE (data);
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkSurfaceState new_state = 0;
   uint32_t *p;
 
@@ -2985,7 +2957,7 @@ static const struct gtk_surface1_listener gtk_surface_listener = {
 static void
 gdk_wayland_surface_init_gtk_surface (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkWaylandDisplay *display =
     GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
 
@@ -3010,7 +2982,7 @@ gdk_wayland_surface_init_gtk_surface (GdkSurface *surface)
 static void
 maybe_set_gtk_surface_modal (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   gdk_wayland_surface_init_gtk_surface (surface);
   if (impl->display_server.gtk_surface == NULL)
@@ -3037,7 +3009,7 @@ gdk_wayland_surface_set_geometry_hints (GdkSurface         *surface,
                                         GdkSurfaceHints     geom_mask)
 {
   GdkWaylandDisplay *display_wayland;
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
   int min_width, min_height;
   int max_width, max_height;
 
@@ -3045,7 +3017,7 @@ gdk_wayland_surface_set_geometry_hints (GdkSurface         *surface,
       !SURFACE_IS_TOPLEVEL (surface))
     return;
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
   display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
 
   impl->geometry_hints = *geometry;
@@ -3103,7 +3075,7 @@ static void
 gdk_wayland_surface_set_title (GdkSurface  *surface,
                                const gchar *title)
 {
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
   const char *end;
   gsize title_length;
 
@@ -3112,7 +3084,7 @@ gdk_wayland_surface_set_title (GdkSurface  *surface,
   if (GDK_SURFACE_DESTROYED (surface))
     return;
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
 
   if (g_strcmp0 (impl->title, title) == 0)
     return;
@@ -3147,12 +3119,12 @@ check_transient_for_loop (GdkSurface *surface,
 {
   while (parent)
     {
-      GdkSurfaceImplWayland *impl;
+      GdkWaylandSurface *impl;
 
-      if (!GDK_IS_SURFACE_IMPL_WAYLAND(parent->impl))
+      if (!GDK_IS_WAYLAND_SURFACE (parent))
         return FALSE;
 
-      impl = GDK_SURFACE_IMPL_WAYLAND (parent->impl);
+      impl = GDK_WAYLAND_SURFACE (parent);
       if (impl->transient_for == surface)
         return TRUE;
       parent = impl->transient_for;
@@ -3164,7 +3136,7 @@ static void
 gdk_wayland_surface_set_transient_for (GdkSurface *surface,
                                        GdkSurface *parent)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkWaylandDisplay *display_wayland =
     GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
   GdkSurface *previous_parent;
@@ -3235,7 +3207,7 @@ gdk_wayland_surface_set_icon_name (GdkSurface  *surface,
 static void
 gdk_wayland_surface_iconify (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkWaylandDisplay *display_wayland;
 
   if (GDK_SURFACE_DESTROYED (surface) ||
@@ -3286,7 +3258,7 @@ gdk_wayland_surface_unstick (GdkSurface *surface)
 static void
 gdk_wayland_surface_maximize (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (GDK_SURFACE_DESTROYED (surface))
     return;
@@ -3319,7 +3291,7 @@ gdk_wayland_surface_maximize (GdkSurface *surface)
 static void
 gdk_wayland_surface_unmaximize (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (GDK_SURFACE_DESTROYED (surface))
     return;
@@ -3351,7 +3323,7 @@ static void
 gdk_wayland_surface_fullscreen_on_monitor (GdkSurface *surface,
                                            GdkMonitor *monitor)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   struct wl_output *output = ((GdkWaylandMonitor *)monitor)->output;
 
   if (GDK_SURFACE_DESTROYED (surface))
@@ -3388,7 +3360,7 @@ gdk_wayland_surface_fullscreen_on_monitor (GdkSurface *surface,
 static void
 gdk_wayland_surface_fullscreen (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (GDK_SURFACE_DESTROYED (surface))
     return;
@@ -3425,7 +3397,7 @@ gdk_wayland_surface_fullscreen (GdkSurface *surface)
 static void
 gdk_wayland_surface_unfullscreen (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (GDK_SURFACE_DESTROYED (surface))
     return;
@@ -3495,7 +3467,7 @@ gdk_wayland_surface_begin_resize_drag (GdkSurface     *surface,
                                        gint            y,
                                        guint32         timestamp)
 {
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
   GdkWaylandDisplay *display_wayland;
   GdkEventSequence *sequence;
   uint32_t resize_edges, serial;
@@ -3543,7 +3515,7 @@ gdk_wayland_surface_begin_resize_drag (GdkSurface     *surface,
       return;
     }
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
   display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
 
   if (!is_realized_toplevel (surface))
@@ -3585,7 +3557,7 @@ gdk_wayland_surface_begin_move_drag (GdkSurface *surface,
                                      gint        y,
                                      guint32     timestamp)
 {
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
   GdkWaylandDisplay *display_wayland;
   GdkEventSequence *sequence;
   uint32_t serial;
@@ -3594,7 +3566,7 @@ gdk_wayland_surface_begin_move_drag (GdkSurface *surface,
       !SURFACE_IS_TOPLEVEL (surface))
     return;
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
   display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
 
   if (!is_realized_toplevel (surface))
@@ -3648,7 +3620,7 @@ gdk_wayland_surface_destroy_notify (GdkSurface *surface)
 static gint
 gdk_wayland_surface_get_scale_factor (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (GDK_SURFACE_DESTROYED (surface))
     return 1;
@@ -3660,7 +3632,7 @@ static void
 gdk_wayland_surface_set_opaque_region (GdkSurface     *surface,
                                        cairo_region_t *region)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (GDK_SURFACE_DESTROYED (surface))
     return;
@@ -3677,7 +3649,7 @@ gdk_wayland_surface_set_shadow_width (GdkSurface *surface,
                                       int         top,
                                       int         bottom)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   gint new_width, new_height;
 
   if (GDK_SURFACE_DESTROYED (surface))
@@ -3700,7 +3672,7 @@ static gboolean
 gdk_wayland_surface_show_window_menu (GdkSurface *surface,
                                       GdkEvent   *event)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   GdkWaylandDisplay *display_wayland =
     GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
   struct wl_seat *seat;
@@ -3748,7 +3720,7 @@ gdk_wayland_surface_show_window_menu (GdkSurface *surface,
 static gboolean
 gdk_wayland_surface_supports_edge_constraints (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   struct gtk_surface1 *gtk_surface = impl->display_server.gtk_surface;
 
   if (!gtk_surface)
@@ -3758,27 +3730,27 @@ gdk_wayland_surface_supports_edge_constraints (GdkSurface *surface)
 }
 
 static void
-_gdk_surface_impl_wayland_class_init (GdkSurfaceImplWaylandClass *klass)
+gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  GdkSurfaceImplClass *impl_class = GDK_SURFACE_IMPL_CLASS (klass);
+  GdkSurfaceClass *impl_class = GDK_SURFACE_CLASS (klass);
 
-  object_class->finalize = gdk_surface_impl_wayland_finalize;
+  object_class->finalize = gdk_wayland_surface_finalize;
 
   impl_class->show = gdk_wayland_surface_show;
   impl_class->hide = gdk_wayland_surface_hide;
-  impl_class->withdraw = gdk_surface_wayland_withdraw;
-  impl_class->raise = gdk_surface_wayland_raise;
-  impl_class->lower = gdk_surface_wayland_lower;
-  impl_class->restack_toplevel = gdk_surface_wayland_restack_toplevel;
-  impl_class->move_resize = gdk_surface_wayland_move_resize;
-  impl_class->move_to_rect = gdk_surface_wayland_move_to_rect;
-  impl_class->get_geometry = gdk_surface_wayland_get_geometry;
-  impl_class->get_root_coords = gdk_surface_wayland_get_root_coords;
-  impl_class->get_device_state = gdk_surface_wayland_get_device_state;
-  impl_class->input_shape_combine_region = gdk_surface_wayland_input_shape_combine_region;
+  impl_class->withdraw = gdk_wayland_surface_withdraw;
+  impl_class->raise = gdk_wayland_surface_raise;
+  impl_class->lower = gdk_wayland_surface_lower;
+  impl_class->restack_toplevel = gdk_wayland_surface_restack_toplevel;
+  impl_class->move_resize = gdk_wayland_surface_move_resize;
+  impl_class->move_to_rect = gdk_wayland_surface_move_to_rect;
+  impl_class->get_geometry = gdk_wayland_surface_get_geometry;
+  impl_class->get_root_coords = gdk_wayland_surface_get_root_coords;
+  impl_class->get_device_state = gdk_wayland_surface_get_device_state;
+  impl_class->input_shape_combine_region = gdk_wayland_surface_input_shape_combine_region;
   impl_class->destroy = gdk_wayland_surface_destroy;
-  impl_class->beep = gdk_surface_impl_wayland_beep;
+  impl_class->beep = gdk_wayland_surface_beep;
 
   impl_class->focus = gdk_wayland_surface_focus;
   impl_class->set_type_hint = gdk_wayland_surface_set_type_hint;
@@ -3832,11 +3804,11 @@ void
 _gdk_wayland_surface_set_grab_seat (GdkSurface *surface,
                                     GdkSeat    *seat)
 {
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
 
   g_return_if_fail (surface != NULL);
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
   impl->grab_input_seat = seat;
 }
 
@@ -3853,17 +3825,17 @@ gdk_wayland_surface_get_wl_surface (GdkSurface *surface)
 {
   g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
 
-  return GDK_SURFACE_IMPL_WAYLAND (surface->impl)->display_server.wl_surface;
+  return GDK_WAYLAND_SURFACE (surface)->display_server.wl_surface;
 }
 
 struct wl_output *
 gdk_wayland_surface_get_wl_output (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
 
   g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
   /* We pick the head of the list as this is the last entered output */
   if (impl->display_server.outputs)
     return (struct wl_output *) impl->display_server.outputs->data;
@@ -3874,14 +3846,14 @@ gdk_wayland_surface_get_wl_output (GdkSurface *surface)
 static struct wl_egl_window *
 gdk_wayland_surface_get_wl_egl_window (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (impl->display_server.egl_window == NULL)
     {
       impl->display_server.egl_window =
         wl_egl_window_create (impl->display_server.wl_surface,
-                              impl->wrapper->width * impl->scale,
-                              impl->wrapper->height * impl->scale);
+                              surface->width * impl->scale,
+                              surface->height * impl->scale);
       wl_surface_set_buffer_scale (impl->display_server.wl_surface, impl->scale);
     }
 
@@ -3893,12 +3865,12 @@ gdk_wayland_surface_get_egl_surface (GdkSurface *surface,
                                      EGLConfig   config)
 {
   GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
   struct wl_egl_window *egl_window;
 
   g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
 
   if (impl->egl_surface == NULL)
     {
@@ -3916,11 +3888,11 @@ gdk_wayland_surface_get_dummy_egl_surface (GdkSurface *surface,
                                            EGLConfig   config)
 {
   GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
 
   g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
 
   if (impl->dummy_egl_surface == NULL)
     {
@@ -3939,13 +3911,13 @@ gdk_wayland_surface_get_gtk_surface (GdkSurface *surface)
 {
   g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), NULL);
 
-  return GDK_SURFACE_IMPL_WAYLAND (surface->impl)->display_server.gtk_surface;
+  return GDK_WAYLAND_SURFACE (surface)->display_server.gtk_surface;
 }
 
 static void
 maybe_set_gtk_surface_dbus_properties (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   if (impl->application.was_set)
     return;
@@ -3981,11 +3953,11 @@ gdk_wayland_surface_set_dbus_properties_libgtk_only (GdkSurface *surface,
                                                      const char *application_object_path,
                                                      const char *unique_bus_name)
 {
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
 
   g_return_if_fail (GDK_IS_WAYLAND_SURFACE (surface));
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
 
   impl->application.application_id = g_strdup (application_id);
   impl->application.app_menu_path = g_strdup (app_menu_path);
@@ -4003,11 +3975,11 @@ _gdk_wayland_surface_offset_next_wl_buffer (GdkSurface *surface,
                                             int         x,
                                             int         y)
 {
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
 
   g_return_if_fail (GDK_IS_WAYLAND_SURFACE (surface));
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
 
   impl->pending_buffer_offset_x = x;
   impl->pending_buffer_offset_y = y;
@@ -4019,7 +3991,7 @@ xdg_exported_handle (void                    *data,
                      const char              *handle)
 {
   GdkSurface *surface = data;
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   impl->exported.callback (surface, handle, impl->exported.user_data);
   g_clear_pointer (&impl->exported.user_data,
@@ -4045,7 +4017,7 @@ static const struct zxdg_exported_v1_listener xdg_exported_listener = {
 static gboolean
 gdk_wayland_surface_is_exported (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   return !!impl->display_server.xdg_exported;
 }
@@ -4083,7 +4055,7 @@ gdk_wayland_surface_export_handle (GdkSurface                *surface,
                                    gpointer                   user_data,
                                    GDestroyNotify             destroy_func)
 {
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
   GdkWaylandDisplay *display_wayland;
   GdkDisplay *display = gdk_surface_get_display (surface);
   struct zxdg_exported_v1 *xdg_exported;
@@ -4091,7 +4063,7 @@ gdk_wayland_surface_export_handle (GdkSurface                *surface,
   g_return_val_if_fail (GDK_IS_WAYLAND_SURFACE (surface), FALSE);
   g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE);
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
   display_wayland = GDK_WAYLAND_DISPLAY (display);
 
   g_return_val_if_fail (!impl->display_server.xdg_exported, FALSE);
@@ -4130,11 +4102,11 @@ gdk_wayland_surface_export_handle (GdkSurface                *surface,
 void
 gdk_wayland_surface_unexport_handle (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
 
   g_return_if_fail (GDK_IS_WAYLAND_SURFACE (surface));
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
 
   g_return_if_fail (impl->display_server.xdg_exported);
 
@@ -4147,7 +4119,7 @@ gdk_wayland_surface_unexport_handle (GdkSurface *surface)
 static void
 unset_transient_for_exported (GdkSurface *surface)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
 
   g_clear_pointer (&impl->imported_transient_for, zxdg_imported_v1_destroy);
 }
@@ -4184,7 +4156,7 @@ gboolean
 gdk_wayland_surface_set_transient_for_exported (GdkSurface *surface,
                                                 char       *parent_handle_str)
 {
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
   GdkWaylandDisplay *display_wayland;
   GdkDisplay *display = gdk_surface_get_display (surface);
 
@@ -4192,7 +4164,7 @@ gdk_wayland_surface_set_transient_for_exported (GdkSurface *surface,
   g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE);
   g_return_val_if_fail (!should_map_as_popup (surface), FALSE);
 
-  impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  impl = GDK_WAYLAND_SURFACE (surface);
   display_wayland = GDK_WAYLAND_DISPLAY (display);
 
   if (!display_wayland->xdg_importer)
@@ -4215,7 +4187,7 @@ gdk_wayland_surface_set_transient_for_exported (GdkSurface *surface,
 }
 
 static struct zwp_keyboard_shortcuts_inhibitor_v1 *
-gdk_wayland_surface_get_inhibitor (GdkSurfaceImplWayland *impl,
+gdk_wayland_surface_get_inhibitor (GdkWaylandSurface *impl,
                                   struct wl_seat *seat)
 {
   return g_hash_table_lookup (impl->shortcuts_inhibitors, seat);
@@ -4225,7 +4197,7 @@ void
 gdk_wayland_surface_inhibit_shortcuts (GdkSurface *surface,
                                        GdkSeat    *gdk_seat)
 {
-  GdkSurfaceImplWayland *impl= GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl= GDK_WAYLAND_SURFACE (surface);
   GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
   struct wl_surface *wl_surface = impl->display_server.wl_surface;
   struct wl_seat *seat = gdk_wayland_seat_get_wl_seat (gdk_seat);
@@ -4248,7 +4220,7 @@ void
 gdk_wayland_surface_restore_shortcuts (GdkSurface *surface,
                                        GdkSeat    *gdk_seat)
 {
-  GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl);
+  GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
   struct wl_seat *seat = gdk_wayland_seat_get_wl_seat (gdk_seat);
   struct zwp_keyboard_shortcuts_inhibitor_v1 *inhibitor;
 
diff --git a/gdk/x11/gdkcairocontext-x11.c b/gdk/x11/gdkcairocontext-x11.c
index 00a3e18be3..3409e30b97 100644
--- a/gdk/x11/gdkcairocontext-x11.c
+++ b/gdk/x11/gdkcairocontext-x11.c
@@ -25,6 +25,7 @@
 #include "gdkprivate-x11.h"
 
 #include "gdkcairo.h"
+#include "gdksurfaceprivate.h"
 #include "gdkinternals.h"
 
 #include <X11/Xlib.h>
diff --git a/gdk/x11/gdkdevice-xi2.c b/gdk/x11/gdkdevice-xi2.c
index 255cad2ba4..f6b94da061 100644
--- a/gdk/x11/gdkdevice-xi2.c
+++ b/gdk/x11/gdkdevice-xi2.c
@@ -318,7 +318,7 @@ gdk_x11_device_xi2_query_state (GdkDevice        *device,
   else
     {
       xwindow = GDK_SURFACE_XID (surface);
-      scale = GDK_SURFACE_IMPL_X11 (surface->impl)->surface_scale;
+      scale = GDK_X11_SURFACE (surface)->surface_scale;
     }
 
   if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_SLAVE)
@@ -467,7 +467,7 @@ gdk_x11_device_xi2_surface_at_position (GdkDevice       *device,
                                        GdkModifierType *mask,
                                        gboolean         get_toplevel)
 {
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
   GdkX11DeviceXI2 *device_xi2 = GDK_X11_DEVICE_XI2 (device);
   GdkDisplay *display;
   GdkX11Screen *screen;
@@ -616,7 +616,7 @@ gdk_x11_device_xi2_surface_at_position (GdkDevice       *device,
       surface = gdk_x11_surface_lookup_for_display (display, last);
       impl = NULL;
       if (surface)
-        impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+        impl = GDK_X11_SURFACE (surface);
 
       if (mask)
         *mask = _gdk_x11_device_xi2_translate_state (&mod_state, &button_state, &group_state);
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index 35711053a9..cbd51d979f 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -1480,7 +1480,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
   GdkDevice *device, *source_device;
   gboolean return_val = TRUE;
   GdkSurface *surface;
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
   int scale;
   XIEvent *ev;
 
@@ -1505,7 +1505,7 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
   scale = 1;
   if (surface)
     {
-      impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+      impl = GDK_X11_SURFACE (surface);
       scale = impl->surface_scale;
     }
 
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 7d17dee28f..95ca2211f3 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -34,6 +34,7 @@
 #include "gdkframeclockprivate.h"
 #include "gdkinternals.h"
 #include "gdkdeviceprivate.h"
+#include "gdksurfaceprivate.h"
 #include "gdkkeysprivate.h"
 #include "gdkmarshalers.h"
 #include "xsettings-client.h"
@@ -638,7 +639,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
   Window xwindow;
   GdkSurface *surface;
   gboolean is_substructure;
-  GdkSurfaceImplX11 *surface_impl = NULL;
+  GdkX11Surface *surface_impl = NULL;
   GdkX11Screen *x11_screen = NULL;
   GdkToplevelX11 *toplevel = NULL;
   GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
@@ -668,7 +669,7 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
 
       x11_screen = GDK_SURFACE_SCREEN (surface);
       toplevel = _gdk_x11_surface_get_toplevel (surface);
-      surface_impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+      surface_impl = GDK_X11_SURFACE (surface);
 
       g_object_ref (surface);
     }
@@ -1209,8 +1210,8 @@ _gdk_wm_protocols_filter (const XEvent *xevent,
    * in the message for everything that gets stuffed in */
   if (xevent->xclient.message_type == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_FRAME_DRAWN"))
     {
-      GdkSurfaceImplX11 *surface_impl;
-      surface_impl = GDK_SURFACE_IMPL_X11 (win->impl);
+      GdkX11Surface *surface_impl;
+      surface_impl = GDK_X11_SURFACE (win);
       if (surface_impl->toplevel)
         {
           guint32 d0 = xevent->xclient.data.l[0];
@@ -1247,8 +1248,8 @@ _gdk_wm_protocols_filter (const XEvent *xevent,
 
   if (xevent->xclient.message_type == gdk_x11_get_xatom_by_name_for_display (display, 
"_NET_WM_FRAME_TIMINGS"))
     {
-      GdkSurfaceImplX11 *surface_impl;
-      surface_impl = GDK_SURFACE_IMPL_X11 (win->impl);
+      GdkX11Surface *surface_impl;
+      surface_impl = GDK_X11_SURFACE (win);
       if (surface_impl->toplevel)
         {
           guint32 d0 = xevent->xclient.data.l[0];
@@ -3023,7 +3024,6 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
   object_class->dispose = gdk_x11_display_dispose;
   object_class->finalize = gdk_x11_display_finalize;
 
-  display_class->surface_type = GDK_TYPE_X11_SURFACE;
   display_class->cairo_context_type = GDK_TYPE_X11_CAIRO_CONTEXT;
 #ifdef GDK_RENDERING_VULKAN
   display_class->vk_context_type = GDK_TYPE_X11_VULKAN_CONTEXT;
@@ -3045,7 +3045,7 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
   display_class->get_next_serial = gdk_x11_display_get_next_serial;
   display_class->get_startup_notification_id = gdk_x11_display_get_startup_notification_id;
   display_class->notify_startup_complete = gdk_x11_display_notify_startup_complete;
-  display_class->create_surface_impl = _gdk_x11_display_create_surface_impl;
+  display_class->create_surface = _gdk_x11_display_create_surface;
   display_class->get_keymap = gdk_x11_display_get_keymap;
   display_class->text_property_to_utf8_list = _gdk_x11_display_text_property_to_utf8_list;
   display_class->utf8_to_string_target = _gdk_x11_display_utf8_to_string_target;
diff --git a/gdk/x11/gdkdrag-x11.c b/gdk/x11/gdkdrag-x11.c
index 8c1e9869ea..65b2b71075 100644
--- a/gdk/x11/gdkdrag-x11.c
+++ b/gdk/x11/gdkdrag-x11.c
@@ -33,6 +33,7 @@
 #include "gdkdeviceprivate.h"
 #include "gdkdisplay-x11.h"
 #include "gdkdragprivate.h"
+#include "gdksurfaceprivate.h"
 #include "gdkinternals.h"
 #include "gdkintl.h"
 #include "gdkproperty.h"
@@ -532,14 +533,14 @@ gdk_surface_cache_new (GdkDisplay *display)
     {
       GList *toplevel_windows, *list;
       GdkSurface *surface;
-      GdkSurfaceImplX11 *impl;
+      GdkX11Surface *impl;
       gint x, y, width, height;
 
       toplevel_windows = gdk_x11_display_get_toplevel_windows (display);
       for (list = toplevel_windows; list; list = list->next)
         {
           surface = GDK_SURFACE (list->data);
-         impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+         impl = GDK_X11_SURFACE (surface);
           gdk_surface_get_geometry (surface, &x, &y, &width, &height);
           gdk_surface_cache_add (result, GDK_SURFACE_XID (surface),
                                 x * impl->surface_scale, y * impl->surface_scale, 
@@ -1401,11 +1402,11 @@ drag_find_window_cache (GdkX11Drag *drag_x11,
 }
 
 static Window
-gdk_x11_drag_find_surface (GdkDrag  *drag,
-                                   GdkSurface       *drag_surface,
-                                   gint             x_root,
-                                   gint             y_root,
-                                   GdkDragProtocol *protocol)
+gdk_x11_drag_find_surface (GdkDrag         *drag,
+                           GdkSurface      *drag_surface,
+                           gint             x_root,
+                           gint             y_root,
+                           GdkDragProtocol *protocol)
 {
   GdkX11Screen *screen_x11;
   GdkX11Drag *drag_x11 = GDK_X11_DRAG (drag);
@@ -1420,7 +1421,7 @@ gdk_x11_drag_find_surface (GdkDrag  *drag,
   window_cache = drag_find_window_cache (drag_x11, display);
 
   dest = get_client_window_at_coords (window_cache,
-                                      drag_surface && GDK_SURFACE_IS_X11 (drag_surface) ?
+                                      drag_surface && GDK_IS_X11_SURFACE (drag_surface) ?
                                       GDK_SURFACE_XID (drag_surface) : None,
                                       x_root * screen_x11->surface_scale,
                                      y_root * screen_x11->surface_scale);
diff --git a/gdk/x11/gdkdrop-x11.c b/gdk/x11/gdkdrop-x11.c
index bb5fbef238..7c8712c09f 100644
--- a/gdk/x11/gdkdrop-x11.c
+++ b/gdk/x11/gdkdrop-x11.c
@@ -621,7 +621,7 @@ static gboolean
 xdnd_position_filter (GdkSurface   *surface,
                       const XEvent *xevent)
 {
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
   Window source_window = xevent->xclient.data.l[0];
   gint16 x_root = xevent->xclient.data.l[2] >> 16;
   gint16 y_root = xevent->xclient.data.l[2] & 0xffff;
@@ -647,7 +647,7 @@ xdnd_position_filter (GdkSurface   *surface,
   if ((drop != NULL) &&
       (drop_x11->source_window == source_window))
     {
-      impl = GDK_SURFACE_IMPL_X11 (gdk_drop_get_surface (drop)->impl);
+      impl = GDK_X11_SURFACE (gdk_drop_get_surface (drop));
 
       drop_x11->suggested_action = xdnd_action_from_atom (display, action);
       gdk_x11_drop_update_actions (drop_x11);
diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c
index 5de9d55cf0..b95a18517c 100644
--- a/gdk/x11/gdkglcontext-x11.c
+++ b/gdk/x11/gdkglcontext-x11.c
@@ -410,7 +410,7 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *paint_context,
 
   GDK_DISPLAY_NOTE (GDK_DISPLAY (display_x11), OPENGL, g_message ("Using GLX_EXT_texture_from_pixmap to draw 
surface"));
 
-  surface = gdk_gl_context_get_surface (paint_context)->impl_surface;
+  surface = gdk_gl_context_get_surface (paint_context);
   surface_scale = gdk_surface_get_scale_factor (surface);
   gdk_surface_get_unscaled_size (surface, NULL, &unscaled_surface_height);
 
@@ -679,7 +679,7 @@ gdk_x11_gl_context_realize (GdkGLContext  *context,
 
   xvisinfo = find_xvisinfo_for_fbconfig (display, context_x11->glx_config);
 
-  info = get_glx_drawable_info (surface->impl_surface);
+  info = get_glx_drawable_info (surface);
   if (info == NULL)
     {
       XSetWindowAttributes attrs;
@@ -708,7 +708,7 @@ gdk_x11_gl_context_realize (GdkGLContext  *context,
       if (GDK_X11_DISPLAY (display)->glx_version >= 13)
         {
           info->glx_drawable = glXCreateWindow (dpy, context_x11->glx_config,
-                                                gdk_x11_surface_get_xid (surface->impl_surface),
+                                                gdk_x11_surface_get_xid (surface),
                                                 NULL);
           info->dummy_glx = glXCreateWindow (dpy, context_x11->glx_config, info->dummy_xwin, NULL);
         }
@@ -727,12 +727,12 @@ gdk_x11_gl_context_realize (GdkGLContext  *context,
           return FALSE;
         }
 
-      set_glx_drawable_info (surface->impl_surface, info);
+      set_glx_drawable_info (surface, info);
     }
 
   XFree (xvisinfo);
 
-  context_x11->attached_drawable = info->glx_drawable ? info->glx_drawable : gdk_x11_surface_get_xid 
(surface->impl_surface);
+  context_x11->attached_drawable = info->glx_drawable ? info->glx_drawable : gdk_x11_surface_get_xid 
(surface);
   context_x11->unattached_drawable = info->dummy_glx ? info->dummy_glx : info->dummy_xwin;
 
   context_x11->is_direct = glXIsDirect (dpy, context_x11->glx_context);
diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h
index 345439fb8c..05b8c1f7df 100644
--- a/gdk/x11/gdkprivate-x11.h
+++ b/gdk/x11/gdkprivate-x11.h
@@ -176,9 +176,14 @@ void       _gdk_x11_display_get_default_cursor_size (GdkDisplay *display,
 void       _gdk_x11_display_get_maximal_cursor_size (GdkDisplay *display,
                                                      guint      *width,
                                                      guint      *height);
-void       _gdk_x11_display_create_surface_impl     (GdkDisplay    *display,
-                                                     GdkSurface     *window,
-                                                     GdkSurface     *real_parent);
+
+GdkSurface * _gdk_x11_display_create_surface (GdkDisplay     *display,
+                                              GdkSurfaceType  surface_type,
+                                              GdkSurface     *parent,
+                                              int             x,
+                                              int             y,
+                                              int             width,
+                                              int             height);
 GList *    gdk_x11_display_get_toplevel_windows     (GdkDisplay *display);
 
 void _gdk_x11_precache_atoms (GdkDisplay          *display,
@@ -240,7 +245,6 @@ extern const gint        _gdk_x11_event_mask_table_size;
 #define GDK_SURFACE_SCREEN(win)        (GDK_X11_DISPLAY (gdk_surface_get_display (win))->screen)
 #define GDK_SURFACE_DISPLAY(win)       (gdk_surface_get_display (win))
 #define GDK_SURFACE_XROOTWIN(win)      (GDK_X11_SCREEN (GDK_SURFACE_SCREEN (win))->xroot_window)
-#define GDK_SURFACE_IS_X11(win)        (GDK_IS_SURFACE_IMPL_X11 ((win)->impl))
 
 /* override some macros from gdkx.h with direct-access variants */
 #undef GDK_DISPLAY_XDISPLAY
@@ -250,7 +254,7 @@ extern const gint        _gdk_x11_event_mask_table_size;
 
 #define GDK_DISPLAY_XDISPLAY(display) (GDK_X11_DISPLAY(display)->xdisplay)
 #define GDK_SURFACE_XDISPLAY(win)      (GDK_X11_SCREEN (GDK_SURFACE_SCREEN (win))->xdisplay)
-#define GDK_SURFACE_XID(win)           (GDK_SURFACE_IMPL_X11(GDK_SURFACE (win)->impl)->xid)
+#define GDK_SURFACE_XID(win)           (GDK_X11_SURFACE (win)->xid)
 #define GDK_SCREEN_XDISPLAY(screen)   (GDK_X11_SCREEN (screen)->xdisplay)
 
 #endif /* __GDK_PRIVATE_X11_H__ */
diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c
index 11c9d97755..87b2fd7804 100644
--- a/gdk/x11/gdksurface-x11.c
+++ b/gdk/x11/gdksurface-x11.c
@@ -27,12 +27,11 @@
 
 #include "gdksurface-x11.h"
 
-#include "gdksurface.h"
-#include "gdksurfaceimpl.h"
+#include "gdksurfaceprivate.h"
 #include "gdkvisual-x11.h"
 #include "gdkinternals.h"
 #include "gdkdeviceprivate.h"
-#include "gdkframeclockprivate.h"
+#include "gdkframeclockidleprivate.h"
 #include "gdkasync.h"
 #include "gdkeventsource.h"
 #include "gdkdisplay-x11.h"
@@ -108,8 +107,6 @@ static void     set_wm_name                       (GdkDisplay  *display,
                                                   const gchar *name);
 static void     move_to_current_desktop           (GdkSurface *surface);
 
-static void        gdk_surface_impl_x11_finalize   (GObject            *object);
-
 #define SURFACE_IS_TOPLEVEL(surface)                      \
   (GDK_SURFACE_TYPE (surface) == GDK_SURFACE_TOPLEVEL ||   \
    GDK_SURFACE_TYPE (surface) == GDK_SURFACE_TEMP)
@@ -122,31 +119,10 @@ static void        gdk_surface_impl_x11_finalize   (GObject            *object);
     (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 ))     \
   )
 
-struct _GdkX11Surface {
-  GdkSurface parent;
-};
-
-struct _GdkX11SurfaceClass {
-  GdkSurfaceClass parent_class;
-};
-
 G_DEFINE_TYPE (GdkX11Surface, gdk_x11_surface, GDK_TYPE_SURFACE)
 
 static void
-gdk_x11_surface_class_init (GdkX11SurfaceClass *x11_surface_class)
-{
-}
-
-static void
-gdk_x11_surface_init (GdkX11Surface *x11_surface)
-{
-}
-
-
-G_DEFINE_TYPE (GdkSurfaceImplX11, gdk_surface_impl_x11, GDK_TYPE_SURFACE_IMPL)
-
-static void
-gdk_surface_impl_x11_init (GdkSurfaceImplX11 *impl)
+gdk_x11_surface_init (GdkX11Surface *impl)
 {  
   impl->surface_scale = 1;
   impl->frame_sync_enabled = TRUE;
@@ -155,14 +131,14 @@ gdk_surface_impl_x11_init (GdkSurfaceImplX11 *impl)
 GdkToplevelX11 *
 _gdk_x11_surface_get_toplevel (GdkSurface *surface)
 {
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
   
   g_return_val_if_fail (GDK_IS_SURFACE (surface), NULL);
 
   if (!SURFACE_IS_TOPLEVEL (surface))
     return NULL;
 
-  impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  impl = GDK_X11_SURFACE (surface);
 
   if (!impl->toplevel)
     {
@@ -175,13 +151,13 @@ _gdk_x11_surface_get_toplevel (GdkSurface *surface)
 
 /**
  * _gdk_x11_surface_update_size:
- * @impl: a #GdkSurfaceImplX11.
+ * @impl: a #GdkX11Surface.
  * 
  * Updates the state of the surface (in particular the drawable's
  * cairo surface) when its size has changed.
  **/
 void
-_gdk_x11_surface_update_size (GdkSurfaceImplX11 *impl)
+_gdk_x11_surface_update_size (GdkX11Surface *impl)
 {
   if (impl->cairo_surface)
     {
@@ -195,7 +171,7 @@ gdk_x11_surface_get_unscaled_size (GdkSurface *surface,
                                   int *unscaled_width,
                                   int *unscaled_height)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
 
   if (unscaled_width)
     *unscaled_width = impl->unscaled_width;
@@ -228,18 +204,18 @@ void
 gdk_x11_surface_pre_damage (GdkSurface *surface)
 {
   GdkSurface *toplevel_surface = surface;
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
 
   if (!toplevel_surface || !SURFACE_IS_TOPLEVEL (toplevel_surface))
     return;
 
-  impl = GDK_SURFACE_IMPL_X11 (toplevel_surface->impl);
+  impl = GDK_X11_SURFACE (toplevel_surface);
 
   if (impl->toplevel->in_frame &&
       impl->toplevel->current_counter_value % 2 == 0)
     {
       impl->toplevel->current_counter_value += 1;
-      set_sync_counter (GDK_SURFACE_XDISPLAY (impl->wrapper),
+      set_sync_counter (GDK_SURFACE_XDISPLAY (surface),
                        impl->toplevel->extended_update_counter,
                         impl->toplevel->current_counter_value);
     }
@@ -249,7 +225,7 @@ static void
 on_surface_changed (void *data)
 {
   GdkSurface *surface = data;
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
 
   if (impl->tracking_damage)
     gdk_x11_surface_pre_damage (surface);
@@ -267,7 +243,7 @@ on_surface_changed (void *data)
 static void
 hook_surface_changed (GdkSurface *surface)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
 
   if (impl->cairo_surface)
     {
@@ -284,7 +260,7 @@ hook_surface_changed (GdkSurface *surface)
 static void
 unhook_surface_changed (GdkSurface *surface)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
 
   if (impl->cairo_surface)
     {
@@ -299,7 +275,7 @@ unhook_surface_changed (GdkSurface *surface)
 static void
 gdk_x11_surface_predict_presentation_time (GdkSurface *surface)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
   GdkFrameClock *clock;
   GdkFrameTimings *timings;
   gint64 presentation_time;
@@ -346,11 +322,11 @@ static void
 gdk_x11_surface_begin_frame (GdkSurface *surface,
                             gboolean   force_frame)
 {
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
 
   g_return_if_fail (GDK_IS_SURFACE (surface));
 
-  impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  impl = GDK_X11_SURFACE (surface);
 
   if (!SURFACE_IS_TOPLEVEL (surface) ||
       impl->toplevel->extended_update_counter == None)
@@ -387,11 +363,11 @@ gdk_x11_surface_end_frame (GdkSurface *surface)
 {
   GdkFrameClock *clock;
   GdkFrameTimings *timings;
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
 
   g_return_if_fail (GDK_IS_SURFACE (surface));
 
-  impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  impl = GDK_X11_SURFACE (surface);
 
   if (!SURFACE_IS_TOPLEVEL (surface) ||
       impl->toplevel->extended_update_counter == None ||
@@ -428,7 +404,7 @@ gdk_x11_surface_end_frame (GdkSurface *surface)
       else
         impl->toplevel->current_counter_value += 1;
 
-      set_sync_counter(GDK_SURFACE_XDISPLAY (impl->wrapper),
+      set_sync_counter(GDK_SURFACE_XDISPLAY (surface),
                       impl->toplevel->extended_update_counter,
                       impl->toplevel->current_counter_value);
 
@@ -463,25 +439,22 @@ gdk_x11_surface_end_frame (GdkSurface *surface)
  *****************************************************/
 
 static void
-gdk_surface_impl_x11_finalize (GObject *object)
+gdk_x11_surface_finalize (GObject *object)
 {
-  GdkSurface *wrapper;
-  GdkSurfaceImplX11 *impl;
-
-  g_return_if_fail (GDK_IS_SURFACE_IMPL_X11 (object));
+  GdkX11Surface *impl;
 
-  impl = GDK_SURFACE_IMPL_X11 (object);
+  g_return_if_fail (GDK_IS_X11_SURFACE (object));
 
-  wrapper = impl->wrapper;
+  impl = GDK_X11_SURFACE (object);
 
-  if (SURFACE_IS_TOPLEVEL (wrapper) && impl->toplevel->in_frame)
-    unhook_surface_changed (wrapper);
+  if (SURFACE_IS_TOPLEVEL (impl) && impl->toplevel->in_frame)
+    unhook_surface_changed (GDK_SURFACE (impl));
 
-  _gdk_x11_surface_grab_check_destroy (wrapper);
+  _gdk_x11_surface_grab_check_destroy (GDK_SURFACE (impl));
 
-  if (!GDK_SURFACE_DESTROYED (wrapper))
+  if (!GDK_SURFACE_DESTROYED (impl))
     {
-      GdkDisplay *display = GDK_SURFACE_DISPLAY (wrapper);
+      GdkDisplay *display = GDK_SURFACE_DISPLAY (GDK_SURFACE (impl));
 
       _gdk_x11_display_remove_window (display, impl->xid);
       if (impl->toplevel && impl->toplevel->focus_window)
@@ -493,7 +466,7 @@ gdk_surface_impl_x11_finalize (GObject *object)
   if (impl->cursor)
     g_object_unref (impl->cursor);
 
-  G_OBJECT_CLASS (gdk_surface_impl_x11_parent_class)->finalize (object);
+  G_OBJECT_CLASS (gdk_x11_surface_parent_class)->finalize (object);
 }
 
 typedef struct {
@@ -708,7 +681,7 @@ setup_toplevel_window (GdkSurface    *surface,
                       GdkX11Screen *x11_screen)
 {
   GdkToplevelX11 *toplevel = _gdk_x11_surface_get_toplevel (surface);
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
   GdkDisplay *display = gdk_surface_get_display (surface);
   Display *xdisplay = GDK_SURFACE_XDISPLAY (surface);
   XID xid = GDK_SURFACE_XID (surface);
@@ -795,9 +768,9 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
 static void
 connect_frame_clock (GdkSurface *surface)
 {
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
 
-  impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  impl = GDK_X11_SURFACE (surface);
   if (SURFACE_IS_TOPLEVEL (surface) && !impl->frame_clock_connected)
     {
       GdkFrameClock *frame_clock = gdk_surface_get_frame_clock (surface);
@@ -811,12 +784,18 @@ connect_frame_clock (GdkSurface *surface)
     }
 }
 
-void
-_gdk_x11_display_create_surface_impl (GdkDisplay    *display,
-                                      GdkSurface     *surface,
-                                      GdkSurface     *real_parent)
+GdkSurface *
+_gdk_x11_display_create_surface (GdkDisplay     *display,
+                                 GdkSurfaceType  surface_type,
+                                 GdkSurface     *parent,
+                                 int             x,
+                                 int             y,
+                                 int             width,
+                                 int             height)
 {
-  GdkSurfaceImplX11 *impl;
+  GdkSurface *surface;
+  GdkFrameClock *frame_clock;
+  GdkX11Surface *impl;
   GdkX11Screen *x11_screen;
   GdkX11Display *display_x11;
 
@@ -836,14 +815,27 @@ _gdk_x11_display_create_surface_impl (GdkDisplay    *display,
 
   display_x11 = GDK_X11_DISPLAY (display);
   x11_screen = GDK_X11_SCREEN (display_x11->screen);
-  if (real_parent)
-    xparent = GDK_SURFACE_XID (real_parent);
+  if (parent)
+    xparent = GDK_SURFACE_XID (parent);
   else
     xparent = GDK_SCREEN_XROOTWIN (x11_screen);
 
-  impl = g_object_new (GDK_TYPE_SURFACE_IMPL_X11, NULL);
-  surface->impl = GDK_SURFACE_IMPL (impl);
-  impl->wrapper = GDK_SURFACE (surface);
+  frame_clock = _gdk_frame_clock_idle_new ();
+
+  surface = g_object_new (GDK_TYPE_X11_SURFACE,
+                          "display", display,
+                          "frame-clock", frame_clock,
+                          NULL);
+
+  g_object_unref (frame_clock);
+
+  surface->surface_type = surface_type;
+  surface->x = x;
+  surface->y = y;
+  surface->width = width;
+  surface->height = height;
+
+  impl = GDK_X11_SURFACE (surface);
   impl->surface_scale = x11_screen->surface_scale;
 
   xdisplay = x11_screen->xdisplay;
@@ -933,6 +925,8 @@ _gdk_x11_display_create_surface_impl (GdkDisplay    *display,
   connect_frame_clock (surface);
 
   gdk_surface_freeze_toplevel_updates (surface);
+
+  return surface;
 }
 
 static void
@@ -973,7 +967,7 @@ static void
 gdk_x11_surface_destroy (GdkSurface *surface,
                          gboolean    foreign_destroy)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
   GdkToplevelX11 *toplevel;
 
   g_return_if_fail (GDK_IS_SURFACE (surface));
@@ -1000,9 +994,9 @@ gdk_x11_surface_destroy (GdkSurface *surface,
 static void
 gdk_x11_surface_destroy_notify (GdkSurface *surface)
 {
-  GdkSurfaceImplX11 *surface_impl;
+  GdkX11Surface *surface_impl;
 
-  surface_impl = GDK_SURFACE_IMPL_X11 ((surface)->impl);
+  surface_impl = GDK_X11_SURFACE (surface);
 
   if (!GDK_SURFACE_DESTROYED (surface))
     {
@@ -1202,7 +1196,7 @@ set_initial_hints (GdkSurface *surface)
 }
 
 static void
-gdk_surface_x11_show (GdkSurface *surface, gboolean already_mapped)
+gdk_x11_surface_show (GdkSurface *surface, gboolean already_mapped)
 {
   GdkDisplay *display;
   GdkX11Display *display_x11;
@@ -1236,7 +1230,7 @@ gdk_surface_x11_show (GdkSurface *surface, gboolean already_mapped)
 }
 
 static void
-gdk_surface_x11_withdraw (GdkSurface *surface)
+gdk_x11_surface_withdraw (GdkSurface *surface)
 {
   if (!surface->destroyed)
     {
@@ -1253,7 +1247,7 @@ gdk_surface_x11_withdraw (GdkSurface *surface)
 }
 
 static void
-gdk_surface_x11_hide (GdkSurface *surface)
+gdk_x11_surface_hide (GdkSurface *surface)
 {
   /* We'll get the unmap notify eventually, and handle it then,
    * but checking here makes things more consistent if we are
@@ -1267,7 +1261,7 @@ gdk_surface_x11_hide (GdkSurface *surface)
     {
     case GDK_SURFACE_TOPLEVEL:
     case GDK_SURFACE_TEMP: /* ? */
-      gdk_surface_x11_withdraw (surface);
+      gdk_x11_surface_withdraw (surface);
       return;
       
     default:
@@ -1281,11 +1275,11 @@ gdk_surface_x11_hide (GdkSurface *surface)
 }
 
 static inline void
-surface_x11_move (GdkSurface *surface,
+x11_surface_move (GdkSurface *surface,
                  gint       x,
                  gint       y)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
 
   XMoveWindow (GDK_SURFACE_XDISPLAY (surface),
                GDK_SURFACE_XID (surface),
@@ -1299,11 +1293,11 @@ surface_x11_move (GdkSurface *surface,
 }
 
 static inline void
-surface_x11_resize (GdkSurface *surface,
+x11_surface_resize (GdkSurface *surface,
                    gint       width,
                    gint       height)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
 
   if (width < 1)
     width = 1;
@@ -1323,7 +1317,7 @@ surface_x11_resize (GdkSurface *surface,
       impl->unscaled_height = height * impl->surface_scale;
       surface->width = width;
       surface->height = height;
-      _gdk_x11_surface_update_size (GDK_SURFACE_IMPL_X11 (surface->impl));
+      _gdk_x11_surface_update_size (GDK_X11_SURFACE (surface));
     }
   else
     {
@@ -1333,13 +1327,13 @@ surface_x11_resize (GdkSurface *surface,
 }
 
 static inline void
-surface_x11_move_resize (GdkSurface *surface,
+x11_surface_move_resize (GdkSurface *surface,
                         gint       x,
                         gint       y,
                         gint       width,
                         gint       height)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
 
   if (width < 1)
     width = 1;
@@ -1364,7 +1358,7 @@ surface_x11_move_resize (GdkSurface *surface,
       surface->width = width;
       surface->height = height;
 
-      _gdk_x11_surface_update_size (GDK_SURFACE_IMPL_X11 (surface->impl));
+      _gdk_x11_surface_update_size (GDK_X11_SURFACE (surface));
     }
   else
     {
@@ -1374,7 +1368,7 @@ surface_x11_move_resize (GdkSurface *surface,
 }
 
 static void
-gdk_surface_x11_move_resize (GdkSurface *surface,
+gdk_x11_surface_move_resize (GdkSurface *surface,
                             gboolean   with_move,
                             gint       x,
                             gint       y,
@@ -1382,13 +1376,13 @@ gdk_surface_x11_move_resize (GdkSurface *surface,
                             gint       height)
 {
   if (with_move && (width < 0 && height < 0))
-    surface_x11_move (surface, x, y);
+    x11_surface_move (surface, x, y);
   else
     {
       if (with_move)
-        surface_x11_move_resize (surface, x, y, width, height);
+        x11_surface_move_resize (surface, x, y, width, height);
       else
-        surface_x11_resize (surface, width, height);
+        x11_surface_resize (surface, width, height);
     }
 }
 
@@ -1396,11 +1390,11 @@ void
 _gdk_x11_surface_set_surface_scale (GdkSurface *surface,
                                  int scale)
 {
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
   GdkToplevelX11 *toplevel;
   GdkSurfaceHints geom_mask;
 
-  impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  impl = GDK_X11_SURFACE (surface);
 
   impl->surface_scale = scale;
   if (impl->cairo_surface)
@@ -1434,13 +1428,13 @@ _gdk_x11_surface_set_surface_scale (GdkSurface *surface,
 }
 
 static void
-gdk_surface_x11_raise (GdkSurface *surface)
+gdk_x11_surface_raise (GdkSurface *surface)
 {
   XRaiseWindow (GDK_SURFACE_XDISPLAY (surface), GDK_SURFACE_XID (surface));
 }
 
 static void
-gdk_surface_x11_restack_toplevel (GdkSurface *surface,
+gdk_x11_surface_restack_toplevel (GdkSurface *surface,
                                 GdkSurface *sibling,
                                 gboolean   above)
 {
@@ -1455,7 +1449,7 @@ gdk_surface_x11_restack_toplevel (GdkSurface *surface,
 }
 
 static void
-gdk_surface_x11_lower (GdkSurface *surface)
+gdk_x11_surface_lower (GdkSurface *surface)
 {
   XLowerWindow (GDK_SURFACE_XDISPLAY (surface), GDK_SURFACE_XID (surface));
 }
@@ -1899,7 +1893,7 @@ gdk_x11_surface_set_geometry_hints (GdkSurface         *surface,
                                   const GdkGeometry *geometry,
                                   GdkSurfaceHints     geom_mask)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
   XSizeHints size_hints;
   GdkToplevelX11 *toplevel;
 
@@ -2016,7 +2010,7 @@ gdk_surface_get_geometry_hints (GdkSurface      *surface,
                                GdkGeometry    *geometry,
                                GdkSurfaceHints *geom_mask)
 {
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
   XSizeHints *size_hints;  
   glong junk_supplied_mask = 0;
 
@@ -2030,7 +2024,7 @@ gdk_surface_get_geometry_hints (GdkSurface      *surface,
       !SURFACE_IS_TOPLEVEL (surface))
     return;
 
-  impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  impl = GDK_X11_SURFACE (surface);
 
   size_hints = XAllocSizeHints ();
   if (!size_hints)
@@ -2244,23 +2238,23 @@ gdk_x11_surface_set_transient_for (GdkSurface *surface,
 GdkCursor *
 _gdk_x11_surface_get_cursor (GdkSurface *surface)
 {
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
   
   g_return_val_if_fail (GDK_IS_SURFACE (surface), NULL);
     
-  impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  impl = GDK_X11_SURFACE (surface);
 
   return impl->cursor;
 }
 
 static void
-gdk_surface_x11_get_geometry (GdkSurface *surface,
+gdk_x11_surface_get_geometry (GdkSurface *surface,
                              gint      *x,
                              gint      *y,
                              gint      *width,
                              gint      *height)
 {
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
   Window root;
   gint tx;
   gint ty;
@@ -2271,7 +2265,7 @@ gdk_surface_x11_get_geometry (GdkSurface *surface,
   
   if (!GDK_SURFACE_DESTROYED (surface))
     {
-      impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+      impl = GDK_X11_SURFACE (surface);
 
       XGetGeometry (GDK_SURFACE_XDISPLAY (surface),
                    GDK_SURFACE_XID (surface),
@@ -2289,13 +2283,13 @@ gdk_surface_x11_get_geometry (GdkSurface *surface,
 }
 
 static void
-gdk_surface_x11_get_root_coords (GdkSurface *surface,
+gdk_x11_surface_get_root_coords (GdkSurface *surface,
                                gint       x,
                                gint       y,
                                gint      *root_x,
                                gint      *root_y)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
   Window child;
   gint tx;
   gint ty;
@@ -2317,7 +2311,7 @@ gdk_x11_surface_get_frame_extents (GdkSurface    *surface,
                                   GdkRectangle *rect)
 {
   GdkDisplay *display;
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
   Window xwindow;
   Window xparent;
   Window root;
@@ -2343,7 +2337,7 @@ gdk_x11_surface_get_frame_extents (GdkSurface    *surface,
   rect->width = 1;
   rect->height = 1;
 
-  impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  impl = GDK_X11_SURFACE (surface);
 
   /* Refine our fallback answer a bit using local information */
   rect->x = surface->x * impl->surface_scale;
@@ -2481,7 +2475,7 @@ gdk_x11_surface_get_frame_extents (GdkSurface    *surface,
 }
 
 static gboolean
-gdk_surface_x11_get_device_state (GdkSurface       *surface,
+gdk_x11_surface_get_device_state (GdkSurface       *surface,
                                  GdkDevice       *device,
                                  gdouble         *x,
                                  gdouble         *y,
@@ -2501,13 +2495,13 @@ gdk_surface_x11_get_device_state (GdkSurface       *surface,
 }
 
 static void 
-gdk_surface_x11_input_shape_combine_region (GdkSurface           *surface,
+gdk_x11_surface_input_shape_combine_region (GdkSurface           *surface,
                                            const cairo_region_t *shape_region,
                                            gint                  offset_x,
                                            gint                  offset_y)
 {
 #ifdef ShapeInput
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
 
   if (GDK_SURFACE_DESTROYED (surface))
     return;
@@ -2689,7 +2683,7 @@ gdk_x11_surface_set_shadow_width (GdkSurface *surface,
                                  int        top,
                                  int        bottom)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
   Atom frame_extents;
   gulong data[4] = {
     left * impl->surface_scale,
@@ -3602,7 +3596,7 @@ wmspec_send_message (GdkDisplay *display,
                      gint        action,
                      gint        button)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
   XClientMessageEvent xclient;
 
   memset (&xclient, 0, sizeof (xclient));
@@ -3973,7 +3967,7 @@ _gdk_x11_moveresize_handle_event (const XEvent *event)
   guint button_mask = 0;
   GdkDisplay *display = gdk_x11_lookup_xdisplay (event->xany.display);
   MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
 
   if (!mv_resize || !mv_resize->moveresize_surface)
     {
@@ -3981,7 +3975,7 @@ _gdk_x11_moveresize_handle_event (const XEvent *event)
       return FALSE;
     }
 
-  impl = GDK_SURFACE_IMPL_X11 (mv_resize->moveresize_surface->impl);
+  impl = GDK_X11_SURFACE (mv_resize->moveresize_surface);
 
   if (mv_resize->moveresize_button != 0)
     button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1);
@@ -4294,7 +4288,7 @@ gdk_x11_surface_begin_resize_drag (GdkSurface     *surface,
       !SURFACE_IS_TOPLEVEL (surface))
     return;
 
-  gdk_surface_x11_get_root_coords (surface, x, y, &root_x, &root_y);
+  gdk_x11_surface_get_root_coords (surface, x, y, &root_x, &root_y);
 
   /* Avoid EWMH for touch devices */
   if (_should_perform_ewmh_drag (surface, device))
@@ -4322,7 +4316,7 @@ gdk_x11_surface_begin_move_drag (GdkSurface *surface,
   else
     direction = _NET_WM_MOVERESIZE_MOVE;
 
-  gdk_surface_x11_get_root_coords (surface, x, y, &root_x, &root_y);
+  gdk_x11_surface_get_root_coords (surface, x, y, &root_x, &root_y);
 
   /* Avoid EWMH for touch devices */
   if (_should_perform_ewmh_drag (surface, device))
@@ -4454,13 +4448,13 @@ gdk_x11_get_server_time (GdkSurface *surface)
 XID
 gdk_x11_surface_get_xid (GdkSurface *surface)
 {
-  return GDK_SURFACE_IMPL_X11 (surface->impl)->xid;
+  return GDK_X11_SURFACE (surface)->xid;
 }
 
 static gint
 gdk_x11_surface_get_scale_factor (GdkSurface *surface)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
 
   if (GDK_SURFACE_DESTROYED (surface))
     return 1;
@@ -4484,14 +4478,14 @@ void
 gdk_x11_surface_set_frame_sync_enabled (GdkSurface *surface,
                                        gboolean   frame_sync_enabled)
 {
-  GDK_SURFACE_IMPL_X11 (surface->impl)->frame_sync_enabled = FALSE;
+  GDK_X11_SURFACE (surface)->frame_sync_enabled = FALSE;
 }
 
 static void
 gdk_x11_surface_set_opaque_region (GdkSurface      *surface,
                                   cairo_region_t *region)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
   GdkDisplay *display;
   int nitems;
   gulong *data;
@@ -4538,7 +4532,7 @@ static gboolean
 gdk_x11_surface_show_window_menu (GdkSurface *surface,
                                   GdkEvent   *event)
 {
-  GdkSurfaceImplX11 *impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+  GdkX11Surface *impl = GDK_X11_SURFACE (surface);
   GdkDisplay *display = GDK_SURFACE_DISPLAY (surface);
   GdkDevice *device;
   int device_id;
@@ -4560,7 +4554,7 @@ gdk_x11_surface_show_window_menu (GdkSurface *surface,
     return FALSE;
 
   gdk_event_get_coords (event, &x, &y);
-  gdk_surface_x11_get_root_coords (surface, x, y, &x_root, &y_root);
+  gdk_x11_surface_get_root_coords (surface, x, y, &x_root, &y_root);
   device = gdk_event_get_device (event);
   g_object_get (G_OBJECT (device),
                 "device-id", &device_id,
@@ -4585,24 +4579,24 @@ gdk_x11_surface_show_window_menu (GdkSurface *surface,
 }
 
 static void
-gdk_surface_impl_x11_class_init (GdkSurfaceImplX11Class *klass)
+gdk_x11_surface_class_init (GdkX11SurfaceClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  GdkSurfaceImplClass *impl_class = GDK_SURFACE_IMPL_CLASS (klass);
+  GdkSurfaceClass *impl_class = GDK_SURFACE_CLASS (klass);
   
-  object_class->finalize = gdk_surface_impl_x11_finalize;
+  object_class->finalize = gdk_x11_surface_finalize;
   
-  impl_class->show = gdk_surface_x11_show;
-  impl_class->hide = gdk_surface_x11_hide;
-  impl_class->withdraw = gdk_surface_x11_withdraw;
-  impl_class->raise = gdk_surface_x11_raise;
-  impl_class->lower = gdk_surface_x11_lower;
-  impl_class->restack_toplevel = gdk_surface_x11_restack_toplevel;
-  impl_class->move_resize = gdk_surface_x11_move_resize;
-  impl_class->get_geometry = gdk_surface_x11_get_geometry;
-  impl_class->get_root_coords = gdk_surface_x11_get_root_coords;
-  impl_class->get_device_state = gdk_surface_x11_get_device_state;
-  impl_class->input_shape_combine_region = gdk_surface_x11_input_shape_combine_region;
+  impl_class->show = gdk_x11_surface_show;
+  impl_class->hide = gdk_x11_surface_hide;
+  impl_class->withdraw = gdk_x11_surface_withdraw;
+  impl_class->raise = gdk_x11_surface_raise;
+  impl_class->lower = gdk_x11_surface_lower;
+  impl_class->restack_toplevel = gdk_x11_surface_restack_toplevel;
+  impl_class->move_resize = gdk_x11_surface_move_resize;
+  impl_class->get_geometry = gdk_x11_surface_get_geometry;
+  impl_class->get_root_coords = gdk_x11_surface_get_root_coords;
+  impl_class->get_device_state = gdk_x11_surface_get_device_state;
+  impl_class->input_shape_combine_region = gdk_x11_surface_input_shape_combine_region;
   impl_class->destroy = gdk_x11_surface_destroy;
   impl_class->beep = gdk_x11_surface_beep;
 
diff --git a/gdk/x11/gdksurface-x11.h b/gdk/x11/gdksurface-x11.h
index 07c67d6666..6ffdbf24e6 100644
--- a/gdk/x11/gdksurface-x11.h
+++ b/gdk/x11/gdksurface-x11.h
@@ -22,11 +22,11 @@
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
-#ifndef __GDK_SURFACE_X11_H__
-#define __GDK_SURFACE_X11_H__
+#ifndef __GDK_X11_SURFACE__
+#define __GDK_X11_SURFACE__
 
-#include "gdk/x11/gdkprivate-x11.h"
-#include "gdk/gdksurfaceimpl.h"
+#include "gdksurfaceprivate.h"
+#include "gdkx11surface.h"
 
 #include <X11/Xlib.h>
 
@@ -42,25 +42,11 @@
 G_BEGIN_DECLS
 
 typedef struct _GdkToplevelX11 GdkToplevelX11;
-typedef struct _GdkSurfaceImplX11 GdkSurfaceImplX11;
-typedef struct _GdkSurfaceImplX11Class GdkSurfaceImplX11Class;
 typedef struct _GdkXPositionInfo GdkXPositionInfo;
 
-/* Window implementation for X11
- */
-
-#define GDK_TYPE_SURFACE_IMPL_X11              (gdk_surface_impl_x11_get_type ())
-#define GDK_SURFACE_IMPL_X11(object)           (G_TYPE_CHECK_INSTANCE_CAST ((object), 
GDK_TYPE_SURFACE_IMPL_X11, GdkSurfaceImplX11))
-#define GDK_SURFACE_IMPL_X11_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_SURFACE_IMPL_X11, 
GdkSurfaceImplX11Class))
-#define GDK_IS_SURFACE_IMPL_X11(object)        (G_TYPE_CHECK_INSTANCE_TYPE ((object), 
GDK_TYPE_SURFACE_IMPL_X11))
-#define GDK_IS_SURFACE_IMPL_X11_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_SURFACE_IMPL_X11))
-#define GDK_SURFACE_IMPL_X11_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_SURFACE_IMPL_X11, 
GdkSurfaceImplX11Class))
-
-struct _GdkSurfaceImplX11
+struct _GdkX11Surface
 {
-  GdkSurfaceImpl parent_instance;
-
-  GdkSurface *wrapper;
+  GdkSurface parent_instance;
 
   Window xid;
 
@@ -91,9 +77,9 @@ struct _GdkSurfaceImplX11
 #endif
 };
  
-struct _GdkSurfaceImplX11Class 
+struct _GdkX11SurfaceClass 
 {
-  GdkSurfaceImplClass parent_class;
+  GdkSurfaceClass parent_class;
 };
 
 struct _GdkToplevelX11
@@ -184,13 +170,11 @@ struct _GdkToplevelX11
 #endif
 };
 
-GType gdk_surface_impl_x11_get_type (void);
-
 GdkToplevelX11 *_gdk_x11_surface_get_toplevel        (GdkSurface *window);
 
 GdkCursor      *_gdk_x11_surface_get_cursor          (GdkSurface *window);
 
-void            _gdk_x11_surface_update_size         (GdkSurfaceImplX11 *impl);
+void            _gdk_x11_surface_update_size         (GdkX11Surface *impl);
 void            _gdk_x11_surface_set_surface_scale   (GdkSurface *window,
                                                       int        scale);
 
@@ -198,4 +182,4 @@ void            gdk_x11_surface_pre_damage           (GdkSurface *surface);
 
 G_END_DECLS
 
-#endif /* __GDK_SURFACE_X11_H__ */
+#endif /* __GDK_X11_SURFACE__ */



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