[gtk/wip/matthiasc/popup4: 85/105] Get rid of GdkSurfaceImpl



commit 1ad8b2bd6ae5078a0f1817bf2297793d8d1ce613
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                    | 570 ++++++++++++++++++++++++------------
 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    | 405 ++++++++++++-------------
 gdk/x11/gdkcairocontext-x11.c       |   1 +
 gdk/x11/gdkdevice-core-x11.c        |  21 +-
 gdk/x11/gdkdevice-xi2.c             |   6 +-
 gdk/x11/gdkdevicemanager-core-x11.c |   5 +-
 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.             |   0
 gdk/x11/gdksurface-x11.c            | 264 ++++++++---------
 gdk/x11/gdksurface-x11.h            |  36 +--
 34 files changed, 1117 insertions(+), 1475 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 0eb9519982..53d74a461e 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;
 
@@ -157,10 +130,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);
@@ -175,7 +148,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;
@@ -200,29 +173,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,
@@ -230,7 +220,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);
@@ -238,15 +227,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);
@@ -254,14 +243,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);
@@ -279,15 +268,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));
 
@@ -318,13 +307,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 ? */
@@ -336,12 +325,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 ? */
@@ -358,20 +347,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;
 
@@ -415,19 +404,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)
 {
 }
 
@@ -436,7 +425,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));
@@ -445,7 +434,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);
@@ -470,26 +459,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)
 {
 }
@@ -499,66 +488,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);
@@ -572,7 +553,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,
@@ -593,7 +574,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)
@@ -680,7 +661,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;
@@ -689,7 +670,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;
@@ -715,13 +696,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;
@@ -1185,9 +1166,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))
@@ -1204,8 +1185,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);
@@ -1228,9 +1209,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))
@@ -1246,8 +1227,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);
@@ -1293,25 +1274,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 96952567e9..d5358917b6 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"
 
@@ -115,79 +115,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 2f53f12b31..5cb326449a 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);
 
@@ -407,7 +665,7 @@ gdk_surface_set_property (GObject      *object,
       break;
 
     case PROP_FRAME_CLOCK:
-      gdk_surface_set_frame_clock (surface, GDK_FRAME_CLOCK (g_value_get_object (value));
+      gdk_surface_set_frame_clock (surface, GDK_FRAME_CLOCK (g_value_get_object (value)));
       break;
 
     default:
@@ -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);
+  surface = gdk_display_create_surface (display,
+                                        surface_type,
+                                        parent,
+                                        x, y, width, height);
 
-  gdk_display_create_surface_impl (display, surface, parent);
-  surface->impl_surface = surface;
-
-  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;
 }
@@ -609,7 +847,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));
@@ -635,8 +872,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;
@@ -840,40 +1076,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;
 }
 
 /**
@@ -906,7 +1139,7 @@ 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,
+  return GDK_SURFACE_GET_CLASS (surface)->create_gl_context (surface,
                                                                         FALSE,
                                                                         paint_context,
                                                                         error);
@@ -1086,7 +1319,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;
@@ -1266,7 +1498,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++;
 }
 
 /**
@@ -1278,16 +1510,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 (surface->update_freeze_count > 0);
 
-  g_return_if_fail (impl_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
@@ -1468,10 +1696,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;
@@ -1484,10 +1712,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 */
@@ -1512,7 +1737,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;
 
