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