changeset 905:c15f25529e61

[xemacs-hg @ 2002-07-06 21:05:42 by andyp] toolbar redisplay patch
author andyp
date Sat, 06 Jul 2002 21:05:58 +0000
parents 47c30044fc4e
children 7f5ac0d2a71f
files src/ChangeLog src/console-impl.h src/device-impl.h src/frame-impl.h src/gutter.c src/redisplay.c src/redisplay.h src/toolbar-common.c src/toolbar-common.h src/toolbar-gtk.c src/toolbar-msw.c src/toolbar-x.c src/toolbar.c src/toolbar.h
diffstat 14 files changed, 182 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Sat Jul 06 18:56:31 2002 +0000
+++ b/src/ChangeLog	Sat Jul 06 21:05:58 2002 +0000
@@ -1,3 +1,49 @@
+2002-06-24  Andy Piper  <andy@xemacs.org>
+
+	* toolbar-x.c (console_type_create_toolbar_x): declare
+	x_clear_frame_toolbars.
+	* toolbar-gtk.c (console_type_create_toolbar_gtk): ditto.
+	* toolbar-common.h (common_clear_frame_toolbars): ditto.
+
+	* toolbar-common.c (COMMON_OUTPUT_BUTTONS_LOOP): output button if
+	whole toolbar was cleared.
+
+	* toolbar-msw.c (mswindows_clear_frame_toolbars): new
+	function. Split out from mswindows_output_frame_toolbars.
+	(mswindows_output_frame_toolbars): move clear pieces to
+	mswindows_output_frame_toolbars.
+
+	* toolbar-common.c (common_clear_frame_toolbars): new function. Split
+	out from gtk_output_frame_toolbars.
+	(common_output_frame_toolbars): move clear pieces to
+	gtk_clear_frame_toolbars.
+
+	* console-impl.h (struct console_methods): add
+	clear_frame_toolbars_method.
+
+	* redisplay.c (redisplay_frame): call
+	update_frame_toolbars_geometry and re-order update_frame_toolbars.
+
+	* toolbar.h: declare update_frame_toolbars_geometry.
+
+	* toolbar.c (update_frame_toolbars_geometry): new function. Split
+	out from update_frame_toolbars.  Call clear_frame_toolbars.
+	(update_frame_toolbars): only output, do not change geometry.
+
+	* redisplay.c: add frame_layout_changed.
+
+	* redisplay.h: add frame_layout_changed.
+	(CLASS_RESET_CHANGED_FLAGS): set it.
+	(GLOBAL_RESET_CHANGED_FLAGS): ditto.
+	(CLASS_REDISPLAY_FLAGS_CHANGEDP): test it.
+	(GLOBAL_REDISPLAY_FLAGS_CHANGEDP): ditto.
+
+	* device-impl.h (struct device): add frame_layout_changed.
+	(MARK_DEVICE_FRAME_LAYOUT_CHANGED): new.
+
+	* frame-impl.h (struct frame): add frame_layout_changed.
+	(MARK_FRAME_LAYOUT_CHANGED): new.
+
 2002-07-02  Paul Moore  <gustav@morpheus.demon.co.uk>
 
 	* console-msw.h:
--- a/src/console-impl.h	Sat Jul 06 18:56:31 2002 +0000
+++ b/src/console-impl.h	Sat Jul 06 21:05:58 2002 +0000
@@ -261,6 +261,7 @@
 #ifdef HAVE_TOOLBARS
   /* toolbar methods */
   void (*output_frame_toolbars_method) (struct frame *);
+  void (*clear_frame_toolbars_method) (struct frame *);
   void (*initialize_frame_toolbars_method) (struct frame *);
   void (*free_frame_toolbars_method) (struct frame *);
   void (*output_toolbar_button_method) (struct frame *, Lisp_Object);
--- a/src/device-impl.h	Sat Jul 06 18:56:31 2002 +0000
+++ b/src/device-impl.h	Sat Jul 06 21:05:58 2002 +0000
@@ -88,6 +88,8 @@
   unsigned int extents_changed :1;
   unsigned int faces_changed :1;
   unsigned int frame_changed :1;
+  unsigned int frame_layout_changed :1;	/* The layout of frame
+					   elements has changed. */
   unsigned int glyphs_changed :1;
   unsigned int subwindows_changed :1;
   unsigned int subwindows_state_changed :1;
@@ -322,6 +324,9 @@
 #define MARK_DEVICE_FRAME_CHANGED(d)			\
   ((void) (frame_changed = (d)->frame_changed = 1))
 
