Index: src/glyphs.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs.c,v
retrieving revision 1.23.2.81
diff -u -r1.23.2.81 glyphs.c
--- src/glyphs.c 2000/08/21 22:05:18 1.23.2.81
+++ src/glyphs.c 2000/08/22 22:09:54
@@ -4333,7 +4333,7 @@
   finalize_all_subwindow_instances (XWINDOW (f->root_window));
 }
 
-/* Unmap and remove all instances from the frame cache. */
+/* Unmap all instances in the frame cache. */
 void
 reset_frame_subwindow_instance_cache (struct frame* f)
 {
@@ -4342,11 +4342,8 @@
   LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))
     {
       Lisp_Object value = XCAR (rest);
-      /* Make sure that the subwindow is unmapped so that window
-	 deletion will not try and do it again. */
       unmap_subwindow (value);
     }
-  XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)) = Qnil;
 }
 
 /*****************************************************************************
@@ -4492,6 +4489,7 @@
       /* Reset the changed flags. */
       IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0;
       IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
+      IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii) = 0;
       IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0;
     }
   else if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW
@@ -4542,7 +4540,8 @@
   else if (WIDGET_IMAGE_INSTANCEP (subwindow)
 	   && (!internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (ii),
 				IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii), 0)
-	       || !NILP (IMAGE_INSTANCE_LAYOUT_CHILDREN (ii))))
+	       || !NILP (IMAGE_INSTANCE_LAYOUT_CHILDREN (ii))
+	       || IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii)))
     return 1;
   else
     return 0;
Index: src/glyphs.h
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs.h,v
retrieving revision 1.18.2.57
diff -u -r1.18.2.57 glyphs.h
--- src/glyphs.h 2000/08/18 17:16:05 1.18.2.57
+++ src/glyphs.h 2000/08/22 22:09:57
@@ -600,6 +600,7 @@
       /* Change flags to augment dirty. */
       unsigned int face_changed : 1;
       unsigned int items_changed : 1;
+      unsigned int action_occurred : 1;
     } subwindow;
   } u;
 
@@ -654,6 +655,8 @@
   ((i)->u.subwindow.face_changed)
 #define IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED(i) \
   ((i)->u.subwindow.items_changed)
+#define IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED(i) \
+  ((i)->u.subwindow.action_occurred)
 #define IMAGE_INSTANCE_LAYOUT_CHANGED(i) ((i)->layout_changed)
 #define IMAGE_INSTANCE_OPTIMIZE_OUTPUT(i) ((i)->optimize_output)
 