@@ -1531,8 +1755,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)
     {
@@ -1585,10 +1808,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);
 }
 
 /**
@@ -1640,8 +1860,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));
 
@@ -1657,8 +1875,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);
 }
 
 
@@ -1694,7 +1911,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));
@@ -1740,8 +1956,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
@@ -1752,10 +1967,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);
 }
 
 
@@ -1883,20 +2095,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
@@ -2098,15 +2307,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);
 }
 
 /**
@@ -2199,8 +2405,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))
@@ -2210,9 +2414,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);
 }
 
 /**
@@ -2245,8 +2447,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))
@@ -2263,8 +2463,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
@@ -2434,7 +2633,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);
@@ -2838,7 +3037,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);
 }
 
 /**
@@ -2857,7 +3056,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);
 }
 
 /**
@@ -2871,7 +3070,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);
 }
 
 /**
@@ -2891,7 +3090,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);
 }
 
 /**
@@ -2929,7 +3128,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);
 }
 
 /**
@@ -2947,7 +3146,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);
 }
 
 /**
@@ -2962,7 +3161,7 @@ void
 gdk_surface_set_startup_id (GdkSurface   *surface,
                             const gchar *startup_id)
 {
-  GDK_SURFACE_IMPL_GET_CLASS (surface->impl)->set_startup_id (surface, startup_id);
+  GDK_SURFACE_GET_CLASS (surface)->set_startup_id (surface, startup_id);
 }
 
 /**
@@ -2984,7 +3183,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);
 }
 
 /**
@@ -3002,7 +3201,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);
 }
 
 /**
@@ -3020,7 +3219,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);
 }
 
 /**
@@ -3041,7 +3240,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);
 }
 
 /**
@@ -3064,7 +3263,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);
 }
 
 /**
@@ -3089,7 +3288,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);
 }
 
 /**
@@ -3106,7 +3305,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);
 }
 
 /**
@@ -3123,7 +3322,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);
 }
 
 /**
@@ -3144,7 +3343,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);
 }
 
 /**
@@ -3158,7 +3357,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);
 }
 
 /**
@@ -3181,7 +3380,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);
 }
 
 /**
@@ -3204,7 +3403,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);
 }
 
 /**
@@ -3228,7 +3427,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);
 }
 
 /**
@@ -3250,10 +3449,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);
 }
 
 /**
@@ -3283,17 +3482,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);
     }
 }
 
@@ -3331,7 +3527,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);
 }
 
 /**
@@ -3353,7 +3549,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);
 }
 
 /**
@@ -3375,7 +3571,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);
 }
 
 /**
@@ -3403,7 +3599,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);
 }
 
 /**
@@ -3420,7 +3616,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);
 }
 
 /**
@@ -3447,7 +3643,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);
 }
 
 /**
@@ -3472,7 +3668,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);
 }
 
 /**
@@ -3526,8 +3722,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);
 }
 
 /**
@@ -3593,7 +3789,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.
@@ -3601,7 +3797,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);
 }
 
 /**
@@ -3613,7 +3809,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);
 }
 
 /**
@@ -3645,7 +3841,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
@@ -3768,17 +3964,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;
 }
@@ -3791,20 +3986,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);
@@ -3840,7 +4032,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));
@@ -3853,10 +4045,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);
 }
 
 /**
@@ -3884,7 +4075,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));
@@ -3895,10 +4086,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);
 }
 
 /**
@@ -3918,15 +4108,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;
 }
@@ -3934,15 +4123,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 b2bf69620a..4dfa72ee3e 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',
 ])
 
 gdk_public_headers = files([
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 777b90b7ef..873037dccf 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"
@@ -995,7 +995,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
@@ -1017,7 +1016,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 22977dae5b..d70c0a75cf 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;
@@ -295,7 +256,7 @@ gdk_wayland_surface_update_size (GdkSurface *surface,
                                  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 +339,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);
@@ -465,7 +426,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;
 
@@ -484,7 +445,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)
     {
@@ -515,7 +476,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;
@@ -539,31 +500,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);
 
-  if (surface->width > 65535)
+  impl = GDK_WAYLAND_SURFACE (surface);
+
+  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 */
@@ -573,14 +549,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
@@ -588,7 +567,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;
@@ -629,7 +608,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);
@@ -638,14 +617,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);
@@ -663,7 +642,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
@@ -691,7 +670,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);
@@ -700,7 +679,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);
@@ -709,7 +688,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);
@@ -721,7 +700,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;
 
@@ -752,10 +731,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));
@@ -764,9 +743,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)
@@ -809,7 +788,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;
@@ -837,12 +816,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)
@@ -858,7 +837,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));
 
@@ -887,7 +866,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,
@@ -900,7 +879,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;
@@ -959,7 +938,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)
@@ -983,7 +962,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)
@@ -1010,7 +989,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));
@@ -1026,7 +1005,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));
@@ -1045,7 +1024,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);
@@ -1056,7 +1035,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;
@@ -1164,7 +1143,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;
@@ -1259,7 +1238,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,
@@ -1346,7 +1325,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,
@@ -1366,7 +1345,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);
@@ -1446,7 +1425,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;
@@ -1666,7 +1645,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 =
@@ -1682,7 +1661,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;
@@ -1724,7 +1703,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;
@@ -1897,7 +1876,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;
@@ -1973,7 +1952,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;
@@ -2153,8 +2132,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)
@@ -2259,8 +2238,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
@@ -2278,14 +2257,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);
@@ -2299,7 +2278,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)
@@ -2314,7 +2293,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)
@@ -2358,7 +2337,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;
@@ -2372,7 +2351,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))
@@ -2408,8 +2387,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);
@@ -2478,7 +2457,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);
@@ -2496,7 +2475,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)
          {
@@ -2512,7 +2491,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);
 
