]> git.pld-linux.org Git - packages/metacity.git/commitdiff
- futurported patch for wireframe move/resize
authorMarcin Krzyżanowski <marcin.krzyzanowski@hakore.com>
Wed, 3 Dec 2003 20:45:21 +0000 (20:45 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    metacity-reduced_resource.patch -> 1.1

metacity-reduced_resource.patch [new file with mode: 0644]

diff --git a/metacity-reduced_resource.patch b/metacity-reduced_resource.patch
new file mode 100644 (file)
index 0000000..e49bc9b
--- /dev/null
@@ -0,0 +1,1533 @@
+diff -Nuard metacity-2.6.3.orig/README metacity-2.6.3/README
+--- metacity-2.6.3.orig/README 2003-09-08 21:42:02.000000000 +0200
++++ metacity-2.6.3/README      2003-12-03 21:24:03.603521208 +0100
+@@ -370,12 +370,11 @@
+      http://pobox.com/~hp/free-software-ui.html
+      http://pobox.com/~hp/features.html   
+-Q: Why no wireframe move/resize?
++Q: Why does wireframe move/resize suck?
+-A: It's implemented in a patch that will be merged for GNOME 2.6
+-   and is already in some vendor packages.
++A: You can turn it on with the reduced_resources setting.
+-   But: Because it has low usability, and is a pain
++   But: it has low usability, and is a pain
+    to implement, and there's no reason opaque move/resize should be a
+    problem on any setup that can run a modern desktop worth a darn to
+    begin with.
+diff -Nuard metacity-2.6.3.orig/src/display.c metacity-2.6.3/src/display.c
+--- metacity-2.6.3.orig/src/display.c  2003-10-13 22:15:40.000000000 +0200
++++ metacity-2.6.3/src/display.c       2003-12-03 21:24:03.606520752 +0100
+@@ -35,6 +35,7 @@
+ #include "resizepopup.h"
+ #include "workspace.h"
+ #include "bell.h"
++#include "effects.h"
+ #include <X11/Xatom.h>
+ #include <X11/cursorfont.h>
+ #ifdef HAVE_SOLARIS_XINERAMA
+@@ -1219,7 +1220,8 @@
+        * goes to the frame.
+        */
+       frame_was_receiver = TRUE;
+-      meta_topic (META_DEBUG_EVENTS, "Frame was receiver of event\n");
++      meta_topic (META_DEBUG_EVENTS, "Frame was receiver of event for %s\n",
++                  window->desc);
+     }
+ #ifdef HAVE_XSYNC
+@@ -1231,6 +1233,7 @@
+       
+       if (display->grab_op != META_GRAB_OP_NONE &&
+           display->grab_window != NULL &&
++          event->xany.serial > display->grab_start_serial &&
+           grab_op_is_mouse (display->grab_op))
+         meta_window_handle_mouse_grab_op_event (display->grab_window, event);
+     }
+@@ -1296,7 +1299,8 @@
+     case ButtonPress:
+       if ((window &&
+            grab_op_is_mouse (display->grab_op) &&
+-           display->grab_button != (int) event->xbutton.button && 
++           display->grab_button != (int) event->xbutton.button &&
++           event->xany.serial > display->grab_start_serial &&
+            display->grab_window == window) ||
+           grab_op_is_keyboard (display->grab_op))
+         {
+@@ -1455,16 +1459,19 @@
+       break;
+     case ButtonRelease:
+       if (display->grab_window == window &&
++          event->xany.serial > display->grab_start_serial &&
+           grab_op_is_mouse (display->grab_op))
+         meta_window_handle_mouse_grab_op_event (window, event);
+       break;
+     case MotionNotify:
+       if (display->grab_window == window &&
++          event->xany.serial > display->grab_start_serial &&
+           grab_op_is_mouse (display->grab_op))
+         meta_window_handle_mouse_grab_op_event (window, event);
+       break;
+     case EnterNotify:
+       if (display->grab_window == window &&
++          event->xany.serial > display->grab_start_serial &&
+           grab_op_is_mouse (display->grab_op))
+         meta_window_handle_mouse_grab_op_event (window, event);
+       /* do this even if window->has_focus to avoid races */
+@@ -1528,6 +1535,7 @@
+       break;
+     case LeaveNotify:
+       if (display->grab_window == window &&
++          event->xany.serial > display->grab_start_serial &&
+           grab_op_is_mouse (display->grab_op))
+         meta_window_handle_mouse_grab_op_event (window, event);
+       else if (window != NULL)
+@@ -2806,8 +2814,9 @@
+   Window grab_xwindow;
+   
+   meta_topic (META_DEBUG_WINDOW_OPS,
+-              "Doing grab op %d on window %s button %d pointer already grabbed: %d\n",
+-              op, window ? window->desc : "none", button, pointer_already_grabbed);
++              "Doing grab op %d on window %s button %d pointer already grabbed: %d pointer pos %d,%d\n",
++              op, window ? window->desc : "none", button, pointer_already_grabbed,
++              root_x, root_y);
+   
+   if (display->grab_op != META_GRAB_OP_NONE)
+     {
+@@ -2817,6 +2826,9 @@
+       return FALSE;
+     }
++  /* We'll ignore any events < this serial. */
++  display->grab_start_serial = XNextRequest (display->xdisplay);
++  
+   /* FIXME:
+    *   If we have no MetaWindow we do our best
+    *   and try to do the grab on the RootWindow.
+@@ -2832,7 +2844,7 @@
+   
+   if (pointer_already_grabbed)
+     display->grab_have_pointer = TRUE;
+-      
++  
+   meta_display_set_grab_op_cursor (display, screen, op, FALSE, grab_xwindow,
+                                    timestamp);
+@@ -2869,8 +2881,8 @@
+   display->grab_xwindow = grab_xwindow;
+   display->grab_button = button;
+   display->grab_mask = modmask;
+-  display->grab_initial_root_x = root_x;
+-  display->grab_initial_root_y = root_y;
++  display->grab_anchor_root_x = root_x;
++  display->grab_anchor_root_y = root_y;
+   display->grab_latest_motion_x = root_x;
+   display->grab_latest_motion_y = root_y;
+   display->grab_last_moveresize_time.tv_sec = 0;
+@@ -2879,6 +2891,7 @@
+ #ifdef HAVE_XSYNC
+   display->grab_update_alarm = None;
+ #endif
++  display->grab_was_cancelled = FALSE;
+   
+   if (display->grab_window)
+     {
+@@ -2886,9 +2899,34 @@
+       meta_window_get_position (display->grab_window,
+                                 &display->grab_initial_window_pos.x,
+                                 &display->grab_initial_window_pos.y);
++      display->grab_anchor_window_pos = display->grab_initial_window_pos;
++      display->grab_wireframe_active =
++        meta_prefs_get_reduced_resources () && 
++        (meta_grab_op_is_resizing (display->grab_op) ||
++         meta_grab_op_is_moving (display->grab_op));
++      
++      if (display->grab_wireframe_active)
++        {
++          /* FIXME we should really display the outer frame rect,
++           * but that complicates all the move/resize code since
++           * it works in terms of window rect.
++           */
++          display->grab_wireframe_rect = window->rect;
++          if (window->frame)
++            {
++              display->grab_wireframe_rect.x += window->frame->rect.x;
++              display->grab_wireframe_rect.y += window->frame->rect.y;
++            }
++          
++          meta_window_calc_showing (display->grab_window);
++          meta_effects_begin_wireframe (display->grab_window->screen,
++                                        &display->grab_wireframe_rect);
++        }
++      
+ #ifdef HAVE_XSYNC
+-      if (meta_grab_op_is_resizing (display->grab_op) &&
++      if (!display->grab_wireframe_active &&
++          meta_grab_op_is_resizing (display->grab_op) &&
+           display->grab_window->update_counter != None)
+         {
+           XSyncAlarmAttributes values;
+@@ -3018,6 +3056,21 @@
+                          display->grab_update_alarm);
+     }
+ #endif /* HAVE_XSYNC */
++
++  if (display->grab_wireframe_active)
++    {
++      display->grab_wireframe_active = FALSE;
++      meta_effects_end_wireframe (display->grab_window->screen,
++                                  &display->grab_wireframe_rect);
++      if (!display->grab_was_cancelled)
++        meta_window_move_resize (display->grab_window,
++                                 TRUE,
++                                 display->grab_wireframe_rect.x,
++                                 display->grab_wireframe_rect.y,
++                                 display->grab_wireframe_rect.width,
++                                 display->grab_wireframe_rect.height);
++      meta_window_calc_showing (display->grab_window);
++    }
+   
+   display->grab_window = NULL;
+   display->grab_screen = NULL;
+diff -Nuard metacity-2.6.3.orig/src/display.h metacity-2.6.3/src/display.h
+--- metacity-2.6.3.orig/src/display.h  2003-10-13 22:15:40.000000000 +0200
++++ metacity-2.6.3/src/display.h       2003-12-03 21:24:03.607520600 +0100
+@@ -225,19 +225,24 @@
+   MetaScreen *grab_screen;
+   MetaWindow *grab_window;
+   Window      grab_xwindow;
++  gulong      grab_start_serial;
+   int         grab_button;
+-  int         grab_initial_root_x;
+-  int         grab_initial_root_y;
++  int         grab_anchor_root_x;
++  int         grab_anchor_root_y;
++  MetaRectangle grab_anchor_window_pos;
+   int         grab_latest_motion_x;
+   int         grab_latest_motion_y;
+   gulong      grab_mask;
+   guint       grab_have_pointer : 1;
+   guint       grab_have_keyboard : 1;
++  guint       grab_wireframe_active : 1;
++  guint       grab_was_cancelled : 1;
++  MetaRectangle grab_wireframe_rect;
+   MetaRectangle grab_initial_window_pos;
+   MetaResizePopup *grab_resize_popup;
+   GTimeVal    grab_last_moveresize_time;
+   Time        grab_motion_notify_time;
+-
++  
+   /* we use property updates as sentinels for certain window focus events
+    * to avoid some race conditions on EnterNotify events
+    */
+diff -Nuard metacity-2.6.3.orig/src/effects.c metacity-2.6.3/src/effects.c
+--- metacity-2.6.3.orig/src/effects.c  2002-10-19 00:46:37.000000000 +0200
++++ metacity-2.6.3/src/effects.c       2003-12-03 21:24:03.608520448 +0100
+@@ -409,5 +409,108 @@
+   XFlush (context->screen->display->xdisplay);  
+ }
++void
++meta_effects_begin_wireframe (MetaScreen          *screen,
++                              const MetaRectangle *rect)
++{
++  /* Grab the X server to avoid screen dirt */
++  meta_display_grab (screen->display);
++  meta_ui_push_delay_exposes (screen->ui);  
++
++  meta_effects_update_wireframe (screen, NULL, rect);
++}
++
++static void
++draw_xor_rect (MetaScreen          *screen,
++               const MetaRectangle *rect)
++{
++  /* The lines in the center can't overlap the rectangle or each
++   * other, or the XOR gets reversed. So we have to draw things
++   * a bit oddly.
++   */
++  XSegment segments[8];
++  int i;
++  
++#define LINE_WIDTH META_WIREFRAME_XOR_LINE_WIDTH
++  
++  XDrawRectangle (screen->display->xdisplay,
++                  screen->xroot,
++                  screen->root_xor_gc,
++                  rect->x, rect->y,
++                  rect->width, rect->height);
++
++  /* Don't put lines inside small rectangles where they won't fit */
++  if (rect->width < (LINE_WIDTH * 4) ||
++      rect->height < (LINE_WIDTH * 4))
++    return;
++  
++  /* Two vertical lines at 1/3 and 2/3 */
++  segments[0].x1 = rect->x + rect->width / 3;
++  segments[0].y1 = rect->y + LINE_WIDTH / 2 + LINE_WIDTH % 2;
++  segments[0].x2 = segments[0].x1;
++  segments[0].y2 = rect->y + rect->height - LINE_WIDTH / 2;  
++  segments[1] = segments[0];
++  segments[1].x1 = rect->x + (rect->width / 3) * 2;
++  segments[1].x2 = segments[1].x1;
++
++  /* Now make two horizontal lines at 1/3 and 2/3, but not
++   * overlapping the verticals
++   */
++
++  segments[2].x1 = rect->x + LINE_WIDTH / 2 + LINE_WIDTH % 2;
++  segments[2].x2 = segments[0].x1 - LINE_WIDTH / 2;
++  segments[2].y1 = rect->y + rect->height / 3;
++  segments[2].y2 = segments[2].y1;
++
++  segments[3] = segments[2];
++  segments[3].x1 = segments[2].x2 + LINE_WIDTH;
++  segments[3].x2 = segments[1].x1 - LINE_WIDTH / 2;
++  
++  segments[4] = segments[3];
++  segments[4].x1 = segments[3].x2 + LINE_WIDTH;
++  segments[4].x2 = rect->x + rect->width - LINE_WIDTH / 2;
++
++  /* Second horizontal line is just like the first, but
++   * shifted down
++   */
++  i = 5;
++  while (i < 8)
++    {
++      segments[i] = segments[i - 3];
++      segments[i].y1 = rect->y + (rect->height / 3) * 2;
++      segments[i].y2 = segments[i].y1;
++      ++i;
++    }
++  
++  XDrawSegments (screen->display->xdisplay,
++                 screen->xroot,
++                 screen->root_xor_gc,
++                 segments,
++                 G_N_ELEMENTS (segments));
++}
++
++void
++meta_effects_update_wireframe (MetaScreen          *screen,
++                               const MetaRectangle *old_rect,
++                               const MetaRectangle *new_rect)
++{
++  if (old_rect)
++    draw_xor_rect (screen, old_rect);
++    
++  if (new_rect)
++    draw_xor_rect (screen, new_rect);
++    
++  XFlush (screen->display->xdisplay);
++}
++
++void
++meta_effects_end_wireframe (MetaScreen          *screen,
++                            const MetaRectangle *old_rect)
++{
++  meta_effects_update_wireframe (screen, old_rect, NULL);
++  
++  meta_display_ungrab (screen->display);
++  meta_ui_pop_delay_exposes (screen->ui);
++}
+diff -Nuard metacity-2.6.3.orig/src/effects.h metacity-2.6.3/src/effects.h
+--- metacity-2.6.3.orig/src/effects.h  2002-09-30 05:49:22.000000000 +0200
++++ metacity-2.6.3/src/effects.h       2003-12-03 21:24:03.608520448 +0100
+@@ -41,4 +41,12 @@
+                                       double          seconds_duration,
+                                       MetaBoxAnimType anim_type);
++void meta_effects_begin_wireframe  (MetaScreen          *screen,
++                                    const MetaRectangle *rect);
++void meta_effects_update_wireframe (MetaScreen          *screen,
++                                    const MetaRectangle *old_rect,
++                                    const MetaRectangle *new_rect);
++void meta_effects_end_wireframe    (MetaScreen          *screen,
++                                    const MetaRectangle *old_rect);
++
+ #endif /* META_EFFECTS_H */
+diff -Nuard metacity-2.6.3.orig/src/frames.c metacity-2.6.3/src/frames.c
+--- metacity-2.6.3.orig/src/frames.c   2003-08-16 18:32:10.000000000 +0200
++++ metacity-2.6.3/src/frames.c        2003-12-03 21:24:03.610520144 +0100
+@@ -2110,6 +2110,13 @@
+ void
+ meta_frames_push_delay_exposes (MetaFrames *frames)
+ {
++  if (frames->expose_delay_count == 0)
++    {
++      /* Make sure we've repainted things */
++      gdk_window_process_all_updates ();
++      XFlush (gdk_display);
++    }
++  
+   frames->expose_delay_count += 1;
+ }
+diff -Nuard metacity-2.6.3.orig/src/keybindings.c metacity-2.6.3/src/keybindings.c
+--- metacity-2.6.3.orig/src/keybindings.c      2003-09-29 18:55:25.000000000 +0200
++++ metacity-2.6.3/src/keybindings.c   2003-12-03 21:24:03.613519688 +0100
+@@ -27,6 +27,7 @@
+ #include "frame.h"
+ #include "place.h"
+ #include "prefs.h"
++#include "effects.h"
+ #include <X11/keysym.h>
+ #include <string.h>
+@@ -1693,10 +1694,24 @@
+   if (is_modifier (display, event->xkey.keycode))
+     return TRUE;
+-  meta_window_get_position (window, &x, &y);
++  if (display->grab_wireframe_active)
++    {
++      x = display->grab_wireframe_rect.x;
++      y = display->grab_wireframe_rect.y;
++    }
++  else
++    {
++      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
+@@ -1709,13 +1724,18 @@
+   if (keysym == XK_Escape)
+     {
+-      /* End move and restore to original position */
++      /* End resize and restore to original state.
++       * The move_resize is only needed when !wireframe
++       * 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);
++      display->grab_was_cancelled = TRUE;
+     }
+   
+   /* When moving by increments, we still snap to edges if the move
+@@ -1729,11 +1749,14 @@
+     case XK_KP_Prior:
+     case XK_Up:
+     case XK_KP_Up:
+-      edge = meta_window_find_next_horizontal_edge (window, FALSE);
+       y -= incr;
+-          
+-      if (smart_snap || ((edge > y) && ABS (edge - y) < incr))
+-        y = edge;
++
++      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;
++        }
+           
+       handled = TRUE;
+       break;
+@@ -1741,11 +1764,14 @@
+     case XK_KP_Next:
+     case XK_Down:
+     case XK_KP_Down:
+-      edge = meta_window_find_next_horizontal_edge (window, TRUE);
+       y += incr;
+-      if (smart_snap || ((edge < y) && ABS (edge - y) < incr))
+-        y = edge;
++      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;
++        }
+           
+       handled = TRUE;
+       break;
+@@ -1757,11 +1783,14 @@
+     case XK_KP_End:
+     case XK_Left:
+     case XK_KP_Left:
+-      edge = meta_window_find_next_vertical_edge (window, FALSE);
+       x -= incr;
+-          
+-      if (smart_snap || ((edge > x) && ABS (edge - x) < incr))
+-        x = edge;
++
++      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;
++        }
+       handled = TRUE;
+       break;
+@@ -1769,18 +1798,43 @@
+     case XK_KP_Next:
+     case XK_Right:
+     case XK_KP_Right:
+-      edge = meta_window_find_next_vertical_edge (window, TRUE);
+       x += incr;
+-      if (smart_snap || ((edge < x) && ABS (edge - x) < incr))
+-        x = edge;
++
++      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;
++        }
++      
+       handled = TRUE;
+       break;
+     }
+   if (handled)
+     {
+-      meta_window_move (window, TRUE, x, y);
+-      meta_window_warp_pointer (window, display->grab_op);
++      meta_topic (META_DEBUG_KEYBINDINGS,
++                  "Computed new window location %d,%d due to keypress\n",
++                  x, y);
++      if (display->grab_wireframe_active)
++        {
++          MetaRectangle new_xor;
++
++          new_xor = display->grab_wireframe_rect;
++          new_xor.x = x;
++          new_xor.y = y;
++          
++          meta_effects_update_wireframe (window->screen,
++                                         &display->grab_wireframe_rect,
++                                         &new_xor);
++          display->grab_wireframe_rect = new_xor;
++        }
++      else
++        {
++          meta_window_move (window, TRUE, x, y);
++        }
++      
++      meta_window_update_keyboard_move (window);
+     }
+   return handled;
+@@ -1815,13 +1869,18 @@
+   if (keysym == XK_Escape)
+     {
+-      /* End resize and restore to original state */
++      /* End resize and restore to original state.
++       * The move_resize is only needed when !wireframe
++       * 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);
++      display->grab_was_cancelled = TRUE;
+       return FALSE;
+     }
+@@ -1931,20 +1990,38 @@
+   if (handled)
+     {
+-      meta_window_update_resize_grab_op (window, TRUE);
++      meta_window_update_keyboard_resize (window, TRUE);
+       return TRUE; 
+-    } 
++    }
+-  meta_window_get_position (window, &orig_x, &orig_y);
+-  x = orig_x;
+-  y = orig_y;
+-  width = window->rect.width;
+-  height = window->rect.height;
++  if (display->grab_wireframe_active)
++    {
++      x = display->grab_wireframe_rect.x;
++      y = display->grab_wireframe_rect.y;
++      orig_x = x;
++      orig_y = 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;
++    }
+   gravity = meta_resize_gravity_from_grab_op (display->grab_op);
+-  
+-  smart_snap = (event->xkey.state & ShiftMask) != 0;
++  /* 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
+@@ -1994,12 +2071,16 @@
+         case NorthWestGravity:
+         case NorthEastGravity:
+           /* Move bottom edge up */
+-          edge = meta_window_find_next_horizontal_edge (window, TRUE);
+           height -= height_inc;
+           
+-          if (smart_snap || ((edge > (y+height)) &&
+-                             ABS (edge - (y+height)) < height_inc))
+-            height = edge - y;
++          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;
+           break;
+@@ -2008,11 +2089,15 @@
+         case SouthWestGravity:
+         case SouthEastGravity:
+           /* Move top edge up */
+-          edge = meta_window_find_next_horizontal_edge (window, FALSE);
+           y -= height_inc;
+-          
+-          if (smart_snap || ((edge > y) && ABS (edge - y) < height_inc))
+-            y = edge;
++
++          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;
++            }
+           
+           height += (orig_y - y);
+           break;
+@@ -2035,12 +2120,16 @@
+         case NorthWestGravity:
+         case NorthEastGravity:
+           /* Move bottom edge down */
+-          edge = meta_window_find_next_horizontal_edge (window, TRUE);
+           height += height_inc;
+-          
+-          if (smart_snap || ((edge < (y+height)) &&
+-                             ABS (edge - (y+height)) < height_inc))
+-            height = edge - y;
++
++          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;
+           break;
+@@ -2049,11 +2138,15 @@
+         case SouthWestGravity:
+         case SouthEastGravity:
+           /* Move top edge down */
+-          edge = meta_window_find_next_horizontal_edge (window, FALSE);
+           y += height_inc;
+-          
+-          if (smart_snap || ((edge < y) && ABS (edge - y) < height_inc))
+-            y = edge;
++
++          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;
++            }
+           
+           height -= (y - orig_y);
+           break;
+@@ -2076,11 +2169,15 @@
+         case SouthEastGravity:
+         case NorthEastGravity:
+           /* Move left edge left */
+-          edge = meta_window_find_next_vertical_edge (window, TRUE);
+           x -= width_inc;
+           
+-          if (smart_snap || ((edge > x) && ABS (edge - x) < width_inc))
+-            x = edge;
++          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;
++            }
+           
+           width += (orig_x - x);
+           break;
+@@ -2089,12 +2186,16 @@
+         case SouthWestGravity:
+         case NorthWestGravity:
+           /* Move right edge left */
+-          edge = meta_window_find_next_vertical_edge (window, FALSE);
+           width -= width_inc;
+           
+-          if (smart_snap || ((edge > (x+width)) &&
+-                             ABS (edge - (x+width)) < width_inc))
+-            width = edge - x;
++          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;
++            }
+           
+           handled = TRUE;
+           break;
+@@ -2117,11 +2218,15 @@
+         case SouthEastGravity:
+         case NorthEastGravity:
+           /* Move left edge right */
+-          edge = meta_window_find_next_vertical_edge (window, FALSE);
+           x += width_inc;
+-          
+-          if (smart_snap || ((edge < x) && ABS (edge - x) < width_inc))
+-            x = edge;
++
++          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;
++            }
+           
+           width -= (x - orig_x);
+           break;
+@@ -2130,12 +2235,16 @@
+         case SouthWestGravity:
+         case NorthWestGravity:
+           /* Move right edge right */
+-          edge = meta_window_find_next_vertical_edge (window, TRUE);
+           width += width_inc;
+-          
+-          if (smart_snap || ((edge > (x+width)) &&
+-                             ABS (edge - (x+width)) < width_inc))
+-            width = edge - x;
++
++          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;
++            }
+           
+           handled = TRUE;
+           break;
+@@ -2162,8 +2271,32 @@
+   
+   if (handled)
+     {
+-      meta_window_move_resize (window, TRUE, x, y, width, height);
+-      meta_window_update_resize_grab_op (window, FALSE);
++      meta_topic (META_DEBUG_KEYBINDINGS,
++                  "Computed new window location %d,%d %dx%d due to keypress\n",
++                  x, y, width, height);
++      
++      if (display->grab_wireframe_active)
++        {
++          MetaRectangle new_xor;
++      
++          new_xor.x = x;
++          new_xor.y = y;
++          new_xor.width = width;
++          new_xor.height = height;
++
++          meta_effects_update_wireframe (window->screen,
++                                         &window->display->grab_wireframe_rect,
++                                         &new_xor);
++          window->display->grab_wireframe_rect = new_xor;
++
++          /* do this after drawing the wires, so we don't draw over it */
++          meta_window_refresh_resize_popup (window);
++        }
++      else
++        {
++          meta_window_move_resize (window, TRUE, x, y, width, height);
++        }
++      meta_window_update_keyboard_resize (window, FALSE);
+     }
+   return handled;
+diff -Nuard metacity-2.6.3.orig/src/metacity.schemas.in metacity-2.6.3/src/metacity.schemas.in
+--- metacity-2.6.3.orig/src/metacity.schemas.in        2003-06-27 16:49:56.000000000 +0200
++++ metacity-2.6.3/src/metacity.schemas.in     2003-12-03 21:24:03.615519384 +0100
+@@ -257,6 +257,25 @@
+       </locale>
+     </schema>
++    <schema>
++      <key>/schemas/apps/metacity/general/reduced_resources</key>
++      <applyto>/apps/metacity/general/reduced_resources</applyto>
++      <owner>metacity</owner>
++      <type>bool</type>
++      <default>false</default>
++      <locale name="C">
++         <short>If true, trade off usability for less resource usage</short>
++         <long>
++          If true, metacity will give the user less feedback and 
++        less sense of "direct manipulation", by using wireframes, 
++        avoiding animations, or other means. This is a significant 
++        reduction in usability for many users, but may allow 
++        legacy applications and terminal servers to function 
++        when they would otherwise be impractical.
++         </long>
++      </locale>
++    </schema>
++
+     <!-- Window Keybindings -->
+     <schema>
+diff -Nuard metacity-2.6.3.orig/src/prefs.c metacity-2.6.3/src/prefs.c
+--- metacity-2.6.3.orig/src/prefs.c    2003-06-27 16:49:56.000000000 +0200
++++ metacity-2.6.3/src/prefs.c 2003-12-03 21:24:03.617519080 +0100
+@@ -51,6 +51,7 @@
+ #define KEY_APPLICATION_BASED "/apps/metacity/general/application_based"
+ #define KEY_DISABLE_WORKAROUNDS "/apps/metacity/general/disable_workarounds"
+ #define KEY_BUTTON_LAYOUT "/apps/metacity/general/button_layout"
++#define KEY_REDUCED_RESOURCES "/apps/metacity/general/reduced_resources"
+ #define KEY_COMMAND_PREFIX "/apps/metacity/keybinding_commands/command_"
+ #define KEY_SCREEN_BINDINGS_PREFIX "/apps/metacity/global_keybindings"
+@@ -83,6 +84,8 @@
+ static gboolean auto_raise_delay = 500;
+ static gboolean provide_visual_bell = TRUE;
+ static gboolean bell_is_audible = TRUE;
++static gboolean reduced_resources = FALSE;
++
+ static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_INVALID;
+ static MetaButtonLayout button_layout = {
+   {
+@@ -129,6 +132,7 @@
+                                            const char  *value);
+ static gboolean update_workspace_name     (const char  *name,
+                                            const char  *value);
++static gboolean update_reduced_resources  (gboolean     value);
+ static void change_notify (GConfClient    *client,
+                            guint           cnxn_id,
+@@ -372,7 +376,6 @@
+   cleanup_error (&err);
+   update_button_layout (str_val);
+   g_free (str_val);
+-#endif /* HAVE_GCONF */
+   
+   bool_val = gconf_client_get_bool (default_client, KEY_VISUAL_BELL,
+                                     &err);
+@@ -388,6 +391,12 @@
+   update_visual_bell_type (str_val);
+   g_free (str_val);
++  bool_val = gconf_client_get_bool (default_client, KEY_REDUCED_RESOURCES,
++                                  &err);
++  cleanup_error (&err);
++  update_reduced_resources (bool_val);
++#endif /* HAVE_GCONF */
++  
+   /* Load keybindings prefs */
+   init_bindings ();
+@@ -733,6 +742,22 @@
+       if (update_visual_bell_type (str))
+       queue_changed (META_PREF_VISUAL_BELL_TYPE);
+     }
++  else if (strcmp (key, KEY_REDUCED_RESOURCES) == 0)
++    {
++      gboolean b;
++
++      if (value && value->type != GCONF_VALUE_BOOL)
++        {
++          meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
++                        KEY_REDUCED_RESOURCES);
++          goto out;
++        }
++
++      b = value ? gconf_value_get_bool (value) : reduced_resources;
++
++      if (update_reduced_resources (b))
++        queue_changed (META_PREF_REDUCED_RESOURCES);
++    }
+   else
+     {
+       meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n",
+@@ -1239,6 +1264,16 @@
+   return old != auto_raise_delay;
+ }
++
++static gboolean
++update_reduced_resources (gboolean value)
++{
++  gboolean old = reduced_resources;
++
++  reduced_resources = value;
++
++  return old != reduced_resources;
++}
+ #endif /* HAVE_GCONF */
+ #ifdef WITH_VERBOSE_MODE
+@@ -1305,6 +1340,10 @@
+     case META_PREF_VISUAL_BELL_TYPE:
+       return "VISUAL_BELL_TYPE";
+       break;
++
++    case META_PREF_REDUCED_RESOURCES:
++      return "REDUCED_RESOURCES";
++      break;
+     }
+   return "(unknown)";
+@@ -1974,6 +2013,12 @@
+   return auto_raise_delay;
+ }
++gboolean
++meta_prefs_get_reduced_resources ()
++{
++  return reduced_resources;
++}
++
+ MetaKeyBindingAction
+ meta_prefs_get_keybinding_action (const char *name)
+ {
+diff -Nuard metacity-2.6.3.orig/src/prefs.h metacity-2.6.3/src/prefs.h
+--- metacity-2.6.3.orig/src/prefs.h    2003-06-27 16:49:56.000000000 +0200
++++ metacity-2.6.3/src/prefs.h 2003-12-03 21:24:03.617519080 +0100
+@@ -45,7 +45,8 @@
+   META_PREF_WORKSPACE_NAMES,
+   META_PREF_VISUAL_BELL,
+   META_PREF_AUDIBLE_BELL,
+-  META_PREF_VISUAL_BELL_TYPE
++  META_PREF_VISUAL_BELL_TYPE,
++  META_PREF_REDUCED_RESOURCES
+ } MetaPreference;
+ typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
+@@ -69,6 +70,7 @@
+ gboolean                    meta_prefs_get_disable_workarounds (void);
+ gboolean                    meta_prefs_get_auto_raise         (void);
+ int                         meta_prefs_get_auto_raise_delay   (void);
++gboolean                    meta_prefs_get_reduced_resources  (void);
+ const char*                 meta_prefs_get_command            (int i);
+diff -Nuard metacity-2.6.3.orig/src/screen.c metacity-2.6.3/src/screen.c
+--- metacity-2.6.3.orig/src/screen.c   2003-08-16 00:09:55.000000000 +0200
++++ metacity-2.6.3/src/screen.c        2003-12-03 21:25:25.123128344 +0100
+@@ -538,10 +538,23 @@
+   screen->starting_corner = META_SCREEN_TOPLEFT;
+   screen->showing_desktop = FALSE;
++
++  {
++    XGCValues gc_values;
++    
++    gc_values.subwindow_mode = IncludeInferiors;
++    gc_values.function = GXinvert;
++    gc_values.line_width = META_WIREFRAME_XOR_LINE_WIDTH;
++    
++    screen->root_xor_gc = XCreateGC (screen->display->xdisplay,
++                                     screen->xroot,
++                                     GCSubwindowMode | GCFunction | GCLineWidth,
++                                     &gc_values);
++  }
+   
+   screen->xinerama_infos = NULL;
+   screen->n_xinerama_infos = 0;
+-  screen->last_xinerama_index = 0;
++  screen->last_xinerama_index = 0;  
+   
+   reload_xinerama_infos (screen);
+   
+@@ -679,6 +692,9 @@
+   
+   if (screen->work_area_idle != 0)
+     g_source_remove (screen->work_area_idle);
++
++  XFreeGC (screen->display->xdisplay,
++           screen->root_xor_gc);
+   
+   g_free (screen->screen_name);
+   g_free (screen);
+diff -Nuard metacity-2.6.3.orig/src/screen.h metacity-2.6.3/src/screen.h
+--- metacity-2.6.3.orig/src/screen.h   2003-08-16 00:09:55.000000000 +0200
++++ metacity-2.6.3/src/screen.h        2003-12-03 21:25:25.123128344 +0100
+@@ -56,6 +56,8 @@
+   META_SCREEN_RIGHT
+ } MetaScreenDirection;
++#define META_WIREFRAME_XOR_LINE_WIDTH 5
++
+ struct _MetaScreen
+ {
+   MetaDisplay *display;
+@@ -108,6 +110,9 @@
+   guint showing_desktop : 1;
+   
+   int closing;
++
++  /* gc for XOR on root window */
++  GC root_xor_gc;
+ };
+ MetaScreen*   meta_screen_new                 (MetaDisplay                *display,
+diff -Nuard metacity-2.6.3.orig/src/window.c metacity-2.6.3/src/window.c
+--- metacity-2.6.3.orig/src/window.c   2003-10-26 17:22:54.000000000 +0100
++++ metacity-2.6.3/src/window.c        2003-12-03 21:25:25.323097944 +0100
+@@ -1207,6 +1207,14 @@
+         showing = FALSE;
+     }
++#if 0
++  /* 5. See if we're drawing wireframe
++   */
++  if (window->display->grab_window == window &&
++      window->display->grab_wireframe_active)    
++    showing = FALSE;
++#endif
++  
+   return showing;
+ }
+@@ -1231,7 +1239,8 @@
+        * if we are mapped now, we are supposed to
+        * be minimized, and we are on the current workspace.
+        */
+-      if (on_workspace && window->minimized && window->mapped)
++      if (on_workspace && window->minimized && window->mapped &&
++          !meta_prefs_get_reduced_resources ())
+         {
+         MetaRectangle icon_rect, window_rect;
+         gboolean result;
+@@ -1857,7 +1866,7 @@
+       if (meta_grab_op_is_moving (window->display->grab_op) &&
+           window->display->grab_window == window)
+         {
+-          window->display->grab_initial_window_pos = window->saved_rect;
++          window->display->grab_anchor_window_pos = window->saved_rect;
+         }
+       meta_window_move_resize (window,
+@@ -5692,7 +5701,7 @@
+   window->display->grab_last_moveresize_time = current_time;
+   
+   meta_topic (META_DEBUG_RESIZING,
+-              " Doing move/resize now (%g of %g seconds elapsed)\n",
++              " Checked moveresize freq, allowing move/resize now (%g of %g seconds elapsed)\n",
+               elapsed / 1000.0, 1.0 / max_resizes_per_second);
+   
+   return TRUE;
+@@ -5711,12 +5720,20 @@
+   window->display->grab_latest_motion_x = x;
+   window->display->grab_latest_motion_y = y;
+   
+-  dx = x - window->display->grab_initial_root_x;
+-  dy = y - window->display->grab_initial_root_y;
++  dx = x - window->display->grab_anchor_root_x;
++  dy = y - window->display->grab_anchor_root_y;
+-  new_x = window->display->grab_initial_window_pos.x + dx;
+-  new_y = window->display->grab_initial_window_pos.y + dy;
++  new_x = window->display->grab_anchor_window_pos.x + dx;
++  new_y = window->display->grab_anchor_window_pos.y + dy;
++  meta_verbose ("x,y = %d,%d anchor ptr %d,%d anchor pos %d,%d dx,dy %d,%d\n",
++                x, y,
++                window->display->grab_anchor_root_x,
++                window->display->grab_anchor_root_y,
++                window->display->grab_anchor_window_pos.x,
++                window->display->grab_anchor_window_pos.y,
++                dx, dy);
++  
+   /* shake loose (unmaximize) maximized window if dragged beyond the threshold
+    * in the Y direction. You can't pull a window loose via X motion.
+    */
+@@ -5805,14 +5822,33 @@
+   if (window->maximized)
+     return;
+-  if (mask & ShiftMask)
++  if (window->display->grab_wireframe_active)
+     {
+-      /* 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);
+-    }
++      /* FIXME Horribly broken, does not honor position
++       * constraints
++       */
++      MetaRectangle new_xor;
++      new_xor = window->display->grab_wireframe_rect;
++      new_xor.x = new_x;
++      new_xor.y = new_y;
+-  meta_window_move (window, TRUE, new_x, new_y);
++      meta_effects_update_wireframe (window->screen,
++                                     &window->display->grab_wireframe_rect,
++                                     &new_xor);
++      window->display->grab_wireframe_rect = new_xor;
++    }
++  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);
++    }
+ }
+ static void
+@@ -5823,16 +5859,21 @@
+   int new_w, new_h;
+   int gravity;
+   MetaRectangle old;
++  int new_x, new_y;
+   
+   window->display->grab_latest_motion_x = x;
+   window->display->grab_latest_motion_y = y;
+   
+-  dx = x - window->display->grab_initial_root_x;
+-  dy = y - window->display->grab_initial_root_y;
++  dx = x - window->display->grab_anchor_root_x;
++  dy = y - window->display->grab_anchor_root_y;
+-  new_w = window->display->grab_initial_window_pos.width;
+-  new_h = window->display->grab_initial_window_pos.height;
++  new_w = window->display->grab_anchor_window_pos.width;
++  new_h = window->display->grab_anchor_window_pos.height;
++  /* 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;
++  
+   switch (window->display->grab_op)
+     {
+     case META_GRAB_OP_RESIZING_SE:
+@@ -5851,6 +5892,7 @@
+     case META_GRAB_OP_KEYBOARD_RESIZING_SW:
+     case META_GRAB_OP_KEYBOARD_RESIZING_W:
+       new_w -= dx;
++      new_x += dx;
+       break;
+       
+     default:
+@@ -5875,6 +5917,7 @@
+     case META_GRAB_OP_KEYBOARD_RESIZING_NE:
+     case META_GRAB_OP_KEYBOARD_RESIZING_NW:
+       new_h -= dy;
++      new_y += dy;
+       break;
+     default:
+       break;
+@@ -5884,12 +5927,42 @@
+     return;
+   
+   old = window->rect;
+-  
++
+   /* compute gravity of client during operation */
+   gravity = meta_resize_gravity_from_grab_op (window->display->grab_op);
+   g_assert (gravity >= 0);
+   
+-  meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
++  if (window->display->grab_wireframe_active)
++    {
++      /* FIXME This is crap. For example, the wireframe isn't
++       * constrained in the way that a real resize would be. An
++       * obvious elegant solution is to unmap the window during
++       * wireframe, but still resize it; however, that probably
++       * confuses broken clients that have problems with opaque
++       * resize, they probably don't track their visibility.
++       */
++      MetaRectangle new_xor;
++      
++      if ((new_x + new_w <= new_x) || (new_y + new_h <= new_y))
++        return;
++      
++      new_xor.x = new_x;
++      new_xor.y = new_y;
++      new_xor.width = new_w;
++      new_xor.height = new_h;
++
++      meta_effects_update_wireframe (window->screen,
++                                     &window->display->grab_wireframe_rect,
++                                     &new_xor);
++      window->display->grab_wireframe_rect = new_xor;
++
++      /* do this after drawing the wires, so we don't draw over it */
++      meta_window_refresh_resize_popup (window);
++    }
++  else
++    {
++      meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
++    }
+   /* If we don't actually resize the window, we clear the timestamp,
+    * so we'll quickly try again.  Otherwise you get "stuck" because
+@@ -6291,6 +6364,13 @@
+   if (window->display->grab_window != window)
+     return;
++  /* FIXME for now we bail out when doing wireframe, because our
++   * server grab keeps us from being able to redraw the stuff
++   * underneath the resize popup.
++   */
++  if (window->display->grab_wireframe_active)
++    return;
++  
+   switch (window->display->grab_op)
+     {
+     case META_GRAB_OP_RESIZING_SE:
+@@ -6329,7 +6409,7 @@
+   if (window->display->grab_resize_popup != NULL)
+     {
+       int gravity;
+-      int x, y;
++      int x, y, width, height;
+       MetaFrameGeometry fgeom;
+       if (window->frame)
+@@ -6345,13 +6425,24 @@
+       gravity = meta_resize_gravity_from_grab_op (window->display->grab_op);
+       g_assert (gravity >= 0);
+-      meta_window_get_position (window, &x, &y);
++      if (window->display->grab_wireframe_active)
++        {
++          x = window->display->grab_wireframe_rect.x;
++          y = window->display->grab_wireframe_rect.y;
++          width = window->display->grab_wireframe_rect.width;
++          height = window->display->grab_wireframe_rect.height;
++        }
++      else
++        {
++          meta_window_get_position (window, &x, &y);
++          width = window->rect.width;
++          height = window->rect.height;
++        }
+       
+       meta_ui_resize_popup_set (window->display->grab_resize_popup,
+                                 gravity,
+                                 x, y,
+-                                window->rect.width,
+-                                window->rect.height,
++                                width, height,
+                                 window->size_hints.base_width,
+                                 window->size_hints.base_height,
+                                 window->size_hints.min_width,
+@@ -6478,53 +6569,70 @@
+   return d.found;
+ }
++/* Warp pointer to location appropriate for grab,
++ * return root coordinates where pointer ended up.
++ */
+ static gboolean
+-warp_pointer (MetaWindow *window,
+-              MetaGrabOp  grab_op,
+-              int        *x,
+-              int        *y)
++warp_grab_pointer (MetaWindow          *window,
++                   MetaGrabOp           grab_op,
++                   int                 *x,
++                   int                 *y)
+ {
++  MetaRectangle rect;
++
++  /* We may not have done begin_grab_op yet, i.e. may not be in a grab
++   */
++  
++  if (window == window->display->grab_window &&
++      window->display->grab_wireframe_active)
++    rect = window->display->grab_wireframe_rect;
++  else
++    {
++      rect = window->rect;
++      meta_window_get_position (window, &rect.x, &rect.y);
++    }
++  
+   switch (grab_op)
+     {
+       case META_GRAB_OP_KEYBOARD_MOVING:
+       case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
+-        *x = window->rect.width / 2;
+-        *y = window->rect.height / 2;
++        *x = rect.width / 2;
++        *y = rect.height / 2;
+         break;
+       case META_GRAB_OP_KEYBOARD_RESIZING_S:
+-        *x = window->rect.width / 2;
+-        *y = window->rect.height;
++        *x = rect.width / 2;
++        *y = rect.height;
+         break;
+       case META_GRAB_OP_KEYBOARD_RESIZING_N:
+-        *x = window->rect.width / 2;
++        *x = rect.width / 2;
+         *y = 0;
+         break;
+       case META_GRAB_OP_KEYBOARD_RESIZING_W:
+         *x = 0;
+-        *y = window->rect.height / 2;
++        *y = rect.height / 2;
+         break;
+       case META_GRAB_OP_KEYBOARD_RESIZING_E:
+-        *x = window->rect.width;
+-        *y = window->rect.height / 2;
++        *x = rect.width;
++        *y = rect.height / 2;
+         break;
+       case META_GRAB_OP_KEYBOARD_RESIZING_SE:
+-        *x = window->rect.width;
+-        *y = window->rect.height;
++        *x = rect.width;
++        *y = rect.height;
+         break;
+       case META_GRAB_OP_KEYBOARD_RESIZING_NE:
+-        *x = window->rect.width;
++        *x = rect.width;
+         *y = 0;
+         break;
+       case META_GRAB_OP_KEYBOARD_RESIZING_SW:
+         *x = 0;
+-        *y = window->rect.height;
++        *y = rect.height;
+         break;
+       case META_GRAB_OP_KEYBOARD_RESIZING_NW:
+@@ -6536,45 +6644,45 @@
+         return FALSE;
+     }
++  *x += rect.x;
++  *y += rect.y;
++  
+   meta_error_trap_push_with_return (window->display);
++
++  meta_topic (META_DEBUG_WINDOW_OPS,
++              "Warping pointer to %d,%d with window at %d,%d\n",
++              *x, *y, rect.x, rect.y);
+   
+   XWarpPointer (window->display->xdisplay,
+                 None,
+-                window->xwindow,
++                window->screen->xroot,
+                 0, 0, 0, 0, 
+-                *x,
+-                *y);
++                *x, *y);
+   if (meta_error_trap_pop_with_return (window->display, FALSE) != Success)
+     {
+-      meta_verbose ("Failed to warp pointer for window %s\n", window->desc);
++      meta_verbose ("Failed to warp pointer for window %s\n",
++                    window->desc);
+       return FALSE;
+     }
+-
++  
+   return TRUE;
+ }
+-gboolean
+-meta_window_warp_pointer (MetaWindow *window,
+-                          MetaGrabOp  grab_op)
+-{
+-  int x, y;
+- 
+-  return warp_pointer (window, grab_op, &x, &y); 
+-}
+-
+ void
+ meta_window_begin_grab_op (MetaWindow *window,
+                            MetaGrabOp  op,
+                            Time        timestamp)
+ {
+-  int x, y, x_offset, y_offset;
+-
+-  meta_window_get_position (window, &x, &y);
++  int x, y;
++  gulong grab_start_serial;
++  grab_start_serial = XNextRequest (window->display->xdisplay);
++  
+   meta_window_raise (window);
+-  warp_pointer (window, op, &x_offset, &y_offset);
++  warp_grab_pointer (window,
++                     op, &x, &y);
+   meta_display_begin_grab_op (window->display,
+                               window->screen,
+@@ -6582,31 +6690,50 @@
+                               op,
+                               FALSE, 0, 0,
+                               timestamp,
+-                              x + x_offset, 
+-                              y + y_offset);
++                              x, y);
++
++  /* We override the one set in display_begin_grab_op since we
++   * did additional stuff as part of the grabbing process
++   */
++  window->display->grab_start_serial = grab_start_serial;
+ }
+ void
+-meta_window_update_resize_grab_op (MetaWindow *window,
+-                                   gboolean    update_cursor)
++meta_window_update_keyboard_resize (MetaWindow *window,
++                                    gboolean    update_cursor)
+ {
+-  int x, y, x_offset, y_offset;
+-
+-  meta_window_get_position (window, &x, &y);
++  int x, y;
+   
+-  warp_pointer (window, window->display->grab_op, &x_offset, &y_offset);
++  warp_grab_pointer (window,
++                     window->display->grab_op,
++                     &x, &y);
+-  /* As we warped the pointer, we have to reset the apparent
+-   * initial window state, since if the mouse moves we want
+-   * to use those events to do the right thing.
+-   */
+-  if (window->display->grab_window == window)
+-    {
+-      window->display->grab_initial_root_x = x + x_offset;
+-      window->display->grab_initial_root_y = y + y_offset;
+-      
+-      window->display->grab_initial_window_pos = window->rect;
+-    }
++  {
++    /* As we warped the pointer, we have to reset the anchor state,
++     * since if the mouse moves we want to use those events to do the
++     * right thing. Also, this means that the motion notify
++     * from the pointer warp comes back as a no-op.
++     */
++    int dx, dy;
++
++    dx = x - window->display->grab_anchor_root_x;
++    dy = y - window->display->grab_anchor_root_y;
++    
++    window->display->grab_anchor_root_x += dx;
++    window->display->grab_anchor_root_y += dy;
++    if (window->display->grab_wireframe_active)
++      {
++        window->display->grab_anchor_window_pos =
++          window->display->grab_wireframe_rect;
++      }
++    else
++      {
++        window->display->grab_anchor_window_pos = window->rect;
++        meta_window_get_position (window,
++                                  &window->display->grab_anchor_window_pos.x,
++                                  &window->display->grab_anchor_window_pos.y);
++      }
++  }
+   
+   if (update_cursor)
+     {
+@@ -6620,6 +6747,16 @@
+ }
+ void
++meta_window_update_keyboard_move (MetaWindow *window)
++{
++  int x, y;
++  
++  warp_grab_pointer (window,
++                     window->display->grab_op,
++                     &x, &y);
++}
++
++void
+ meta_window_update_layer (MetaWindow *window)
+ {
+   MetaGroup *group;
+diff -Nuard metacity-2.6.3.orig/src/window.h metacity-2.6.3/src/window.h
+--- metacity-2.6.3.orig/src/window.h   2003-10-13 22:15:40.000000000 +0200
++++ metacity-2.6.3/src/window.h        2003-12-03 21:25:25.357092776 +0100
+@@ -472,15 +472,13 @@
+                                                MetaWindowForeachFunc  func,
+                                                void                  *data);
+-gboolean meta_window_warp_pointer (MetaWindow *window,
+-                                   MetaGrabOp  grab_op);
+-
+ void meta_window_begin_grab_op (MetaWindow *window,
+                                 MetaGrabOp  op,
+                                 Time        timestamp);
+-void meta_window_update_resize_grab_op (MetaWindow *window,
+-                                        gboolean    update_cursor);
++void meta_window_update_keyboard_resize (MetaWindow *window,
++                                         gboolean    update_cursor);
++void meta_window_update_keyboard_move   (MetaWindow *window);
+ void meta_window_update_layer (MetaWindow *window);
This page took 0.093221 seconds and 4 git commands to generate.