diff -uN metacity-2.5.2-base/src/Makefile.am metacity-2.5.2-patch/src/Makefile.am
--- metacity-2.5.2-base/src/Makefile.am	2003-04-21 19:34:45.000000000 -0400
+++ metacity-2.5.2-patch/src/Makefile.am	2003-08-30 14:58:33.000000000 -0400
@@ -31,6 +31,7 @@
 	eventqueue.h				\
 	fixedtip.c				\
 	fixedtip.h				\
+	flip.c                  \
 	frame.c					\
 	frame.h					\
 	frames.c				\
diff -uN metacity-2.5.2-base/src/Makefile.in metacity-2.5.2-patch/src/Makefile.in
--- metacity-2.5.2-base/src/Makefile.in	2003-05-20 12:32:21.000000000 -0400
+++ metacity-2.5.2-patch/src/Makefile.in	2003-08-30 14:57:52.000000000 -0400
@@ -122,7 +122,7 @@
 EGGFILES =  	eggaccelerators.c		eggaccelerators.h
 
 
-metacity_SOURCES =  	async-getprop.c					async-getprop.h					bell.h						bell.c						common.h					constraints.c					constraints.h					core.c						core.h						delete.c					display.c					display.h					draw-workspace.c				draw-workspace.h				effects.c					effects.h					errors.c					errors.h					eventqueue.c					eventqueue.h					fixedtip.c					fixedtip.h					frame.c						frame.h						frames.c					frames.h					gradient.c					gradient.h					group.c						group.h						group-private.h					group-props.c					group-props.h					iconcache.c					iconcache.h					inlinepixbufs.h					keybindings.c					keybindings.h					main.c						main.h						menu.c						menu.h						metaaccellabel.c				metaaccellabel.h				metacity-Xatomtype.h				place.c						place.h						prefs.c						prefs.h						resizepopup.c					resizepopup.h					screen.c					screen.h					session.c					session.h					stack.c						stack.h						tabpopup.c					tabpopup.h					theme.c						theme.h						theme-parser.c					theme-parser.h					themewidget.c					themewidget.h					ui.c						ui.h						util.c						util.h						window.c					window.h					window-props.c					window-props.h					workspace.c					workspace.h					xprops.c					xprops.h					$(EGGFILES)
+metacity_SOURCES =  	async-getprop.c					async-getprop.h					bell.h						bell.c						common.h					constraints.c					constraints.h					core.c						core.h						delete.c					display.c					display.h					draw-workspace.c				draw-workspace.h				effects.c					effects.h					errors.c					errors.h					eventqueue.c					eventqueue.h					fixedtip.c					fixedtip.h					frame.c						frame.h						frames.c					frames.h					gradient.c					gradient.h					group.c						group.h						group-private.h					group-props.c					group-props.h					iconcache.c					iconcache.h					inlinepixbufs.h					keybindings.c					keybindings.h					main.c						main.h						menu.c						menu.h						metaaccellabel.c				metaaccellabel.h				metacity-Xatomtype.h				place.c						place.h						prefs.c						prefs.h						resizepopup.c					resizepopup.h					screen.c					screen.h					session.c					session.h					stack.c						stack.h						tabpopup.c					tabpopup.h					theme.c						theme.h						theme-parser.c					theme-parser.h					themewidget.c					themewidget.h					ui.c						ui.h						util.c						util.h						window.c					window.h					window-props.c					window-props.h					workspace.c					workspace.h					xprops.c					xprops.h					flip.c              $(EGGFILES)
 
 
 libmetacity_private_la_SOURCES =  	gradient.c			gradient.h			preview-widget.c		preview-widget.h		theme.c				theme.h				theme-parser.c			theme-parser.h			util.c				util.h				common.h
@@ -207,7 +207,7 @@
 metacity_OBJECTS =  async-getprop.$(OBJEXT) bell.$(OBJEXT) \
 constraints.$(OBJEXT) core.$(OBJEXT) delete.$(OBJEXT) display.$(OBJEXT) \
 draw-workspace.$(OBJEXT) effects.$(OBJEXT) errors.$(OBJEXT) \
