]> Pileus Git - ~andy/gtk/blobdiff - gdk/wayland/gdkwindow-wayland.c
wayland: Also synthesize a configure event from gdk_window_wayland_move_resize
[~andy/gtk] / gdk / wayland / gdkwindow-wayland.c
index 3d796cde2c8f3fa0927963fc3ad664e3b41ab9b8..5cab6f56b832376d4c542625058ebc1898c748c3 100644 (file)
 #include "gdkwindow.h"
 #include "gdkwindowimpl.h"
 #include "gdkdisplay-wayland.h"
-#include "gdkscreen-wayland.h"
 #include "gdkprivate-wayland.h"
 #include "gdkinternals.h"
-#include "gdkwindow-wayland.h"
 #include "gdkdeviceprivate.h"
-#include "gdkdevice-wayland.h"
-#include "gdkeventsource.h"
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 
+#include <wayland-egl.h>
+
 #define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window) \
   (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&   \
    GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
@@ -96,18 +94,33 @@ struct _GdkWindowImplWayland
 
   GdkWindow *wrapper;
 
-  GdkToplevelWayland *toplevel;        /* Toplevel-specific information */
   GdkCursor *cursor;
-  GHashTable *device_cursor;
 
   gint8 toplevel_window_type;
 
   struct wl_surface *surface;
+  struct wl_shell_surface *shell_surface;
   unsigned int mapped : 1;
+  GdkWindow *transient_for;
+  GdkWindowTypeHint hint;
 
   cairo_surface_t *cairo_surface;
   cairo_surface_t *server_surface;
   GLuint texture;
+  uint32_t resize_edges;
+
+  int focus_count;
+
+  gulong map_serial;   /* Serial of last transition from unmapped */
+
+  cairo_surface_t *icon_pixmap;
+  cairo_surface_t *icon_mask;
+
+  /* Time of most recent user interaction. */
+  gulong user_time;
+
+  GdkGeometry geometry_hints;
+  GdkWindowHints geometry_mask;
 };
 
 struct _GdkWindowImplWaylandClass
@@ -121,52 +134,53 @@ static void
 _gdk_window_impl_wayland_init (GdkWindowImplWayland *impl)
 {
   impl->toplevel_window_type = -1;
-  impl->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
-                                              (GDestroyNotify) gdk_cursor_unref);
 }
 
-GdkToplevelWayland *
-_gdk_wayland_window_get_toplevel (GdkWindow *window)
+void
+_gdk_wayland_window_add_focus (GdkWindow *window)
 {
-  GdkWindowImplWayland *impl;
-
-  g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
-
-  if (!WINDOW_IS_TOPLEVEL (window))
-    return NULL;
+  GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
 
-  impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+  impl->focus_count++;
+  if (impl->focus_count == 1)
+    gdk_synthesize_window_state (window, 0, GDK_WINDOW_STATE_FOCUSED);
+}
 
-  if (!impl->toplevel)
-    impl->toplevel = g_new0 (GdkToplevelWayland, 1);
+void
+_gdk_wayland_window_remove_focus (GdkWindow *window)
+{
+  GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
 
-  return impl->toplevel;
+  impl->focus_count--;
+  if (impl->focus_count == 0)
+    gdk_synthesize_window_state (window, GDK_WINDOW_STATE_FOCUSED, 0);
 }
 
 /**
- * _gdk_wayland_window_update_size:
+ * gdk_wayland_window_update_size:
  * @drawable: a #GdkDrawableImplWayland.
  * 
  * Updates the state of the drawable (in particular the drawable's
  * cairo surface) when its size has changed.
  **/