@@ -2629,7 +2608,7 @@ gdk_wayland_surface_hide (GdkSurface *surface)
 }
 
 static void
-gdk_surface_wayland_withdraw (GdkSurface *surface)
+gdk_wayland_surface_withdraw (GdkSurface *surface)
 {
   if (!surface->destroyed)
     {
@@ -2643,31 +2622,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)
     {
@@ -2702,7 +2681,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,
@@ -2710,7 +2689,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);
@@ -2725,7 +2704,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,
@@ -2745,7 +2724,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,
@@ -2781,7 +2760,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,
@@ -2808,12 +2787,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;
@@ -2852,7 +2831,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;
@@ -2871,9 +2850,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;
@@ -2884,12 +2863,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;
 }
@@ -2900,7 +2879,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;
 
@@ -2942,7 +2921,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;
 
@@ -2981,7 +2960,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));
 
@@ -3006,7 +2985,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)
@@ -3033,7 +3012,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;
 
@@ -3041,7 +3020,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;
@@ -3099,7 +3078,7 @@ static void
 gdk_wayland_surface_set_title (GdkSurface  *surface,
                                const gchar *title)
 {
-  GdkSurfaceImplWayland *impl;
+  GdkWaylandSurface *impl;
   const char *end;
   gsize title_length;
 
@@ -3108,7 +3087,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;
@@ -3143,12 +3122,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;
@@ -3160,7 +3139,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;
@@ -3231,7 +3210,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) ||
@@ -3282,7 +3261,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;
@@ -3315,7 +3294,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;
@@ -3347,7 +3326,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))
@@ -3384,7 +3363,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;
@@ -3421,7 +3400,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;
@@ -3491,7 +3470,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;
@@ -3539,7 +3518,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))
@@ -3581,7 +3560,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;
@@ -3590,7 +3569,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))
@@ -3644,7 +3623,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;
@@ -3656,7 +3635,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;
@@ -3673,7 +3652,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))
@@ -3696,7 +3675,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;
@@ -3744,7 +3723,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)
@@ -3754,27 +3733,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;
@@ -3828,11 +3807,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;
 }
 
@@ -3849,17 +3828,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;
@@ -3870,14 +3849,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);
     }
 
@@ -3889,12 +3868,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)
     {
@@ -3912,11 +3891,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)
     {
@@ -3935,13 +3914,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;
@@ -3977,11 +3956,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);
@@ -3999,11 +3978,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;
@@ -4015,7 +3994,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,
@@ -4041,7 +4020,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;
 }
@@ -4079,7 +4058,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;
@@ -4087,7 +4066,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);
@@ -4126,11 +4105,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);
 
@@ -4143,7 +4122,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);
 }
@@ -4180,7 +4159,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);
 
@@ -4188,7 +4167,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)
@@ -4211,7 +4190,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);
@@ -4221,7 +4200,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);
@@ -4244,7 +4223,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-core-x11.c b/gdk/x11/gdkdevice-core-x11.c
index 20318618ca..59eca14b31 100644
--- a/gdk/x11/gdkdevice-core-x11.c
+++ b/gdk/x11/gdkdevice-core-x11.c
@@ -21,8 +21,6 @@
 #include "gdkx11device-core.h"
 #include "gdkdeviceprivate.h"
 
-#include "gdkinternals.h"
-#include "gdksurface.h"
 #include "gdkprivate-x11.h"
 #include "gdkdisplay-x11.h"
 #include "gdkasync.h"