+#define MARK_DEVICE_FRAME_LAYOUT_CHANGED(d)			\
+  ((void) (frame_layout_changed = (d)->frame_layout_changed = 1))
+
 #define MARK_DEVICE_WINDOWS_CHANGED(d)			\
   ((void) (windows_changed = (d)->windows_changed = 1))
 
--- a/src/frame-impl.h	Sat Jul 06 18:56:31 2002 +0000
+++ b/src/frame-impl.h	Sat Jul 06 21:05:58 2002 +0000
@@ -172,6 +172,8 @@
   unsigned int extents_changed :1;
   unsigned int faces_changed :1;
   unsigned int frame_changed :1;
+  unsigned int frame_layout_changed :1;	/* The layout of frame
+ 					   elements has changed. */
   unsigned int subwindows_changed :1;
   unsigned int subwindows_state_changed :1;
   unsigned int glyphs_changed :1;
@@ -398,6 +400,19 @@
     frame_changed = 1;					\
 } while (0)
 
+#define MARK_FRAME_LAYOUT_CHANGED(f) do {		\
+  struct frame *mfc_f = (f);				\
+  mfc_f->frame_layout_changed = 1;			\
+  mfc_f->modiff++;					\
+  if (!NILP (mfc_f->device))				\
+    {							\
+      struct device *mfc_d = XDEVICE (mfc_f->device);	\
+      MARK_DEVICE_FRAME_LAYOUT_CHANGED (mfc_d);		\
+    }							\
+  else							\
+    frame_layout_changed = 1;				\
+} while (0)
+
 #define MARK_FRAME_WINDOWS_CHANGED(f) do {		\
   struct frame *mfwc_f = (f);				\
   mfwc_f->windows_changed = 1;				\
--- a/src/gutter.c	Sat Jul 06 18:56:31 2002 +0000
+++ b/src/gutter.c	Sat Jul 06 21:05:58 2002 +0000
@@ -588,6 +588,7 @@
       pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
 			  &width, &height);
       change_frame_size (f, height, width, 0);
+      MARK_FRAME_LAYOUT_CHANGED (f);
     }
 
   /* Mark sizes as up-to-date. */