-eventqueue.$(OBJEXT) fixedtip.$(OBJEXT) frame.$(OBJEXT) \
+eventqueue.$(OBJEXT) fixedtip.$(OBJEXT) flip.$(OBJEXT) frame.$(OBJEXT) \
 frames.$(OBJEXT) gradient.$(OBJEXT) group.$(OBJEXT) \
 group-props.$(OBJEXT) iconcache.$(OBJEXT) keybindings.$(OBJEXT) \
 main.$(OBJEXT) menu.$(OBJEXT) metaaccellabel.$(OBJEXT) place.$(OBJEXT) \
@@ -625,6 +625,7 @@
 	common.h
 eventqueue.o: eventqueue.c eventqueue.h
 fixedtip.o: fixedtip.c ../config.h fixedtip.h
+flip.o: flip.c ../config.h
 frame.o: frame.c ../config.h frame.h window.h screen.h display.h \
 	eventqueue.h common.h ui.h tabpopup.h util.h stack.h \
 	iconcache.h bell.h errors.h keybindings.h
diff -uN metacity-2.5.2-base/src/display.c metacity-2.5.2-patch/src/display.c
--- metacity-2.5.2-base/src/display.c	2003-05-16 17:53:42.000000000 -0400
+++ metacity-2.5.2-patch/src/display.c	2003-08-30 14:56:35.000000000 -0400
@@ -96,6 +96,10 @@
 
 static void    prefs_changed_callback    (MetaPreference pref,
                                           void          *data);
+int meta_flip_event( int xl, int yt );
+void meta_flip_init( MetaScreen * mscr );
+
+
 
 static void
 set_utf8_string_hint (MetaDisplay *display,
@@ -611,9 +615,9 @@
     
     meta_error_trap_pop (display, FALSE);
   }
-  
+  meta_flip_init(display->screens->data);
   meta_display_ungrab (display);  
-  
+
   return TRUE;
 }
 
@@ -1430,6 +1434,14 @@
         meta_window_handle_mouse_grab_op_event (window, event);
       break;
     case EnterNotify:
+      {
+        XEnterWindowEvent *ewp = &(event->xcrossing);
+        if( meta_flip_event( ewp->x_root, ewp->y_root ) )
+        {
+          break;
+        } 
+      }
+
       if (display->grab_window == window &&
           grab_op_is_mouse (display->grab_op))
         meta_window_handle_mouse_grab_op_event (window, event);