@@ -112,15 +110,13 @@ gdk_x11_device_core_get_history (GdkDevice      *device,
 {
   XTimeCoord *xcoords;
   GdkTimeCoord **coords;
-  GdkSurface *impl_surface;
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
   int tmp_n_events;
   int i, j;
 
-  impl_surface = gdk_surface_get_impl_surface (surface);
-  impl =  GDK_SURFACE_IMPL_X11 (impl_surface->impl);
+  impl = GDK_X11_SURFACE (surface);
   xcoords = XGetMotionEvents (GDK_SURFACE_XDISPLAY (surface),
-                              GDK_SURFACE_XID (impl_surface),
+                              GDK_SURFACE_XID (surface),
                               start, stop, &tmp_n_events);
   if (!xcoords)
     return FALSE;
@@ -226,7 +222,7 @@ gdk_x11_device_core_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_X11_DISPLAY (display)->trusted_client ||
@@ -293,9 +289,6 @@ gdk_x11_device_core_grab (GdkDevice    *device,
 
   xwindow = GDK_SURFACE_XID (surface);
 
-  if (confine_to)
-    confine_to = gdk_surface_get_impl_surface (confine_to);
-
   if (!confine_to || GDK_SURFACE_DESTROYED (confine_to))
     xconfine_to = None;
   else
@@ -382,7 +375,7 @@ gdk_x11_device_core_surface_at_position (GdkDevice       *device,
                                         GdkModifierType *mask,
                                         gboolean         get_toplevel)
 {
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
   GdkDisplay *display;
   Display *xdisplay;
   GdkSurface *surface;
@@ -432,7 +425,7 @@ gdk_x11_device_core_surface_at_position (GdkDevice       *device,
       for (list = toplevels; list != NULL; list = list->next)
         {
           surface = GDK_SURFACE (list->data);
-          impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+          impl = GDK_X11_SURFACE (surface);
           xwindow = GDK_SURFACE_XID (surface);
           gdk_x11_display_error_trap_push (display);
           XQueryPointer (xdisplay, xwindow,
@@ -500,7 +493,7 @@ gdk_x11_device_core_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 (win_x)
     *win_x = (surface) ? (double)xwin_x / impl->surface_scale : -1;
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-core-x11.c b/gdk/x11/gdkdevicemanager-core-x11.c
index dc0a51be55..927eb4c078 100644
--- a/gdk/x11/gdkdevicemanager-core-x11.c
+++ b/gdk/x11/gdkdevicemanager-core-x11.c
@@ -22,6 +22,7 @@
 #include "gdkx11device-core.h"
 
 #include "gdkdeviceprivate.h"
+#include "gdksurfaceprivate.h"
 #include "gdkseatdefaultprivate.h"
 #include "gdkdisplayprivate.h"
 #include "gdkeventtranslator.h"
@@ -342,7 +343,7 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
                                              GdkEvent           *event,
                                              const XEvent       *xevent)
 {
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
   GdkX11DeviceManagerCore *device_manager;
   GdkSurface *surface;
   gboolean return_val;
@@ -360,7 +361,7 @@ gdk_x11_device_manager_core_translate_event (GdkEventTranslator *translator,
         return FALSE;
 
       g_object_ref (surface);
-      impl = GDK_SURFACE_IMPL_X11 (surface->impl);
+      impl = GDK_X11_SURFACE (surface);
       scale = impl->surface_scale;
     }
 
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index 0f0f0aadce..372dc82719 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -1428,7 +1428,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;
 
@@ -1454,7 +1454,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 398ce7b22c..5b3f7c74cd 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];
@@ -3020,7 +3021,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;
@@ -3042,7 +3042,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 f40ff8de5c..8ca3f3fb8d 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 abb32a9fc8..2e2b420560 100644
--- a/gdk/x11/gdkprivate-x11.h
+++ b/gdk/x11/gdkprivate-x11.h
@@ -180,9 +180,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,
@@ -244,7 +249,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
@@ -254,7 +258,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. b/gdk/x11/gdksurface-x11.
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c
index fe27a00e20..956c23d7d3 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));
 }
@@ -1875,7 +1869,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;
 
@@ -1992,7 +1986,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;
 
@@ -2006,7 +2000,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)
@@ -2220,23 +2214,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;
@@ -2247,7 +2241,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),
@@ -2265,13 +2259,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;
@@ -2293,7 +2287,7 @@ gdk_x11_surface_get_frame_extents (GdkSurface    *surface,
                                   GdkRectangle *rect)
 {
   GdkDisplay *display;
-  GdkSurfaceImplX11 *impl;
+  GdkX11Surface *impl;
   Window xwindow;
   Window xparent;
   Window root;
@@ -2319,7 +2313,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;
@@ -2457,7 +2451,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,
@@ -2477,13 +2471,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;
@@ -2665,7 +2659,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,
@@ -3570,7 +3564,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));
@@ -3947,7 +3941,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)
     {
@@ -3955,7 +3949,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);
@@ -4270,7 +4264,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))
@@ -4298,7 +4292,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))
@@ -4430,13 +4424,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;
@@ -4460,14 +4454,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;
@@ -4514,7 +4508,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;
@@ -4536,7 +4530,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,
@@ -4561,24 +4555,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]