@@ -597,7 +598,9 @@
 void
 update_frame_gutter_geometry (struct frame *f)
 {
-  if (f->gutter_changed || f->windows_structure_changed)
+  if (f->gutter_changed 
+      || f->frame_layout_changed 
+      || f->windows_structure_changed)
     {
       enum gutter_pos pos;
 
@@ -619,7 +622,7 @@
       f->gutter_changed || f->glyphs_changed ||
       f->size_changed || f->subwindows_changed ||
       f->windows_changed || f->windows_structure_changed ||
-      f->extents_changed)
+      f->extents_changed || f->frame_layout_changed)
     {
       enum gutter_pos pos;
 
--- a/src/redisplay.c	Sat Jul 06 18:56:31 2002 +0000
+++ b/src/redisplay.c	Sat Jul 06 21:05:58 2002 +0000
@@ -436,6 +436,10 @@
 int toolbar_changed;
 int toolbar_changed_set;
 
+/* Nonzero if some frame has changed the layout of internal elements
+   (gutters or toolbars). */
+int frame_layout_changed;
+
 /* non-nil if any gutter has changed */
 int gutter_changed;
 int gutter_changed_set;
@@ -6571,8 +6575,13 @@
   update_frame_menubars (f);
 #endif /* HAVE_MENUBARS */
 #ifdef HAVE_TOOLBARS
-  /* Update the toolbars. */
-  update_frame_toolbars (f);
+  /* Update the toolbars geometry. We don't update the toolbars
+     themselves at this point since the space they are trying to
+     occupy may currently by occupied by gutter elements. Instead we
+     update the geometry, then update the gutter geometry, then update
+     the gutters - which will cause mapped windows to be repositioned
+     - and finally update the toolbars. */
+  update_frame_toolbars_geometry (f);
 #endif /* HAVE_TOOLBARS */
   /* Gutter update proper has to be done inside display when no frame
      size changes can occur, thus we separately update the gutter
@@ -6652,6 +6661,14 @@
 
   update_frame_title (f);
 
+#ifdef HAVE_TOOLBARS
+  /* Finally update the toolbars. It seems its possible to get in a
+     cycle between updating the gutter and the toolbars. Basically we
+     want to end up with both being up-to-date and this doesn't seem
+     possible in a single pass. */
+  update_frame_toolbars (f);
+#endif /* HAVE_TOOLBARS */
+
   CLASS_RESET_CHANGED_FLAGS (f);
   f->window_face_cache_reset = 0;
   f->echo_area_garbaged = 0;
--- a/src/redisplay.h	Sat Jul 06 18:56:31 2002 +0000
+++ b/src/redisplay.h	Sat Jul 06 21:05:58 2002 +0000
@@ -479,6 +479,10 @@
 /* Nonzero if some device has signaled that it wants to change size. */
 extern int asynch_device_change_pending;
 
+/* Nonzero if some frame has changed the layout of internal elements
+   (gutters or toolbars). */
+extern int frame_layout_changed;
+
 /* Nonzero if any toolbar has changed. */
 extern int toolbar_changed;
 extern int toolbar_changed_set;
@@ -549,6 +553,7 @@
   (p)->extents_changed = 0;			\
   (p)->faces_changed = 0;			\
   (p)->frame_changed = 0;			\
+  (p)->frame_layout_changed = 0;		\
   (p)->icon_changed = 0;			\
   (p)->menubar_changed = 0;			\
   (p)->modeline_changed = 0;			\
@@ -567,6 +572,7 @@
   clip_changed = 0;				\
   extents_changed = 0;				\
   frame_changed = 0;				\
+  frame_layout_changed = 0;			\
   icon_changed = 0;				\
   menubar_changed = 0;				\
   modeline_changed = 0;				\
@@ -586,6 +592,7 @@
     (p)->extents_changed ||			\
     (p)->faces_changed ||			\
     (p)->frame_changed ||			\
+    (p)->frame_layout_changed ||		\
     (p)->icon_changed ||			\
     (p)->menubar_changed ||			\
     (p)->modeline_changed ||			\
@@ -605,6 +612,7 @@
     extents_changed ||				\
     faces_changed ||				\
     frame_changed ||				\
+    frame_layout_changed ||			\
     icon_changed ||				\
     menubar_changed ||				\
     modeline_changed ||				\
--- a/src/toolbar-common.c	Sat Jul 06 18:56:31 2002 +0000
+++ b/src/toolbar-common.c	Sat Jul 06 21:05:58 2002 +0000
@@ -396,7 +396,8 @@
 	    || tb->y != y						\
 	    || tb->width != width					\
 	    || tb->height != height					\
-	    || tb->dirty)						\
+	    || tb->dirty						\
+	    || f->clear) /* This is clearly necessary. */		\
 	  {								\
 	    if (width && height)					\
 	      {								\
@@ -612,22 +613,33 @@
 
   if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f))
     common_output_toolbar (f, TOP_TOOLBAR);
-  else if (f->top_toolbar_was_visible)
-    common_clear_toolbar (f, TOP_TOOLBAR, 0);
 
   if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f))
     common_output_toolbar (f, BOTTOM_TOOLBAR);
-  else if (f->bottom_toolbar_was_visible)
-    common_clear_toolbar (f, BOTTOM_TOOLBAR, 0);
 
   if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f))
     common_output_toolbar (f, LEFT_TOOLBAR);
-  else if (f->left_toolbar_was_visible)
-    common_clear_toolbar (f, LEFT_TOOLBAR, 0);
 
   if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f))
     common_output_toolbar (f, RIGHT_TOOLBAR);
-  else if (f->right_toolbar_was_visible)
+}
+
+void
+common_clear_frame_toolbars (struct frame *f)
+{
+  __INTERNAL_APPROPRIATENESS_CHECK(f);
+
+  if (f->top_toolbar_was_visible
+      && !FRAME_REAL_TOP_TOOLBAR_VISIBLE (f))
+    common_clear_toolbar (f, TOP_TOOLBAR, 0);
+  if (f->bottom_toolbar_was_visible
+      && !FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f))
+    common_clear_toolbar (f, BOTTOM_TOOLBAR, 0);
+  if (f->left_toolbar_was_visible 
+      && !FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f))
+    common_clear_toolbar (f, LEFT_TOOLBAR, 0);
+  if (f->right_toolbar_was_visible 
+       && !FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f))
     common_clear_toolbar (f, RIGHT_TOOLBAR, 0);
 }
 