diff -uN metacity-2.5.2-base/src/flip.c metacity-2.5.2-patch/src/flip.c
--- metacity-2.5.2-base/src/flip.c	1969-12-31 19:00:00.000000000 -0500
+++ metacity-2.5.2-patch/src/flip.c	2003-08-30 14:56:35.000000000 -0400
@@ -0,0 +1,529 @@
+/* Metacity Edge Flip Handling */
+
+/* 
+ * Copyright (C) 2001, 2002 Havoc Pennington
+ * Copyright (C) 2002, 2003 Red Hat Inc.
+ * Some edge flip code derived from fvwm2 by John Rothe.
+ * Some ICCCM manager selection code derived from fvwm2,
+ * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team
+ * Copyright (C) 2003 Rob Adams
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <unistd.h>
+#include "display.h"
+#include "util.h"
+#include "main.h"
+#include "screen.h"
+#include "window.h"
+#include "window-props.h"
+#include "group-props.h"
+#include "frame.h"
+#include "errors.h"
+#include "keybindings.h"
+#include "prefs.h"
+#include "resizepopup.h"
+#include "workspace.h"
+#include <X11/Xatom.h>
+#include <X11/cursorfont.h>
+#ifdef HAVE_SOLARIS_XINERAMA
+#include <X11/extensions/xinerama.h>
+#endif
+#ifdef HAVE_XFREE_XINERAMA
+#include <X11/extensions/Xinerama.h>
+#endif
+#ifdef HAVE_RANDR
+#include <X11/extensions/Xrandr.h>
+#endif
+#ifdef HAVE_SHAPE
+#include <X11/extensions/shape.h>
+#endif
+#include <string.h>
+
+#define USE_GDK_DISPLAY
+
+
+
+/* the root window is surrounded by four window slices, which are InputOnly.
+ * So you can see 'through' them, but they eat the input. An EnterEvent in
+ * one of these windows causes a Paging. The windows have the according cursor
+ * pointing in the pan direction or are hidden if there is no more panning
+ * in that direction. This is mostly intended to get a panning even atop
+ * of Motif applictions, which does not work yet. It seems Motif windows
+ * eat all mouse events.
+ *
+ * Hermann Dunkel, HEDU, dunkel@cul-ipn.uni-kiel.de 1/94
+**/
+
+#define XEVMASK_PANFW   (ButtonPressMask | ButtonReleaseMask | \
+                          KeyReleaseMask | KeyPressMask | \
+                         EnterWindowMask | LeaveWindowMask | \
+                         VisibilityChangeMask)
+/* Don't page if the pointer has moved for more than this many pixels between
+ * two samples */
+#define MAX_PAGING_MOVE_DISTANCE       10    /* pixels */
+
+typedef struct {
+    Window win;                    // window ID
+    int isMapped;
+} PanFrame;
+
+PanFrame PanFrameTop;
+PanFrame PanFrameLeft;
+PanFrame PanFrameRight;
+PanFrame PanFrameBottom;
+unsigned ScrollResistance = 100;
+int MyDisplayHeight = 0;
+int MyDisplayWidth = 0;
+int edge_thickness = 2;
+Time lastTimestamp = 0;
+XEvent Event;                    /* the current event */
+MetaScreen *mscreen;
+Display *dpy = NULL;            /* which display are we talking to */
+MetaDisplay *mdpy = NULL;
+
+/** External hooks **/
+void meta_flip_init( MetaScreen * mscr );
+void meta_flip_update_frames ( void );
+int meta_flip_event( int xl, int yt );
+void meta_flip_raise_frames( void );
+
+
+/* Records the time of the last processed event. Used in XSetInputFocus */
+Bool StashEventTime ( XEvent * ev );
+void initPanFrames( void );
+Bool has_neighbor( MetaMotionDirection direction );
+Bool GetLocationFromEventOrQuery ( Display * dpy, Window w, XEvent * eventp, int *ret_x, int *ret_y );
+int discard_events ( long event_mask );
+int discard_window_events ( Window w, long event_mask );
+Window create_pan_frame( int x, int y, int width, int height, 
+                          unsigned int valuemask, XSetWindowAttributes *attributes );
+
+void
+meta_flip_init( MetaScreen * mscr )
+{
+    mscreen = mscr;
+    mdpy = mscreen->display;
+    dpy = mdpy->xdisplay;
+
+    meta_display_ungrab( mdpy );
+    initPanFrames();
+    meta_display_grab( mdpy );
+    meta_flip_update_frames();
+}
+
+
+
+/***************************************************************************
+ * meta_flip_update_frames hides PanFrames if they are on the very border of the
+ * VIRTUAL screen and EdgeWrap for that direction is off.
+ * (A special cursor for the EdgeWrap border could be nice) HEDU
+ ****************************************************************************/
+void
+meta_flip_update_frames( void )
+{
+    if( mscreen == NULL )
+        return;
+    Bool do_unmap_l = !has_neighbor( META_MOTION_LEFT );
+    Bool do_unmap_r = !has_neighbor( META_MOTION_RIGHT );
+    Bool do_unmap_t = !has_neighbor( META_MOTION_UP );
+    Bool do_unmap_b = !has_neighbor( META_MOTION_DOWN );
+
+    /* thickness of 0 means remove the pan frames */
+    if( edge_thickness == 0 ) {
+        do_unmap_l = True;
+        do_unmap_r = True;
+        do_unmap_t = True;
+        do_unmap_b = True;
+    }
+
+    /* left */
+    if( do_unmap_l ) {
+        if( PanFrameLeft.isMapped ) {
+            XUnmapWindow ( dpy, PanFrameLeft.win );
+            PanFrameLeft.isMapped = False;
+        }
+    } else {
+        if( !PanFrameLeft.isMapped ) {
+            XMapRaised ( dpy, PanFrameLeft.win );
+            PanFrameLeft.isMapped = True;
+        }
+    }
+    /* right */
+    if( do_unmap_r ) {
+        if( PanFrameRight.isMapped ) {
+            XUnmapWindow ( dpy, PanFrameRight.win );
+            PanFrameRight.isMapped = False;
+        }
+    } else {
+        if( !PanFrameRight.isMapped ) {
+            XMapRaised ( dpy, PanFrameRight.win );
+            PanFrameRight.isMapped = True;
+        }
+    }
+    /* top */
+    if( do_unmap_t ) {
+        if( PanFrameTop.isMapped ) {
+            XUnmapWindow ( dpy, PanFrameTop.win );
+            PanFrameTop.isMapped = False;
+        }
+    } else {
+        if( !PanFrameTop.isMapped ) {
+            XMapRaised ( dpy, PanFrameTop.win );
+            PanFrameTop.isMapped = True;
+        }
+    }
+    /* bottom */
+    if( do_unmap_b ) {
+        if( PanFrameBottom.isMapped ) {
+            XUnmapWindow ( dpy, PanFrameBottom.win );
+            PanFrameBottom.isMapped = False;
+        }
+    } else {
+        if( !PanFrameBottom.isMapped ) {
+            XMapRaised ( dpy, PanFrameBottom.win );
+            PanFrameBottom.isMapped = True;
+        }
+    }
+    return;
+}
+
+
+/****************************************************************************
+ *
+ * Creates the windows for edge-scrolling
+ *
+ ****************************************************************************/
+void
+initPanFrames( )
+{   
+    MyDisplayWidth = DisplayWidth ( dpy, mscreen->number );
+    MyDisplayHeight = DisplayHeight ( dpy, mscreen->number );
+    XSetWindowAttributes attributes;
+    unsigned long valuemask = ( CWEventMask | CWCursor );
+
+    int saved_thickness = edge_thickness;
+    if( edge_thickness == 0 )
+        edge_thickness = 2;
+
+    attributes.event_mask = XEVMASK_PANFW;
+
+    /* I know these overlap, it's useful when at (0,0) and the top one is
+     * unmapped */
+    attributes.cursor = meta_display_create_x_cursor( mdpy, META_CURSOR_NORTH_RESIZE );
+    PanFrameTop.win = create_pan_frame( 0, 0, MyDisplayWidth, edge_thickness, valuemask, &attributes);
+    
+    attributes.cursor = meta_display_create_x_cursor( mdpy,  META_CURSOR_WEST_RESIZE);
+    PanFrameLeft.win = create_pan_frame( 0, 0, edge_thickness, MyDisplayHeight, valuemask, &attributes);
+    
+    attributes.cursor = meta_display_create_x_cursor( mdpy, META_CURSOR_EAST_RESIZE );
+    PanFrameRight.win = create_pan_frame( MyDisplayWidth - edge_thickness, 0, 
+                                          edge_thickness, MyDisplayHeight, 
+                                          valuemask, &attributes);
+
+    attributes.cursor = meta_display_create_x_cursor( mdpy, META_CURSOR_SOUTH_RESIZE );
+    PanFrameBottom.win = create_pan_frame( 0, MyDisplayHeight - edge_thickness,
+                                          MyDisplayWidth, edge_thickness, 
+                                          valuemask, &attributes);
+
+    PanFrameTop.isMapped    = False;
+    PanFrameLeft.isMapped   = False;
+    PanFrameRight.isMapped  = False;
+    PanFrameBottom.isMapped = False;
+
+    edge_thickness = saved_thickness;
+
+}
+void
+meta_flip_raise_frames( void )
+{
+    if( PanFrameTop.isMapped )
+        XRaiseWindow ( dpy, PanFrameTop.win );
+    if( PanFrameLeft.isMapped )
+        XRaiseWindow ( dpy, PanFrameLeft.win );
+    if( PanFrameRight.isMapped )
+        XRaiseWindow ( dpy, PanFrameRight.win );
+    if( PanFrameBottom.isMapped )
+        XRaiseWindow ( dpy, PanFrameBottom.win );
+}
+
+/**
+ *
+ * Check to see if the pointer is on the edge of the screen, and scroll/page
+ * if needed
+**/ 
+int
+meta_flip_event( int xl, int yt )
+{
+
+    static unsigned int add_time = 0;
+    int x, y;
+    XEvent e;
+    static Time my_timestamp = 0;
+    static Time my_last_timestamp = 0;
+    static Bool is_timestamp_valid = False;
+    static int last_x = 0;
+    static int last_y = 0;
+    static Bool is_last_position_valid = False;
+
+    if( ScrollResistance >= 10000 ) {
+        is_timestamp_valid = False;
+        add_time = 0;
+        return 0;
+    }
+    if( !is_timestamp_valid ) {
+        is_timestamp_valid = True;
+        my_timestamp = lastTimestamp;
+        is_last_position_valid = False;
+        add_time = 0;
+        last_x = -1;
+        last_y = -1;
+    } else if( my_last_timestamp != lastTimestamp ) {
+        add_time = 0;
+    }
+    my_last_timestamp = lastTimestamp;
+
+    do {
+        if( XPending ( dpy ) > 0 &&
+            ( XCheckWindowEvent ( dpy, PanFrameTop.win, LeaveWindowMask, &Event ) || 
+              XCheckWindowEvent ( dpy, PanFrameBottom.win, LeaveWindowMask, &Event ) || 
+              XCheckWindowEvent ( dpy, PanFrameLeft.win, LeaveWindowMask, &Event ) || 
+              XCheckWindowEvent ( dpy, PanFrameRight.win, LeaveWindowMask, &Event ) ) ) 
+        {
+            StashEventTime ( &Event );
+            is_timestamp_valid = False;
+            add_time = 0;
+            return 0;
+        } else if( XCheckMaskEvent ( dpy, ButtonPressMask | ButtonReleaseMask, &e ) ) {
+            XPutBackEvent ( dpy, &e );
+            is_timestamp_valid = False;
+            add_time = 0;
+            return 0;
+        }
+        /* get pointer location */
+        GetLocationFromEventOrQuery ( dpy, mscreen->xroot, &Event, &x, &y );
+        /* check actual pointer location since PanFrames can get buried under
+           a window being moved or resized - mab */
+        if( x >= edge_thickness && x < MyDisplayWidth - edge_thickness &&
+            y >= edge_thickness && y < MyDisplayHeight - edge_thickness ) 
+        {
+            is_timestamp_valid = False;
+            add_time = 0;
+            discard_window_events ( PanFrameTop.win, LeaveWindowMask );
+            discard_window_events ( PanFrameBottom.win, LeaveWindowMask );
+            discard_window_events ( PanFrameLeft.win, LeaveWindowMask );
+            discard_window_events ( PanFrameRight.win, LeaveWindowMask );
+            return 0;
+        }
+        last_x = x;
+        last_y = y;
+        is_last_position_valid = True;
+        usleep ( 10000 );
+        add_time += 10;
+    } while( lastTimestamp - my_timestamp + add_time < ScrollResistance );
+
+    if( lastTimestamp - my_timestamp + add_time < ScrollResistance ) {
+        return 0;
+    }
+
+    /* determine the flip direction and mouse destination */
+    MetaMotionDirection direction;
+    if( x < edge_thickness ) {
+        direction = META_MOTION_LEFT;
+        xl = MyDisplayWidth - edge_thickness - 2;
+    } else if( x >= MyDisplayWidth - edge_thickness ) {
+        direction = META_MOTION_RIGHT;
+        xl = edge_thickness + 2;
+    } else if( y < edge_thickness ) {
+        direction = META_MOTION_UP;
+        yt = MyDisplayHeight - edge_thickness - 2;
+    } else if( y >= MyDisplayHeight - edge_thickness ) {
+        direction = META_MOTION_DOWN;
+        yt = edge_thickness + 2;
+    } else {
+        return 0;
+    }
+
+    is_timestamp_valid = False;
+    add_time = 0;
+    MetaWorkspace *flipto = meta_workspace_get_neighbor( mscreen->active_workspace, 
+                                                         direction);
+
+    if( flipto != NULL && flipto != mscreen->active_workspace ) {
+        Window junkW = 0;
+        int junkV = 0;
+        unsigned int junkMask = 0;
+        XWarpPointer ( dpy, None, mscreen->xroot, 0, 0, 0, 0, xl, yt );
+        meta_workspace_activate( flipto );
+        XQueryPointer ( dpy, mscreen->xroot, &junkW, &junkW,
+                        &xl, &yt, &junkV, &junkV, &junkMask );
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+
+/*
+ * This function determines the location of the mouse pointer from the event
+ * if possible, if not it queries the X server. Returns False if it had to
+ * query the server and the call failed.
+ */
+Bool
+GetLocationFromEventOrQuery ( Display * dpy, Window w, XEvent * eventp, int *ret_x, int *ret_y )
+{
+    Window JunkW;
+    int JunkC;
+    unsigned int JunkM;
+
+    switch ( eventp->type ) {
+    case ButtonPress:
+    case ButtonRelease:
+        *ret_x = eventp->xbutton.x_root;
+        *ret_y = eventp->xbutton.y_root;
+        return True;
+    case KeyPress:
+    case KeyRelease:
+        *ret_x = eventp->xkey.x_root;
+        *ret_y = eventp->xkey.y_root;
+        return True;
+    case MotionNotify:
+        if( eventp->xmotion.same_screen == True ) {
+            *ret_x = eventp->xmotion.x_root;
+            *ret_y = eventp->xmotion.y_root;
+        } else {
+            /* pointer is on different screen */
+            *ret_x = 0;
+            *ret_y = 0;
+        }
+        return True;
+    default:
+        return XQueryPointer ( dpy, w, &JunkW, &JunkW, ret_x, ret_y, &JunkC, &JunkC, &JunkM );
+    }
+
+}
+
+
+/* This function discards all queued up ButtonPress, ButtonRelease and
+ * ButtonMotion events. */
+int
+discard_events ( long event_mask )
+{
+    XEvent e;
+    int count;
+
+    XSync ( dpy, 0 );
+    for( count = 0; XCheckMaskEvent ( dpy, event_mask, &e ); count++ ) {
+        StashEventTime ( &e );
+    }
+
+    return count;
+}
+
+/* This function discards all queued up ButtonPress, ButtonRelease and
+ * ButtonMotion events. */
+int
+discard_window_events ( Window w, long event_mask )
+{
+    XEvent e;
+    int count;
+
+    XSync ( dpy, 0 );
+    for( count = 0; XCheckWindowEvent ( dpy, w, event_mask, &e ); count++ ) {
+        StashEventTime ( &e );
+    }
+
+    return count;
+}
+
+Window
+create_pan_frame( int x, int y, int width, int height, 
+                  unsigned int valuemask, XSetWindowAttributes *attributes )
+{
+    return XCreateWindow ( dpy, mscreen->xroot, 
+                            x, y, width, height, 
+                            0,    /* no border */
+                            CopyFromParent, InputOnly, CopyFromParent, 
+                            valuemask, attributes );
+}
+
+
+
+Bool
+has_neighbor( MetaMotionDirection direction )
+{
+    MetaWorkspace *flipto = meta_workspace_get_neighbor( mscreen->active_workspace, 
+                                                         direction);
+    if( flipto != NULL && flipto != mscreen->active_workspace ) {
+        return True;
+    }
+    return False;
+}
+
+/****************************************************************************
+ *
+ * Records the time of the last processed event. Used in XSetInputFocus
+ *
+ ****************************************************************************/
+#define CLOCK_SKEW_MS                  30000    /* ms */
+Bool
+StashEventTime ( XEvent * ev )
+{
+    Time NewTimestamp = CurrentTime;
+
+    switch ( ev->type ) {
+    case KeyPress:
+    case KeyRelease:
+        NewTimestamp = ev->xkey.time;
+        break;
+    case ButtonPress:
+    case ButtonRelease:
+        NewTimestamp = ev->xbutton.time;
+        break;
+    case MotionNotify:
+        NewTimestamp = ev->xmotion.time;
+        break;
+    case EnterNotify:
+    case LeaveNotify:
+        NewTimestamp = ev->xcrossing.time;
+        break;
+    case PropertyNotify:
+        NewTimestamp = ev->xproperty.time;
+        break;
+    case SelectionClear:
+        NewTimestamp = ev->xselectionclear.time;
+        break;
+    case SelectionRequest:
+        NewTimestamp = ev->xselectionrequest.time;
+        break;
+    case SelectionNotify:
+        NewTimestamp = ev->xselection.time;
+        break;
+    default:
+        return False;
+    }
+    /* Only update if the new timestamp is later than the old one, or
+     * if the new one is from a time at least 30 seconds earlier than the
+     * old one (in which case the system clock may have changed) */
+    if( NewTimestamp > lastTimestamp ||
+        lastTimestamp - NewTimestamp > CLOCK_SKEW_MS )
+        lastTimestamp = NewTimestamp;
+    return True;
+}
+
+#undef CLOCK_SKEW_MS
Common subdirectories: metacity-2.5.2-base/src/themes and metacity-2.5.2-patch/src/themes
Common subdirectories: metacity-2.5.2-base/src/tools and metacity-2.5.2-patch/src/tools
diff -uN metacity-2.5.2-base/src/window.c metacity-2.5.2-patch/src/window.c
--- metacity-2.5.2-base/src/window.c	2003-05-20 12:27:15.000000000 -0400
+++ metacity-2.5.2-patch/src/window.c	2003-08-30 14:56:35.000000000 -0400
@@ -114,7 +114,7 @@
 static void meta_window_update_icon_now (MetaWindow *window);
 void meta_window_unqueue_update_icon    (MetaWindow *window);
 void meta_window_flush_update_icon      (MetaWindow *window);
-
+void meta_flip_raise_frames             (void);
 static void meta_window_apply_session_info (MetaWindow                  *window,
                                             const MetaWindowSessionInfo *info);
 
@@ -3284,6 +3284,7 @@
               "Raising window %s\n", window->desc);
 
   meta_stack_raise (window->screen->stack, window);
+	meta_flip_raise_frames();
 }
 
 void
Common subdirectories: metacity-2.5.2-base/src/wm-tester and metacity-2.5.2-patch/src/wm-tester
diff -uN metacity-2.5.2-base/src/workspace.c metacity-2.5.2-patch/src/workspace.c
--- metacity-2.5.2-base/src/workspace.c	2003-02-23 12:09:46.000000000 -0500
+++ metacity-2.5.2-patch/src/workspace.c	2003-08-30 14:56:35.000000000 -0400
@@ -27,7 +27,7 @@
 #include <string.h>
 
 void meta_workspace_queue_calc_showing  (MetaWorkspace *workspace);
-
+void meta_flip_update_frames ( void );
 static void set_active_space_hint      (MetaScreen *screen);
 
 MetaWorkspace*
@@ -220,6 +220,7 @@
 
   meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace\n");
   meta_screen_focus_default_window (workspace->screen, NULL);
+  meta_flip_update_frames();
 }
 
 int
