Index: src/glyphs-x.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/glyphs-x.c,v retrieving revision 1.49.2.58 diff -u -r1.49.2.58 glyphs-x.c --- src/glyphs-x.c 2000/02/22 22:03:03 1.49.2.58 +++ src/glyphs-x.c 2000/03/11 17:56:53 @@ -2201,6 +2201,9 @@ /* Now do non structural updates. */ wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (p)); + if (!wv) + return; + /* Possibly update the colors and font */ if (IMAGE_INSTANCE_WIDGET_FACE_CHANGED (p) || Index: src/gutter.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/Attic/gutter.c,v retrieving revision 1.1.2.26 diff -u -r1.1.2.26 gutter.c --- src/gutter.c 2000/03/08 15:06:52 1.1.2.26 +++ src/gutter.c 2000/03/11 17:57:03 @@ -88,6 +88,7 @@ } } +#if 0 static Lisp_Object frame_topmost_window (struct frame *f) { @@ -102,6 +103,7 @@ return w; } +#endif static Lisp_Object frame_bottommost_window (struct frame *f) @@ -344,7 +346,7 @@ w->gutter_extent_modiff [pos] = 0; } -/* sizing gutters is a pain so we try and help the user by detemining +/* Sizing gutters is a pain so we try and help the user by detemining what height will accommodate all lines. This is useless on left and right gutters as we always have a maximal number of lines. */ static Lisp_Object @@ -464,26 +466,19 @@ } } +/* We have to change the gutter geometry separately to the gutter + update since it needs to occur outside of redisplay proper. */ void -update_frame_gutters (struct frame *f) +update_frame_gutter_geometry (struct frame *f) { - if (f->faces_changed || f->frame_changed || - f->gutter_changed || f->glyphs_changed || - f->size_changed || f->subwindows_changed || - f->windows_changed || f->windows_structure_changed || - f->extents_changed) + if (f->gutter_changed || f->windows_structure_changed) { enum gutter_pos pos; - - /* We don't actually care about these when outputting the gutter - so locally disable them. */ - int local_clip_changed = f->clip_changed; - int local_buffers_changed = f->buffers_changed; - f->clip_changed = 0; - f->buffers_changed = 0; /* If the gutter geometry has changed then re-layout the - frame. */ + frame. If we are in display there is almost no point in doing + anything else since the frame size changes will be delayed + until we are out of redisplay proper. */ GUTTER_POS_LOOP (pos) { if (FRAME_GUTTER_BOUNDS (f, pos) != f->current_gutter_bounds[pos]) @@ -495,7 +490,33 @@ break; } } + + GUTTER_POS_LOOP (pos) + { + /* Mark sizes as up-to-date. */ + f->current_gutter_bounds[pos] = FRAME_GUTTER_BOUNDS (f, pos); + } + } +} + +void +update_frame_gutters (struct frame *f) +{ + if (f->faces_changed || f->frame_changed || + f->gutter_changed || f->glyphs_changed || + f->size_changed || f->subwindows_changed || + f->windows_changed || f->windows_structure_changed || + f->extents_changed) + { + enum gutter_pos pos; + /* We don't actually care about these when outputting the gutter + so locally disable them. */ + int local_clip_changed = f->clip_changed; + int local_buffers_changed = f->buffers_changed; + f->clip_changed = 0; + f->buffers_changed = 0; + /* and output */ GUTTER_POS_LOOP (pos) { @@ -504,9 +525,6 @@ else if (gutter_was_visible (f, pos)) clear_gutter (f, pos); - - /* Mark sizes as up-to-date. */ - f->current_gutter_bounds[pos] = FRAME_GUTTER_BOUNDS (f, pos); } f->clip_changed = local_clip_changed; @@ -919,19 +937,45 @@ DEVICE_FRAME_LOOP (frmcons, d) { struct frame *f = XFRAME (XCAR (frmcons)); - - if (FRAME_REPAINT_P (f)) + + /* Sequence is quite important here. We not only want to + redisplay the gutter area but we also want to flush any + frame size changes out so that the gutter redisplay happens + in a kosha environment. + + This is not only so that things look right but so that + glyph redisplay optimization kicks in, by default display + lines will be completely re-output if + f->windows_structure_changed is 1, and this is true if + frame size changes haven't been flushed out. Once frame + size changes have been flushed out we then need to + redisplay the frame in order to flush out pending window + size changes. */ + update_frame_gutter_geometry (f); + + if (f->windows_structure_changed) + redisplay_frame (f, 1); + else if (FRAME_REPAINT_P (f)) { + /* We have to be "in display" when we output the gutter + - make it so. */ + hold_frame_size_changes (); update_frame_gutters (f); + unhold_one_frame_size_changes (f); } } - /* We now call the output_end routine for tty frames. We delay doing so in order to avoid cursor flicker. So much for 100% encapsulation. */ if (DEVICE_TTY_P (d)) DEVMETH (d, output_end, (d)); + + d->gutter_changed = 0; } + + /* This is so that further changes to the gutters will trigger redisplay. */ + gutter_changed_set = 0; + gutter_changed = 0; return Qnil; } Index: src/gutter.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/Attic/gutter.h,v retrieving revision 1.1.2.11 diff -u -r1.1.2.11 gutter.h --- src/gutter.h 2000/03/04 16:53:33 1.1.2.11 +++ src/gutter.h 2000/03/11 17:57:09 @@ -54,6 +54,7 @@ extern Lisp_Object Vgutter_size[4]; extern Lisp_Object Vgutter_border_width[4]; void update_frame_gutters (struct frame *f); +void update_frame_gutter_geometry (struct frame *f); void mark_gutters (struct frame* f); void init_frame_gutters (struct frame *f); void init_device_gutters (struct device *d); Index: src/redisplay.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay.c,v retrieving revision 1.55.2.47 diff -u -r1.55.2.47 redisplay.c --- src/redisplay.c 2000/03/10 08:03:30 1.55.2.47 +++ src/redisplay.c 2000/03/11 17:58:40 @@ -6294,7 +6294,7 @@ /* Ensure that all windows on the given frame are correctly displayed. */ -static int +int redisplay_frame (struct frame *f, int preemption_check) { struct device *d = XDEVICE (f->device); @@ -6345,6 +6345,10 @@ /* Update the toolbars. */ update_frame_toolbars (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 + geometry here if it needs it. */ + update_frame_gutter_geometry (f); /* If we clear the frame we have to force its contents to be redrawn. */ if (f->clear) @@ -8910,6 +8914,9 @@ f->clear = 1; redisplay_frame (f, 1); + /* See the comment in Fredisplay_frame. */ + RESET_CHANGED_SET_FLAGS; + return unbind_to (count, Qnil); } @@ -8937,6 +8944,15 @@ redisplay_frame (f, 1); + /* If we don't reset the global redisplay flafs here, subsequent + changes to the display will not get registered by redisplay + because it thinks it already has registered changes. If you + really knew what you were doing you could confuse redisplay by + calling Fredisplay_frame while updating another frame. We assume + that if you know what you are doing you will not be that + stupid. */ + RESET_CHANGED_SET_FLAGS; + return unbind_to (count, Qnil); } @@ -8966,6 +8982,9 @@ } redisplay_device (d, 0); + /* See the comment in Fredisplay_frame. */ + RESET_CHANGED_SET_FLAGS; + return unbind_to (count, Qnil); } @@ -8992,6 +9011,9 @@ } redisplay_device (d, 0); + + /* See the comment in Fredisplay_frame. */ + RESET_CHANGED_SET_FLAGS; return unbind_to (count, Qnil); } Index: src/redisplay.h =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/redisplay.h,v retrieving revision 1.7.2.24 diff -u -r1.7.2.24 redisplay.h --- src/redisplay.h 2000/03/10 08:03:31 1.7.2.24 +++ src/redisplay.h 2000/03/11 17:58:47 @@ -685,6 +685,7 @@ Bufbyte *nonreloc, Lisp_Object reloc, Bytecount offset, Bytecount len); +int redisplay_frame (struct frame *f, int preemption_check); void redisplay (void); struct display_block *get_display_block_from_line (struct display_line *dl, enum display_type type); Index: src/window.c =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/src/window.c,v retrieving revision 1.41.2.42 diff -u -r1.41.2.42 window.c --- src/window.c 2000/03/04 16:53:36 1.41.2.42 +++ src/window.c 2000/03/11 17:59:35 @@ -3432,6 +3432,10 @@ p->line_start_cache = Dynarr_new (line_start_cache); p->face_cachels = Dynarr_new (face_cachel); p->glyph_cachels = Dynarr_new (glyph_cachel); + p->subwindow_instance_cache = + make_lisp_hash_table (10, + HASH_TABLE_KEY_WEAK, + HASH_TABLE_EQ); /* Put new into window structure in place of window */ replace_window (window, new); @@ -5208,6 +5212,10 @@ w->glyph_cachels = Dynarr_new (glyph_cachel); if (!w->line_start_cache) w->line_start_cache = Dynarr_new (line_start_cache); + w->gutter_extent_modiff[0] = 0; + w->gutter_extent_modiff[1] = 0; + w->gutter_extent_modiff[2] = 0; + w->gutter_extent_modiff[3] = 0; w->dead = 0; if (p->parent_index >= 0) Index: tests/glyph-test.el =================================================================== RCS file: /usr/CVSroot/XEmacs/xemacs/tests/Attic/glyph-test.el,v retrieving revision 1.1.2.17 diff -u -r1.1.2.17 glyph-test.el --- tests/glyph-test.el 2000/01/13 14:38:18 1.1.2.17 +++ tests/glyph-test.el 2000/03/11 17:59:37 @@ -69,9 +69,9 @@ [tab-control :descriptor "My Tab" :face highlight :orientation right - :properties (:items (["One" foo] - ["Two" fee] - ["Three" foo]))]))) + :properties (:items (["One" foo :selected t] + ["Two" fee :selected nil] + ["Three" foo :selected nil]))]))) ;; progress gauge (set-extent-begin-glyph