changeset 3381:374186f156d5

[xemacs-hg @ 2006-05-06 17:55:58 by stephent] metacity maximization fix, see src/ChangeLog. <87ejz7t57b.fsf_-_@tleepslib.sk.tsukuba.ac.jp>
author stephent
date Sat, 06 May 2006 17:56:00 +0000
parents 72f5451ab2f0
children 6b7bd79fac38
files src/ChangeLog src/EmacsFrame.c src/EmacsFrameP.h src/EmacsManager.c src/EmacsShell-sub.c src/console-x-impl.h src/console-x.c src/emacs.c src/frame-x.c src/symsinit.h
diffstat 10 files changed, 113 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sat May 06 08:46:38 2006 +0000
+++ b/src/ChangeLog	Sat May 06 17:56:00 2006 +0000
@@ -1,3 +1,29 @@
+2006-04-30  Stephen J. Turnbull  <stephen@xemacs.org>
+
+	Move geometry management from EmacsFrameResize to x_set_frame_size.
+	Should fix "metacity maximization" bug.
+	Provide (deprecated, temporary) backward compatibility option.
+
+	* EmacsFrame.c (EmacsFrameResize):
+	* frame-x.c (x_set_frame_size):
+	Move call of EmacsManagerChangeSize.
+	Don't bogusly notify WM about size changes the WM asked for.
+
+	* console-x.c (wedge-metacity): New builtin Boolean Lisp variable.
+	* console-x-impl.h (wedge_metacity): Declare C variable.
+	* console-x.c (vars_of_console_x): New function to initialize it.
+	* symsinit.h (vars_of_console_x): declare it.
+	* emacs.c (main_1): Call vars_of_console_x.
+
+	* EmacsFrameP.h (struct EmacsFrame):
+	* EmacsManager.c (EmacsManagerChangeSize):
+	* EmacsShell-sub.c (SuperClassRootGeometryManager):
+	* console-x-impl.h (wedge_metacity):
+	Various comments, some improved documentation, mostly sad comments
+	on the state of the art of Xt programming.
+
+	* frame-x.c (defi): #undef it.  (Random code cleanliness.)
+
 2006-05-06  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* lisp.h (struct Lisp_Subr):
--- a/src/EmacsFrame.c	Sat May 06 08:46:38 2006 +0000
+++ b/src/EmacsFrame.c	Sat May 06 17:56:00 2006 +0000
@@ -360,19 +360,32 @@
   pixel_to_char_size (f, ew->core.width, ew->core.height, &columns, &rows);
   change_frame_size (f, rows, columns, 0);
 
-  /* Now we tell the EmacsShell that we've changed the size of the non-fixed
-     portion of the frame.  Note that, if we the resize occurred as a result
-     of EmacsFrameSetCharSize(), this information will be stored twice.
-     This is not a big deal, as storing this information doesn't actually
-     do anything until the next resize. */
-  if (FRAME_X_TOP_LEVEL_FRAME_P (f))
-    x_wm_set_variable_size (FRAME_X_SHELL_WIDGET (f), columns, rows);
+  /* The code below is just plain wrong.  If the EmacsShell or EmacsManager
+     needs to know, they should just ask.  If needed information is being
+     updated here, then we should set a dirty flag and have it updated on an
+     as-needed basis.
+     For now, conditionalize so people can get work done if this breaks
+     something. */
+  if (wedge_metacity)		/* cf. x_set_frame_size */
+    {
+      /* Now we tell the EmacsShell that we've changed the size of the
+	 non-fixed portion of the frame.  Note that, if the resize occurred
+	 as a result of EmacsFrameSetCharSize(), this information will be
+	 stored twice.  This is not a big deal, as storing this information
+	 doesn't actually do anything until the next resize. */
+      if (FRAME_X_TOP_LEVEL_FRAME_P (f))
+	x_wm_set_variable_size (FRAME_X_SHELL_WIDGET (f), columns, rows);
 
-  /* Kick the manager so that it knows we've changed size. */
-  req.request_mode = 0;
-  XtQueryGeometry (FRAME_X_CONTAINER_WIDGET (f), &req, &repl);
-  EmacsManagerChangeSize (FRAME_X_CONTAINER_WIDGET (f), repl.width,
-			  repl.height);
+      /* Kick the manager so that it knows we've changed size.
+	 #### No, no, no!  If this does anything at all, it will involve
+	 changing the manager's size.  That's not something that a child
+	 widget should initialize as part of a purely informational
+	 method!! */
+      req.request_mode = 0;
+      XtQueryGeometry (FRAME_X_CONTAINER_WIDGET (f), &req, &repl);
+      EmacsManagerChangeSize (FRAME_X_CONTAINER_WIDGET (f),
+			      repl.width, repl.height);
+    }
 }
 
 static Boolean
