[mutter/wayland] Start moving X11-specific code to window-x11.c



commit f7097e6f66ba6d7ea41c8c7bde24926c77843848
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Thu Jan 23 16:33:53 2014 -0500

    Start moving X11-specific code to window-x11.c
    
    The goal here is to make MetaWindow represent a toplevel, managed window,
    regardless of if it's X11 or Wayland, and build an abstraction layer up.
    Right now, most of the X11 code is in core/ and the wayland code in wayland/,
    but in the future, I want to move a lot of the X11 code to a new toplevel, x11/.

 src/Makefile.am           |    2 +
 src/core/display.c        |   15 +-
 src/core/window-private.h |   17 +-
 src/core/window-props.c   |    7 +-
 src/core/window-x11.c     | 1148 +++++++++++++++++++++++++++++++++++++++++++++
 src/core/window-x11.h     |   44 ++
 src/core/window.c         | 1131 +-------------------------------------------
 7 files changed, 1223 insertions(+), 1141 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index b81c6ec..53f6f7a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -163,6 +163,8 @@ libmutter_wayland_la_SOURCES =                      \
        core/util-private.h                     \
        core/window-props.c                     \
        core/window-props.h                     \
+       core/window-x11.c                       \
+       core/window-x11.h                       \
        core/window.c                           \
        core/window-private.h                   \
        meta/window.h                           \
diff --git a/src/core/display.c b/src/core/display.c
index 7376f0e..24365f3 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -36,6 +36,7 @@
 #include <meta/main.h>
 #include "screen-private.h"
 #include "window-private.h"
+#include "window-x11.h"
 #include "window-props.h"
 #include "group-props.h"
 #include "frame.h"
