File gnomebug.patch of Package xemacs

diff -ru xemacs-21.5.18.orig/src/EmacsFrame.c xemacs-21.5.18/src/EmacsFrame.c
--- xemacs-21.5.18.orig/src/EmacsFrame.c	2004-09-20 21:19:34.000000000 +0200
+++ xemacs-21.5.18/src/EmacsFrame.c	2004-12-10 14:33:40.000000000 +0100
@@ -33,6 +33,7 @@
 #include "faces.h"
 #include "frame-impl.h"
 #include "toolbar.h"
+#include "sysdep.h"
 #include "window.h"
 
 #include "console-x-impl.h"
@@ -510,15 +511,22 @@
      setting, automatically forces a redisplay as necessary. */
 }
 
+int update_hints_inhibit = 0;
+
 static XtGeometryResult
 EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request,
 			 XtWidgetGeometry *result)
 {
   EmacsFrame ew = (EmacsFrame) widget;
+  struct frame *f = (struct frame*)ew->emacs_frame.frame;
   int mask = request->request_mode;
-  Dimension width, height;
-  int ok_width_int, ok_height_int;
+  const Dimension width  = (mask & CWWidth ) ? request->width  : ew->core.width;
+  const Dimension height = (mask & CWHeight) ? request->height : ew->core.height;
+  int ok_width_int, ok_height_int, columns, rows, char_width, char_height;
   Dimension ok_width, ok_height;
+  int delta_w, delta_h;
+
+  update_hints_inhibit = 1;
 
   /* We have a definite preference for what size we would like
      to be.
@@ -530,19 +538,42 @@
      3) Otherwise, take our current size and round it to the
         nearest multiple of the default char size. */
 
-  width = mask & CWWidth ? request->width : ew->core.width;
-  height = mask & CWHeight ? request->height : ew->core.height;
-  round_size_to_char (ew->emacs_frame.frame, width, height,
-		      &ok_width_int, &ok_height_int);
-  ok_width = (Dimension) ok_width_int;
+  pixel_to_char_size (f, width, height, &columns, &rows);
+  round_size_to_char (f, width, height, &ok_width_int, &ok_height_int);
+
+  ok_width  = (Dimension) ok_width_int;
   ok_height = (Dimension) ok_height_int;
+
   if (ew->emacs_frame.preferred_width)
     ok_width = ew->emacs_frame.preferred_width;
   if (ew->emacs_frame.preferred_height)
     ok_height = ew->emacs_frame.preferred_height;
-  result->request_mode |= CWWidth | CWHeight;
+
+  char_width  = ok_width  / columns; 
+  char_height = ok_height / rows;
+  delta_w = width  - f->gnomewidth;
+  delta_h = height - f->gnomeheight;
+
+  if (abs(delta_w) < char_width)
+    ok_width  = result->width  = f->gnomewidth;
+  else
+    f->gnomewidth = width;
+
+  if (abs(delta_h) < char_height)
+    ok_height = result->height = f->gnomeheight;
+  else
+    f->gnomeheight = height;
+
+  if (ok_width != width)
+    result->request_mode |= CWWidth;
+  if (ok_height != height)
+    result->request_mode |= CWHeight;
+
   result->width = ok_width;
   result->height = ok_height;
+
+  update_hints_inhibit = 0;
+
   if (((mask & CWWidth) && ok_width != request->width)
       || ((mask & CWHeight) && ok_height != request->height))
     return XtGeometryAlmost;
@@ -632,8 +663,21 @@
   if (rows < 1)
     rows = 1;
 
+  check_frame_size (f, &rows, &columns);
   char_to_pixel_size (f, columns, rows, &pixel_width, &pixel_height);
 
+  if (ew->core.width == pixel_width && ew->core.height == pixel_height)
+    return;
+
+#if 0
+  {
+    Arg al[1];
+    XtSetArg (al [0], XtNwaitForWm, FALSE);
+    XtSetValues ((Widget) ew, al, countof (al));
+  }
+#endif
+  stop_interrupts ();
+
   if (FRAME_X_TOP_LEVEL_FRAME_P (f))
     x_wm_set_variable_size (FRAME_X_SHELL_WIDGET (f), columns, rows);
 
@@ -643,4 +687,6 @@
     XtSetArg (al [1], XtNheight, pixel_height);
     XtSetValues ((Widget) ew, al, countof (al));
   }
+
+  start_interrupts();
 }
diff -ru xemacs-21.5.18.orig/src/EmacsShell-sub.c xemacs-21.5.18/src/EmacsShell-sub.c
--- xemacs-21.5.18.orig/src/EmacsShell-sub.c	2003-02-14 08:38:30.000000000 +0100
+++ xemacs-21.5.18/src/EmacsShell-sub.c	2004-12-10 14:33:40.000000000 +0100
@@ -232,6 +232,20 @@
 
 WidgetClass EMACS_SHELL_WIDGET_CLASS = (WidgetClass) &EMACS_SHELL_CLASS_REC;
 