@@ -836,6 +839,8 @@
   IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (XIMAGE_INSTANCE (i))
 #define XIMAGE_INSTANCE_WIDGET_TEXT(i) \
   IMAGE_INSTANCE_WIDGET_TEXT (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_WIDGET_ACTION_OCCURRED(i) \
+  IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (XIMAGE_INSTANCE (i))
 
 #define XIMAGE_INSTANCE_LAYOUT_CHILDREN(i) \
   IMAGE_INSTANCE_LAYOUT_CHILDREN (XIMAGE_INSTANCE (i))
Index: src/gui-msw.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/Attic/gui-msw.c,v
retrieving revision 1.1.2.14
diff -u -r1.1.2.14 gui-msw.c
--- src/gui-msw.c 2000/07/22 19:33:26 1.1.2.14
+++ src/gui-msw.c 2000/08/22 22:09:58
@@ -50,6 +50,10 @@
 
   image_instance = Fgethash (make_int (id), 
 			     FRAME_MSWINDOWS_WIDGET_HASH_TABLE1 (f), Qnil);
+  /* It is possible for a widget action to cause it to get out of sync
+     with its instantiator. Thus it is necessary to signal this
+     possibility. */
+  XIMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (image_instance) = 1;
   callback = Fgethash (make_int (id), 
 		       FRAME_MSWINDOWS_WIDGET_HASH_TABLE2 (f), Qnil);
   callback_ex = Fgethash (make_int (id), 
Index: src/gui-x.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/gui-x.c,v
retrieving revision 1.14.2.28
diff -u -r1.14.2.28 gui-x.c
--- src/gui-x.c 2000/08/06 09:27:17 1.14.2.28
+++ src/gui-x.c 2000/08/22 22:09:59
@@ -256,6 +256,10 @@
       callback = XCAR (XCDR (data));
       callback_ex = XCDR (XCDR (data));
       update_subwindows_p = 1;
+      /* It is possible for a widget action to cause it to get out of
+	 sync with its instantiator. Thus it is necessary to signal
+	 this possibility. */
+      XIMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (image_instance) = 1;
 
       if (!NILP (callback_ex) && !UNBOUNDP (callback_ex))
 	{
Index: src/redisplay-output.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay-output.c,v
retrieving revision 1.11.2.40
diff -u -r1.11.2.40 redisplay-output.c
--- src/redisplay-output.c 2000/07/22 19:33:28 1.11.2.40
+++ src/redisplay-output.c 2000/08/22 22:10:05
@@ -1169,7 +1169,6 @@
   LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))
     {
       Lisp_Image_Instance *ii = XIMAGE_INSTANCE (XCAR (rest));
-
       if (IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii)
 	  &&
 	  IMAGE_INSTANCE_DISPLAY_X (ii)
Index: src/redisplay.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay.c,v
retrieving revision 1.55.2.59
diff -u -r1.55.2.59 redisplay.c
--- src/redisplay.c 2000/06/12 04:18:22 1.55.2.59
+++ src/redisplay.c 2000/08/22 22:10:28
@@ -6331,12 +6331,15 @@
   if (f->clear)
     f->frame_changed = 1;
 
-  /* Invalidate the subwindow cache. We use subwindows_changed here to
-     cause subwindows to get instantiated. This is because
+  /* Invalidate the subwindow caches. We use subwindows_changed here
+     to cause subwindows to get instantiated. This is because
      subwindows_state_changed is less strict - dealing with things
      like the clicked state of button. We have to do this before
      redisplaying the gutters as subwindows get unmapped in the
      process.*/
+  if (f->frame_changed)
+    reset_frame_subwindow_instance_cache (f);
+
   if (f->frame_changed || f->subwindows_changed)
     {
       /* we have to do this so the gutter gets regenerated. */
Index: src/window.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/window.c,v
retrieving revision 1.41.2.59
diff -u -r1.41.2.59 window.c
--- src/window.c 2000/08/21 22:05:17 1.41.2.59
+++ src/window.c 2000/08/22 22:10:43
@@ -1879,7 +1879,7 @@
 {
   assert (!NILP (w->subwindow_instance_cache));
   elisp_maphash (unmap_subwindow_instance_cache_mapper,
-		 w->subwindow_instance_cache, 0);
+		 w->subwindow_instance_cache, (void*)1);
 }
 
 /* we're deleting W; set the structure of W to indicate this. */
@@ -5200,16 +5200,19 @@
       record_unwind_protect (free_window_configuration, old_window_config);
 
       mark_windows_in_use (f, 1);
-#if 0
-      /* Force subwindows to be reinstantiated. They are all going
-	 anyway and if we don't do this GC may not happen between now
-	 and the next time we check their integrity.  
-
-	 #### This is wrong because an instance is only put in the
-	 frame cache when it is instantiated, so if we do this there
-	 is a chance that stuff will never get put back in the frame
-	 task. However, there maybe other reasons for doing something
-	 similar.*/
+#ifdef BROKEN_SUBWINDOW_REDISPLAY
+      /* Force subwindows to be remapped. This is overkill but saves
+	us having to rely on the redisplay code to unmap any extant
+	subwindows. 
+
+	#### It does cause some extra flashing though which we could
+	possibly avoid. So consider trying to get redisplay to work
+	correctly.
+
+	Removing the instances from the frame cache is wrong because
+	an instance is only put in the frame cache when it is
+	instantiated. So if we do this there is a chance that stuff
+	will never get put back in the frame cache. */
       reset_frame_subwindow_instance_cache (f);
 #endif
 #if 0
Index: src/glyphs-x.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs-x.c,v
retrieving revision 1.49.2.78
diff -u -r1.49.2.78 glyphs-x.c
--- glyphs-x.c	2000/08/21 22:05:19	1.49.2.78
+++ glyphs-x.c	2000/08/23 09:38:01
@@ -2717,7 +2717,9 @@
 {
   Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
 
-  if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
+  if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)
+      ||
+      IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii))
     {
       /* If only the order has changed then simply select the first
 	 one of the pending set. This stops horrendous rebuilding -
@@ -2725,9 +2727,12 @@
 	 one. */
       if (tab_control_order_only_changed (image_instance))
 	{
-	  Lisp_Object rest;
-	  Lisp_Object selected = gui_item_list_find_selected 
-	    (XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
+	  Lisp_Object rest, selected = 
+	    gui_item_list_find_selected 
+	    (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ?
+	     XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) :
+	     XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
+
 	  LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
 	    {
 	      if (gui_item_equal_sans_selected (XCAR (rest), selected, 0))
Index: src/glyphs-msw.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs-msw.c,v
retrieving revision 1.21.2.65
diff -u -r1.21.2.65 glyphs-msw.c
--- glyphs-msw.c	2000/08/21 22:05:20	1.21.2.65
+++ glyphs-msw.c	2000/08/23 09:38:24
@@ -2926,19 +2926,29 @@
 {
   /* This function can GC if IN_REDISPLAY is false. */
   Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
-
-  if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii))
+#ifdef DEBUG_WIDGET_OUTPUT
+  stderr_out ("tab control %p redisplayed\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
+#endif
+  if (IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii)
+      ||
+      IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii))
     {
       HWND wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
       int i = 0, selected = 0;
       Lisp_Object rest;
+
+      assert (!NILP (IMAGE_INSTANCE_WIDGET_ITEMS (ii)));
+
       /* If only the order has changed then simply select the first
 	 one. This stops horrendous rebuilding of the tabs each time
 	 you click on one. */
       if (tab_control_order_only_changed (image_instance))
 	{
-	  Lisp_Object selected = gui_item_list_find_selected 
-	    (XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
+	  Lisp_Object selected = 
+	    gui_item_list_find_selected 
+	    (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)) ?
+	     XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)) :
+	     XCDR (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)));
 
 	  LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
 	    {
@@ -2957,6 +2967,10 @@
 		  IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) = Qnil;
 		  
 		  SendMessage (wnd, TCM_SETCURSEL, i, 0);