@@ -1581,7 +1582,7 @@ handle_net_restack_window (MetaDisplay* display,
        *
        * Also, unconditionally following these is REALLY stupid--we should
        * combine this code with the stuff in
-       * meta_window_configure_request() which is smart about whether to
+       * meta_window_x11_configure_request() which is smart about whether to
        * follow the request or do something else (though not smart enough
        * and is also too stupid to handle the sibling stuff).
        */
@@ -2692,9 +2693,9 @@ handle_other_xevent (MetaDisplay *display,
           XShapeEvent *sev = (XShapeEvent*) event;
 
           if (sev->kind == ShapeBounding)
-            meta_window_update_shape_region_x11 (window);
+            meta_window_x11_update_shape_region (window);
           else if (sev->kind == ShapeInput)
-            meta_window_update_input_region_x11 (window);
+            meta_window_x11_update_input_region (window);
         }
       else
         {
@@ -2903,7 +2904,7 @@ handle_other_xevent (MetaDisplay *display,
       else
         {
           if (!frame_was_receiver)
-            meta_window_configure_request (window, event);
+            meta_window_x11_configure_request (window, event);
         }
       break;
     case GravityNotify:
@@ -2920,9 +2921,9 @@ handle_other_xevent (MetaDisplay *display,
         MetaScreen *screen;
 
         if (window && !frame_was_receiver)
-          meta_window_property_notify (window, event);
+          meta_window_x11_property_notify (window, event);
         else if (property_for_window && !frame_was_receiver)
-          meta_window_property_notify (property_for_window, event);
+          meta_window_x11_property_notify (property_for_window, event);
 
         group = meta_display_lookup_group (display,
                                            event->xproperty.window);
@@ -2993,7 +2994,7 @@ handle_other_xevent (MetaDisplay *display,
       if (window)
         {
           if (!frame_was_receiver)
-            meta_window_client_message (window, event);
+            meta_window_x11_client_message (window, event);
         }
       else
         {
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 7c09e68..679719b 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -615,12 +615,6 @@ void     meta_window_move_resize_wayland (MetaWindow *window,
                                           int         height,
                                           int         dx,
                                           int         dy);
-gboolean meta_window_configure_request (MetaWindow *window,
-                                        XEvent     *event);
-gboolean meta_window_property_notify   (MetaWindow *window,
-                                        XEvent     *event);
-gboolean meta_window_client_message    (MetaWindow *window,
-                                        XEvent     *event);
 void     meta_window_set_focused_internal (MetaWindow *window,
                                            gboolean    focused);
 
@@ -697,8 +691,6 @@ void meta_window_set_user_time (MetaWindow *window,
 
 void meta_window_update_icon_now (MetaWindow *window);
 
-void meta_window_update_role (MetaWindow *window);
-void meta_window_update_net_wm_type (MetaWindow *window);
 void meta_window_update_for_monitors_changed (MetaWindow *window);
 void meta_window_update_on_all_workspaces (MetaWindow *window);
 
@@ -712,10 +704,6 @@ void meta_window_compute_tile_match (MetaWindow *window);
 
 gboolean meta_window_updates_are_frozen (MetaWindow *window);
 
-void meta_window_update_opaque_region_x11 (MetaWindow *window);
-void meta_window_update_input_region_x11  (MetaWindow *window);
-void meta_window_update_shape_region_x11  (MetaWindow *window);
-
 void meta_window_set_title                (MetaWindow *window,
                                            const char *title);
 void meta_window_set_wm_class             (MetaWindow *window,
@@ -756,4 +744,9 @@ void meta_window_pong (MetaWindow *window,
                        guint32     timestamp);
 Window meta_window_get_toplevel_xwindow (MetaWindow *window);
 
+void meta_window_activate_full (MetaWindow     *window,
+                                guint32         timestamp,
+                                MetaClientType  source_indication,
+                                MetaWorkspace  *workspace);
+
 #endif
diff --git a/src/core/window-props.c b/src/core/window-props.c
index 6e07d6e..ca73bd2 100644
--- a/src/core/window-props.c
+++ b/src/core/window-props.c
@@ -39,6 +39,7 @@
 
 #include <config.h>
 #include "window-props.h"
+#include "window-x11.h"
 #include <meta/errors.h>
 #include "xprops.h"
 #include "frame.h"
@@ -229,7 +230,7 @@ reload_net_wm_window_type (MetaWindow    *window,
                            MetaPropValue *value,
                            gboolean       initial)
 {
-  meta_window_update_net_wm_type (window);
+  meta_window_x11_update_net_wm_type (window);
 }
 
 static void
@@ -333,7 +334,7 @@ reload_wm_window_role (MetaWindow    *window,
                        MetaPropValue *value,
                        gboolean       initial)
 {
-  meta_window_update_role (window);
+  meta_window_x11_update_role (window);
 }
 
 static void
@@ -558,7 +559,7 @@ reload_opaque_region (MetaWindow    *window,
                       MetaPropValue *value,
                       gboolean       initial)
 {
-  meta_window_update_opaque_region_x11 (window);
+  meta_window_x11_update_opaque_region (window);
 }
 
 static void
diff --git a/src/core/window-x11.c b/src/core/window-x11.c
new file mode 100644
index 0000000..3391a54
--- /dev/null
+++ b/src/core/window-x11.c
@@ -0,0 +1,1148 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2001 Havoc Pennington, Anders Carlsson
+ * Copyright (C) 2002, 2003 Red Hat, Inc.
+ * Copyright (C) 2003 Rob Adams
+ * Copyright (C) 2004-2006 Elijah Newren
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "window-x11.h"
+
+#include <string.h>
+#include <X11/Xatom.h>
+#include <X11/Xlibint.h> /* For display->resource_mask */
+
+#ifdef HAVE_SHAPE
+#include <X11/extensions/shape.h>
+#endif
+
+#include <meta/common.h>
+#include <meta/errors.h>
+#include <meta/prefs.h>
+
+#include "window-private.h"
+#include "window-props.h"
+#include "xprops.h"
+
+void
+meta_window_x11_set_net_wm_state (MetaWindow *window)
+{
+  int i;
+  unsigned long data[13];
+
+  i = 0;
+  if (window->shaded)
+    {
+      data[i] = window->display->atom__NET_WM_STATE_SHADED;
+      ++i;
+    }
+  if (window->wm_state_modal)
+    {
+      data[i] = window->display->atom__NET_WM_STATE_MODAL;
+      ++i;
+    }
+  if (window->skip_pager)
+    {
+      data[i] = window->display->atom__NET_WM_STATE_SKIP_PAGER;
+      ++i;
+    }
+  if (window->skip_taskbar)
+    {
+      data[i] = window->display->atom__NET_WM_STATE_SKIP_TASKBAR;
+      ++i;
+    }
+  if (window->maximized_horizontally)
+    {
+      data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_HORZ;
+      ++i;
+    }
+  if (window->maximized_vertically)
+    {
+      data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_VERT;
+      ++i;
+    }
+  if (window->fullscreen)
+    {
+      data[i] = window->display->atom__NET_WM_STATE_FULLSCREEN;
+      ++i;
+    }
+  if (!meta_window_showing_on_its_workspace (window) || window->shaded)
+    {
+      data[i] = window->display->atom__NET_WM_STATE_HIDDEN;
+      ++i;
+    }
+  if (window->wm_state_above)
+    {
+      data[i] = window->display->atom__NET_WM_STATE_ABOVE;
+      ++i;
+    }
+  if (window->wm_state_below)
+    {
+      data[i] = window->display->atom__NET_WM_STATE_BELOW;
+      ++i;
+    }
+  if (window->wm_state_demands_attention)
+    {
+      data[i] = window->display->atom__NET_WM_STATE_DEMANDS_ATTENTION;
+      ++i;
+    }
+  if (window->on_all_workspaces_requested)
+    {
+      data[i] = window->display->atom__NET_WM_STATE_STICKY;
+      ++i;
+    }
+  if (meta_window_appears_focused (window))
+    {
+      data[i] = window->display->atom__NET_WM_STATE_FOCUSED;
+      ++i;
+    }
+
+  meta_verbose ("Setting _NET_WM_STATE with %d atoms\n", i);
+
+  meta_error_trap_push (window->display);
+  XChangeProperty (window->display->xdisplay, window->xwindow,
+                   window->display->atom__NET_WM_STATE,
+                   XA_ATOM,
+                   32, PropModeReplace, (guchar*) data, i);
+  meta_error_trap_pop (window->display);
+
+  if (window->fullscreen)
+    {
+      data[0] = meta_screen_monitor_index_to_xinerama_index (window->screen,
+                                                             window->fullscreen_monitors[0]);
+      data[1] = meta_screen_monitor_index_to_xinerama_index (window->screen,
+                                                             window->fullscreen_monitors[1]);
+      data[2] = meta_screen_monitor_index_to_xinerama_index (window->screen,
+                                                             window->fullscreen_monitors[2]);
+      data[3] = meta_screen_monitor_index_to_xinerama_index (window->screen,
+                                                             window->fullscreen_monitors[3]);
+
+      meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS\n");
+      meta_error_trap_push (window->display);
+      XChangeProperty (window->display->xdisplay,
+                       window->xwindow,
+                       window->display->atom__NET_WM_FULLSCREEN_MONITORS,
+                       XA_CARDINAL, 32, PropModeReplace,
+                       (guchar*) data, 4);
+      meta_error_trap_pop (window->display);
+    }
+}
+
+void
+meta_window_x11_update_net_wm_type (MetaWindow *window)
+{
+  int n_atoms;
+  Atom *atoms;
+  int i;
+
+  window->type_atom = None;
+  n_atoms = 0;
+  atoms = NULL;
+
+  meta_prop_get_atom_list (window->display, window->xwindow,
+                           window->display->atom__NET_WM_WINDOW_TYPE,
+                           &atoms, &n_atoms);
+
+  i = 0;
+  while (i < n_atoms)
+    {
+      /* We break as soon as we find one we recognize,
+       * supposed to prefer those near the front of the list
+       */
+      if (atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP ||
+          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DOCK ||
+          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR ||
+          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_MENU ||
+          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY ||
+          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH ||
+          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG ||
+          atoms[i] ==
+           window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU ||
+          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU ||
+          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP ||
+          atoms[i] ==
+           window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION ||
+          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_COMBO ||
+          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DND ||
+          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL)
+        {
+          window->type_atom = atoms[i];
+          break;
+        }
+
+      ++i;
+    }
+
+  meta_XFree (atoms);
+
+  if (meta_is_verbose ())
+    {
+      char *str;
+
+      str = NULL;
+      if (window->type_atom != None)
+        {
+          meta_error_trap_push (window->display);
+          str = XGetAtomName (window->display->xdisplay, window->type_atom);
+          meta_error_trap_pop (window->display);
+        }
+
+      meta_verbose ("Window %s type atom %s\n", window->desc,
+                    str ? str : "(none)");
+
+      if (str)
+        meta_XFree (str);
+    }
+
+  meta_window_recalc_window_type (window);
+}
+
+void
+meta_window_x11_update_role (MetaWindow *window)
+{
+  char *str;
+
+  g_return_if_fail (!window->override_redirect);
+
+  if (window->role)
+    g_free (window->role);
+  window->role = NULL;
+
+  if (meta_prop_get_latin1_string (window->display, window->xwindow,
+                                   window->display->atom_WM_WINDOW_ROLE,
+                                   &str))
+    {
+      window->role = g_strdup (str);
+      meta_XFree (str);
+    }
+
+  meta_verbose ("Updated role of %s to '%s'\n",
+                window->desc, window->role ? window->role : "null");
+}
+
+static void
+meta_window_set_opaque_region (MetaWindow     *window,
+                               cairo_region_t *region)
+{
+  g_clear_pointer (&window->opaque_region, cairo_region_destroy);
+
+  if (region != NULL)
+    window->opaque_region = cairo_region_reference (region);
+
+  if (window->display->compositor)
+    meta_compositor_window_shape_changed (window->display->compositor, window);
+}
+
+void
+meta_window_x11_update_opaque_region (MetaWindow *window)
+{
+  cairo_region_t *opaque_region = NULL;
+  gulong *region = NULL;
+  int nitems;
+
+  if (meta_prop_get_cardinal_list (window->display,
+                                   window->xwindow,
+                                   window->display->atom__NET_WM_OPAQUE_REGION,
+                                   &region, &nitems))
+    {
+      cairo_rectangle_int_t *rects;
+      int i, rect_index, nrects;
+
+      if (nitems % 4 != 0)
+        {
+          meta_verbose ("_NET_WM_OPAQUE_REGION does not have a list of 4-tuples.");
+          goto out;
+        }
+
+      /* empty region */
+      if (nitems == 0)
+        goto out;
+
+      nrects = nitems / 4;
+
+      rects = g_new (cairo_rectangle_int_t, nrects);
+
+      rect_index = 0;
+      i = 0;
+      while (i < nitems)
+        {
+          cairo_rectangle_int_t *rect = &rects[rect_index];
+
+          rect->x = region[i++];
+          rect->y = region[i++];
+          rect->width = region[i++];
+          rect->height = region[i++];
+
+          rect_index++;
+        }
+
+      opaque_region = cairo_region_create_rectangles (rects, nrects);
+
+      g_free (rects);
+    }
+
+ out:
+  meta_XFree (region);
+
+  meta_window_set_opaque_region (window, opaque_region);
+  cairo_region_destroy (opaque_region);
+}
+
+static cairo_region_t *
+region_create_from_x_rectangles (const XRectangle *rects,
+                                 int n_rects)
+{
+  int i;
+  cairo_rectangle_int_t *cairo_rects = g_newa (cairo_rectangle_int_t, n_rects);
+
+  for (i = 0; i < n_rects; i ++)
+    {
+      cairo_rects[i].x = rects[i].x;
+      cairo_rects[i].y = rects[i].y;
+      cairo_rects[i].width = rects[i].width;
+      cairo_rects[i].height = rects[i].height;
+    }
+
+  return cairo_region_create_rectangles (cairo_rects, n_rects);
+}
+
+static void
+meta_window_set_input_region (MetaWindow     *window,
+                              cairo_region_t *region)
+{
+  g_clear_pointer (&window->input_region, cairo_region_destroy);
+
+  if (region != NULL)
+    window->input_region = cairo_region_reference (region);
+
+  if (window->display->compositor)
+    meta_compositor_window_shape_changed (window->display->compositor, window);
+}
+
+void
+meta_window_x11_update_input_region (MetaWindow *window)
+{
+  cairo_region_t *region = NULL;
+
+#ifdef HAVE_SHAPE
+  if (META_DISPLAY_HAS_SHAPE (window->display))
+    {
+      /* Translate the set of XShape rectangles that we
+       * get from the X server to a cairo_region. */
+      XRectangle *rects = NULL;
+      int n_rects, ordering;
+
+      int x_bounding, y_bounding, x_clip, y_clip;
+      unsigned w_bounding, h_bounding, w_clip, h_clip;
+      int bounding_shaped, clip_shaped;
+
+      meta_error_trap_push (window->display);
+      XShapeQueryExtents (window->display->xdisplay, window->xwindow,
+                          &bounding_shaped, &x_bounding, &y_bounding,
+                          &w_bounding, &h_bounding,
+                          &clip_shaped, &x_clip, &y_clip,
+                          &w_clip, &h_clip);
+
+      rects = XShapeGetRectangles (window->display->xdisplay,
+                                   window->xwindow,
+                                   ShapeInput,
+                                   &n_rects,
+                                   &ordering);
+      meta_error_trap_pop (window->display);
+
+      /* XXX: The x shape extension doesn't provide a way to only test if an
+       * input shape has been specified, so we have to query and throw away the
+       * rectangles. */
+      if (rects)
+        {
+          if (n_rects > 1 ||
+              (n_rects == 1 &&
+               (rects[0].x != x_bounding ||
+                rects[1].y != y_bounding ||
+                rects[2].width != w_bounding ||
+                rects[3].height != h_bounding)))
+            region = region_create_from_x_rectangles (rects, n_rects);
+
+          XFree (rects);
+        }
+    }
+#endif /* HAVE_SHAPE */
+
+  if (region != NULL)
+    {
+      cairo_rectangle_int_t client_area;
+
+      client_area.x = 0;
+      client_area.y = 0;
+      client_area.width = window->rect.width;
+      client_area.height = window->rect.height;
+
+      /* The shape we get back from the client may have coordinates
+       * outside of the frame. The X SHAPE Extension requires that
+       * the overall shape the client provides never exceeds the
+       * "bounding rectangle" of the window -- the shape that the
+       * window would have gotten if it was unshaped. In our case,
+       * this is simply the client area.
+       */
+      cairo_region_intersect_rectangle (region, &client_area);
+    }
+
+  meta_window_set_input_region (window, region);
+  cairo_region_destroy (region);
+}
+
+static void
+meta_window_set_shape_region (MetaWindow     *window,
+                              cairo_region_t *region)
+{
+  g_clear_pointer (&window->shape_region, cairo_region_destroy);
+
+  if (region != NULL)
+    window->shape_region = cairo_region_reference (region);
+
+  if (window->display->compositor)
+    meta_compositor_window_shape_changed (window->display->compositor, window);
+}
+
+void
+meta_window_x11_update_shape_region (MetaWindow *window)
+{
+  cairo_region_t *region = NULL;
+
+#ifdef HAVE_SHAPE
+  if (META_DISPLAY_HAS_SHAPE (window->display))
+    {
+      /* Translate the set of XShape rectangles that we
+       * get from the X server to a cairo_region. */
+      XRectangle *rects = NULL;
+      int n_rects, ordering;
+
+      int x_bounding, y_bounding, x_clip, y_clip;
+      unsigned w_bounding, h_bounding, w_clip, h_clip;
+      int bounding_shaped, clip_shaped;
+
+      meta_error_trap_push (window->display);
+      XShapeQueryExtents (window->display->xdisplay, window->xwindow,
+                          &bounding_shaped, &x_bounding, &y_bounding,
+                          &w_bounding, &h_bounding,
+                          &clip_shaped, &x_clip, &y_clip,
+                          &w_clip, &h_clip);
+
+      if (bounding_shaped)
+        {
+          rects = XShapeGetRectangles (window->display->xdisplay,
+                                       window->xwindow,
+                                       ShapeBounding,
+                                       &n_rects,
+                                       &ordering);
+        }
+      meta_error_trap_pop (window->display);
+
+      if (rects)
+        {
+          region = region_create_from_x_rectangles (rects, n_rects);
+          XFree (rects);
+        }
+    }
+#endif /* HAVE_SHAPE */
+
+  if (region != NULL)
+    {
+      cairo_rectangle_int_t client_area;
+
+      client_area.x = 0;
+      client_area.y = 0;
+      client_area.width = window->rect.width;
+      client_area.height = window->rect.height;
+
+      /* The shape we get back from the client may have coordinates
+       * outside of the frame. The X SHAPE Extension requires that
+       * the overall shape the client provides never exceeds the
+       * "bounding rectangle" of the window -- the shape that the
+       * window would have gotten if it was unshaped. In our case,
+       * this is simply the client area.
+       */
+      cairo_region_intersect_rectangle (region, &client_area);
+    }
+
+  meta_window_set_shape_region (window, region);
+  cairo_region_destroy (region);
+}
+
+/* Generally meta_window_same_application() is a better idea
+ * of "sameness", since it handles the case where multiple apps
+ * want to look like the same app or the same app wants to look
+ * like multiple apps, but in the case of workarounds for legacy
+ * applications (which likely aren't setting the group properly
+ * anyways), it may be desirable to check this as well.
+ */
+static gboolean
+meta_window_same_client (MetaWindow *window,
+                         MetaWindow *other_window)
+{
+  int resource_mask = window->display->xdisplay->resource_mask;
+
+  return ((window->xwindow & ~resource_mask) ==
+          (other_window->xwindow & ~resource_mask));
+}
+
+gboolean
+meta_window_x11_configure_request (MetaWindow *window,
+                                   XEvent     *event)
+{
+  /* Note that x, y is the corner of the window border,
+   * and width, height is the size of the window inside
+   * its border, but that we always deny border requests
+   * and give windows a border of 0. But we save the
+   * requested border here.
+   */
+  if (event->xconfigurerequest.value_mask & CWBorderWidth)
+    window->border_width = event->xconfigurerequest.border_width;
+
+  meta_window_move_resize_request(window,
+                                  event->xconfigurerequest.value_mask,
+                                  window->size_hints.win_gravity,
+                                  event->xconfigurerequest.x,
+                                  event->xconfigurerequest.y,
+                                  event->xconfigurerequest.width,
+                                  event->xconfigurerequest.height);
+
+  /* Handle stacking. We only handle raises/lowers, mostly because
+   * stack.c really can't deal with anything else.  I guess we'll fix
+   * that if a client turns up that really requires it. Only a very
+   * few clients even require the raise/lower (and in fact all client
+   * attempts to deal with stacking order are essentially broken,
+   * since they have no idea what other clients are involved or how
+   * the stack looks).
+   *
+   * I'm pretty sure no interesting client uses TopIf, BottomIf, or
+   * Opposite anyway, so the only possible missing thing is
+   * Above/Below with a sibling set. For now we just pretend there's
+   * never a sibling set and always do the full raise/lower instead of
+   * the raise-just-above/below-sibling.
+   */
+  if (event->xconfigurerequest.value_mask & CWStackMode)
+    {
+      MetaWindow *active_window;
+      active_window = window->display->focus_window;
+      if (meta_prefs_get_disable_workarounds ())
+        {
+          meta_topic (META_DEBUG_STACK,
+                      "%s sent an xconfigure stacking request; this is "
+                      "broken behavior and the request is being ignored.\n",
+                      window->desc);
+        }
+      else if (active_window &&
+               !meta_window_same_application (window, active_window) &&
+               !meta_window_same_client (window, active_window) &&
+               XSERVER_TIME_IS_BEFORE (window->net_wm_user_time,
+                                       active_window->net_wm_user_time))
+        {
+          meta_topic (META_DEBUG_STACK,
+                      "Ignoring xconfigure stacking request from %s (with "
+                      "user_time %u); currently active application is %s (with "
+                      "user_time %u).\n",
+                      window->desc,
+                      window->net_wm_user_time,
+                      active_window->desc,
+                      active_window->net_wm_user_time);
+          if (event->xconfigurerequest.detail == Above)
+            meta_window_set_demands_attention(window);
+        }
+      else
+        {
+          switch (event->xconfigurerequest.detail)
+            {
+            case Above:
+              meta_window_raise (window);
+              break;
+            case Below:
+              meta_window_lower (window);
+              break;
+            case TopIf:
+            case BottomIf:
+            case Opposite:
+              break;
+            }
+        }
+    }
+
+  return TRUE;
+}
+
+static gboolean
+process_property_notify (MetaWindow     *window,
+                         XPropertyEvent *event)
+{
+  Window xid = window->xwindow;
+
+  if (meta_is_verbose ()) /* avoid looking up the name if we don't have to */
+    {
+      char *property_name = XGetAtomName (window->display->xdisplay,
+                                          event->atom);
+
+      meta_verbose ("Property notify on %s for %s\n",
+                    window->desc, property_name);
+      XFree (property_name);
+    }
+
+  if (event->atom == window->display->atom__NET_WM_USER_TIME &&
+      window->user_time_window)
+    {
+        xid = window->user_time_window;
+    }
+
+  meta_window_reload_property_from_xwindow (window, xid, event->atom, FALSE);
+
+  return TRUE;
+}
+
+gboolean
+meta_window_x11_property_notify (MetaWindow *window,
+                                 XEvent     *event)
+{
+  return process_property_notify (window, &event->xproperty);
+}
+
+#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT      0
+#define _NET_WM_MOVERESIZE_SIZE_TOP          1
+#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT     2
+#define _NET_WM_MOVERESIZE_SIZE_RIGHT        3
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT  4
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOM       5
+#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT   6
+#define _NET_WM_MOVERESIZE_SIZE_LEFT         7
+#define _NET_WM_MOVERESIZE_MOVE              8
+#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD     9
+#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD    10
+#define _NET_WM_MOVERESIZE_CANCEL           11
+
+static int
+query_pressed_buttons (MetaWindow *window)
+{
+  double x, y, query_root_x, query_root_y;
+  Window root, child;
+  XIButtonState buttons;
+  XIModifierState mods;
+  XIGroupState group;
+  int button = 0;
+
+  meta_error_trap_push (window->display);
+  XIQueryPointer (window->display->xdisplay,
+                  META_VIRTUAL_CORE_POINTER_ID,
+                  window->xwindow,
+                  &root, &child,
+                  &query_root_x, &query_root_y,
+                  &x, &y,
+                  &buttons, &mods, &group);
+
+  if (meta_error_trap_pop_with_return (window->display) != Success)
+    goto out;
+
+  if (XIMaskIsSet (buttons.mask, Button1))
+    button |= 1 << 1;
+  if (XIMaskIsSet (buttons.mask, Button2))
+    button |= 1 << 2;
+  if (XIMaskIsSet (buttons.mask, Button3))
+    button |= 1 << 3;
+
+  free (buttons.mask);
+
+ out:
+  return button;
+}
+
+gboolean
+meta_window_x11_client_message (MetaWindow *window,
+                                XEvent     *event)
+{
+  MetaDisplay *display;
+
+  display = window->display;
+
+  if (window->override_redirect)
+    {
+      /* Don't warn here: we could warn on any of the messages below,
+       * but we might also receive other client messages that are
+       * part of protocols we don't know anything about. So, silently
+       * ignoring is simplest.
+       */
+      return FALSE;
+    }
+
+  if (event->xclient.message_type ==
+      display->atom__NET_CLOSE_WINDOW)
+    {
+      guint32 timestamp;
+
+      if (event->xclient.data.l[0] != 0)
+       timestamp = event->xclient.data.l[0];
+      else
+        {
+          meta_warning ("Receiving a NET_CLOSE_WINDOW message for %s without "
+                        "a timestamp!  This means some buggy (outdated) "
+                        "application is on the loose!\n",
+                        window->desc);
+          timestamp = meta_display_get_current_time (window->display);
+        }
+
+      meta_window_delete (window, timestamp);
+
+      return TRUE;
+    }
+  else if (event->xclient.message_type ==
+           display->atom__NET_WM_DESKTOP)
+    {
+      int space;
+      MetaWorkspace *workspace;
+
+      space = event->xclient.data.l[0];
+
+      meta_verbose ("Request to move %s to workspace %d\n",
+                    window->desc, space);
+
+      workspace =
+        meta_screen_get_workspace_by_index (window->screen,
+                                            space);
+
+      if (workspace)
+        {
+          if (window->on_all_workspaces_requested)
+            meta_window_unstick (window);
+          meta_window_change_workspace (window, workspace);
+        }
+      else if (space == (int) 0xFFFFFFFF)
+        {
+          meta_window_stick (window);
+        }
+      else
+        {
+          meta_verbose ("No such workspace %d for screen\n", space);
+        }
+
+      meta_verbose ("Window %s now on_all_workspaces = %d\n",
+                    window->desc, window->on_all_workspaces);
+
+      return TRUE;
+    }
+  else if (event->xclient.message_type ==
+           display->atom__NET_WM_STATE)
+    {
+      gulong action;
+      Atom first;
+      Atom second;
+
+      action = event->xclient.data.l[0];
+      first = event->xclient.data.l[1];
+      second = event->xclient.data.l[2];
+
+      if (meta_is_verbose ())
+        {
+          char *str1;
+          char *str2;
+
+          meta_error_trap_push_with_return (display);
+          str1 = XGetAtomName (display->xdisplay, first);
+          if (meta_error_trap_pop_with_return (display) != Success)
+            str1 = NULL;
+
+          meta_error_trap_push_with_return (display);
+          str2 = XGetAtomName (display->xdisplay, second);
+          if (meta_error_trap_pop_with_return (display) != Success)
+            str2 = NULL;
+
+          meta_verbose ("Request to change _NET_WM_STATE action %lu atom1: %s atom2: %s\n",
+                        action,
+                        str1 ? str1 : "(unknown)",
+                        str2 ? str2 : "(unknown)");
+
+          meta_XFree (str1);
+          meta_XFree (str2);
+        }
+
+      if (first == display->atom__NET_WM_STATE_SHADED ||
+          second == display->atom__NET_WM_STATE_SHADED)
+        {
+          gboolean shade;
+          guint32 timestamp;
+
+          /* Stupid protocol has no timestamp; of course, shading
+           * sucks anyway so who really cares that we're forced to do
+           * a roundtrip here?
+           */
+          timestamp = meta_display_get_current_time_roundtrip (window->display);
+
+          shade = (action == _NET_WM_STATE_ADD ||
+                   (action == _NET_WM_STATE_TOGGLE && !window->shaded));
+          if (shade && window->has_shade_func)
+            meta_window_shade (window, timestamp);
+          else
+            meta_window_unshade (window, timestamp);
+        }
+
+      if (first == display->atom__NET_WM_STATE_FULLSCREEN ||
+          second == display->atom__NET_WM_STATE_FULLSCREEN)
+        {
+          gboolean make_fullscreen;
+
+          make_fullscreen = (action == _NET_WM_STATE_ADD ||
+                             (action == _NET_WM_STATE_TOGGLE && !window->fullscreen));
+          if (make_fullscreen && window->has_fullscreen_func)
+            meta_window_make_fullscreen (window);
+          else
+            meta_window_unmake_fullscreen (window);
+        }
+
+      if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ ||
+          second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ ||
+          first == display->atom__NET_WM_STATE_MAXIMIZED_VERT ||
+          second == display->atom__NET_WM_STATE_MAXIMIZED_VERT)
+        {
+          gboolean max;
+          MetaMaximizeFlags directions = 0;
+
+          max = (action == _NET_WM_STATE_ADD ||
+                 (action == _NET_WM_STATE_TOGGLE &&
+                  !window->maximized_horizontally));
+
+          if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ ||
+              second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ)
+            directions |= META_MAXIMIZE_HORIZONTAL;
+
+          if (first == display->atom__NET_WM_STATE_MAXIMIZED_VERT ||
+              second == display->atom__NET_WM_STATE_MAXIMIZED_VERT)
+            directions |= META_MAXIMIZE_VERTICAL;
+
+          if (max && window->has_maximize_func)
+            {
+              if (meta_prefs_get_raise_on_click ())
+                meta_window_raise (window);
+              meta_window_maximize (window, directions);
+            }
+          else
+            {
+              if (meta_prefs_get_raise_on_click ())
+                meta_window_raise (window);
+              meta_window_unmaximize (window, directions);
+            }
+        }
+
+      if (first == display->atom__NET_WM_STATE_MODAL ||
+          second == display->atom__NET_WM_STATE_MODAL)
+        {
+          window->wm_state_modal =
+            (action == _NET_WM_STATE_ADD) ||
+            (action == _NET_WM_STATE_TOGGLE && !window->wm_state_modal);
+
+          meta_window_recalc_window_type (window);
+          meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
+        }
+
+      if (first == display->atom__NET_WM_STATE_SKIP_PAGER ||
+          second == display->atom__NET_WM_STATE_SKIP_PAGER)
+        {
+          window->wm_state_skip_pager =
+            (action == _NET_WM_STATE_ADD) ||
+            (action == _NET_WM_STATE_TOGGLE && !window->skip_pager);
+
+          meta_window_recalc_features (window);
+          meta_window_x11_set_net_wm_state (window);
+        }
+
+      if (first == display->atom__NET_WM_STATE_SKIP_TASKBAR ||
+          second == display->atom__NET_WM_STATE_SKIP_TASKBAR)
+        {
+          window->wm_state_skip_taskbar =
+            (action == _NET_WM_STATE_ADD) ||
+            (action == _NET_WM_STATE_TOGGLE && !window->skip_taskbar);
+
+          meta_window_recalc_features (window);
+          meta_window_x11_set_net_wm_state (window);
+        }
+
+      if (first == display->atom__NET_WM_STATE_ABOVE ||
+          second == display->atom__NET_WM_STATE_ABOVE)
+        {
+          if ((action == _NET_WM_STATE_ADD) ||
+              (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention))
+            meta_window_make_above (window);
+          else
+            meta_window_unmake_above (window);
+        }
+
+      if (first == display->atom__NET_WM_STATE_BELOW ||
+          second == display->atom__NET_WM_STATE_BELOW)
+        {
+          window->wm_state_below =
+            (action == _NET_WM_STATE_ADD) ||
+            (action == _NET_WM_STATE_TOGGLE && !window->wm_state_below);
+
+          meta_window_update_layer (window);
+          meta_window_x11_set_net_wm_state (window);
+        }
+
+      if (first == display->atom__NET_WM_STATE_DEMANDS_ATTENTION ||
+          second == display->atom__NET_WM_STATE_DEMANDS_ATTENTION)
+        {
+          if ((action == _NET_WM_STATE_ADD) ||
+              (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention))
+            meta_window_set_demands_attention (window);
+          else
+            meta_window_unset_demands_attention (window);
+        }
+
+       if (first == display->atom__NET_WM_STATE_STICKY ||
+          second == display->atom__NET_WM_STATE_STICKY)
+        {
+          if ((action == _NET_WM_STATE_ADD) ||
+              (action == _NET_WM_STATE_TOGGLE && !window->on_all_workspaces_requested))
+            meta_window_stick (window);
+          else
+            meta_window_unstick (window);
+        }
+
+      return TRUE;
+    }
+  else if (event->xclient.message_type ==
+           display->atom_WM_CHANGE_STATE)
+    {
+      meta_verbose ("WM_CHANGE_STATE client message, state: %ld\n",
+                    event->xclient.data.l[0]);
+      if (event->xclient.data.l[0] == IconicState &&
+          window->has_minimize_func)
+        meta_window_minimize (window);
+
+      return TRUE;
+    }
+  else if (event->xclient.message_type ==
+           display->atom__NET_WM_MOVERESIZE)
+    {
+      int x_root;
+      int y_root;
+      int action;
+      MetaGrabOp op;
+      int button;
+      guint32 timestamp;
+
+      /* _NET_WM_MOVERESIZE messages are almost certainly going to come from
+       * clients when users click on the fake "frame" that the client has,
+       * thus we should also treat such messages as though it were a
+       * "frame action".
+       */
+      gboolean const frame_action = TRUE;
+
+      x_root = event->xclient.data.l[0];
+      y_root = event->xclient.data.l[1];
+      action = event->xclient.data.l[2];
+      button = event->xclient.data.l[3];
+
+      /* FIXME: What a braindead protocol; no timestamp?!? */
+      timestamp = meta_display_get_current_time_roundtrip (display);
+      meta_topic (META_DEBUG_WINDOW_OPS,
+                  "Received _NET_WM_MOVERESIZE message on %s, %d,%d action = %d, button %d\n",
+                  window->desc,
+                  x_root, y_root, action, button);
+
+      op = META_GRAB_OP_NONE;
+      switch (action)
+        {
+        case _NET_WM_MOVERESIZE_SIZE_TOPLEFT:
+          op = META_GRAB_OP_RESIZING_NW;
+          break;
+        case _NET_WM_MOVERESIZE_SIZE_TOP:
+          op = META_GRAB_OP_RESIZING_N;
+          break;
+        case _NET_WM_MOVERESIZE_SIZE_TOPRIGHT:
+          op = META_GRAB_OP_RESIZING_NE;
+          break;
+        case _NET_WM_MOVERESIZE_SIZE_RIGHT:
+          op = META_GRAB_OP_RESIZING_E;
+          break;
+        case _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
+          op = META_GRAB_OP_RESIZING_SE;
+          break;
+        case _NET_WM_MOVERESIZE_SIZE_BOTTOM:
+          op = META_GRAB_OP_RESIZING_S;
+          break;
+        case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT:
+          op = META_GRAB_OP_RESIZING_SW;
+          break;
+        case _NET_WM_MOVERESIZE_SIZE_LEFT:
+          op = META_GRAB_OP_RESIZING_W;
+          break;
+        case _NET_WM_MOVERESIZE_MOVE:
+          op = META_GRAB_OP_MOVING;
+          break;
+        case _NET_WM_MOVERESIZE_SIZE_KEYBOARD:
+          op = META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN;
+          break;
+        case _NET_WM_MOVERESIZE_MOVE_KEYBOARD:
+          op = META_GRAB_OP_KEYBOARD_MOVING;
+          break;
+        case _NET_WM_MOVERESIZE_CANCEL:
+          /* handled below */
+          break;
+        default:
+          break;
+        }
+
+      if (action == _NET_WM_MOVERESIZE_CANCEL)
+        {
+          meta_display_end_grab_op (window->display, timestamp);
+        }
+      else if (op != META_GRAB_OP_NONE &&
+          ((window->has_move_func && op == META_GRAB_OP_KEYBOARD_MOVING) ||
+           (window->has_resize_func && op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN)))
+        {
+          meta_window_begin_grab_op (window, op, frame_action, timestamp);
+        }
+      else if (op != META_GRAB_OP_NONE &&
+               ((window->has_move_func && op == META_GRAB_OP_MOVING) ||
+               (window->has_resize_func &&
+                (op != META_GRAB_OP_MOVING &&
+                 op != META_GRAB_OP_KEYBOARD_MOVING))))
+        {
+          int button_mask;
+
+          meta_topic (META_DEBUG_WINDOW_OPS,
+                      "Beginning move/resize with button = %d\n", button);
+          meta_display_begin_grab_op (window->display,
+                                      window->screen,
+                                      window,
+                                      op,
+                                      FALSE,
+                                      frame_action,
+                                      button, 0,
+                                      timestamp,
+                                      x_root,
+                                      y_root);
+
+          button_mask = query_pressed_buttons (window);
+
+          if (button == 0)
+            {
+              /*
+               * the button SHOULD already be included in the message
+               */
+              if ((button_mask & (1 << 1)) != 0)
+                button = 1;
+              else if ((button_mask & (1 << 2)) != 0)
+                button = 2;
+              else if ((button_mask & (1 << 3)) != 0)
+                button = 3;
+
+              if (button != 0)
+                window->display->grab_button = button;
+              else
+                meta_display_end_grab_op (window->display,
+                                          timestamp);
+            }
+          else
+            {
+              /* There is a potential race here. If the user presses and
+               * releases their mouse button very fast, it's possible for
+               * both the ButtonPress and ButtonRelease to be sent to the
+               * client before it can get a chance to send _NET_WM_MOVERESIZE
+               * to us. When that happens, we'll become stuck in a grab
+               * state, as we haven't received a ButtonRelease to cancel the
+               * grab.
+               *
+               * We can solve this by querying after we take the explicit
+               * pointer grab -- if the button isn't pressed, we cancel the
+               * drag immediately.
+               */
+
+              if ((button_mask & (1 << button)) == 0)
+                meta_display_end_grab_op (window->display, timestamp);
+            }
+        }
+
+      return TRUE;
+    }
+  else if (event->xclient.message_type ==
+           display->atom__NET_MOVERESIZE_WINDOW)
+    {
+      int gravity;
+      guint value_mask;
+
+      gravity = (event->xclient.data.l[0] & 0xff);
+      value_mask = (event->xclient.data.l[0] & 0xf00) >> 8;
+      /* source = (event->xclient.data.l[0] & 0xf000) >> 12; */
+
+      if (gravity == 0)
+        gravity = window->size_hints.win_gravity;
+
+      meta_window_move_resize_request(window,
+                                      value_mask,
+                                      gravity,
+                                      event->xclient.data.l[1],  /* x */
+                                      event->xclient.data.l[2],  /* y */
+                                      event->xclient.data.l[3],  /* width */
+                                      event->xclient.data.l[4]); /* height */
+    }
+  else if (event->xclient.message_type ==
+           display->atom__NET_ACTIVE_WINDOW)
+    {
+      MetaClientType source_indication;
+      guint32        timestamp;
+
+      meta_verbose ("_NET_ACTIVE_WINDOW request for window '%s', activating\n",
+                    window->desc);
+
+      source_indication = event->xclient.data.l[0];
+      timestamp = event->xclient.data.l[1];
+
+      if (source_indication > META_CLIENT_TYPE_MAX_RECOGNIZED)
+        source_indication = META_CLIENT_TYPE_UNKNOWN;
+
+      if (timestamp == 0)
+        {
+          /* Client using older EWMH _NET_ACTIVE_WINDOW without a timestamp */
+          meta_warning ("Buggy client sent a _NET_ACTIVE_WINDOW message with a "
+                        "timestamp of 0 for %s\n",
+                        window->desc);
+          timestamp = meta_display_get_current_time (display);
+        }
+
+      meta_window_activate_full (window, timestamp, source_indication, NULL);
+      return TRUE;
+    }
+  else if (event->xclient.message_type ==
+           display->atom__NET_WM_FULLSCREEN_MONITORS)
+    {
+      gulong top, bottom, left, right;
+
+      meta_verbose ("_NET_WM_FULLSCREEN_MONITORS request for window '%s'\n",
+                    window->desc);
+
+      top = meta_screen_xinerama_index_to_monitor_index (window->screen,
+                                                         event->xclient.data.l[0]);
+      bottom = meta_screen_xinerama_index_to_monitor_index (window->screen,
+                                                            event->xclient.data.l[1]);
+      left = meta_screen_xinerama_index_to_monitor_index (window->screen,
+                                                          event->xclient.data.l[2]);
+      right = meta_screen_xinerama_index_to_monitor_index (window->screen,
+                                                           event->xclient.data.l[3]);
+      /* source_indication = event->xclient.data.l[4]; */
+
+      meta_window_update_fullscreen_monitors (window, top, bottom, left, right);
+    }
+
+  return FALSE;
+}
diff --git a/src/core/window-x11.h b/src/core/window-x11.h
new file mode 100644
index 0000000..aea216f
--- /dev/null
+++ b/src/core/window-x11.h
@@ -0,0 +1,44 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2002 Red Hat, Inc.
+ * Copyright (C) 2003, 2004 Rob Adams
+ * Copyright (C) 2004-2006 Elijah Newren
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef META_WINDOW_X11_H
+#define META_WINDOW_X11_H
+
+#include <meta/window.h>
+#include <X11/Xlib.h>
+
+void meta_window_x11_set_net_wm_state  (MetaWindow *window);
+
+void meta_window_x11_update_role (MetaWindow *window);
+void meta_window_x11_update_net_wm_type (MetaWindow *window);
+void meta_window_x11_update_opaque_region (MetaWindow *window);
+void meta_window_x11_update_input_region  (MetaWindow *window);
+void meta_window_x11_update_shape_region  (MetaWindow *window);
+
+gboolean meta_window_x11_configure_request       (MetaWindow *window,
+                                                  XEvent     *event);
+gboolean meta_window_x11_property_notify         (MetaWindow *window,
+                                                  XEvent     *event);
+gboolean meta_window_x11_client_message          (MetaWindow *window,
+                                                  XEvent     *event);
+
+#endif
diff --git a/src/core/window.c b/src/core/window.c
index e1455d2..db8fd42 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -28,6 +28,7 @@
 
 #include <config.h>
 #include "window-private.h"
+#include "window-x11.h"
 #include "boxes-private.h"
 #include "edge-resistance.h"
 #include "util-private.h"
@@ -49,7 +50,6 @@
 #include "core.h"
 
 #include <X11/Xatom.h>
-#include <X11/Xlibint.h> /* For display->resource_mask */
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
@@ -105,17 +105,12 @@ static void     meta_window_set_above     (MetaWindow     *window,
                                            gboolean        new_value);
 
 static void     send_configure_notify     (MetaWindow     *window);
-static gboolean process_property_notify   (MetaWindow     *window,
-                                           XPropertyEvent *event);
 
 static void     meta_window_force_placement (MetaWindow     *window);
 
 static void     meta_window_show          (MetaWindow     *window);
 static void     meta_window_hide          (MetaWindow     *window);
 
-static gboolean meta_window_same_client (MetaWindow *window,
-                                         MetaWindow *other_window);
-
 static void     meta_window_save_rect         (MetaWindow    *window);
 static void     save_user_window_placement    (MetaWindow    *window);
 static void     force_save_user_window_placement (MetaWindow    *window);
@@ -1031,8 +1026,8 @@ meta_window_new_shared (MetaDisplay         *display,
   if (client_type == META_WINDOW_CLIENT_TYPE_X11)
     {
       meta_display_register_x_window (display, &window->xwindow, window);
-      meta_window_update_shape_region_x11 (window);
-      meta_window_update_input_region_x11 (window);
+      meta_window_x11_update_shape_region (window);
+      meta_window_x11_update_input_region (window);
     }
   else
     meta_display_register_wayland_window (display, window);
@@ -2112,105 +2107,8 @@ set_wm_state (MetaWindow *window,
 static void
 set_net_wm_state (MetaWindow *window)
 {
-  int i;
-  unsigned long data[13];
-
-  i = 0;
-  if (window->shaded)
-    {
-      data[i] = window->display->atom__NET_WM_STATE_SHADED;
-      ++i;
-    }
-  if (window->wm_state_modal)
-    {
-      data[i] = window->display->atom__NET_WM_STATE_MODAL;
-      ++i;
-    }
-  if (window->skip_pager)
-    {
-      data[i] = window->display->atom__NET_WM_STATE_SKIP_PAGER;
-      ++i;
-    }
-  if (window->skip_taskbar)
-    {
-      data[i] = window->display->atom__NET_WM_STATE_SKIP_TASKBAR;
-      ++i;
-    }
-  if (window->maximized_horizontally)
-    {
-      data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_HORZ;
-      ++i;
-    }
-  if (window->maximized_vertically)
-    {
-      data[i] = window->display->atom__NET_WM_STATE_MAXIMIZED_VERT;
-      ++i;
-    }
-  if (window->fullscreen)
-    {
-      data[i] = window->display->atom__NET_WM_STATE_FULLSCREEN;
-      ++i;
-    }
-  if (!meta_window_showing_on_its_workspace (window) || window->shaded)
-    {
-      data[i] = window->display->atom__NET_WM_STATE_HIDDEN;
-      ++i;
-    }
-  if (window->wm_state_above)
-    {
-      data[i] = window->display->atom__NET_WM_STATE_ABOVE;
-      ++i;
-    }
-  if (window->wm_state_below)
-    {
-      data[i] = window->display->atom__NET_WM_STATE_BELOW;
-      ++i;
-    }
-  if (window->wm_state_demands_attention)
-    {
-      data[i] = window->display->atom__NET_WM_STATE_DEMANDS_ATTENTION;
-      ++i;
-    }
-  if (window->on_all_workspaces_requested)
-    {
-      data[i] = window->display->atom__NET_WM_STATE_STICKY;
-      ++i;
-    }
-  if (meta_window_appears_focused (window))
-    {
-      data[i] = window->display->atom__NET_WM_STATE_FOCUSED;
-      ++i;
-    }
-
-  meta_verbose ("Setting _NET_WM_STATE with %d atoms\n", i);
-
-  meta_error_trap_push (window->display);
-  XChangeProperty (window->display->xdisplay, window->xwindow,
-                   window->display->atom__NET_WM_STATE,
-                   XA_ATOM,
-                   32, PropModeReplace, (guchar*) data, i);
-  meta_error_trap_pop (window->display);
-
-  if (window->fullscreen)
-    {
-      data[0] = meta_screen_monitor_index_to_xinerama_index (window->screen,
-                                                             window->fullscreen_monitors[0]);
-      data[1] = meta_screen_monitor_index_to_xinerama_index (window->screen,
-                                                             window->fullscreen_monitors[1]);
-      data[2] = meta_screen_monitor_index_to_xinerama_index (window->screen,
-                                                             window->fullscreen_monitors[2]);
-      data[3] = meta_screen_monitor_index_to_xinerama_index (window->screen,
-                                                             window->fullscreen_monitors[3]);
-
-      meta_verbose ("Setting _NET_WM_FULLSCREEN_MONITORS\n");
-      meta_error_trap_push (window->display);
-      XChangeProperty (window->display->xdisplay,
-                       window->xwindow,
-                       window->display->atom__NET_WM_FULLSCREEN_MONITORS,
-                       XA_CARDINAL, 32, PropModeReplace,
-                       (guchar*) data, 4);
-      meta_error_trap_pop (window->display);
-    }
+  if (window->client_type == META_WINDOW_CLIENT_TYPE_X11)
+    meta_window_x11_set_net_wm_state (window);
 }
 
 /**
@@ -4374,11 +4272,11 @@ unminimize_window_and_all_transient_parents (MetaWindow *window)
   meta_window_foreach_ancestor (window, unminimize_func, NULL);
 }
 
-static void
-window_activate (MetaWindow     *window,
-                 guint32         timestamp,
-                 MetaClientType  source_indication,
-                 MetaWorkspace  *workspace)
+void
+meta_window_activate_full (MetaWindow     *window,
+                           guint32         timestamp,
+                           MetaClientType  source_indication,
+                           MetaWorkspace  *workspace)
 {
   gboolean can_ignore_outdated_timestamps;
   meta_topic (META_DEBUG_FOCUS,
@@ -4471,7 +4369,7 @@ meta_window_activate (MetaWindow     *window,
    * we were such.  If we change the pager behavior later, we could revisit
    * this and just add extra flags to window_activate.
    */
-  window_activate (window, timestamp, META_CLIENT_TYPE_PAGER, NULL);
+  meta_window_activate_full (window, timestamp, META_CLIENT_TYPE_PAGER, NULL);
 }
 
 void
@@ -4481,11 +4379,7 @@ meta_window_activate_with_workspace (MetaWindow     *window,
 {
   g_return_if_fail (!window->override_redirect);
 
-  /* We're not really a pager, but the behavior we want is the same as if
-   * we were such.  If we change the pager behavior later, we could revisit
-   * this and just add extra flags to window_activate.
-   */
-  window_activate (window, timestamp, META_CLIENT_TYPE_APPLICATION, workspace);
+  meta_window_activate_full (window, timestamp, META_CLIENT_TYPE_APPLICATION, workspace);
 }
 
 /* Manually fix all the weirdness explained in the big comment at the
@@ -6825,97 +6719,6 @@ meta_window_move_resize_request (MetaWindow *window,
   save_user_window_placement (window);
 }
 
-gboolean
-meta_window_configure_request (MetaWindow *window,
-                               XEvent     *event)
-{
-  /* Note that x, y is the corner of the window border,
-   * and width, height is the size of the window inside
-   * its border, but that we always deny border requests
-   * and give windows a border of 0. But we save the
-   * requested border here.
-   */
-  if (event->xconfigurerequest.value_mask & CWBorderWidth)
-    window->border_width = event->xconfigurerequest.border_width;
-
-  meta_window_move_resize_request(window,
-                                  event->xconfigurerequest.value_mask,
-                                  window->size_hints.win_gravity,
-                                  event->xconfigurerequest.x,
-                                  event->xconfigurerequest.y,
-                                  event->xconfigurerequest.width,
-                                  event->xconfigurerequest.height);
-
-  /* Handle stacking. We only handle raises/lowers, mostly because
-   * stack.c really can't deal with anything else.  I guess we'll fix
-   * that if a client turns up that really requires it. Only a very
-   * few clients even require the raise/lower (and in fact all client
-   * attempts to deal with stacking order are essentially broken,
-   * since they have no idea what other clients are involved or how
-   * the stack looks).
-   *
-   * I'm pretty sure no interesting client uses TopIf, BottomIf, or
-   * Opposite anyway, so the only possible missing thing is
-   * Above/Below with a sibling set. For now we just pretend there's
-   * never a sibling set and always do the full raise/lower instead of
-   * the raise-just-above/below-sibling.
-   */
-  if (event->xconfigurerequest.value_mask & CWStackMode)
-    {
-      MetaWindow *active_window;
-      active_window = window->display->focus_window;
-      if (meta_prefs_get_disable_workarounds ())
-        {
-          meta_topic (META_DEBUG_STACK,
-                      "%s sent an xconfigure stacking request; this is "
-                      "broken behavior and the request is being ignored.\n",
-                      window->desc);
-        }
-      else if (active_window &&
-               !meta_window_same_application (window, active_window) &&
-               !meta_window_same_client (window, active_window) &&
-               XSERVER_TIME_IS_BEFORE (window->net_wm_user_time,
-                                       active_window->net_wm_user_time))
-        {
-          meta_topic (META_DEBUG_STACK,
-                      "Ignoring xconfigure stacking request from %s (with "
-                      "user_time %u); currently active application is %s (with "
-                      "user_time %u).\n",
-                      window->desc,
-                      window->net_wm_user_time,
-                      active_window->desc,
-                      active_window->net_wm_user_time);
-          if (event->xconfigurerequest.detail == Above)
-            meta_window_set_demands_attention(window);
-        }
-      else
-        {
-          switch (event->xconfigurerequest.detail)
-            {
-            case Above:
-              meta_window_raise (window);
-              break;
-            case Below:
-              meta_window_lower (window);
-              break;
-            case TopIf:
-            case BottomIf:
-            case Opposite:
-              break;
-            }
-        }
-    }
-
-  return TRUE;
-}
-
-gboolean
-meta_window_property_notify (MetaWindow *window,
-                             XEvent     *event)
-{
-  return process_property_notify (window, &event->xproperty);
-}
-
 /*
  * Move window to the requested workspace; append controls whether new WS
  * should be created if one does not exist.
@@ -6953,531 +6756,6 @@ meta_window_change_workspace_by_index (MetaWindow *window,
     }
 }
 
-#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT      0
-#define _NET_WM_MOVERESIZE_SIZE_TOP          1
-#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT     2
-#define _NET_WM_MOVERESIZE_SIZE_RIGHT        3
-#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT  4
-#define _NET_WM_MOVERESIZE_SIZE_BOTTOM       5
-#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT   6
-#define _NET_WM_MOVERESIZE_SIZE_LEFT         7
-#define _NET_WM_MOVERESIZE_MOVE              8
-#define _NET_WM_MOVERESIZE_SIZE_KEYBOARD     9
-#define _NET_WM_MOVERESIZE_MOVE_KEYBOARD    10
-#define _NET_WM_MOVERESIZE_CANCEL           11
-
-static int
-query_pressed_buttons (MetaWindow *window)
-{
-  double x, y, query_root_x, query_root_y;
-  Window root, child;
-  XIButtonState buttons;
-  XIModifierState mods;
-  XIGroupState group;
-  int button = 0;
-
-  meta_error_trap_push (window->display);
-  XIQueryPointer (window->display->xdisplay,
-                  META_VIRTUAL_CORE_POINTER_ID,
-                  window->xwindow,
-                  &root, &child,
-                  &query_root_x, &query_root_y,
-                  &x, &y,
-                  &buttons, &mods, &group);
-
-  if (meta_error_trap_pop_with_return (window->display) != Success)
-    goto out;
-
-  if (XIMaskIsSet (buttons.mask, Button1))
-    button |= 1 << 1;
-  if (XIMaskIsSet (buttons.mask, Button2))
-    button |= 1 << 2;
-  if (XIMaskIsSet (buttons.mask, Button3))
-    button |= 1 << 3;
-
-  free (buttons.mask);
-
- out:
-  return button;
-}
-
-gboolean
-meta_window_client_message (MetaWindow *window,
-                            XEvent     *event)
-{
-  MetaDisplay *display;
-
-  display = window->display;
-
-  if (window->override_redirect)
-    {
-      /* Don't warn here: we could warn on any of the messages below,
-       * but we might also receive other client messages that are
-       * part of protocols we don't know anything about. So, silently
-       * ignoring is simplest.
-       */
-      return FALSE;
-    }
-
-  if (event->xclient.message_type ==
-      display->atom__NET_CLOSE_WINDOW)
-    {
-      guint32 timestamp;
-
-      if (event->xclient.data.l[0] != 0)
-       timestamp = event->xclient.data.l[0];
-      else
-        {
-          meta_warning ("Receiving a NET_CLOSE_WINDOW message for %s without "
-                        "a timestamp!  This means some buggy (outdated) "
-                        "application is on the loose!\n",
-                        window->desc);
-          timestamp = meta_display_get_current_time (window->display);
-        }
-
-      meta_window_delete (window, timestamp);
-
-      return TRUE;
-    }
-  else if (event->xclient.message_type ==
-           display->atom__NET_WM_DESKTOP)
-    {
-      int space;
-      MetaWorkspace *workspace;
-
-      space = event->xclient.data.l[0];
-
-      meta_verbose ("Request to move %s to workspace %d\n",
-                    window->desc, space);
-
-      workspace =
-        meta_screen_get_workspace_by_index (window->screen,
-                                            space);
-
-      if (workspace)
-        {
-          if (window->on_all_workspaces_requested)
-            meta_window_unstick (window);
-          meta_window_change_workspace (window, workspace);
-        }
-      else if (space == (int) 0xFFFFFFFF)
-        {
-          meta_window_stick (window);
-        }
-      else
-        {
-          meta_verbose ("No such workspace %d for screen\n", space);
-        }
-
-      meta_verbose ("Window %s now on_all_workspaces = %d\n",
-                    window->desc, window->on_all_workspaces);
-
-      return TRUE;
-    }
-  else if (event->xclient.message_type ==
-           display->atom__NET_WM_STATE)
-    {
-      gulong action;
-      Atom first;
-      Atom second;
-
-      action = event->xclient.data.l[0];
-      first = event->xclient.data.l[1];
-      second = event->xclient.data.l[2];
-
-      if (meta_is_verbose ())
-        {
-          char *str1;
-          char *str2;
-
-          meta_error_trap_push_with_return (display);
-          str1 = XGetAtomName (display->xdisplay, first);
-          if (meta_error_trap_pop_with_return (display) != Success)
-            str1 = NULL;
-
-          meta_error_trap_push_with_return (display);
-          str2 = XGetAtomName (display->xdisplay, second);
-          if (meta_error_trap_pop_with_return (display) != Success)
-            str2 = NULL;
-
-          meta_verbose ("Request to change _NET_WM_STATE action %lu atom1: %s atom2: %s\n",
-                        action,
-                        str1 ? str1 : "(unknown)",
-                        str2 ? str2 : "(unknown)");
-
-          meta_XFree (str1);
-          meta_XFree (str2);
-        }
-
-      if (first == display->atom__NET_WM_STATE_SHADED ||
-          second == display->atom__NET_WM_STATE_SHADED)
-        {
-          gboolean shade;
-          guint32 timestamp;
-
-          /* Stupid protocol has no timestamp; of course, shading
-           * sucks anyway so who really cares that we're forced to do
-           * a roundtrip here?
-           */
-          timestamp = meta_display_get_current_time_roundtrip (window->display);
-
-          shade = (action == _NET_WM_STATE_ADD ||
-                   (action == _NET_WM_STATE_TOGGLE && !window->shaded));
-          if (shade && window->has_shade_func)
-            meta_window_shade (window, timestamp);
-          else
-            meta_window_unshade (window, timestamp);
-        }
-
-      if (first == display->atom__NET_WM_STATE_FULLSCREEN ||
-          second == display->atom__NET_WM_STATE_FULLSCREEN)
-        {
-          gboolean make_fullscreen;
-
-          make_fullscreen = (action == _NET_WM_STATE_ADD ||
-                             (action == _NET_WM_STATE_TOGGLE && !window->fullscreen));
-          if (make_fullscreen && window->has_fullscreen_func)
-            meta_window_make_fullscreen (window);
-          else
-            meta_window_unmake_fullscreen (window);
-        }
-
-      if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ ||
-          second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ ||
-          first == display->atom__NET_WM_STATE_MAXIMIZED_VERT ||
-          second == display->atom__NET_WM_STATE_MAXIMIZED_VERT)
-        {
-          gboolean max;
-          MetaMaximizeFlags directions = 0;
-
-          max = (action == _NET_WM_STATE_ADD ||
-                 (action == _NET_WM_STATE_TOGGLE &&
-                  !window->maximized_horizontally));
-
-          if (first == display->atom__NET_WM_STATE_MAXIMIZED_HORZ ||
-              second == display->atom__NET_WM_STATE_MAXIMIZED_HORZ)
-            directions |= META_MAXIMIZE_HORIZONTAL;
-
-          if (first == display->atom__NET_WM_STATE_MAXIMIZED_VERT ||
-              second == display->atom__NET_WM_STATE_MAXIMIZED_VERT)
-            directions |= META_MAXIMIZE_VERTICAL;
-
-          if (max && window->has_maximize_func)
-            {
-              if (meta_prefs_get_raise_on_click ())
-                meta_window_raise (window);
-              meta_window_maximize (window, directions);
-            }
-          else
-            {
-              if (meta_prefs_get_raise_on_click ())
-                meta_window_raise (window);
-              meta_window_unmaximize (window, directions);
-            }
-        }
-
-      if (first == display->atom__NET_WM_STATE_MODAL ||
-          second == display->atom__NET_WM_STATE_MODAL)
-        {
-          window->wm_state_modal =
-            (action == _NET_WM_STATE_ADD) ||
-            (action == _NET_WM_STATE_TOGGLE && !window->wm_state_modal);
-
-          meta_window_recalc_window_type (window);
-          meta_window_queue(window, META_QUEUE_MOVE_RESIZE);
-        }
-
-      if (first == display->atom__NET_WM_STATE_SKIP_PAGER ||
-          second == display->atom__NET_WM_STATE_SKIP_PAGER)
-        {
-          window->wm_state_skip_pager =
-            (action == _NET_WM_STATE_ADD) ||
-            (action == _NET_WM_STATE_TOGGLE && !window->skip_pager);
-
-          meta_window_recalc_window_features (window);
-          set_net_wm_state (window);
-        }
-
-      if (first == display->atom__NET_WM_STATE_SKIP_TASKBAR ||
-          second == display->atom__NET_WM_STATE_SKIP_TASKBAR)
-        {
-          window->wm_state_skip_taskbar =
-            (action == _NET_WM_STATE_ADD) ||
-            (action == _NET_WM_STATE_TOGGLE && !window->skip_taskbar);
-
-          meta_window_recalc_window_features (window);
-          set_net_wm_state (window);
-        }
-
-      if (first == display->atom__NET_WM_STATE_ABOVE ||
-          second == display->atom__NET_WM_STATE_ABOVE)
-        {
-          meta_window_set_above(window,
-            (action == _NET_WM_STATE_ADD) ||
-            (action == _NET_WM_STATE_TOGGLE && !window->wm_state_above));
-        }
-
-      if (first == display->atom__NET_WM_STATE_BELOW ||
-          second == display->atom__NET_WM_STATE_BELOW)
-        {
-          window->wm_state_below =
-            (action == _NET_WM_STATE_ADD) ||
-            (action == _NET_WM_STATE_TOGGLE && !window->wm_state_below);
-
-          meta_window_update_layer (window);
-          set_net_wm_state (window);
-        }
-
-      if (first == display->atom__NET_WM_STATE_DEMANDS_ATTENTION ||
-          second == display->atom__NET_WM_STATE_DEMANDS_ATTENTION)
-        {
-          if ((action == _NET_WM_STATE_ADD) ||
-              (action == _NET_WM_STATE_TOGGLE && !window->wm_state_demands_attention))
-            meta_window_set_demands_attention (window);
-          else
-            meta_window_unset_demands_attention (window);
-        }
-
-       if (first == display->atom__NET_WM_STATE_STICKY ||
-          second == display->atom__NET_WM_STATE_STICKY)
-        {
-          if ((action == _NET_WM_STATE_ADD) ||
-              (action == _NET_WM_STATE_TOGGLE && !window->on_all_workspaces_requested))
-            meta_window_stick (window);
-          else
-            meta_window_unstick (window);
-        }
-
-      return TRUE;
-    }
-  else if (event->xclient.message_type ==
-           display->atom_WM_CHANGE_STATE)
-    {
-      meta_verbose ("WM_CHANGE_STATE client message, state: %ld\n",
-                    event->xclient.data.l[0]);
-      if (event->xclient.data.l[0] == IconicState &&
-          window->has_minimize_func)
-        meta_window_minimize (window);
-
-      return TRUE;
-    }
-  else if (event->xclient.message_type ==
-           display->atom__NET_WM_MOVERESIZE)
-    {
-      int x_root;
-      int y_root;
-      int action;
-      MetaGrabOp op;
-      int button;
-      guint32 timestamp;
-
-      /* _NET_WM_MOVERESIZE messages are almost certainly going to come from
-       * clients when users click on the fake "frame" that the client has,
-       * thus we should also treat such messages as though it were a
-       * "frame action".
-       */
-      gboolean const frame_action = TRUE;
-
-      x_root = event->xclient.data.l[0];
-      y_root = event->xclient.data.l[1];
-      action = event->xclient.data.l[2];
-      button = event->xclient.data.l[3];
-
-      /* FIXME: What a braindead protocol; no timestamp?!? */
-      timestamp = meta_display_get_current_time_roundtrip (display);
-      meta_topic (META_DEBUG_WINDOW_OPS,
-                  "Received _NET_WM_MOVERESIZE message on %s, %d,%d action = %d, button %d\n",
-                  window->desc,
-                  x_root, y_root, action, button);
-
-      op = META_GRAB_OP_NONE;
-      switch (action)
-        {
-        case _NET_WM_MOVERESIZE_SIZE_TOPLEFT:
-          op = META_GRAB_OP_RESIZING_NW;
-          break;
-        case _NET_WM_MOVERESIZE_SIZE_TOP:
-          op = META_GRAB_OP_RESIZING_N;
-          break;
-        case _NET_WM_MOVERESIZE_SIZE_TOPRIGHT:
-          op = META_GRAB_OP_RESIZING_NE;
-          break;
-        case _NET_WM_MOVERESIZE_SIZE_RIGHT:
-          op = META_GRAB_OP_RESIZING_E;
-          break;
-        case _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
-          op = META_GRAB_OP_RESIZING_SE;
-          break;
-        case _NET_WM_MOVERESIZE_SIZE_BOTTOM:
-          op = META_GRAB_OP_RESIZING_S;
-          break;
-        case _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT:
-          op = META_GRAB_OP_RESIZING_SW;
-          break;
-        case _NET_WM_MOVERESIZE_SIZE_LEFT:
-          op = META_GRAB_OP_RESIZING_W;
-          break;
-        case _NET_WM_MOVERESIZE_MOVE:
-          op = META_GRAB_OP_MOVING;
-          break;
-        case _NET_WM_MOVERESIZE_SIZE_KEYBOARD:
-          op = META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN;
-          break;
-        case _NET_WM_MOVERESIZE_MOVE_KEYBOARD:
-          op = META_GRAB_OP_KEYBOARD_MOVING;
-          break;
-        case _NET_WM_MOVERESIZE_CANCEL:
-          /* handled below */
-          break;
-        default:
-          break;
-        }
-
-      if (action == _NET_WM_MOVERESIZE_CANCEL)
-        {
-          meta_display_end_grab_op (window->display, timestamp);
-        }
-      else if (op != META_GRAB_OP_NONE &&
-          ((window->has_move_func && op == META_GRAB_OP_KEYBOARD_MOVING) ||
-           (window->has_resize_func && op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN)))
-        {
-          meta_window_begin_grab_op (window, op, frame_action, timestamp);
-        }
-      else if (op != META_GRAB_OP_NONE &&
-               ((window->has_move_func && op == META_GRAB_OP_MOVING) ||
-               (window->has_resize_func &&
-                (op != META_GRAB_OP_MOVING &&
-                 op != META_GRAB_OP_KEYBOARD_MOVING))))
-        {
-          int button_mask;
-
-          meta_topic (META_DEBUG_WINDOW_OPS,
-                      "Beginning move/resize with button = %d\n", button);
-          meta_display_begin_grab_op (window->display,
-                                      window->screen,
-                                      window,
-                                      op,
-                                      FALSE,
-                                      frame_action,
-                                      button, 0,
-                                      timestamp,
-                                      x_root,
-                                      y_root);
-
-          button_mask = query_pressed_buttons (window);
-
-          if (button == 0)
-            {
-              /*
-               * the button SHOULD already be included in the message
-               */
-              if ((button_mask & (1 << 1)) != 0)
-                button = 1;
-              else if ((button_mask & (1 << 2)) != 0)
-                button = 2;
-              else if ((button_mask & (1 << 3)) != 0)
-                button = 3;
-
-              if (button != 0)
-                window->display->grab_button = button;
-              else
-                meta_display_end_grab_op (window->display,
-                                          timestamp);
-            }
-          else
-            {
-              /* There is a potential race here. If the user presses and
-               * releases their mouse button very fast, it's possible for
-               * both the ButtonPress and ButtonRelease to be sent to the
-               * client before it can get a chance to send _NET_WM_MOVERESIZE
-               * to us. When that happens, we'll become stuck in a grab
-               * state, as we haven't received a ButtonRelease to cancel the
-               * grab.
-               *
-               * We can solve this by querying after we take the explicit
-               * pointer grab -- if the button isn't pressed, we cancel the
-               * drag immediately.
-               */
-
-              if ((button_mask & (1 << button)) == 0)
-                meta_display_end_grab_op (window->display, timestamp);
-            }
-        }
-
-      return TRUE;
-    }
-  else if (event->xclient.message_type ==
-           display->atom__NET_MOVERESIZE_WINDOW)
-    {
-      int gravity;
-      guint value_mask;
-
-      gravity = (event->xclient.data.l[0] & 0xff);
-      value_mask = (event->xclient.data.l[0] & 0xf00) >> 8;
-      /* source = (event->xclient.data.l[0] & 0xf000) >> 12; */
-
-      if (gravity == 0)
-        gravity = window->size_hints.win_gravity;
-
-      meta_window_move_resize_request(window,
-                                      value_mask,
-                                      gravity,
-                                      event->xclient.data.l[1],  /* x */
-                                      event->xclient.data.l[2],  /* y */
-                                      event->xclient.data.l[3],  /* width */
-                                      event->xclient.data.l[4]); /* height */
-    }
-  else if (event->xclient.message_type ==
-           display->atom__NET_ACTIVE_WINDOW)
-    {
-      MetaClientType source_indication;
-      guint32        timestamp;
-
-      meta_verbose ("_NET_ACTIVE_WINDOW request for window '%s', activating\n",
-                    window->desc);
-
-      source_indication = event->xclient.data.l[0];
-      timestamp = event->xclient.data.l[1];
-
-      if (source_indication > META_CLIENT_TYPE_MAX_RECOGNIZED)
-        source_indication = META_CLIENT_TYPE_UNKNOWN;
-
-      if (timestamp == 0)
-        {
-          /* Client using older EWMH _NET_ACTIVE_WINDOW without a timestamp */
-          meta_warning ("Buggy client sent a _NET_ACTIVE_WINDOW message with a "
-                        "timestamp of 0 for %s\n",
-                        window->desc);
-          timestamp = meta_display_get_current_time (display);
-        }
-
-      window_activate (window, timestamp, source_indication, NULL);
-      return TRUE;
-    }
-  else if (event->xclient.message_type ==
-           display->atom__NET_WM_FULLSCREEN_MONITORS)
-    {
-      gulong top, bottom, left, right;
-
-      meta_verbose ("_NET_WM_FULLSCREEN_MONITORS request for window '%s'\n",
-                    window->desc);
-
-      top = meta_screen_xinerama_index_to_monitor_index (window->screen,
-                                                         event->xclient.data.l[0]);
-      bottom = meta_screen_xinerama_index_to_monitor_index (window->screen,
-                                                            event->xclient.data.l[1]);
-      left = meta_screen_xinerama_index_to_monitor_index (window->screen,
-                                                          event->xclient.data.l[2]);
-      right = meta_screen_xinerama_index_to_monitor_index (window->screen,
-                                                           event->xclient.data.l[3]);
-      /* source_indication = event->xclient.data.l[4]; */
-
-      meta_window_update_fullscreen_monitors (window, top, bottom, left, right);
-    }
-
-  return FALSE;
-}
-
 static void
 meta_window_appears_focused_changed (MetaWindow *window)
 {
@@ -7640,33 +6918,6 @@ meta_window_set_focused_internal (MetaWindow *window,
     }
 }
 
-static gboolean
-process_property_notify (MetaWindow     *window,
-                         XPropertyEvent *event)
-{
-  Window xid = window->xwindow;
-
-  if (meta_is_verbose ()) /* avoid looking up the name if we don't have to */
-    {
-      char *property_name = XGetAtomName (window->display->xdisplay,
-                                          event->atom);
-
-      meta_verbose ("Property notify on %s for %s\n",
-                    window->desc, property_name);
-      XFree (property_name);
-    }
-
-  if (event->atom == window->display->atom__NET_WM_USER_TIME &&
-      window->user_time_window)
-    {
-        xid = window->user_time_window;
-    }
-
-  meta_window_reload_property_from_xwindow (window, xid, event->atom, FALSE);
-
-  return TRUE;
-}
-
 static void
 send_configure_notify (MetaWindow *window)
 {
@@ -7872,347 +7123,6 @@ update_sm_hints (MetaWindow *window)
                 window->sm_client_id ? window->sm_client_id : "none");
 }
 
-void
-meta_window_update_role (MetaWindow *window)
-{
-  char *str;
-
-  g_return_if_fail (!window->override_redirect);
-
-  if (window->role)
-    g_free (window->role);
-  window->role = NULL;
-
-  if (meta_prop_get_latin1_string (window->display, window->xwindow,
-                                   window->display->atom_WM_WINDOW_ROLE,
-                                   &str))
-    {
-      window->role = g_strdup (str);
-      meta_XFree (str);
-    }
-
-  meta_verbose ("Updated role of %s to '%s'\n",
-                window->desc, window->role ? window->role : "null");
-}
-
-void
-meta_window_update_net_wm_type (MetaWindow *window)
-{
-  int n_atoms;
-  Atom *atoms;
-  int i;
-
-  window->type_atom = None;
-  n_atoms = 0;
-  atoms = NULL;
-
-  meta_prop_get_atom_list (window->display, window->xwindow,
-                           window->display->atom__NET_WM_WINDOW_TYPE,
-                           &atoms, &n_atoms);
-
-  i = 0;
-  while (i < n_atoms)
-    {
-      /* We break as soon as we find one we recognize,
-       * supposed to prefer those near the front of the list
-       */
-      if (atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DESKTOP ||
-          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DOCK ||
-          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLBAR ||
-          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_MENU ||
-          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_UTILITY ||
-          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_SPLASH ||
-          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DIALOG ||
-          atoms[i] ==
-           window->display->atom__NET_WM_WINDOW_TYPE_DROPDOWN_MENU ||
-          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_POPUP_MENU ||
-          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_TOOLTIP ||
-          atoms[i] ==
-           window->display->atom__NET_WM_WINDOW_TYPE_NOTIFICATION ||
-          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_COMBO ||
-          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_DND ||
-          atoms[i] == window->display->atom__NET_WM_WINDOW_TYPE_NORMAL)
-        {
-          window->type_atom = atoms[i];
-          break;
-        }
-
-      ++i;
-    }
-
-  meta_XFree (atoms);
-
-  if (meta_is_verbose ())
-    {
-      char *str;
-
-      str = NULL;
-      if (window->type_atom != None)
-        {
-          meta_error_trap_push (window->display);
-          str = XGetAtomName (window->display->xdisplay, window->type_atom);
-          meta_error_trap_pop (window->display);
-        }
-
-      meta_verbose ("Window %s type atom %s\n", window->desc,
-                    str ? str : "(none)");
-
-      if (str)
-        meta_XFree (str);
-    }
-
-  meta_window_recalc_window_type (window);
-}
-
-static void
-meta_window_set_opaque_region (MetaWindow     *window,
-                               cairo_region_t *region)
-{
-  g_clear_pointer (&window->opaque_region, cairo_region_destroy);
-
-  if (region != NULL)
-    window->opaque_region = cairo_region_reference (region);
-
-  if (window->display->compositor)
-    meta_compositor_window_shape_changed (window->display->compositor, window);
-}
-
-void
-meta_window_update_opaque_region_x11 (MetaWindow *window)
-{
-  cairo_region_t *opaque_region = NULL;
-  gulong *region = NULL;
-  int nitems;
-
-  if (meta_prop_get_cardinal_list (window->display,
-                                   window->xwindow,
-                                   window->display->atom__NET_WM_OPAQUE_REGION,
-                                   &region, &nitems))
-    {
-      cairo_rectangle_int_t *rects;
-      int i, rect_index, nrects;
-
-      if (nitems % 4 != 0)
-        {
-          meta_verbose ("_NET_WM_OPAQUE_REGION does not have a list of 4-tuples.");
-          goto out;
-        }
-
-      /* empty region */
-      if (nitems == 0)
-        goto out;
-
-      nrects = nitems / 4;
-
-      rects = g_new (cairo_rectangle_int_t, nrects);
-
-      rect_index = 0;
-      i = 0;
-      while (i < nitems)
-        {
-          cairo_rectangle_int_t *rect = &rects[rect_index];
-
-          rect->x = region[i++];
-          rect->y = region[i++];
-          rect->width = region[i++];
-          rect->height = region[i++];
-
-          rect_index++;
-        }
-
-      opaque_region = cairo_region_create_rectangles (rects, nrects);
-
-      g_free (rects);
-    }
-
- out:
-  meta_XFree (region);
-
-  meta_window_set_opaque_region (window, opaque_region);
-  cairo_region_destroy (opaque_region);
-}
-
-static cairo_region_t *
-region_create_from_x_rectangles (const XRectangle *rects,
-                                 int n_rects)
-{
-  int i;
-  cairo_rectangle_int_t *cairo_rects = g_newa (cairo_rectangle_int_t, n_rects);
-
-  for (i = 0; i < n_rects; i ++)
-    {
-      cairo_rects[i].x = rects[i].x;
-      cairo_rects[i].y = rects[i].y;
-      cairo_rects[i].width = rects[i].width;
-      cairo_rects[i].height = rects[i].height;
-    }
-
-  return cairo_region_create_rectangles (cairo_rects, n_rects);
-}
-
-static void
-meta_window_set_input_region (MetaWindow     *window,
-                              cairo_region_t *region)
-{
-  g_clear_pointer (&window->input_region, cairo_region_destroy);
-
-  if (region != NULL)
-    window->input_region = cairo_region_reference (region);
-
-  if (window->display->compositor)
-    meta_compositor_window_shape_changed (window->display->compositor, window);
-}
-
-void
-meta_window_update_input_region_x11 (MetaWindow *window)
-{
-  cairo_region_t *region = NULL;
-
-#ifdef HAVE_SHAPE
-  if (META_DISPLAY_HAS_SHAPE (window->display))
-    {
-      /* Translate the set of XShape rectangles that we
-       * get from the X server to a cairo_region. */
-      XRectangle *rects = NULL;
-      int n_rects, ordering;
-
-      int x_bounding, y_bounding, x_clip, y_clip;
-      unsigned w_bounding, h_bounding, w_clip, h_clip;
-      int bounding_shaped, clip_shaped;
-
-      meta_error_trap_push (window->display);
-      XShapeQueryExtents (window->display->xdisplay, window->xwindow,
-                          &bounding_shaped, &x_bounding, &y_bounding,
-                          &w_bounding, &h_bounding,
-                          &clip_shaped, &x_clip, &y_clip,
-                          &w_clip, &h_clip);
-
-      rects = XShapeGetRectangles (window->display->xdisplay,
-                                   window->xwindow,
-                                   ShapeInput,
-                                   &n_rects,
-                                   &ordering);
-      meta_error_trap_pop (window->display);
-
-      /* XXX: The x shape extension doesn't provide a way to only test if an
-       * input shape has been specified, so we have to query and throw away the
-       * rectangles. */
-      if (rects)
-        {
-          if (n_rects > 1 ||
-              (n_rects == 1 &&
-               (rects[0].x != x_bounding ||
-                rects[1].y != y_bounding ||
-                rects[2].width != w_bounding ||
-                rects[3].height != h_bounding)))
-            region = region_create_from_x_rectangles (rects, n_rects);
-
-          XFree (rects);
-        }
-    }
-#endif /* HAVE_SHAPE */
-
-  if (region != NULL)
-    {
-      cairo_rectangle_int_t client_area;
-
-      client_area.x = 0;
-      client_area.y = 0;
-      client_area.width = window->rect.width;
-      client_area.height = window->rect.height;
-
-      /* The shape we get back from the client may have coordinates
-       * outside of the frame. The X SHAPE Extension requires that
-       * the overall shape the client provides never exceeds the
-       * "bounding rectangle" of the window -- the shape that the
-       * window would have gotten if it was unshaped. In our case,
-       * this is simply the client area.
-       */
-      cairo_region_intersect_rectangle (region, &client_area);
-    }
-
-  meta_window_set_input_region (window, region);
-  cairo_region_destroy (region);
-}
-
-static void
-meta_window_set_shape_region (MetaWindow     *window,
-                              cairo_region_t *region)
-{
-  g_clear_pointer (&window->shape_region, cairo_region_destroy);
-
-  if (region != NULL)
-    window->shape_region = cairo_region_reference (region);
-
-  if (window->display->compositor)
-    meta_compositor_window_shape_changed (window->display->compositor, window);
-}
-
-void
-meta_window_update_shape_region_x11 (MetaWindow *window)
-{
-  cairo_region_t *region = NULL;
-
-#ifdef HAVE_SHAPE
-  if (META_DISPLAY_HAS_SHAPE (window->display))
-    {
-      /* Translate the set of XShape rectangles that we
-       * get from the X server to a cairo_region. */
-      XRectangle *rects = NULL;
-      int n_rects, ordering;
-
-      int x_bounding, y_bounding, x_clip, y_clip;
-      unsigned w_bounding, h_bounding, w_clip, h_clip;
-      int bounding_shaped, clip_shaped;
-
-      meta_error_trap_push (window->display);
-      XShapeQueryExtents (window->display->xdisplay, window->xwindow,
-                          &bounding_shaped, &x_bounding, &y_bounding,
-                          &w_bounding, &h_bounding,
-                          &clip_shaped, &x_clip, &y_clip,
-                          &w_clip, &h_clip);
-
-      if (bounding_shaped)
-        {
-          rects = XShapeGetRectangles (window->display->xdisplay,
-                                       window->xwindow,
-                                       ShapeBounding,
-                                       &n_rects,
-                                       &ordering);
-        }
-      meta_error_trap_pop (window->display);
-
-      if (rects)
-        {
-          region = region_create_from_x_rectangles (rects, n_rects);
-          XFree (rects);
-        }
-    }
-#endif /* HAVE_SHAPE */
-
-  if (region != NULL)
-    {
-      cairo_rectangle_int_t client_area;
-
-      client_area.x = 0;
-      client_area.y = 0;
-      client_area.width = window->rect.width;
-      client_area.height = window->rect.height;
-
-      /* The shape we get back from the client may have coordinates
-       * outside of the frame. The X SHAPE Extension requires that
-       * the overall shape the client provides never exceeds the
-       * "bounding rectangle" of the window -- the shape that the
-       * window would have gotten if it was unshaped. In our case,
-       * this is simply the client area.
-       */
-      cairo_region_intersect_rectangle (region, &client_area);
-    }
-
-  meta_window_set_shape_region (window, region);
-  cairo_region_destroy (region);
-}
-
 static void
 redraw_icon (MetaWindow *window)
 {
@@ -10483,23 +9393,6 @@ meta_window_same_application (MetaWindow *window,
     group==other_group;
 }
 
-/* Generally meta_window_same_application() is a better idea
- * of "sameness", since it handles the case where multiple apps
- * want to look like the same app or the same app wants to look
- * like multiple apps, but in the case of workarounds for legacy
- * applications (which likely aren't setting the group properly
- * anyways), it may be desirable to check this as well.
- */
-static gboolean
-meta_window_same_client (MetaWindow *window,
-                         MetaWindow *other_window)
-{
-  int resource_mask = window->display->xdisplay->resource_mask;
-
-  return ((window->xwindow & ~resource_mask) ==
-          (other_window->xwindow & ~resource_mask));
-}
-
 void
 meta_window_refresh_resize_popup (MetaWindow *window)
 {



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