+extern int update_hints_inhibit;
+
+static Widget
+get_wm_shell (Widget w)
+{
+  Widget wmshell;
+
+  for (wmshell = XtParent (w);
+       wmshell && !XtIsWMShell (wmshell);
+       wmshell = XtParent (wmshell));
+
+  return wmshell;
+}
+
 static void
 update_size_hints_internal (EMACS_SHELL_WIDGET w,
 			    int width, int height)
@@ -240,6 +254,10 @@
   int cell_width, cell_height;
   Arg al [10];
 
+  if (update_hints_inhibit)
+    return;
+  stop_interrupts ();
+
   /* time to update them thar size hints */
   cell_width = w->wm.size_hints.width_inc;
   cell_height = w->wm.size_hints.height_inc;
@@ -264,6 +282,8 @@
   XtSetArg(al [3], XtNminHeight, base_height +
 	   cell_height * w->emacs_shell.min_height_cells);
   XtSetValues ((Widget) w, al, 4);
+
+  start_interrupts ();
 }
 
 static XtGeometryResult
@@ -302,6 +322,8 @@
   /* OK since this file is not dumped */
   static int reentrant = 0;
   XtGeometryResult result;
+  Dimension ok_width = 0, ok_height = 0;
+  int mask = request->request_mode;
 
   if (reentrant)
     abort ();
@@ -317,13 +339,51 @@
   printf ("\n");
   printf ("  requested shell size: %d %d\n", request->width, request->height);
 #endif
+#if 0
+  if (mask & (CWWidth | CWHeight))
+    {
+      const Dimension cell_width  = w->wm.size_hints.width_inc;
+      const Dimension cell_height = w->wm.size_hints.height_inc;
+      const Dimension requ_width  = ((mask & CWWidth)  ? request->width  : w->core.width );
+      const Dimension requ_height = ((mask & CWHeight) ? request->height : w->core.height);
+      const Dimension base_width  = requ_width  - cell_width  * w->emacs_shell.width_cells;
+      const Dimension base_height = requ_height - cell_height * w->emacs_shell.height_cells;
+
+      const int xw = (requ_width  - base_width ) / cell_width;
+      const int xh = (requ_height - base_height) / cell_height;
+
+      ok_width  = base_width  + (cell_width  * xw);
+      ok_height = base_height + (cell_height * xh);
+
+      if ((mask & CWWidth)  && (ok_width != request->width))
+	{
+	  request->request_mode |= CWWidth;
+	  request->width = ok_width;
+	}
+      if ((mask & CWHeight) && (ok_height != request->height))
+	{
+	  request->request_mode |= CWHeight;
+	  request->height = ok_height;
+	}
+
+      if ((mask & CWWidth)  && (xw == w->emacs_shell.width_cells))
+	{
+	  request->request_mode &= ~CWWidth;
+	  request->width = w->core.width;
+	}
+      if ((mask & CWHeight) && (xh == w->emacs_shell.height_cells))
+	{
+	  request->request_mode &= ~CWHeight;
+	  request->height = w->core.height;
+	}
+    }
+#endif
   /* update the size hints */
   update_size_hints_internal (w,
 			      request->request_mode & CWWidth ?
 			      request->width : w->core.width,
 			      request->request_mode & CWHeight ?
 			      request->height : w->core.height);
-
   result = SuperClassRootGeometryManager (gw, request, reply);
 
 #ifdef DEBUG_GEOMETRY_MANAGEMENT
diff -ru xemacs-21.5.18.orig/src/frame-impl.h xemacs-21.5.18/src/frame-impl.h
--- xemacs-21.5.18.orig/src/frame-impl.h	2003-01-12 12:08:16.000000000 +0100
+++ xemacs-21.5.18/src/frame-impl.h	2004-12-10 15:04:17.337109993 +0100
@@ -68,6 +68,10 @@
      of line glyphs, in pixels */
   int pixheight, pixwidth;
 
+  /* Remember size of the whole frame due be able to work around
+     GNOME metacity bug */
+  int gnomeheight, gnomewidth;
+
 #ifdef HAVE_TTY
   /* The count of frame number.  This applies to TTY frames only. */
   int order_count;
diff -ru xemacs-21.5.18.orig/src/redisplay.c xemacs-21.5.18/src/redisplay.c
--- xemacs-21.5.18.orig/src/redisplay.c	2004-09-20 21:19:57.000000000 +0200
+++ xemacs-21.5.18/src/redisplay.c	2004-12-10 14:33:41.000000000 +0100
@@ -6965,7 +6965,9 @@
   if (f->size_slipped)
     {
       adjust_frame_size (f);
+#if 0
       assert (!f->size_slipped);
+#endif
     }
 
   /* The menubar, toolbar, and icon updates should be done before