--- a/src/toolbar-common.h	Sat Jul 06 18:56:31 2002 +0000
+++ b/src/toolbar-common.h	Sat Jul 06 21:05:58 2002 +0000
@@ -16,5 +16,6 @@
 					    int width, int height);
 extern void common_redraw_frame_toolbars (struct frame *f);
 extern void common_output_toolbar_button (struct frame *f, Lisp_Object button);
+extern void common_clear_frame_toolbars (struct frame *f);
 
 #endif /* __TOOLBAR_COMMON_H__ */
--- a/src/toolbar-gtk.c	Sat Jul 06 18:56:31 2002 +0000
+++ b/src/toolbar-gtk.c	Sat Jul 06 21:05:58 2002 +0000
@@ -40,6 +40,7 @@
 #define gtk_output_toolbar_button common_output_toolbar_button
 #define gtk_redraw_exposed_toolbars common_redraw_exposed_toolbars
 #define gtk_redraw_frame_toolbars common_redraw_frame_toolbars
+#define gtk_clear_frame_toolbars common_clear_frame_toolbars
 
 
 static void
@@ -63,6 +64,7 @@
 console_type_create_toolbar_gtk (void)
 {
   CONSOLE_HAS_METHOD (gtk, output_frame_toolbars);
+  CONSOLE_HAS_METHOD (gtk, clear_frame_toolbars);
   CONSOLE_HAS_METHOD (gtk, initialize_frame_toolbars);
   CONSOLE_HAS_METHOD (gtk, free_frame_toolbars);
   CONSOLE_HAS_METHOD (gtk, output_toolbar_button);
--- a/src/toolbar-msw.c	Sat Jul 06 18:56:31 2002 +0000
+++ b/src/toolbar-msw.c	Sat Jul 06 21:05:58 2002 +0000
@@ -22,7 +22,7 @@
 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-/* This implementation by Andy Piper <andyp@parallax.co.uk>, with bits
+/* This implementation by Andy Piper <andy@xemacs.org>, with bits
    borrowed from toolbar-x.c */
 
 /* Synched up with: Not in FSF. */
@@ -550,22 +550,30 @@
 
   if (FRAME_REAL_TOP_TOOLBAR_VISIBLE (f))
     mswindows_output_toolbar (f, TOP_TOOLBAR);
-  else if (f->top_toolbar_was_visible)
-    mswindows_clear_toolbar (f, TOP_TOOLBAR, 0);
-
   if (FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f))
     mswindows_output_toolbar (f, BOTTOM_TOOLBAR);
-  else if (f->bottom_toolbar_was_visible)
-    mswindows_clear_toolbar (f, BOTTOM_TOOLBAR, 0);
-
   if (FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f))
     mswindows_output_toolbar (f, LEFT_TOOLBAR);
-  else if (f->left_toolbar_was_visible)
-    mswindows_clear_toolbar (f, LEFT_TOOLBAR, 0);
-
   if (FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f))
     mswindows_output_toolbar (f, RIGHT_TOOLBAR);
-  else if (f->right_toolbar_was_visible)
+}
+
+static void
+mswindows_clear_frame_toolbars (struct frame *f)
+{
+  assert (FRAME_MSWINDOWS_P (f));
+
+  if (f->top_toolbar_was_visible
+      && !FRAME_REAL_TOP_TOOLBAR_VISIBLE (f))
+    mswindows_clear_toolbar (f, TOP_TOOLBAR, 0);
+  if (f->bottom_toolbar_was_visible
+      && !FRAME_REAL_BOTTOM_TOOLBAR_VISIBLE (f))
+    mswindows_clear_toolbar (f, BOTTOM_TOOLBAR, 0);
+  if (f->left_toolbar_was_visible 
+      && !FRAME_REAL_LEFT_TOOLBAR_VISIBLE (f))
+    mswindows_clear_toolbar (f, LEFT_TOOLBAR, 0);
+  if (f->right_toolbar_was_visible 
+      && !FRAME_REAL_RIGHT_TOOLBAR_VISIBLE (f))
     mswindows_clear_toolbar (f, RIGHT_TOOLBAR, 0);
 }
 