--- a/src/EmacsFrameP.h	Sat May 06 08:46:38 2006 +0000
+++ b/src/EmacsFrameP.h	Sat May 06 17:56:00 2006 +0000
@@ -65,13 +65,16 @@
   Boolean	iconic;			/* whether this frame is iconic */
 
   /* The rest of this is crap and should be deleted.
+     #### Comments that start with + are fields that actually get referred 
+     to somewhere aside from the init function.
+     I guess the "crap" has mostly moved to specifiers?
    */
   Boolean	minibuffer;	/* 0: normal frames with minibuffers.
 				 * 1: frames without minibuffers
 				 * 2: minibuffer only. */
   Boolean	unsplittable;	/* frame can only have one window */
 
-  int		internal_border_width;	/* internal borders */
+  int		internal_border_width;	/* + internal borders */
   int		scrollbar_width;	/* width of frame vertical sb's */
   int		scrollbar_height;	/* height of frame horizontal sb's */
   int		top_toolbar_height;	/* height of top toolbar */
@@ -82,9 +85,9 @@
   int		bottom_toolbar_border_width;	/* ... of bottom toolbar */
   int		left_toolbar_border_width;	/* ... of left toolbar */
   int		right_toolbar_border_width;	/* ... of right toolbar */
-  Dimension	toolbar_shadow_thickness;
+  Dimension	toolbar_shadow_thickness;	/* + of shadows */
   unsigned char scrollbar_placement;
-  int		interline;		/* skips between lines */
+  int		interline;		/* + skips between lines */
 
   XFontStruct*	font;			/* font */
   Pixel		foreground_pixel;	/* foreground */
@@ -97,7 +100,7 @@
   int		bell_volume;		/* how loud is beep */
 
   Boolean	menubar_p;		/* initially show a menubar? */
-  Boolean	initially_unmapped;	/* inhibit initial window mapping */
+  Boolean	initially_unmapped;	/* + inhibit initial window mapping */
   Boolean	use_backing_store;	/* backing store for menubar & ew? */
 
   Dimension     preferred_width;        /* if non-zero, preferred size for */
--- a/src/EmacsManager.c	Sat May 06 08:46:38 2006 +0000
+++ b/src/EmacsManager.c	Sat May 06 17:56:00 2006 +0000
@@ -241,6 +241,12 @@
   if (height == 0)
     height = w->core.height;
 
+  /* #### AFAICT this gets called in two places.  One is in ChangeManaged(),
+     above.  The other is in EmacsFrameResize().  Perhaps ChangeManaged()
+     should initiate resize requests, but EmacsFrameResize() should not.
+     Unfortunately, I've tried making this conditional on whether we're
+     called from EmacsFrameResize() or not, but that results in an infloop
+     via the callback to x_layout_widgets() in Resize().  Whee! */
   /* do nothing if we're already that size */
   if (w->core.width != width || w->core.height != height)
     {
--- a/src/EmacsShell-sub.c	Sat May 06 08:46:38 2006 +0000
+++ b/src/EmacsShell-sub.c	Sat May 06 17:56:00 2006 +0000
@@ -278,7 +278,8 @@
   GenericClassExtRec *gcer;
 
   /* find the shell extension record that specifies the
-     root geometry manager method */
+     root geometry manager method
+     #### We could use XtGetClassExtension here. */
   for (gcer = (GenericClassExtRec *) swc->shell_class.extension;
        gcer;
        gcer = (GenericClassExtRec *) gcer->next_extension)
@@ -287,6 +288,9 @@
 	break;
     }
 
+  /* #### The R11.6.4 Xt specification says if we don't find NULLQUARK here,
+     we should assume root_geometry_manager = XtInheritRootGeometryManager.
+     Is that actually callable? */
   if (!gcer)
     ABORT ();
 
--- a/src/console-x-impl.h	Sat May 06 08:46:38 2006 +0000
+++ b/src/console-x-impl.h	Sat May 06 17:56:00 2006 +0000
@@ -40,6 +40,8 @@
 
 DECLARE_CONSOLE_TYPE (x);
 
