This first part makes it such that the wireframe edges draw
completely in bounds of the grabbed window edges instead of
having half the wireframe in bounds and half out. This
makes it much more obvious how to precisely place things
and makes edge snapping look prettier.

diff -u -p -u -p -r1.18 effects.c
--- src/effects.c	7 Jun 2005 15:52:56 -0000	1.18
+++ src/effects.c	20 Jul 2005 04:30:32 -0000
@@ -446,7 +446,7 @@ meta_effects_begin_wireframe (MetaScreen
 
 static void
 draw_xor_rect (MetaScreen          *screen,
-               const MetaRectangle *rect,
+               const MetaRectangle *unshrunk_rect,
                int                  width,
                int                  height)
 {
@@ -455,10 +455,23 @@ draw_xor_rect (MetaScreen          *scre
    * a bit oddly.
    */
   XSegment segments[8];
+  MetaRectangle *rect;
   int i;
   
 #define LINE_WIDTH META_WIREFRAME_XOR_LINE_WIDTH
-  
+
+  /* We don't want the wireframe going outside the window area.
+   * It makes it harder for the user to position windows and it exposes other
+   * annoying bugs.
+   */
+  rect = g_new0 (MetaRectangle, 1);
+  *rect = *unshrunk_rect;
+
+  rect->x += LINE_WIDTH / 2 + LINE_WIDTH % 2;
+  rect->y += LINE_WIDTH / 2 + LINE_WIDTH % 2;
+  rect->width -= LINE_WIDTH + 2 * (LINE_WIDTH % 2);
+  rect->height -= LINE_WIDTH + 2 * (LINE_WIDTH % 2);
+
   XDrawRectangle (screen->display->xdisplay,
                   screen->xroot,
                   screen->root_xor_gc,
@@ -468,7 +481,10 @@ draw_xor_rect (MetaScreen          *scre
   /* Don't put lines inside small rectangles where they won't fit */
   if (rect->width < (LINE_WIDTH * 4) ||
       rect->height < (LINE_WIDTH * 4))
-    return;
+    {
+      g_free (rect);
+      return;
+    }
 
   if ((width >= 0) && (height >= 0))
     {
@@ -526,10 +542,16 @@ draw_xor_rect (MetaScreen          *scre
               XFreeFontInfo (NULL, font_struct, 1);
 
               if ((box_width + LINE_WIDTH) >= (rect->width / 3))
-                return;
+                {
+                  g_free (rect);
+                  return;
+                }
 
               if ((box_height + LINE_WIDTH) >= (rect->height / 3))
-                return;
+                {
+                  g_free (rect);
+                  return;
+                }
             }
         }
     }
@@ -578,6 +600,7 @@ draw_xor_rect (MetaScreen          *scre
                  screen->root_xor_gc,
                  segments,
                  G_N_ELEMENTS (segments));
+  g_free (rect);
 }
 
 void

This part changes the semantics of the "next edge" finding functions
such that they return the coordinate of the found edge instead of a
window coordinate.  Also, the functions take a new parameter that
specifies the source edge of the passed window to start from when
looking for the next edge.  Both of these changes are important
for the functions to work with resize snapping.
diff -u -p -u -p -r1.42 place.c
--- src/place.c	20 Feb 2005 22:38:05 -0000	1.42
+++ src/place.c	20 Jul 2005 04:30:35 -0000
@@ -1058,43 +1058,53 @@ get_vertical_edges (MetaWindow *window,
   GSList *windows;
   GSList *tmp;
   int n_windows;
-  int *edges;
-  int i, j;
-  int n_edges;
+  GArray *edges;
+  int edge, i;
   MetaRectangle rect;
   MetaRectangle work_area;
   
   windows = get_windows_on_same_workspace (window, &n_windows);
 
-  i = 0;
-  /* 4 = workspace/screen edges */
-  n_edges = n_windows * 2 + 4 + window->screen->n_xinerama_infos - 1; 
-
-  edges = g_new (int, n_edges);
+  edges = g_array_sized_new (FALSE, FALSE, sizeof (int), 
+                             n_windows * 2 + 4 /* 4 = workspace/screen edges */
+                             + window->screen->n_xinerama_infos - 1
+                             + 2 /* active window edges when in wireframe mode */); 
 
   /* workspace/screen edges */
   meta_window_get_work_area_current_xinerama (window, &work_area);
+  
+  g_array_append_val (edges, work_area.x);
+  edge = work_area.x + work_area.width;
+  g_array_append_val (edges, edge);
+  edge = 0;
+  g_array_append_val (edges, edge);
+  g_array_append_val (edges, window->screen->width);
 
-  edges[i] = work_area.x;
-  ++i;
-  edges[i] = work_area.x + work_area.width;
-  ++i;
-  edges[i] = 0;
-  ++i;
-  edges[i] = window->screen->width;
-  ++i;
+  /* Now get the xinerama screen edges */
+  for (i = 0; i < window->screen->n_xinerama_infos - 1; i++)
+    {
+      edge = window->screen->xinerama_infos[i].x_origin +
+             window->screen->xinerama_infos[i].width;
 
-  g_assert (i == 4);
+      g_array_append_val (edges, edge);
+    }
+
+  if (window->display->grab_wireframe_active)
+    {
+      int left_edge, right_edge, top_edge, bottom_edge;
+
+      meta_window_get_xor_rect (window, &window->display->grab_wireframe_rect,
+                                &rect);
+
+      window_get_edges (window, &left_edge, &right_edge, 
+                        &top_edge, &bottom_edge);
+
+      g_array_append_val (edges, left_edge);
+      g_array_append_val (edges, right_edge);
+    }
+  else
+    meta_window_get_outer_rect (window, &rect);
 
-  /* Now get the xinerama screen edges */
-  for (j = 0; j < window->screen->n_xinerama_infos - 1; j++) {
-    edges[i] = window->screen->xinerama_infos[j].x_origin +
-      window->screen->xinerama_infos[j].width;
-    ++i;
-  }
-  
-  meta_window_get_outer_rect (window, &rect);
-  
   /* get window edges */
   tmp = windows;
   while (tmp != NULL)
@@ -1106,22 +1116,21 @@ get_vertical_edges (MetaWindow *window,
       
       if (rects_overlap_vertically (&rect, &w_rect))
         {
-          window_get_edges (w, &edges[i], &edges[i+1], NULL, NULL);
-          i += 2;
+          g_array_append_val (edges, w_rect.x);
+          edge = w_rect.x + w_rect.width;
+          g_array_append_val (edges, edge);
         }
 
       tmp = tmp->next;
     }
-  n_edges = i;
-  
   g_slist_free (windows);
 
   /* Sort */
-  qsort (edges, n_edges, sizeof (int), intcmp);
+  qsort (edges->data, edges->len, sizeof (int), intcmp);
 
-  *edges_p = edges;
-  *n_edges_p = n_edges;
-}  
+  *n_edges_p = edges->len;  
+  *edges_p = (int *) g_array_free (edges, FALSE);
+}
 
 static void
 get_horizontal_edges (MetaWindow *window,
@@ -1131,41 +1140,52 @@ get_horizontal_edges (MetaWindow *window
   GSList *windows;
   GSList *tmp;
   int n_windows;
-  int *edges;
-  int i, j;
-  int n_edges;
+  GArray *edges;
+  int edge, i;
   MetaRectangle rect;
   MetaRectangle work_area;
   
   windows = get_windows_on_same_workspace (window, &n_windows);
 
-  i = 0;
-  n_edges = n_windows * 2 + 4 + window->screen->n_xinerama_infos - 1; /* 4 = workspace/screen edges */
-  edges = g_new (int, n_edges);
+  edges = g_array_sized_new (FALSE, FALSE, sizeof (int), 
+                             n_windows * 2 + 4 /* 4 = workspace/screen edges */
+                             + window->screen->n_xinerama_infos - 1
+                             + 2 /* active window edges when in wireframe mode */); 
 
   /* workspace/screen edges */
   meta_window_get_work_area_current_xinerama (window, &work_area);
   
-  edges[i] = work_area.y;
-  ++i;
-  edges[i] = work_area.y + work_area.height;
-  ++i;
-  edges[i] = 0;
-  ++i;
-  edges[i] = window->screen->height;
-  ++i;
+  g_array_append_val (edges, work_area.y);
+  edge = work_area.y + work_area.height;
+  g_array_append_val (edges, edge);
+  edge = 0;
+  g_array_append_val (edges, edge);
+  g_array_append_val (edges, window->screen->height);
 
-  g_assert (i == 4);
-  
   /* Now get the xinerama screen edges */
-  for (j = 0; j < window->screen->n_xinerama_infos - 1; j++) {
-    edges[i] = window->screen->xinerama_infos[j].y_origin +
-      window->screen->xinerama_infos[j].height;
-    ++i;
-  }
+  for (i = 0; i < window->screen->n_xinerama_infos - 1; i++) 
+    {
+      edge = window->screen->xinerama_infos[i].y_origin +
+             window->screen->xinerama_infos[i].height;
+      g_array_append_val (edges, edge);
+    }
 
-  meta_window_get_outer_rect (window, &rect);
-  
+  if (window->display->grab_wireframe_active)
+    {
+      int left_edge, right_edge, top_edge, bottom_edge;
+
+      meta_window_get_xor_rect (window, &window->display->grab_wireframe_rect,
+                                &rect);
+
+      window_get_edges (window, &left_edge, &right_edge, 
+                        &top_edge, &bottom_edge);
+
+      g_array_append_val (edges, top_edge);
+      g_array_append_val (edges, bottom_edge);
+    }
+  else
+    meta_window_get_outer_rect (window, &rect);
+ 
   /* get window edges */
   tmp = windows;
   while (tmp != NULL)
@@ -1177,60 +1197,75 @@ get_horizontal_edges (MetaWindow *window
       
       if (rects_overlap_horizontally (&rect, &w_rect))
         {
-          window_get_edges (w, NULL, NULL, &edges[i], &edges[i+1]);
-          i += 2;
+          g_array_append_val (edges, w_rect.y);
+          edge = w_rect.y + w_rect.height;
+          g_array_append_val (edges, edge);
         }
 
       tmp = tmp->next;
     }
-  n_edges = i;
-  
   g_slist_free (windows);
 
   /* Sort */
-  qsort (edges, n_edges, sizeof (int), intcmp);
+  qsort (edges->data, edges->len, sizeof (int), intcmp);
 
-  *edges_p = edges;
-  *n_edges_p = n_edges;  
+  *n_edges_p = edges->len;  
+  *edges_p = (int *) g_array_free (edges, FALSE);
 }
 
 int
 meta_window_find_next_vertical_edge (MetaWindow *window,
+                                     MetaWindowEdgePosition source_edge_position,
                                      gboolean    right)
 {
-  int left_edge, right_edge;
+  int left_edge, right_edge, source_edge;
   int *edges;
   int i;
   int n_edges;
   int retval;
 
   get_vertical_edges (window, &edges, &n_edges);
-  
+
   /* Find next */
-  meta_window_get_position (window, &retval, NULL);
+  if (window->display->grab_wireframe_active)
+    {
+      MetaRectangle rect;
+
+      meta_window_get_xor_rect (window, &window->display->grab_wireframe_rect,
+                                &rect);
+
+      left_edge = rect.x;
+      right_edge = left_edge + rect.width;
+    }
+  else
+    window_get_edges (window, &left_edge, &right_edge, NULL, NULL);
+
+  switch (source_edge_position)
+    {
+      case META_WINDOW_EDGE_LEFT:
+        source_edge = left_edge;
+        break;
+
+      case META_WINDOW_EDGE_RIGHT:
+        source_edge = right_edge;
+        break;
+
+      case META_WINDOW_EDGE_TOP:
+      case META_WINDOW_EDGE_BOTTOM:
+      default:
+        g_assert_not_reached ();
+    }
+
+  retval = source_edge;
 
-  window_get_edges (window, &left_edge, &right_edge, NULL, NULL);
-  
   if (right)
     {
       i = 0;
       while (i < n_edges)
         {
-          if (edges[i] > right_edge)
+          if (edges[i] > source_edge)
             {
-              /* This is the one we want, snap right
-               * edge of window to edges[i]
-               */
               retval = edges[i];
-              if (window->frame)
-                {
-                  retval -= window->frame->rect.width;
-                  retval += window->frame->child_x;
-                }
-              else
-                {
-                  retval -= window->rect.width;
-                }
               break;
             }
           
@@ -1244,13 +1279,9 @@ meta_window_find_next_vertical_edge (Met
         {
           --i;
           
-          if (edges[i] < left_edge)
+          if (edges[i] < source_edge)
             {
-              /* This is the one we want */
               retval = edges[i];
-              if (window->frame)
-                retval += window->frame->child_x;
-
               break;
             }
         }
@@ -1264,9 +1295,10 @@ meta_window_find_next_vertical_edge (Met
 
 int
 meta_window_find_next_horizontal_edge (MetaWindow *window,
+                                       MetaWindowEdgePosition source_edge_position,
                                        gboolean    down)
 {
-  int top_edge, bottom_edge;
+  int top_edge, bottom_edge, source_edge;
   int *edges;
   int i;
   int n_edges;
@@ -1275,30 +1307,45 @@ meta_window_find_next_horizontal_edge (M
   get_horizontal_edges (window, &edges, &n_edges);
   
   /* Find next */
-  meta_window_get_position (window, NULL, &retval);
+  if (window->display->grab_wireframe_active)
+    {
+      MetaRectangle rect;
+
+      meta_window_get_xor_rect (window, &window->display->grab_wireframe_rect,
+                                &rect);
+
+      top_edge = rect.y;
+      bottom_edge = top_edge + rect.height;
+    }
+  else
+    window_get_edges (window, NULL, NULL, &top_edge, &bottom_edge);
+
+  switch (source_edge_position)
+    {
+      case META_WINDOW_EDGE_TOP:
+        source_edge = top_edge;
+        break;
+
+      case META_WINDOW_EDGE_BOTTOM:
+        source_edge = bottom_edge;
+        break;
+
+      case META_WINDOW_EDGE_LEFT:
+      case META_WINDOW_EDGE_RIGHT:
+      default:
+        g_assert_not_reached ();
+    }
+
+  retval = source_edge;
 
-  window_get_edges (window, NULL, NULL, &top_edge, &bottom_edge);
-  
   if (down)
     {
       i = 0;
       while (i < n_edges)
         {
-          if (edges[i] > bottom_edge)
+          if (edges[i] > source_edge)
             {
-              /* This is the one we want, snap right
-               * edge of window to edges[i]
-               */
               retval = edges[i];
-              if (window->frame)
-                {
-                  retval -= window->frame->rect.height;
-                  retval += window->frame->child_y;
-                }
-              else
-                {
-                  retval -= window->rect.height;
-                }
               break;
             }
           
@@ -1312,13 +1359,9 @@ meta_window_find_next_horizontal_edge (M
         {
           --i;
           
-          if (edges[i] < top_edge)
+          if (edges[i] < source_edge)
             {
-              /* This is the one we want */
               retval = edges[i];
-              if (window->frame)
-                retval += window->frame->child_y;
-
               break;
             }
         }
@@ -1353,11 +1396,10 @@ meta_window_find_nearest_vertical_edge (
       int left_pos, right_pos;
 
       left_pos = edges[i];
-      if (window->frame)
-        left_pos += window->frame->child_x;
 
       if (window->frame)
         {
+          left_pos += window->frame->child_x;
           right_pos = edges[i] - window->frame->rect.width;
           right_pos += window->frame->child_x;
         }
@@ -1424,11 +1466,10 @@ meta_window_find_nearest_horizontal_edge
       int top_pos, bottom_pos;
 
       top_pos = edges[i];
-      if (window->frame)
-        top_pos += window->frame->child_y;
 
       if (window->frame)
         {
+          top_pos += window->frame->child_y;
           bottom_pos = edges[i] - window->frame->rect.height;
           bottom_pos += window->frame->child_y;
         }

diff -u -p -u -p -r1.3 place.h
--- src/place.h	26 Jul 2001 03:58:23 -0000	1.3
+++ src/place.h	20 Jul 2005 04:30:35 -0000
@@ -25,6 +25,16 @@
 #include "window.h"
 #include "frame.h"
 
+typedef enum _MetaWindowEdgePosition MetaWindowEdgePosition;
+
+enum _MetaWindowEdgePosition
+{
+  META_WINDOW_EDGE_TOP = 0,
+  META_WINDOW_EDGE_LEFT,
+  META_WINDOW_EDGE_RIGHT,
+  META_WINDOW_EDGE_BOTTOM
+};
+
 void meta_window_place (MetaWindow *window,
                         MetaFrameGeometry *fgeom,
                         int         x,
@@ -32,14 +42,16 @@ void meta_window_place (MetaWindow *wind
                         int        *new_x,
                         int        *new_y);
 
-/* Returns the position to move the window to in order
+/* Returns the position to move the specified window edge to in order
  * to snap it to the next edge in the given direction,
  * while moving.
  */
 int meta_window_find_next_vertical_edge   (MetaWindow *window,
-                                           gboolean    right);
-int meta_window_find_next_horizontal_edge (MetaWindow *window,
+                                           MetaWindowEdgePosition source_edge_position,
                                            gboolean    down);
+int meta_window_find_next_horizontal_edge (MetaWindow *window,
+                                           MetaWindowEdgePosition source_edge_position,
+                                           gboolean    right);
 
 /* Returns the position to move the window to in order
  * to snap it to the nearest edge, while moving.
@@ -49,13 +61,4 @@ int meta_window_find_nearest_vertical_ed
 
 int meta_window_find_nearest_horizontal_edge (MetaWindow *window,
                                               int         y_pos);
-
-/* FIXME need edge-snap functions for resizing as well, those
- * behave somewhat differently.
- */
-
 #endif
-
-
-
-

This part allows edge snapping during keyboard resize even when
in wireframe mode.  Some changes were also made to compensate for
the change in semantics of the "next edge" finding functions.
diff -u -p -u -p -r1.111 keybindings.c
--- src/keybindings.c	26 May 2005 19:58:17 -0000	1.111
+++ src/keybindings.c	20 Jul 2005 04:30:34 -0000
@@ -1690,6 +1690,7 @@ process_keyboard_move_grab (MetaDisplay 
   int incr;
   gboolean smart_snap;
   int edge;
+  int candidate_position;
   
   handled = FALSE;
 
@@ -1711,13 +1712,7 @@ process_keyboard_move_grab (MetaDisplay 
       meta_window_get_position (window, &x, &y);
     }
 
-  /* FIXME in wireframe mode the edge snapping is all fucked up
-   * since the edge-find routines use window->rect. Window
-   * constraints are also broken with wireframe.
-   */  
   smart_snap = (event->xkey.state & ShiftMask) != 0;
-  if (display->grab_wireframe_active)
-    smart_snap = FALSE;
   
 #define SMALL_INCREMENT 1
 #define NORMAL_INCREMENT 10
@@ -1736,12 +1731,13 @@ process_keyboard_move_grab (MetaDisplay 
        * since in wireframe we always moveresize at the end
        * of the grab only.
        */
-      meta_window_move_resize (display->grab_window,
-                               TRUE,
-                               display->grab_initial_window_pos.x,
-                               display->grab_initial_window_pos.y,
-                               display->grab_initial_window_pos.width,
-                               display->grab_initial_window_pos.height);
+      if (!display->grab_wireframe_active)
+        meta_window_move_resize (display->grab_window,
+                                 TRUE,
+                                 display->grab_initial_window_pos.x,
+                                 display->grab_initial_window_pos.y,
+                                 display->grab_initial_window_pos.width,
+                                 display->grab_initial_window_pos.height);
       display->grab_was_cancelled = TRUE;
     }
   
@@ -1758,13 +1754,17 @@ process_keyboard_move_grab (MetaDisplay 
     case XK_KP_Up:
       y -= incr;
 
-      if (!display->grab_wireframe_active)
-        {
-          edge = meta_window_find_next_horizontal_edge (window, FALSE);
-          if (smart_snap || ((edge > y) && ABS (edge - y) < incr))
-            y = edge;
-        }
-          
+      edge = meta_window_find_next_horizontal_edge (window, 
+                                                    META_WINDOW_EDGE_TOP,
+                                                    FALSE);
+      if (window->frame)
+        candidate_position = edge + window->frame->child_y;
+      else
+        candidate_position = edge;
+
+      if (smart_snap || ((candidate_position > y) && ABS (candidate_position - y) < incr))
+        y = candidate_position;
+
       handled = TRUE;
       break;
     case XK_KP_End:
@@ -1773,13 +1773,17 @@ process_keyboard_move_grab (MetaDisplay 
     case XK_KP_Down:
       y += incr;
 
-      if (!display->grab_wireframe_active)
-        {
-          edge = meta_window_find_next_horizontal_edge (window, TRUE);
-          if (smart_snap || ((edge < y) && ABS (edge - y) < incr))
-            y = edge;
-        }
-          
+      edge = meta_window_find_next_horizontal_edge (window, 
+                                                    META_WINDOW_EDGE_BOTTOM,
+                                                    TRUE);
+      if (window->frame)
+        candidate_position = edge - window->frame->bottom_height - window->rect.height;
+      else
+        candidate_position = edge - window->rect.height;
+
+      if (smart_snap || ((candidate_position < y) && ABS (candidate_position - y) < incr))
+        y = candidate_position;
+
       handled = TRUE;
       break;
     }
@@ -1792,12 +1796,17 @@ process_keyboard_move_grab (MetaDisplay 
     case XK_KP_Left:
       x -= incr;
 
-      if (!display->grab_wireframe_active)
-        {
-          edge = meta_window_find_next_vertical_edge (window, FALSE);
-          if (smart_snap || ((edge > x) && ABS (edge - x) < incr))
-            x = edge;
-        }
+      edge = meta_window_find_next_vertical_edge (window, 
+                                                  META_WINDOW_EDGE_LEFT,
+                                                  FALSE);
+      if (window->frame)
+        candidate_position = edge + window->frame->child_x;
+      else
+        candidate_position = edge;
+
+      if (smart_snap || 
+          ((candidate_position > x) && ABS (candidate_position - x) < incr))
+        x = candidate_position;
 
       handled = TRUE;
       break;
@@ -1807,13 +1816,17 @@ process_keyboard_move_grab (MetaDisplay 
     case XK_KP_Right:
       x += incr;
 
-      if (!display->grab_wireframe_active)
-        {
-          edge = meta_window_find_next_vertical_edge (window, TRUE);
-          if (smart_snap || ((edge < x) && ABS (edge - x) < incr))
-            x = edge;
-        }
+      edge = meta_window_find_next_vertical_edge (window, 
+                                                  META_WINDOW_EDGE_RIGHT,
+                                                  TRUE);
+      if (window->frame)
+        candidate_position = edge - window->frame->right_width - window->rect.width;
+      else
+        candidate_position = edge - window->rect.width;
       
+      if (smart_snap || ((candidate_position < x) && ABS (candidate_position - x) < incr))
+        x = candidate_position;
+
       handled = TRUE;
       break;
     }
@@ -1856,6 +1869,7 @@ process_keyboard_resize_grab (MetaDispla
   gboolean smart_snap;
   int edge;
   int gravity;
+  int candidate_position;
   
   handled = FALSE;
 
@@ -1874,12 +1888,13 @@ process_keyboard_resize_grab (MetaDispla
        * since in wireframe we always moveresize at the end
        * of the grab only.
        */
-      meta_window_move_resize (display->grab_window,
-                               TRUE,
-                               display->grab_initial_window_pos.x,
-                               display->grab_initial_window_pos.y,
-                               display->grab_initial_window_pos.width,
-                               display->grab_initial_window_pos.height);
+      if (!display->grab_wireframe_active)
+        meta_window_move_resize (display->grab_window,
+                                 TRUE,
+                                 display->grab_initial_window_pos.x,
+                                 display->grab_initial_window_pos.y,
+                                 display->grab_initial_window_pos.width,
+                                 display->grab_initial_window_pos.height);
       display->grab_was_cancelled = TRUE;
 
       return FALSE;
@@ -1918,12 +1933,12 @@ process_keyboard_resize_grab (MetaDispla
         {
         case XK_Left:
         case XK_KP_Left:
-          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SW;
+          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
           handled = TRUE;
           break;
         case XK_Right:
         case XK_KP_Right:
-          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SE;
+          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
           handled = TRUE;
           break;
         }
@@ -1934,12 +1949,12 @@ process_keyboard_resize_grab (MetaDispla
         {
         case XK_Left:
         case XK_KP_Left:
-          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NW;
+          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
           handled = TRUE;
           break;
         case XK_Right:
         case XK_KP_Right:
-          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NE;
+          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
           handled = TRUE;
           break;
         }
@@ -1950,12 +1965,12 @@ process_keyboard_resize_grab (MetaDispla
         {
         case XK_Up:
         case XK_KP_Up:
-          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NW;          
+          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;          
           handled = TRUE;
           break;
         case XK_Down:
         case XK_KP_Down:
-          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SW;
+          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
           handled = TRUE;
           break;
         }
@@ -1966,12 +1981,12 @@ process_keyboard_resize_grab (MetaDispla
         {
         case XK_Up:
         case XK_KP_Up:
-          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NE; 
+          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N; 
           handled = TRUE;
           break;
         case XK_Down:
         case XK_KP_Down:
-          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SE;
+          display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
           handled = TRUE;
           break;
         }
@@ -1996,31 +2011,24 @@ process_keyboard_resize_grab (MetaDispla
 
   if (display->grab_wireframe_active)
     {
-      x = display->grab_wireframe_rect.x;
-      y = display->grab_wireframe_rect.y;
-      orig_x = x;
-      orig_y = y;
+      orig_x = display->grab_wireframe_rect.x;
+      orig_y = display->grab_wireframe_rect.y;
       width = display->grab_wireframe_rect.width;
       height = display->grab_wireframe_rect.height;
     }
   else
     {
       meta_window_get_position (window, &orig_x, &orig_y);
-      x = orig_x;
-      y = orig_y;
       width = window->rect.width;
       height = window->rect.height;
     }
 
+  x = orig_x;
+  y = orig_y;
+
   gravity = meta_resize_gravity_from_grab_op (display->grab_op);
 
-  /* FIXME in wireframe mode the edge snapping is all fucked up
-   * since the edge-find routines use window->rect. Window
-   * constraints are also broken with wireframe.
-   */  
   smart_snap = (event->xkey.state & ShiftMask) != 0;
-  if (display->grab_wireframe_active)
-    smart_snap = FALSE;
   
 #define SMALL_INCREMENT 1
 #define NORMAL_INCREMENT 10
@@ -2073,15 +2081,19 @@ process_keyboard_resize_grab (MetaDispla
           /* Move bottom edge up */
           height -= height_inc;
           
-          if (!display->grab_wireframe_active)
-            {
-              edge = meta_window_find_next_horizontal_edge (window, TRUE);
-              
-              if (smart_snap || ((edge > (y+height)) &&
-                                 ABS (edge - (y+height)) < height_inc))
-                height = edge - y;
-            }
-          
+          edge = meta_window_find_next_horizontal_edge (window, 
+                                                        META_WINDOW_EDGE_BOTTOM,
+                                                        FALSE);
+
+          if (window->frame)
+            candidate_position = edge - window->frame->bottom_height;
+          else
+            candidate_position = edge;
+
+          if (smart_snap || ((candidate_position > (y + height)) &&
+                             ABS (candidate_position - (y + height)) < height_inc))
+            height = candidate_position - y;
+
           handled = TRUE;
           break;
 
@@ -2091,14 +2103,18 @@ process_keyboard_resize_grab (MetaDispla
           /* Move top edge up */
           y -= height_inc;
 
-          if (!display->grab_wireframe_active)
-            {
-              edge = meta_window_find_next_horizontal_edge (window, FALSE);          
-
-              if (smart_snap || ((edge > y) && ABS (edge - y) < height_inc))
-                y = edge;
-            }
-          
+          edge = meta_window_find_next_horizontal_edge (window, 
+                                                        META_WINDOW_EDGE_TOP,
+                                                        FALSE);          
+
+          if (window->frame)
+            candidate_position = edge + window->frame->child_y;
+          else
+            candidate_position = edge;
+
+          if (smart_snap || ((candidate_position > y) && ABS (candidate_position - y) < height_inc))
+            y = candidate_position;
+
           height += (orig_y - y);
           break;
 
@@ -2122,16 +2138,18 @@ process_keyboard_resize_grab (MetaDispla
           /* Move bottom edge down */
           height += height_inc;
 
-          if (!display->grab_wireframe_active)
-            {
-              edge = meta_window_find_next_horizontal_edge (window, TRUE);
-
-               if (smart_snap || ((edge < (y+height)) &&
-                                  ABS (edge - (y+height)) < height_inc))
-                 height = edge - y;
-            }
-          
-          handled = TRUE;
+          edge = meta_window_find_next_horizontal_edge (window,
+                                                        META_WINDOW_EDGE_BOTTOM,
+                                                        TRUE);
+
+          if (window->frame)
+            candidate_position = edge - window->frame->bottom_height;
+          else
+            candidate_position = edge;
+
+          if (smart_snap || ((candidate_position < (y+height)) &&
+                             ABS (candidate_position - (y+height)) < height_inc))
+            height = candidate_position - y;
           break;
 
         case SouthGravity:
@@ -2140,14 +2158,18 @@ process_keyboard_resize_grab (MetaDispla
           /* Move top edge down */
           y += height_inc;
 
-          if (!display->grab_wireframe_active)
-            {
-              edge = meta_window_find_next_horizontal_edge (window, FALSE);
-
-              if (smart_snap || ((edge < y) && ABS (edge - y) < height_inc))
-                y = edge;
-            }
-          
+          edge = meta_window_find_next_horizontal_edge (window, 
+                                                        META_WINDOW_EDGE_TOP,
+                                                        TRUE);
+
+          if (window->frame)
+            candidate_position = edge + window->frame->child_y;
+          else
+            candidate_position = edge;
+
+          if (smart_snap || ((candidate_position < y) && ABS (candidate_position - y) < height_inc))
+            y = candidate_position;
+
           height -= (y - orig_y);
           break;
 
@@ -2171,14 +2193,18 @@ process_keyboard_resize_grab (MetaDispla
           /* Move left edge left */
           x -= width_inc;
           
-          if (!display->grab_wireframe_active)
-            {
-              edge = meta_window_find_next_vertical_edge (window, TRUE);
-
-               if (smart_snap || ((edge > x) && ABS (edge - x) < width_inc))
-                 x = edge;
-            }
-          
+          edge = meta_window_find_next_vertical_edge (window, 
+                                                      META_WINDOW_EDGE_LEFT,
+                                                      FALSE);
+
+          if (window->frame)
+            candidate_position = edge + window->frame->child_x;
+          else
+            candidate_position = edge;
+
+          if (smart_snap || ((candidate_position > x) && ABS (candidate_position - x) < width_inc))
+            x = candidate_position;
+
           width += (orig_x - x);
           break;
 
@@ -2188,15 +2214,19 @@ process_keyboard_resize_grab (MetaDispla
           /* Move right edge left */
           width -= width_inc;
           
-          if (!display->grab_wireframe_active)
-            {
-              edge = meta_window_find_next_vertical_edge (window, FALSE);
-              
-              if (smart_snap || ((edge > (x+width)) &&
-                                 ABS (edge - (x+width)) < width_inc))
-                width = edge - x;
-            }
-          
+          edge = meta_window_find_next_vertical_edge (window, 
+                                                      META_WINDOW_EDGE_RIGHT,
+                                                      FALSE);
+
+          if (window->frame)
+            candidate_position = edge - window->frame->right_width;
+          else
+            candidate_position = edge;
+
+          if (smart_snap || ((candidate_position > (x+width)) &&
+                             ABS (candidate_position - (x+width)) < width_inc))
+            width = candidate_position - x;
+
           handled = TRUE;
           break;
 
@@ -2220,14 +2250,18 @@ process_keyboard_resize_grab (MetaDispla
           /* Move left edge right */
           x += width_inc;
 
-          if (!display->grab_wireframe_active)
-            {
-              edge = meta_window_find_next_vertical_edge (window, FALSE);
-
-              if (smart_snap || ((edge < x) && ABS (edge - x) < width_inc))
-                x = edge;
-            }
-          
+          edge = meta_window_find_next_vertical_edge (window, 
+                                                      META_WINDOW_EDGE_LEFT,
+                                                      TRUE);
+
+          if (window->frame)
+            candidate_position = edge + window->frame->child_x;
+          else
+            candidate_position = edge;
+
+          if (smart_snap || ((candidate_position < x) && ABS (candidate_position - x) < width_inc))
+            x = candidate_position;
+
           width -= (x - orig_x);
           break;
 
@@ -2237,15 +2271,19 @@ process_keyboard_resize_grab (MetaDispla
           /* Move right edge right */
           width += width_inc;
 
-          if (!display->grab_wireframe_active)
-            {
-              edge = meta_window_find_next_vertical_edge (window, TRUE);
-              
-              if (smart_snap || ((edge > (x+width)) &&
-                                 ABS (edge - (x+width)) < width_inc))
-                width = edge - x;
-            }
-          
+          edge = meta_window_find_next_vertical_edge (window, 
+                                                      META_WINDOW_EDGE_RIGHT,
+                                                      TRUE);
+
+          if (window->frame)
+            candidate_position = edge - window->frame->right_width;
+          else
+            candidate_position = edge;
+
+          if (smart_snap || ((candidate_position > (x+width)) &&
+                             ABS (candidate_position - (x+width)) < width_inc))
+            width = candidate_position - x;
+
           handled = TRUE;
           break;
 
This part makes it such that if the user initiates resize mode 
from the window menu that they don't have to use the keyboard
to choose an edge to resize.

This part also fixes a bug where in resize mode the cursor
wouldn't warp to the correct, outer-most edge of the window.
diff -u -p -u -p -r1.388 window.c
--- src/window.c	2 Jun 2005 15:47:37 -0000	1.388
+++ src/window.c	20 Jul 2005 04:30:40 -0000
@@ -6490,27 +6490,22 @@ update_move (MetaWindow  *window,
   if (window->maximized)
     return;
 
-  if (window->display->grab_wireframe_active)
+  if (mask & ShiftMask)
     {
-      /* FIXME Horribly broken, does not honor position
-       * constraints
-       */
-      meta_window_update_wireframe (window, new_x, new_y, 
-                                    window->display->grab_wireframe_rect.width,
-                                    window->display->grab_wireframe_rect.height);
+      /* snap to edges */
+      if (dy != 0)
+        new_x = meta_window_find_nearest_vertical_edge (window, new_x);
+
+      if (dx != 0)
+        new_y = meta_window_find_nearest_horizontal_edge (window, new_y);
     }
+
+  if (window->display->grab_wireframe_active)
+    meta_window_update_wireframe (window, new_x, new_y, 
+                                  window->display->grab_wireframe_rect.width,
+                                  window->display->grab_wireframe_rect.height);
   else
-    {
-      /* FIXME, edge snapping broken in wireframe mode */
-      if (mask & ShiftMask)
-        {
-          /* snap to edges */
-          new_x = meta_window_find_nearest_vertical_edge (window, new_x);
-          new_y = meta_window_find_nearest_horizontal_edge (window, new_y);
-        }
-      
-      meta_window_move (window, TRUE, new_x, new_y);
-    }
+    meta_window_move (window, TRUE, new_x, new_y);
 }
 
 static void update_resize (MetaWindow *window,
@@ -6554,6 +6549,50 @@ update_resize (MetaWindow *window,
   /* FIXME this is only used in wireframe mode */
   new_x = window->display->grab_anchor_window_pos.x;
   new_y = window->display->grab_anchor_window_pos.y;
+
+  if (window->display->grab_op == META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN)
+    {
+      if ((dx > 0) && (dy > 0))
+        {
+          window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SE;
+          meta_window_update_keyboard_resize (window, TRUE);
+        }
+      else if ((dx < 0) && (dy > 0))
+        {
+          window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SW;
+          meta_window_update_keyboard_resize (window, TRUE);
+        }
+      else if ((dx > 0) && (dy < 0))
+        {
+          window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NE;
+          meta_window_update_keyboard_resize (window, TRUE);
+        }
+      else if ((dx < 0) && (dy < 0))
+        {
+          window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NW;
+          meta_window_update_keyboard_resize (window, TRUE);
+        }
+      else if (dx < 0)
+        {
+          window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
+          meta_window_update_keyboard_resize (window, TRUE);
+        }
+      else if (dx > 0)
+        {
+          window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
+          meta_window_update_keyboard_resize (window, TRUE);
+        }
+      else if (dy > 0)
+        {
+          window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
+          meta_window_update_keyboard_resize (window, TRUE);
+        }
+      else if (dy < 0)
+        {
+          window->display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
+          meta_window_update_keyboard_resize (window, TRUE);
+        }
+    }
   
   switch (window->display->grab_op)
     {
@@ -7262,11 +7301,13 @@ warp_grab_pointer (MetaWindow          *
   
   if (window == window->display->grab_window &&
       window->display->grab_wireframe_active)
-    rect = window->display->grab_wireframe_rect;
+    {
+      meta_window_get_xor_rect (window, &window->display->grab_wireframe_rect,
+                                &rect);
+    }
   else
     {
-      rect = window->rect;
-      meta_window_get_position (window, &rect.x, &rect.y);
+      meta_window_get_outer_rect (window, &rect);
     }
   
   switch (grab_op)