@@ -640,6 +648,7 @@
 console_type_create_toolbar_mswindows (void)
 {
   CONSOLE_HAS_METHOD (mswindows, output_frame_toolbars);
+  CONSOLE_HAS_METHOD (mswindows, clear_frame_toolbars);
   CONSOLE_HAS_METHOD (mswindows, initialize_frame_toolbars);
   CONSOLE_HAS_METHOD (mswindows, free_frame_toolbars);
   CONSOLE_HAS_METHOD (mswindows, redraw_exposed_toolbars);
--- a/src/toolbar-x.c	Sat Jul 06 18:56:31 2002 +0000
+++ b/src/toolbar-x.c	Sat Jul 06 21:05:58 2002 +0000
@@ -50,6 +50,7 @@
 #define x_output_toolbar_button common_output_toolbar_button
 #define x_redraw_exposed_toolbars common_redraw_exposed_toolbars
 #define x_redraw_frame_toolbars common_redraw_frame_toolbars
+#define x_clear_frame_toolbars common_clear_frame_toolbars
 
 static void
 x_initialize_frame_toolbars (struct frame *f)
@@ -77,6 +78,7 @@
 console_type_create_toolbar_x (void)
 {
   CONSOLE_HAS_METHOD (x, output_frame_toolbars);
+  CONSOLE_HAS_METHOD (x, clear_frame_toolbars);
   CONSOLE_HAS_METHOD (x, initialize_frame_toolbars);
   CONSOLE_HAS_METHOD (x, free_frame_toolbars);
   CONSOLE_HAS_METHOD (x, output_toolbar_button);
--- a/src/toolbar.c	Sat Jul 06 18:56:31 2002 +0000
+++ b/src/toolbar.c	Sat Jul 06 21:05:58 2002 +0000
@@ -714,13 +714,26 @@
   set_frame_toolbar (f, RIGHT_TOOLBAR);
 }
 
+/* Update the toolbar geometry separately from actually displaying the
+   toolbar. This is necessary because both the gutter and the toolbar
+   are competing for redisplay cycles and, unfortunately, gutter
+   updates happen late in the game. Firstly they are done inside of
+   redisplay proper and secondly subcontrols may not get moved until
+   the next screen refresh. Only after subcontrols have been moved to
+   their final destinations can we be certain of updating the
+   toolbar. Under X this probably is exacerbated by the toolbar button
+   dirty flags which prevent updates happening when they possibly
+   should. */
 void
-update_frame_toolbars (struct frame *f)
+update_frame_toolbars_geometry (struct frame *f)
 {
   struct device *d = XDEVICE (f->device);
 
   if (DEVICE_SUPPORTS_TOOLBARS_P (d)
-      && (f->toolbar_changed || f->frame_changed || f->clear))
+      && (f->toolbar_changed 
+	  || f->frame_layout_changed
+	  || f->frame_changed
+	  || f->clear))
     {
       int pos;
 
@@ -740,18 +753,39 @@
 	    pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
 				&width, &height);
 	    change_frame_size (f, height, width, 0);
+	    MARK_FRAME_LAYOUT_CHANGED (f);
 	    break;
 	  }
 
-      for (pos = 0; pos < 4; pos++)
+      for (pos = 0; pos < 4; pos++) {
 	f->current_toolbar_size[pos] = FRAME_REAL_TOOLBAR_SIZE (f, pos);
+      }
 
       /* Removed the check for the minibuffer here.  We handle this
 	 more correctly now by consistently using
 	 FRAME_LAST_NONMINIBUF_WINDOW instead of FRAME_SELECTED_WINDOW
 	 throughout the toolbar code. */
       compute_frame_toolbars_data (f);
+      
+      /* Clear the previous toolbar locations. If we do it later
+	 (after redisplay) we end up clearing what we have just
+	 displayed. */
+      MAYBE_DEVMETH (d, clear_frame_toolbars, (f));
+    }
+}
 
+/* Actually redisplay the toolbar buttons. */
+void
+update_frame_toolbars (struct frame *f)
+{
+  struct device *d = XDEVICE (f->device);
+
+  if (DEVICE_SUPPORTS_TOOLBARS_P (d)
+      && (f->toolbar_changed 
+	  || f->frame_layout_changed
+	  || f->frame_changed 
+	  || f->clear))
+    {
       DEVMETH (d, output_frame_toolbars, (f));
     }
 
--- a/src/toolbar.h	Sat Jul 06 18:56:31 2002 +0000
+++ b/src/toolbar.h	Sat Jul 06 21:05:58 2002 +0000
@@ -99,6 +99,7 @@
 extern Lisp_Object Vtoolbar_size[4];
 extern Lisp_Object Vtoolbar_border_width[4];
 void update_frame_toolbars (struct frame *f);
+void update_frame_toolbars_geometry (struct frame *f);
 void init_frame_toolbars (struct frame *f);
 void init_device_toolbars (struct device *d);
 void init_global_toolbars (struct device *d);