-void
-_gdk_wayland_window_update_size (GdkWindow *window)
+static void
+gdk_wayland_window_update_size (GdkWindow *window,
+                               int32_t width, int32_t height, uint32_t edges)
 {
   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
-  GdkDisplayWayland *display_wayland =
-    GDK_DISPLAY_WAYLAND (gdk_window_get_display (impl->wrapper));
   GdkRectangle area;
   cairo_region_t *region;
 
-  fprintf(stderr, "update size, window %p\n", impl->wrapper);
-
   if (impl->cairo_surface)
     {
       cairo_surface_destroy (impl->cairo_surface);
       impl->cairo_surface = NULL;
     }
 
+  window->width = width;
+  window->height = height;
+  impl->resize_edges = edges;
+
   area.x = 0;
   area.y = 0;
   area.width = window->width;
@@ -234,17 +248,12 @@ _gdk_wayland_display_create_window_impl (GdkDisplay    *display,
                                         gint           attributes_mask)
 {
   GdkWindowImplWayland *impl;
-  GdkDisplayWayland *display_wayland;
   const char *title;
 
-  display_wayland = GDK_DISPLAY_WAYLAND (display);
-
   impl = g_object_new (GDK_TYPE_WINDOW_IMPL_WAYLAND, NULL);
   window->impl = GDK_WINDOW_IMPL (impl);
   impl->wrapper = GDK_WINDOW (window);
 
-  printf("impl_new for window %p: %p\n", window, impl);
-
   if (window->width > 65535 ||
       window->height > 65535)
     {
@@ -279,65 +288,23 @@ _gdk_wayland_display_create_window_impl (GdkDisplay    *display,
     gdk_window_set_type_hint (window, attributes->type_hint);
 }
 
-static void
-gdk_toplevel_wayland_free_contents (GdkDisplay *display,
-                               GdkToplevelWayland *toplevel)
-{
-  if (toplevel->icon_pixmap)
-    {
-      cairo_surface_destroy (toplevel->icon_pixmap);
-      toplevel->icon_pixmap = NULL;
-    }
-  if (toplevel->icon_mask)
-    {
-      cairo_surface_destroy (toplevel->icon_mask);
-      toplevel->icon_mask = NULL;
-    }
-}
-
 static const cairo_user_data_key_t gdk_wayland_cairo_key;
 
 typedef struct _GdkWaylandCairoSurfaceData {
   EGLImageKHR image;
   GLuint texture;
+  struct wl_egl_pixmap *pixmap;
   struct wl_buffer *buffer;
   GdkDisplayWayland *display;
+  int32_t width, height;
 } GdkWaylandCairoSurfaceData;
 
-struct wl_buffer *
-_gdk_wayland_surface_get_buffer (GdkDisplayWayland *display,
-                                cairo_surface_t *surface)
-{
-  GdkWaylandCairoSurfaceData *data;
-  EGLint name, stride;
-  struct wl_visual *visual;
-  int width, height;
-
-  data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key);
-
-  if (data->buffer)
-    return data->buffer;
-
-  visual =
-    wl_display_get_premultiplied_argb_visual(display->wl_display);
-
-  width = cairo_gl_surface_get_width (surface);
-  height = cairo_gl_surface_get_height (surface);
-  display->export_drm_image (display->egl_display,
-                            data->image, &name, NULL, &stride);
-  data->buffer = wl_drm_create_buffer(display->drm,
-                                     name, width, height, stride, visual);
-
-  return data->buffer;
-}
-
 static void
 gdk_wayland_window_attach_image (GdkWindow *window)
 {
-  GdkDisplayWayland *display_wayland =
-    GDK_DISPLAY_WAYLAND (gdk_window_get_display (window));
   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
-  struct wl_buffer *buffer;
+  GdkWaylandCairoSurfaceData *data;
+  int32_t server_width, server_height, dx, dy;
 
   if (GDK_WINDOW_DESTROYED (window))
     return;
@@ -345,32 +312,53 @@ gdk_wayland_window_attach_image (GdkWindow *window)
   if (impl->server_surface == impl->cairo_surface)
     return;
 
-  impl->server_surface = impl->cairo_surface;
-  buffer = _gdk_wayland_surface_get_buffer (display_wayland,
-                                           impl->cairo_surface);
-  wl_surface_attach (impl->surface, buffer, 0, 0);
+  if (impl->server_surface)
+    {
+      data = cairo_surface_get_user_data (impl->server_surface,
+                                         &gdk_wayland_cairo_key);
+      server_width = data->width;
+      server_height = data->height;
+      cairo_surface_destroy (impl->server_surface);
+    }
+  else
+    {
+      server_width = 0;
+      server_height = 0;
+    }
+
+  impl->server_surface = cairo_surface_reference (impl->cairo_surface);
+  data = cairo_surface_get_user_data (impl->cairo_surface,
+                                     &gdk_wayland_cairo_key);
+  if (!data->buffer)
+    data->buffer =
+      wl_egl_pixmap_create_buffer(data->pixmap);
 
-  fprintf(stderr, "attach %p %dx%d\n", window, window->width, window->height);
+  if (impl->resize_edges & WL_SHELL_SURFACE_RESIZE_LEFT)
+    dx = server_width - data->width;
+  else
+    dx = 0;
+
+  if (impl->resize_edges & WL_SHELL_SURFACE_RESIZE_TOP)
+    dy = server_height - data->height;
+  else
+    dy = 0;
+
+  wl_surface_attach (impl->surface, data->buffer, dx, dy);
 }
 
 static void
 gdk_window_impl_wayland_finalize (GObject *object)
 {
-  GdkWindow *wrapper;
   GdkWindowImplWayland *impl;
 
   g_return_if_fail (GDK_IS_WINDOW_IMPL_WAYLAND (object));
 
   impl = GDK_WINDOW_IMPL_WAYLAND (object);
 
-  wrapper = impl->wrapper;
-
-  g_free (impl->toplevel);
-
   if (impl->cursor)
-    gdk_cursor_unref (impl->cursor);
-
-  g_hash_table_destroy (impl->device_cursor);
+    g_object_unref (impl->cursor);
+  if (impl->server_surface)
+    cairo_surface_destroy (impl->server_surface);
 
   G_OBJECT_CLASS (_gdk_window_impl_wayland_parent_class)->finalize (object);
 }
@@ -396,25 +384,21 @@ gdk_wayland_create_cairo_surface (GdkDisplayWayland *display,
   GdkWaylandCairoSurfaceData *data;
   cairo_surface_t *surface;
 
-  EGLint image_attribs[] = {
-    EGL_WIDTH,                 0,
-    EGL_HEIGHT,                        0,
-    EGL_DRM_BUFFER_FORMAT_MESA,        EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
-    EGL_DRM_BUFFER_USE_MESA,   EGL_DRM_BUFFER_USE_SCANOUT_MESA,
-    EGL_NONE
-  };
-
   data = g_new (GdkWaylandCairoSurfaceData, 1);
   data->display = display;
   data->buffer = NULL;
-  image_attribs[1] = width;
-  image_attribs[3] = height;
-  data->image = display->create_drm_image(display->egl_display, image_attribs);
+  data->width = width;
+  data->height = height;
+  data->pixmap = wl_egl_pixmap_create(width, height, 0);
+  data->image =
+    display->create_image(display->egl_display, NULL, EGL_NATIVE_PIXMAP_KHR,
+                         (EGLClientBuffer) data->pixmap, NULL);
+
+  cairo_device_acquire(display->cairo_device);
   glGenTextures(1, &data->texture);
   glBindTexture(GL_TEXTURE_2D, data->texture);
   display->image_target_texture_2d(GL_TEXTURE_2D, data->image);
-
-  printf("allocate image %dx%d (image %p)\n", width, height, data->image);
+  cairo_device_release(display->cairo_device);
 
   surface = cairo_gl_surface_create_for_texture(display->cairo_device,
                                                CAIRO_CONTENT_COLOR_ALPHA,
@@ -452,38 +436,121 @@ gdk_wayland_window_ref_cairo_surface (GdkWindow *window)
   return impl->cairo_surface;
 }
 
+static cairo_surface_t *
+gdk_wayland_window_configure (GdkWindow *window,
+                             int width, int height, int edges)
+{
+  GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+  GdkDisplay *display;
+  GdkEvent *event;
+
+  display = gdk_window_get_display (window);
+
+  /* TODO: Only generate a configure event if width or height have actually
+   * changed?
+   */
+  event = gdk_event_new (GDK_CONFIGURE);
+  event->configure.window = window;
+  event->configure.send_event = FALSE;
+  event->configure.width = width;
+  event->configure.height = height;
+
+  _gdk_window_update_size (window);
+  gdk_wayland_window_update_size (window, width, height, edges);
+
+  g_object_ref(window);
+
+  _gdk_wayland_display_deliver_event (display, event);
+}
+
 static void
 gdk_wayland_window_set_user_time (GdkWindow *window, guint32 user_time)
 {
 }
 
+static void
+gdk_wayland_window_map (GdkWindow *window)
+{
+  GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+  GdkWindowImplWayland *parent;
+
+  if (!impl->mapped)
+    {
+      if (impl->transient_for)
+       {
+         fprintf(stderr, "parent surface: %d, %d, transient surface %d, %d\n",
+                 impl->transient_for->x,
+                 impl->transient_for->y,
+                 window->x,
+                 window->y);
+
+         parent = GDK_WINDOW_IMPL_WAYLAND (impl->transient_for->impl);
+          wl_shell_surface_set_transient (impl->shell_surface, parent->shell_surface,
+                                          window->x, window->y, 0);
+       }
+      else
+        wl_shell_surface_set_toplevel (impl->shell_surface);
+      impl->mapped = TRUE;
+    }
+}
+
+static void
+shell_surface_handle_configure(void *data,
+                               struct wl_shell_surface *shell_surface,
+                               uint32_t time,
+                               uint32_t edges,
+                               int32_t width,
+                               int32_t height)
+{
+  GdkWindow *window = GDK_WINDOW (data);
+  GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+
+  gdk_window_constrain_size (&impl->geometry_hints,
+                             impl->geometry_mask,
+                             width,
+                             height,
+                             &width,
+                             &height);
+
+  gdk_wayland_window_configure (window, width, height, edges);
+}
+
+static const struct wl_shell_surface_listener shell_surface_listener = {
+  shell_surface_handle_configure,
+};
+
 static void
 gdk_wayland_window_show (GdkWindow *window, gboolean already_mapped)
 {
   GdkDisplay *display;
   GdkDisplayWayland *display_wayland;
-  GdkToplevelWayland *toplevel;
   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+  GdkEvent *event;
 
   display = gdk_window_get_display (window);
   display_wayland = GDK_DISPLAY_WAYLAND (display);
 
-  if (WINDOW_IS_TOPLEVEL (window))
-    {
-      toplevel = _gdk_wayland_window_get_toplevel (window);
-
-      if (toplevel->user_time != 0 &&
-             display_wayland->user_time != 0 &&
-         XSERVER_TIME_IS_LATER (display_wayland->user_time, toplevel->user_time))
-       gdk_wayland_window_set_user_time (window, display_wayland->user_time);
-    }
+  if (impl->user_time != 0 &&
+      display_wayland->user_time != 0 &&
+      XSERVER_TIME_IS_LATER (display_wayland->user_time, impl->user_time))
+    gdk_wayland_window_set_user_time (window, impl->user_time);
 
   impl->surface = wl_compositor_create_surface(display_wayland->compositor);
   wl_surface_set_user_data(impl->surface, window);
 
+  impl->shell_surface = wl_shell_get_shell_surface (display_wayland->shell,
+                                                    impl->surface);
+  wl_shell_surface_add_listener(impl->shell_surface,
+                                &shell_surface_listener, window);
+
+  gdk_window_set_type_hint (window, impl->hint);  
+
   _gdk_make_event (window, GDK_MAP, NULL, FALSE);
+  event = _gdk_make_event (window, GDK_VISIBILITY_NOTIFY, NULL, FALSE);
+  event->visibility.state = GDK_VISIBILITY_UNOBSCURED;
 
-  fprintf(stderr, "window show, faked map event\n");
+  if (impl->cairo_surface)
+    gdk_wayland_window_attach_image (window);
 }
 
 static void
@@ -493,10 +560,11 @@ gdk_wayland_window_hide (GdkWindow *window)
 
   if (impl->surface)
     {
-      fprintf (stderr, "hide surface %p\n", impl->surface);
-
       wl_surface_destroy(impl->surface);
       impl->surface = NULL;
+      cairo_surface_destroy(impl->server_surface);
+      impl->server_surface = NULL;
+      impl->mapped = FALSE;
     }
 
   _gdk_window_clear_update_area (window);
@@ -517,11 +585,11 @@ gdk_window_wayland_withdraw (GdkWindow *window)
       impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
       if (impl->surface)
        {
-         fprintf (stderr, "hide surface %p\n", impl->surface);
-
          wl_surface_destroy(impl->surface);
          impl->surface = NULL;
-         cairo_surface_destroy(GDK_WINDOW_IMPL_WAYLAND(impl)->cairo_surface);
+         cairo_surface_destroy(impl->server_surface);
+         impl->server_surface = NULL;
+         impl->mapped = FALSE;
        }
     }
 }
@@ -575,18 +643,14 @@ gdk_window_wayland_move_resize (GdkWindow *window,
                                gint       width,
                                gint       height)
 {
-  GdkWindowImplWayland *impl;
-
-  impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
-
   window->x = x;
   window->y = y;
-  if (width > 0)
-    window->width = width;
-  if (height > 0)
-    window->height = height;
 
-  _gdk_wayland_window_update_size (window);
+  /* If this function is called with width and height = -1 then that means
+   * just move the window - don't update its size
+   */
+  if (width > 0 && height > 0)
+    gdk_wayland_window_configure (window, width, height, 0);
 }
 
 static void
@@ -609,21 +673,9 @@ gdk_window_wayland_set_device_cursor (GdkWindow *window,
                                      GdkDevice *device,
                                      GdkCursor *cursor)
 {
-  GdkWindowImplWayland *impl;
-
   g_return_if_fail (GDK_IS_WINDOW (window));
   g_return_if_fail (GDK_IS_DEVICE (device));
 
-  impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
-
-  if (!cursor)
-    g_hash_table_remove (impl->device_cursor, device);
-  else
-    {
-      g_hash_table_replace (impl->device_cursor,
-                           device, gdk_cursor_ref (cursor));
-    }
-
   if (!GDK_WINDOW_DESTROYED (window))
     GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
 }
@@ -749,16 +801,10 @@ gdk_wayland_window_destroy (GdkWindow *window,
                            gboolean   recursing,
                            gboolean   foreign_destroy)
 {
-  GdkToplevelWayland *toplevel;
   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
-  toplevel = _gdk_wayland_window_get_toplevel (window);
-  if (toplevel)
-    gdk_toplevel_wayland_free_contents (gdk_window_get_display (window),
-                                       toplevel);
-
   if (impl->cairo_surface)
     {
       cairo_surface_finish (impl->cairo_surface);
@@ -771,11 +817,9 @@ gdk_wayland_window_destroy (GdkWindow *window,
 
   if (!recursing && !foreign_destroy)
     {
-      fprintf (stderr, "destroy window, surface %p\n",
-              GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface);
-
       if (GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface)
        wl_surface_destroy(GDK_WINDOW_IMPL_WAYLAND (window->impl)->surface);
+       wl_shell_surface_destroy(GDK_WINDOW_IMPL_WAYLAND (window->impl)->shell_surface);
     }
 }
 
@@ -816,16 +860,20 @@ static void
 gdk_wayland_window_set_type_hint (GdkWindow        *window,
                                  GdkWindowTypeHint hint)
 {
+  GdkWindowImplWayland *impl;
+
+  impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
+  impl->hint = hint;
+
   switch (hint)
     {
-    case GDK_WINDOW_TYPE_HINT_DIALOG:
     case GDK_WINDOW_TYPE_HINT_MENU:
     case GDK_WINDOW_TYPE_HINT_TOOLBAR:
     case GDK_WINDOW_TYPE_HINT_UTILITY:
-    case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
     case GDK_WINDOW_TYPE_HINT_DOCK:
     case GDK_WINDOW_TYPE_HINT_DESKTOP:
     case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
@@ -838,7 +886,11 @@ gdk_wayland_window_set_type_hint (GdkWindow        *window,
     default:
       g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
       /* Fall thru */
+    case GDK_WINDOW_TYPE_HINT_DIALOG:
     case GDK_WINDOW_TYPE_HINT_NORMAL:
+    case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
+      if (impl->shell_surface)
+       wl_shell_surface_set_toplevel (impl->shell_surface);
       break;
     }
 }
@@ -878,10 +930,17 @@ gdk_wayland_window_set_geometry_hints (GdkWindow         *window,
                                       const GdkGeometry *geometry,
                                       GdkWindowHints     geom_mask)
 {
+  GdkWindowImplWayland *impl;
+
   if (GDK_WINDOW_DESTROYED (window) ||
       !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
     return;
 
+  impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+
+  impl->geometry_hints = *geometry;
+  impl->geometry_mask = geom_mask;
+
   /*
    * GDK_HINT_POS
    * GDK_HINT_USER_POS
@@ -921,6 +980,10 @@ static void
 gdk_wayland_window_set_transient_for (GdkWindow *window,
                                      GdkWindow *parent)
 {
+  GdkWindowImplWayland *impl;
+
+  impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+  impl->transient_for = parent;
 }
 
 static void
@@ -1113,15 +1176,13 @@ gdk_wayland_window_set_functions (GdkWindow    *window,
 static void
 gdk_wayland_window_begin_resize_drag (GdkWindow     *window,
                                      GdkWindowEdge  edge,
+                                      GdkDevice     *device,
                                      gint           button,
                                      gint           root_x,
                                      gint           root_y,
                                      guint32        timestamp)
 {
-  GdkDisplay *display = gdk_window_get_display (window);
-  GdkDeviceManager *dm;
   GdkWindowImplWayland *impl;
-  GdkDevice *device;
   uint32_t grab_type;
 
   if (GDK_WINDOW_DESTROYED (window) ||
@@ -1131,35 +1192,35 @@ gdk_wayland_window_begin_resize_drag (GdkWindow     *window,
   switch (edge)
     {
     case GDK_WINDOW_EDGE_NORTH_WEST:
-      grab_type = WL_GRAB_RESIZE_TOP_LEFT;
+      grab_type = WL_SHELL_SURFACE_RESIZE_TOP_LEFT;
       break;
 
     case GDK_WINDOW_EDGE_NORTH:
-      grab_type = WL_GRAB_RESIZE_TOP;
+      grab_type = WL_SHELL_SURFACE_RESIZE_TOP;
       break;
 
     case GDK_WINDOW_EDGE_NORTH_EAST:
-      grab_type = WL_GRAB_RESIZE_RIGHT;
+      grab_type = WL_SHELL_SURFACE_RESIZE_RIGHT;
       break;
 
     case GDK_WINDOW_EDGE_WEST:
-      grab_type = WL_GRAB_RESIZE_LEFT;
+      grab_type = WL_SHELL_SURFACE_RESIZE_LEFT;
       break;
 
     case GDK_WINDOW_EDGE_EAST:
-      grab_type = WL_GRAB_RESIZE_RIGHT;
+      grab_type = WL_SHELL_SURFACE_RESIZE_RIGHT;
       break;
 
     case GDK_WINDOW_EDGE_SOUTH_WEST:
-      grab_type = WL_GRAB_RESIZE_BOTTOM_LEFT;
+      grab_type = WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT;
       break;
 
     case GDK_WINDOW_EDGE_SOUTH:
-      grab_type = WL_GRAB_RESIZE_BOTTOM;
+      grab_type = WL_SHELL_SURFACE_RESIZE_BOTTOM;
       break;
 
     case GDK_WINDOW_EDGE_SOUTH_EAST:
-      grab_type = WL_GRAB_RESIZE_BOTTOM_RIGHT;
+      grab_type = WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT;
       break;
 
     default:
@@ -1169,25 +1230,26 @@ gdk_wayland_window_begin_resize_drag (GdkWindow     *window,
     }
 
   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
-  dm = gdk_display_get_device_manager (display);
-  device = gdk_device_manager_get_client_pointer (dm);
 
-  wl_shell_resize(GDK_DISPLAY_WAYLAND (display)->shell, impl->surface,
-                 GDK_DEVICE_CORE (device)->device->device,
-                 timestamp, grab_type);
+  wl_shell_surface_resize (impl->shell_surface,
+                           _gdk_wayland_device_get_device (device),
+                           timestamp, grab_type);
+
+  /* This is needed since Wayland will absorb all the pointer events after the
+   * above function - FIXME: Is this always safe..?
+   */
+  gdk_device_ungrab (device, timestamp);
 }
 
 static void
 gdk_wayland_window_begin_move_drag (GdkWindow *window,
+                                    GdkDevice *device,
                                    gint       button,
                                    gint       root_x,
                                    gint       root_y,
                                    guint32    timestamp)
 {
-  GdkDisplay *display = gdk_window_get_display (window);
-  GdkDeviceManager *dm;
   GdkWindowImplWayland *impl;
-  GdkDevice *device;
 
   if (GDK_WINDOW_DESTROYED (window) ||
       !WINDOW_IS_TOPLEVEL (window))
@@ -1195,11 +1257,13 @@ gdk_wayland_window_begin_move_drag (GdkWindow *window,
 
   impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
 
-  dm = gdk_display_get_device_manager (display);
-  device = gdk_device_manager_get_client_pointer (dm);
+  wl_shell_surface_move (impl->shell_surface,
+                         _gdk_wayland_device_get_device (device), timestamp);
 
-  wl_shell_move(GDK_DISPLAY_WAYLAND (display)->shell, impl->surface,
-               GDK_DEVICE_CORE (device)->device->device, timestamp);
+  /* This is needed since Wayland will absorb all the pointer events after the
+   * above function - FIXME: Is this always safe..?
+   */
+  gdk_device_ungrab (device, timestamp);
 }
 
 static void
@@ -1210,17 +1274,11 @@ gdk_wayland_window_enable_synchronized_configure (GdkWindow *window)
 static void
 gdk_wayland_window_configure_finished (GdkWindow *window)
 {
-  GdkWindowImplWayland *impl;
-
   if (!WINDOW_IS_TOPLEVEL (window))
     return;
 
   if (!GDK_IS_WINDOW_IMPL_WAYLAND (window->impl))
     return;
-
-  impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
-
-  fprintf(stderr, "configure %p finished\n", window);
 }
 
 static void
@@ -1238,10 +1296,6 @@ gdk_wayland_window_set_composited (GdkWindow *window,
 static void
 gdk_wayland_window_destroy_notify (GdkWindow *window)
 {
-  GdkWindowImplWayland *window_impl;
-
-  window_impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
-
   if (!GDK_WINDOW_DESTROYED (window))
     {
       if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
@@ -1261,12 +1315,10 @@ gdk_wayland_window_process_updates_recurse (GdkWindow *window,
   cairo_rectangle_int_t rect;
   int i, n;
 
-  gdk_wayland_window_attach_image (window);
-  if (!impl->mapped)
-    {
-      wl_surface_map_toplevel (impl->surface);
-      impl->mapped = TRUE;
-    }
+  if (impl->cairo_surface)
+    gdk_wayland_window_attach_image (window);
+
+  gdk_wayland_window_map (window);
 
   n = cairo_region_num_rectangles(region);
   for (i = 0; i < n; i++)
@@ -1416,6 +1468,7 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
   impl_class->set_opacity = gdk_wayland_window_set_opacity;
   impl_class->set_composited = gdk_wayland_window_set_composited;
   impl_class->destroy_notify = gdk_wayland_window_destroy_notify;
+  impl_class->get_drag_protocol = _gdk_wayland_window_get_drag_protocol;
   impl_class->register_dnd = _gdk_wayland_window_register_dnd;
   impl_class->drag_begin = _gdk_wayland_window_drag_begin;
   impl_class->process_updates_recurse = gdk_wayland_window_process_updates_recurse;