+extern int wedge_metacity;
+
 struct x_device
 {
 #ifdef NEW_GC
@@ -234,7 +236,8 @@
 
 /* The maximum number of widgets that can be displayed above the text
    area at one time.  Currently no more than 3 will ever actually be
-   displayed (menubar, psheet, debugger panel). */
+   displayed (menubar, psheet, debugger panel).
+   #### Are "psheet" and "debugger panel" relevant any more? */
 #define MAX_CONCURRENT_TOP_WIDGETS 8
 
 struct x_frame
@@ -243,12 +246,17 @@
   struct lrecord_header header;
 #endif /* NEW_GC */
 
-  /* The widget of this frame.  This is an EmacsShell or an
-     ExternalShell. */
+  /* The widget of this frame.
+     This is an EmacsShell or an ExternalShell.
+     It negotiates with the window manager or containing app on behalf of
+     the container widget.  Should be (but isn't) invisible to Emacs. */
   Widget widget;
 
   /* The parent of the EmacsFrame, the menubar, and the scrollbars.
-     This is an EmacsManager. */
+     This is an EmacsManager.
+     It is responsible for managing the geometry of the frame.  This is what
+     Emacs mostly talks to.  Anything that affects its geometry will be
+     reflected in the Shell widget, and thus cause WM interaction. */
   Widget container;
 
   /* The widget of the menubar, of whatever widget class it happens to be. */
--- a/src/console-x.c	Sat May 06 08:46:38 2006 +0000
+++ b/src/console-x.c	Sat May 06 17:56:00 2006 +0000
@@ -41,6 +41,8 @@
 
 DEFINE_CONSOLE_TYPE (x);
 
+int wedge_metacity;	/* nonzero means update WM_HINTS always */
+
 extern void x_has_keysym (KeySym, Lisp_Object, int);
 
 static int
@@ -401,6 +403,22 @@
 
 
 void
+vars_of_console_x (void)
+{
+  DEFVAR_BOOL ("wedge-metacity", &wedge_metacity /*
+When non-nil, frame geometry management is backward-compatible.
+This is known to create inflooping window jitter in metacity, et al.
+It also does not conform to Xt conventions for geometry management.
+Specifically, all frame resizes, XEmacs-initiated or not, update WM_HINTS.
+Furthermore, geometry changes occur in the widget resize method.
+
+The default is nil.  This probably gives correct behavior regardless of the
+window manager used.
+This variable is deprecated and will be removed.
+*/ );
+}
+
+void
 reinit_console_type_create_x (void)
 {
   REINITIALIZE_CONSOLE_TYPE (x);
--- a/src/emacs.c	Sat May 06 08:46:38 2006 +0000
+++ b/src/emacs.c	Sat May 06 17:56:00 2006 +0000
@@ -2186,6 +2186,7 @@
 #ifdef HAVE_BALLOON_HELP
       vars_of_balloon_x ();
 #endif
+      vars_of_console_x ();
       vars_of_device_x ();
 #ifdef HAVE_X_DIALOGS
       vars_of_dialog_x ();
--- a/src/frame-x.c	Sat May 06 08:46:38 2006 +0000
+++ b/src/frame-x.c	Sat May 06 17:56:00 2006 +0000
@@ -507,6 +507,7 @@
   defi(Qtop, XtNy);
 
 #undef def
+#undef defi
 }
 
 static Lisp_Object
@@ -2307,6 +2308,17 @@
 x_set_frame_size (struct frame *f, int cols, int rows)
 {
   EmacsFrameSetCharSize (FRAME_X_TEXT_WIDGET (f), cols, rows);
+
+  if (!wedge_metacity)		/* cf. EmacsFrameResize */
+    {
+      /* Kick the manager so that it knows we've changed size. */
+      XtWidgetGeometry req, repl;
+      req.request_mode = 0;
+      XtQueryGeometry (FRAME_X_CONTAINER_WIDGET (f), &req, &repl);
+      EmacsManagerChangeSize (FRAME_X_CONTAINER_WIDGET (f),
+			      repl.width, repl.height);
+    }
+
 #if 0
     /* this is not correct.  x_set_frame_size() is called from
        Fset_frame_size(), which may or may not have been called
--- a/src/symsinit.h	Sat May 06 08:46:38 2006 +0000
+++ b/src/symsinit.h	Sat May 06 17:56:00 2006 +0000
@@ -306,6 +306,7 @@
 void vars_of_console_stream (void);
 void vars_of_console_mswindows (void);
 void vars_of_console_tty (void);
+void vars_of_console_x (void);
 void vars_of_data (void);
 void vars_of_database (void);
 void vars_of_debug (void);