+#ifdef DEBUG_WIDGET_OUTPUT
+		  stderr_out ("tab control %p selected item %d\n",
+			  IMAGE_INSTANCE_SUBWINDOW_ID (ii), i);
+#endif
 		  break;
 		}
 	      i++;
@@ -3127,9 +3141,9 @@
 #endif
       val = XGUI_ITEM (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii))->value;
 #ifdef DEBUG_WIDGET_OUTPUT     
-      printf ("progress gauge displayed value on %p updated to %ld\n",
-	      WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
-	      XINT(val));
+      stderr_out ("progress gauge displayed value on %p updated to %ld\n",
+		  WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+		  XINT(val));
 #endif
       CHECK_INT (val);
       SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
Index: src/glyphs-widget.c
===================================================================
RCS file: /usr/CVSroot/XEmacs/xemacs/src/Attic/glyphs-widget.c,v
retrieving revision 1.1.2.50
diff -u -r1.1.2.50 glyphs-widget.c
--- glyphs-widget.c	2000/08/18 17:16:02	1.1.2.50
+++ glyphs-widget.c	2000/08/23 09:38:35
@@ -789,7 +789,9 @@
     {
       Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
       check_valid_item_list (items);
-      
+#ifdef DEBUG_WIDGET_OUTPUT
+      stderr_out ("tab control %p updated\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
+#endif
       /* Don't set the actual items since we might decide not to use
          the new ones (because nothing has really changed). If we did
          set them and didn't use them then we would get into whole
@@ -808,6 +810,10 @@
   int found = 0, len, pending_len;
   Lisp_Object rest;
 
+  /* Degenerate case. */
+  if (NILP (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii)))
+    return 1;
+
   /* See whether we just need a change in order. */
   GET_LIST_LENGTH (IMAGE_INSTANCE_WIDGET_ITEMS (ii), len);
   GET_LIST_LENGTH (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii), 
@@ -847,7 +853,7 @@
     {
       CHECK_INT (value);
 #ifdef DEBUG_WIDGET_OUTPUT
-      printf ("progress gauge value set to %ld\n", XINT (value));
+      stderr_out ("progress gauge value set to %ld\n", XINT (value));
 #endif
       IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii) =
 	copy_gui_item_tree (IMAGE_INSTANCE_WIDGET_ITEMS (ii));
@@ -934,7 +940,7 @@
     }
 
 #ifdef DEBUG_WIDGET_OUTPUT
-  printf ("layout updated\n");
+  stderr_out ("layout updated\n");
 #endif
   /* Update the border. */
   if (!NILP (border_inst))
@@ -1007,7 +1013,7 @@
   Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation);
 
 #ifdef DEBUG_WIDGET_OUTPUT
-  printf ("layout instantiated\n");
+  stderr_out ("layout instantiated\n");
 #endif
   /* Do widget type instantiation first. */
   widget_instantiate (image_instance, instantiator, pointer_fg, pointer_bg,
