Refine redisplay optimizations to only redisplay *some* frames/windows
rather than all of them. * src/xdisp.c (REDISPLAY_SOME): New constant. (redisplay_other_windows, wset_redisplay, fset_redisplay) (bset_redisplay, bset_update_mode_line): New functions. (message_dolog): Use bset_redisplay. (clear_garbaged_frames): Use fset_redisplay. (echo_area_display): Use wset_redisplay. (buffer_shared_and_changed): Remove. (prepare_menu_bars): Call Vpre_redisplay_function before updating frame titles. Compute the actual set of windows redisplayed. Don't update frame titles and menu bars for frames that don't need to be redisplayed. (propagate_buffer_redisplay): New function. (AINC): New macro. (redisplay_internal): Use it. Be more selective in the set of windows we redisplay. Propagate windows_or_buffers_changed to update_mode_lines a bit later to simplify the code. (mark_window_display_accurate_1): Reset window and buffer's `redisplay' flag. (redisplay_window): Do nothing if neither the window nor the buffer nor the frame needs redisplay. * src/window.h (struct window): Add `redisplay' field. (wset_redisplay, fset_redisplay, bset_redisplay, bset_update_mode_line) (redisplay_other_windows, window_list): New declarations. * src/window.c (select_window, Fset_window_start): Use wset_redisplay. (window_list): Not static any more. (grow_mini_window, shrink_mini_window): Use fset_redisplay. * src/minibuf.c (read_minibuf_unwind): Don't redisplay everything. * src/insdel.c (prepare_to_modify_buffer_1): Use bset_redisplay. * src/frame.c (Fmake_frame_visible): Don't redisplay everything. * src/frame.h (struct frame): Add `redisplay' field. Move `external_menu_bar' bitfield next to other bit-fields. (SET_FRAME_GARBAGED): Use fset_redisplay. (SET_FRAME_VISIBLE): Don't garbage the frame; Use redisplay_other_windows. * src/buffer.h (struct buffer): Add `redisplay' field. * src/buffer.c (Fforce_mode_line_update): Pay attention to the `all' flag. (modify_overlay): Use bset_redisplay. * src/alloc.c (gc_sweep): Don't unmark strings while sweeping symbols. * lisp/doc-view.el (doc-view-goto-page): Update mode-line.
This commit is contained in:
parent
698c0f24f1
commit
655ab9a380
14 changed files with 392 additions and 240 deletions
|
@ -1,5 +1,7 @@
|
|||
2013-11-28 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* doc-view.el (doc-view-goto-page): Update mode-line.
|
||||
|
||||
* vc/vc-dispatcher.el (vc-log-edit): Setup the Summary&Author headers.
|
||||
|
||||
2013-11-27 Glenn Morris <rgm@gnu.org>
|
||||
|
@ -531,8 +533,8 @@
|
|||
* progmodes/ruby-mode.el: Improve encoding comment handling.
|
||||
(ruby-encoding-magic-comment-style): New option.
|
||||
(ruby-custom-encoding-magic-comment-template): New option.
|
||||
(ruby--insert-coding-comment, ruby--detect-encoding): New
|
||||
functions extracted from `ruby-mode-set-encoding'.
|
||||
(ruby--insert-coding-comment, ruby--detect-encoding):
|
||||
New functions extracted from `ruby-mode-set-encoding'.
|
||||
(ruby-mode-set-encoding): Use `ruby-encoding-magic-comment-style'
|
||||
to control the style of the auto-inserted encoding comment.
|
||||
|
||||
|
|
|
@ -499,6 +499,7 @@ Typically \"page-%s.png\".")
|
|||
;; how many pages will be available.
|
||||
(null doc-view--current-converter-processes))
|
||||
(setq page len)))
|
||||
(force-mode-line-update) ;To update `current-page'.
|
||||
(setf (doc-view-current-page) page
|
||||
(doc-view-current-info)
|
||||
(concat
|
||||
|
|
|
@ -1,3 +1,46 @@
|
|||
2013-11-28 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
Refine redisplay optimizations to only redisplay *some* frames/windows
|
||||
rather than all of them.
|
||||
* xdisp.c (REDISPLAY_SOME): New constant.
|
||||
(redisplay_other_windows, wset_redisplay, fset_redisplay)
|
||||
(bset_redisplay, bset_update_mode_line): New functions.
|
||||
(message_dolog): Use bset_redisplay.
|
||||
(clear_garbaged_frames): Use fset_redisplay.
|
||||
(echo_area_display): Use wset_redisplay.
|
||||
(buffer_shared_and_changed): Remove.
|
||||
(prepare_menu_bars): Call Vpre_redisplay_function before updating
|
||||
frame titles. Compute the actual set of windows redisplayed.
|
||||
Don't update frame titles and menu bars for frames that don't need to
|
||||
be redisplayed.
|
||||
(propagate_buffer_redisplay): New function.
|
||||
(AINC): New macro.
|
||||
(redisplay_internal): Use it. Be more selective in the set of windows
|
||||
we redisplay. Propagate windows_or_buffers_changed to
|
||||
update_mode_lines a bit later to simplify the code.
|
||||
(mark_window_display_accurate_1): Reset window and buffer's
|
||||
`redisplay' flag.
|
||||
(redisplay_window): Do nothing if neither the window nor the buffer nor
|
||||
the frame needs redisplay.
|
||||
* window.h (struct window): Add `redisplay' field.
|
||||
(wset_redisplay, fset_redisplay, bset_redisplay, bset_update_mode_line)
|
||||
(redisplay_other_windows, window_list): New declarations.
|
||||
* window.c (select_window, Fset_window_start): Use wset_redisplay.
|
||||
(window_list): Not static any more.
|
||||
(grow_mini_window, shrink_mini_window): Use fset_redisplay.
|
||||
* minibuf.c (read_minibuf_unwind): Don't redisplay everything.
|
||||
* insdel.c (prepare_to_modify_buffer_1): Use bset_redisplay.
|
||||
* frame.c (Fmake_frame_visible): Don't redisplay everything.
|
||||
* frame.h (struct frame): Add `redisplay' field.
|
||||
Move `external_menu_bar' bitfield next to other bit-fields.
|
||||
(SET_FRAME_GARBAGED): Use fset_redisplay.
|
||||
(SET_FRAME_VISIBLE): Don't garbage the frame;
|
||||
Use redisplay_other_windows.
|
||||
* buffer.h (struct buffer): Add `redisplay' field.
|
||||
* buffer.c (Fforce_mode_line_update): Pay attention to the `all' flag.
|
||||
(modify_overlay): Use bset_redisplay.
|
||||
* alloc.c (gc_sweep): Don't unmark strings while sweeping symbols.
|
||||
|
||||
2013-11-28 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
Support w32 file notifications in batch mode.
|
||||
|
@ -6,11 +49,9 @@
|
|||
handle_file_notifications to store file notification events in the
|
||||
input queue. (Bug#15933)
|
||||
|
||||
* w32notify.c (send_notifications): Handle FRAME_INITIAL frames as
|
||||
well.
|
||||
* w32notify.c (send_notifications): Handle FRAME_INITIAL frames as well.
|
||||
|
||||
* w32inevt.c (handle_file_notifications): Now external, not
|
||||
static.
|
||||
* w32inevt.c (handle_file_notifications): Now external, not static.
|
||||
|
||||
* w32term.h (handle_file_notifications): Provide prototype.
|
||||
|
||||
|
@ -209,8 +250,8 @@
|
|||
* insdel.c (invalidate_buffer_caches): New function, consolidated
|
||||
from part of prepare_to_modify_buffer.
|
||||
(insert_from_gap, prepare_to_modify_buffer):
|
||||
* coding.c (code_convert_region, code_convert_string): Call
|
||||
invalidate_buffer_caches. (Bug#15841)
|
||||
* coding.c (code_convert_region, code_convert_string):
|
||||
Call invalidate_buffer_caches. (Bug#15841)
|
||||
|
||||
* lisp.h (invalidate_buffer_caches): Add prototype.
|
||||
|
||||
|
|
12
src/alloc.c
12
src/alloc.c
|
@ -6291,7 +6291,7 @@ survives_gc_p (Lisp_Object obj)
|
|||
|
||||
|
||||
|
||||
/* Sweep: find all structures not marked, and free them. */
|
||||
/* Sweep: find all structures not marked, and free them. */
|
||||
|
||||
static void
|
||||
gc_sweep (void)
|
||||
|
@ -6303,7 +6303,7 @@ gc_sweep (void)
|
|||
sweep_strings ();
|
||||
check_string_bytes (!noninteractive);
|
||||
|
||||
/* Put all unmarked conses on free list */
|
||||
/* Put all unmarked conses on free list. */
|
||||
{
|
||||
register struct cons_block *cblk;
|
||||
struct cons_block **cprev = &cons_block;
|
||||
|
@ -6380,7 +6380,7 @@ gc_sweep (void)
|
|||
total_free_conses = num_free;
|
||||
}
|
||||
|
||||
/* Put all unmarked floats on free list */
|
||||
/* Put all unmarked floats on free list. */
|
||||
{
|
||||
register struct float_block *fblk;
|
||||
struct float_block **fprev = &float_block;
|
||||
|
@ -6426,7 +6426,7 @@ gc_sweep (void)
|
|||
total_free_floats = num_free;
|
||||
}
|
||||
|
||||
/* Put all unmarked intervals on free list */
|
||||
/* Put all unmarked intervals on free list. */
|
||||
{
|
||||
register struct interval_block *iblk;
|
||||
struct interval_block **iprev = &interval_block;
|
||||
|
@ -6475,7 +6475,7 @@ gc_sweep (void)
|
|||
total_free_intervals = num_free;
|
||||
}
|
||||
|
||||
/* Put all unmarked symbols on free list */
|
||||
/* Put all unmarked symbols on free list. */
|
||||
{
|
||||
register struct symbol_block *sblk;
|
||||
struct symbol_block **sprev = &symbol_block;
|
||||
|
@ -6512,7 +6512,7 @@ gc_sweep (void)
|
|||
{
|
||||
++num_used;
|
||||
if (!pure_p)
|
||||
UNMARK_STRING (XSTRING (sym->s.name));
|
||||
eassert (!STRING_MARKED_P (XSTRING (sym->s.name)));
|
||||
sym->s.gcmarkbit = 0;
|
||||
}
|
||||
}
|
||||
|
|
22
src/buffer.c
22
src/buffer.c
|
@ -1336,10 +1336,16 @@ header lines. This function also forces recomputation of the
|
|||
menu bar menus and the frame title. */)
|
||||
(Lisp_Object all)
|
||||
{
|
||||
if (!NILP (all) || buffer_window_count (current_buffer))
|
||||
if (!NILP (all))
|
||||
{
|
||||
update_mode_lines = 10;
|
||||
current_buffer->prevent_redisplay_optimizations_p = 1;
|
||||
/* FIXME: This can't be right. */
|
||||
current_buffer->prevent_redisplay_optimizations_p = true;
|
||||
}
|
||||
else if (buffer_window_count (current_buffer))
|
||||
{
|
||||
bset_update_mode_line (current_buffer);
|
||||
current_buffer->prevent_redisplay_optimizations_p = true;
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
@ -3895,17 +3901,7 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
|
|||
|
||||
BUF_COMPUTE_UNCHANGED (buf, start, end);
|
||||
|
||||
/* If BUF is visible, consider updating the display if ... */
|
||||
if (buffer_window_count (buf) > 0)
|
||||
{
|
||||
/* ... it's visible in other window than selected, */
|
||||
if (buf != XBUFFER (XWINDOW (selected_window)->contents))
|
||||
windows_or_buffers_changed = 11;
|
||||
/* ... or if we modify an overlay at the end of the buffer
|
||||
and so we cannot be sure that window end is still valid. */
|
||||
else if (end >= ZV && start <= ZV)
|
||||
windows_or_buffers_changed = 12;
|
||||
}
|
||||
bset_redisplay (buf);
|
||||
|
||||
++BUF_OVERLAY_MODIFF (buf);
|
||||
}
|
||||
|
|
|
@ -475,7 +475,10 @@ struct buffer_text
|
|||
/* Usually 0. Temporarily set to 1 in decode_coding_gap to
|
||||
prevent Fgarbage_collect from shrinking the gap and losing
|
||||
not-yet-decoded bytes. */
|
||||
bool inhibit_shrinking;
|
||||
bool inhibit_shrinking : 1;
|
||||
|
||||
/* True if it needs to be redisplayed. */
|
||||
bool redisplay : 1;
|
||||
};
|
||||
|
||||
/* Most code should use this macro to access Lisp fields in struct buffer. */
|
||||
|
@ -846,10 +849,10 @@ struct buffer
|
|||
|
||||
/* Non-zero means don't use redisplay optimizations for
|
||||
displaying this buffer. */
|
||||
unsigned prevent_redisplay_optimizations_p : 1;
|
||||
bool prevent_redisplay_optimizations_p : 1;
|
||||
|
||||
/* Non-zero whenever the narrowing is changed in this buffer. */
|
||||
unsigned clip_changed : 1;
|
||||
bool clip_changed : 1;
|
||||
|
||||
/* List of overlays that end at or before the current center,
|
||||
in order of end-position. */
|
||||
|
|
17
src/frame.c
17
src/frame.c
|
@ -339,11 +339,12 @@ make_frame (bool mini_p)
|
|||
non-Lisp data, so do it only for slots which should not be zero.
|
||||
To avoid subtle bugs and for the sake of readability, it's better to
|
||||
initialize enum members explicitly even if their values are zero. */
|
||||
f->wants_modeline = 1;
|
||||
f->garbaged = 1;
|
||||
f->wants_modeline = true;
|
||||
f->redisplay = true;
|
||||
f->garbaged = true;
|
||||
f->vertical_scroll_bar_type = vertical_scroll_bar_none;
|
||||
f->column_width = 1; /* !FRAME_WINDOW_P value */
|
||||
f->line_height = 1; /* !FRAME_WINDOW_P value */
|
||||
f->column_width = 1; /* !FRAME_WINDOW_P value. */
|
||||
f->line_height = 1; /* !FRAME_WINDOW_P value. */
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
f->want_fullscreen = FULLSCREEN_NONE;
|
||||
#endif
|
||||
|
@ -785,9 +786,6 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
|
|||
if (sf == XFRAME (frame))
|
||||
return frame;
|
||||
|
||||
/* This is too greedy; it causes inappropriate focus redirection
|
||||
that's hard to get rid of. */
|
||||
#if 0
|
||||
/* If a frame's focus has been redirected toward the currently
|
||||
selected frame, we should change the redirection to point to the
|
||||
newly selected frame. This means that if the focus is redirected
|
||||
|
@ -795,6 +793,9 @@ do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object nor
|
|||
can use `other-window' to switch between all the frames using
|
||||
that minibuffer frame, and the focus redirection will follow us
|
||||
around. */
|
||||
#if 0
|
||||
/* This is too greedy; it causes inappropriate focus redirection
|
||||
that's hard to get rid of. */
|
||||
if (track)
|
||||
{
|
||||
Lisp_Object tail;
|
||||
|
@ -1681,7 +1682,7 @@ If omitted, FRAME defaults to the currently selected frame. */)
|
|||
make_frame_visible_1 (f->root_window);
|
||||
|
||||
/* Make menu bar update for the Buffers and Frames menus. */
|
||||
windows_or_buffers_changed = 15;
|
||||
/* windows_or_buffers_changed = 15; FIXME: Why? */
|
||||
|
||||
XSETFRAME (frame, f);
|
||||
return frame;
|
||||
|
|
107
src/frame.h
107
src/frame.h
|
@ -178,41 +178,44 @@ struct frame
|
|||
|
||||
/* 1 means that glyphs on this frame have been initialized so it can
|
||||
be used for output. */
|
||||
unsigned glyphs_initialized_p : 1;
|
||||
bool glyphs_initialized_p : 1;
|
||||
|
||||
/* Set to non-zero in change_frame_size when size of frame changed
|
||||
Clear the frame in clear_garbaged_frames if set. */
|
||||
unsigned resized_p : 1;
|
||||
bool resized_p : 1;
|
||||
|
||||
/* Set to non-zero if the default face for the frame has been
|
||||
realized. Reset to zero whenever the default face changes.
|
||||
Used to see the difference between a font change and face change. */
|
||||
unsigned default_face_done_p : 1;
|
||||
bool default_face_done_p : 1;
|
||||
|
||||
/* Set to non-zero if this frame has already been hscrolled during
|
||||
current redisplay. */
|
||||
unsigned already_hscrolled_p : 1;
|
||||
bool already_hscrolled_p : 1;
|
||||
|
||||
/* Set to non-zero when current redisplay has updated frame. */
|
||||
unsigned updated_p : 1;
|
||||
bool updated_p : 1;
|
||||
|
||||
#if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
|
||||
/* Set to non-zero to minimize tool-bar height even when
|
||||
auto-resize-tool-bar is set to grow-only. */
|
||||
unsigned minimize_tool_bar_window_p : 1;
|
||||
bool minimize_tool_bar_window_p : 1;
|
||||
#endif
|
||||
|
||||
#if defined (USE_GTK) || defined (HAVE_NS)
|
||||
/* Nonzero means using a tool bar that comes from the toolkit. */
|
||||
unsigned external_tool_bar : 1;
|
||||
bool external_tool_bar : 1;
|
||||
#endif
|
||||
|
||||
/* Nonzero means that fonts have been loaded since the last glyph
|
||||
matrix adjustments. */
|
||||
unsigned fonts_changed : 1;
|
||||
bool fonts_changed : 1;
|
||||
|
||||
/* Nonzero means that cursor type has been changed. */
|
||||
unsigned cursor_type_changed : 1;
|
||||
bool cursor_type_changed : 1;
|
||||
|
||||
/* True if it needs to be redisplayed. */
|
||||
bool redisplay : 1;
|
||||
|
||||
/* Margin at the top of the frame. Used to display the tool-bar. */
|
||||
int tool_bar_lines;
|
||||
|
@ -220,17 +223,17 @@ struct frame
|
|||
int n_tool_bar_rows;
|
||||
int n_tool_bar_items;
|
||||
|
||||
/* A buffer for decode_mode_line. */
|
||||
/* A buffer for decode_mode_line. */
|
||||
char *decode_mode_spec_buffer;
|
||||
|
||||
/* See do_line_insertion_deletion_costs for info on these arrays. */
|
||||
/* Cost of inserting 1 line on this frame */
|
||||
/* See do_line_insertion_deletion_costs for info on these arrays. */
|
||||
/* Cost of inserting 1 line on this frame. */
|
||||
int *insert_line_cost;
|
||||
/* Cost of deleting 1 line on this frame */
|
||||
/* Cost of deleting 1 line on this frame. */
|
||||
int *delete_line_cost;
|
||||
/* Cost of inserting n lines on this frame */
|
||||
/* Cost of inserting n lines on this frame. */
|
||||
int *insert_n_lines_cost;
|
||||
/* Cost of deleting n lines on this frame */
|
||||
/* Cost of deleting n lines on this frame. */
|
||||
int *delete_n_lines_cost;
|
||||
|
||||
/* Size of this frame, excluding fringes, scroll bars etc.,
|
||||
|
@ -252,7 +255,7 @@ struct frame
|
|||
int pixel_height, pixel_width;
|
||||
|
||||
/* These many pixels are the difference between the outer window (i.e. the
|
||||
left and top of the window manager decoration) and FRAME_X_WINDOW. */
|
||||
left and top of the window manager decoration) and FRAME_X_WINDOW. */
|
||||
int x_pixels_diff, y_pixels_diff;
|
||||
|
||||
/* This is the gravity value for the specified window position. */
|
||||
|
@ -281,23 +284,23 @@ struct frame
|
|||
enum output_method output_method;
|
||||
|
||||
/* The terminal device that this frame uses. If this is NULL, then
|
||||
the frame has been deleted. */
|
||||
the frame has been deleted. */
|
||||
struct terminal *terminal;
|
||||
|
||||
/* Device-dependent, frame-local auxiliary data used for displaying
|
||||
the contents. When the frame is deleted, this data is deleted as
|
||||
well. */
|
||||
well. */
|
||||
union output_data
|
||||
{
|
||||
struct tty_output *tty; /* termchar.h */
|
||||
struct x_output *x; /* xterm.h */
|
||||
struct w32_output *w32; /* w32term.h */
|
||||
struct ns_output *ns; /* nsterm.h */
|
||||
struct tty_output *tty; /* From termchar.h. */
|
||||
struct x_output *x; /* From xterm.h. */
|
||||
struct w32_output *w32; /* From w32term.h. */
|
||||
struct ns_output *ns; /* From nsterm.h. */
|
||||
intptr_t nothing;
|
||||
}
|
||||
output_data;
|
||||
|
||||
/* List of font-drivers available on the frame. */
|
||||
/* List of font-drivers available on the frame. */
|
||||
struct font_driver_list *font_driver_list;
|
||||
/* List of data specific to font-driver and frame, but common to
|
||||
faces. */
|
||||
|
@ -313,80 +316,76 @@ struct frame
|
|||
/* The extra width (in pixels) currently allotted for fringes. */
|
||||
int left_fringe_width, right_fringe_width;
|
||||
|
||||
/* See FULLSCREEN_ enum below */
|
||||
/* See FULLSCREEN_ enum below. */
|
||||
enum fullscreen_type want_fullscreen;
|
||||
|
||||
/* Number of lines of menu bar. */
|
||||
int menu_bar_lines;
|
||||
|
||||
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|
||||
|| defined (HAVE_NS) || defined (USE_GTK)
|
||||
/* Nonzero means using a menu bar that comes from the X toolkit. */
|
||||
unsigned int external_menu_bar : 1;
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_X_WINDOWS)
|
||||
/* Used by x_wait_for_event when watching for an X event on this frame. */
|
||||
int wait_event_type;
|
||||
#endif
|
||||
|
||||
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|
||||
|| defined (HAVE_NS) || defined (USE_GTK)
|
||||
/* Nonzero means using a menu bar that comes from the X toolkit. */
|
||||
bool external_menu_bar : 1;
|
||||
#endif
|
||||
|
||||
/* Next two bitfields are mutually exclusive. They might both be
|
||||
zero if the frame has been made invisible without an icon. */
|
||||
|
||||
/* Nonzero if the frame is currently displayed; we check
|
||||
it to see if we should bother updating the frame's contents.
|
||||
|
||||
Note that, since invisible frames aren't updated, whenever a
|
||||
frame becomes visible again, it must be marked as garbaged.
|
||||
|
||||
On ttys and on Windows NT/9X, to avoid wasting effort updating
|
||||
visible frames that are actually completely obscured by other
|
||||
windows on the display, we bend the meaning of visible slightly:
|
||||
if equal to 2, then the frame is obscured - we still consider
|
||||
it to be "visible" as seen from lisp, but we don't bother
|
||||
updating it. We must take care to garbage the frame when it
|
||||
ceases to be obscured though. See SET_FRAME_VISIBLE below. */
|
||||
updating it. */
|
||||
unsigned visible : 2;
|
||||
|
||||
/* Nonzero if the frame is currently iconified. Do not
|
||||
set this directly, use SET_FRAME_ICONIFIED instead. */
|
||||
unsigned iconified : 1;
|
||||
bool iconified : 1;
|
||||
|
||||
/* Nonzero if this frame should be redrawn. */
|
||||
unsigned garbaged : 1;
|
||||
bool garbaged : 1;
|
||||
|
||||
/* 0 means, if this frame has just one window,
|
||||
show no modeline for that window. */
|
||||
unsigned wants_modeline : 1;
|
||||
bool wants_modeline : 1;
|
||||
|
||||
/* Non-0 means raise this frame to the top of the heap when selected. */
|
||||
unsigned auto_raise : 1;
|
||||
bool auto_raise : 1;
|
||||
|
||||
/* Non-0 means lower this frame to the bottom of the stack when left. */
|
||||
unsigned auto_lower : 1;
|
||||
bool auto_lower : 1;
|
||||
|
||||
/* True if frame's root window can't be split. */
|
||||
unsigned no_split : 1;
|
||||
bool no_split : 1;
|
||||
|
||||
/* If this is set, then Emacs won't change the frame name to indicate
|
||||
the current buffer, etcetera. If the user explicitly sets the frame
|
||||
name, this gets set. If the user sets the name to Qnil, this is
|
||||
cleared. */
|
||||
unsigned explicit_name : 1;
|
||||
bool explicit_name : 1;
|
||||
|
||||
/* Nonzero if size of some window on this frame has changed. */
|
||||
unsigned window_sizes_changed : 1;
|
||||
bool window_sizes_changed : 1;
|
||||
|
||||
/* Nonzero if the mouse has moved on this display device
|
||||
since the last time we checked. */
|
||||
unsigned mouse_moved :1;
|
||||
bool mouse_moved : 1;
|
||||
|
||||
/* Nonzero means that the pointer is invisible. */
|
||||
unsigned pointer_invisible :1;
|
||||
/* Nonzero means that the pointer is invisible. */
|
||||
bool pointer_invisible : 1;
|
||||
|
||||
/* Nonzero means that all windows except mini-window and
|
||||
selected window on this frame have frozen window starts. */
|
||||
unsigned frozen_window_starts : 1;
|
||||
bool frozen_window_starts : 1;
|
||||
|
||||
/* Nonzero if we should actually display the scroll bars on this frame. */
|
||||
enum vertical_scroll_bar_type vertical_scroll_bar_type;
|
||||
|
@ -720,7 +719,8 @@ default_pixels_per_inch_y (void)
|
|||
#define FRAME_ICONIFIED_P(f) (f)->iconified
|
||||
|
||||
/* Mark frame F as currently garbaged. */
|
||||
#define SET_FRAME_GARBAGED(f) (frame_garbaged = 1, f->garbaged = 1)
|
||||
#define SET_FRAME_GARBAGED(f) \
|
||||
(frame_garbaged = true, fset_redisplay (f), f->garbaged = true)
|
||||
|
||||
/* Nonzero if frame F is currently garbaged. */
|
||||
#define FRAME_GARBAGED_P(f) (f)->garbaged
|
||||
|
@ -911,11 +911,14 @@ default_pixels_per_inch_y (void)
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
/* Set visibility of frame F, marking F as garbaged if needed. */
|
||||
/* Set visibility of frame F.
|
||||
We call redisplay_other_windows to make sure the frame gets redisplayed
|
||||
if some changes were applied to it while it wasn't visible (and hence
|
||||
wasn't redisplayed). */
|
||||
|
||||
#define SET_FRAME_VISIBLE(f, v) \
|
||||
(((f)->visible == 0 || ((f)->visible == 2)) \
|
||||
&& ((v) == 1) ? SET_FRAME_GARBAGED (f) : 0, \
|
||||
#define SET_FRAME_VISIBLE(f, v) \
|
||||
(((f)->visible == 0 || ((f)->visible == 2)) && ((v) == 1) \
|
||||
? redisplay_other_windows () : 0, \
|
||||
(f)->visible = (eassert (0 <= (v) && (v) <= 2), (v)))
|
||||
|
||||
/* Set iconify of frame F. */
|
||||
|
|
|
@ -1804,11 +1804,7 @@ prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end,
|
|||
if (!NILP (BVAR (current_buffer, read_only)))
|
||||
Fbarf_if_buffer_read_only ();
|
||||
|
||||
/* If we're modifying the buffer other than shown in a selected window,
|
||||
let redisplay consider other windows if this buffer is visible. */
|
||||
if (XBUFFER (XWINDOW (selected_window)->contents) != current_buffer
|
||||
&& buffer_window_count (current_buffer))
|
||||
windows_or_buffers_changed = 20;
|
||||
bset_redisplay (current_buffer);
|
||||
|
||||
if (buffer_intervals (current_buffer))
|
||||
{
|
||||
|
|
|
@ -865,9 +865,6 @@ read_minibuf_unwind (void)
|
|||
if (minibuf_level == 0)
|
||||
resize_mini_window (XWINDOW (window), 0);
|
||||
|
||||
/* Enforce full redisplay. FIXME: make it more selective. */
|
||||
windows_or_buffers_changed = 22;
|
||||
|
||||
/* In case the previous minibuffer displayed in this miniwindow is
|
||||
dead, we may keep displaying this buffer (tho it's inactive), so reset it,
|
||||
to make sure we don't leave around bindings and stuff which only
|
||||
|
|
25
src/window.c
25
src/window.c
|
@ -60,7 +60,6 @@ static int get_leaf_windows (struct window *, struct window **, int);
|
|||
static void window_scroll (Lisp_Object, EMACS_INT, bool, int);
|
||||
static void window_scroll_pixel_based (Lisp_Object, int, bool, int);
|
||||
static void window_scroll_line_based (Lisp_Object, int, bool, int);
|
||||
static Lisp_Object window_list (void);
|
||||
static int add_window_to_list (struct window *, void *);
|
||||
static Lisp_Object next_window (Lisp_Object, Lisp_Object,
|
||||
Lisp_Object, int);
|
||||
|
@ -482,6 +481,12 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
|
|||
record_buffer before returning here. */
|
||||
goto record_and_return;
|
||||
|
||||
if (NILP (norecord))
|
||||
/* Mark the window for redisplay since the selected-window has a different
|
||||
mode-line. */
|
||||
wset_redisplay (XWINDOW (selected_window));
|
||||
else
|
||||
redisplay_other_windows ();
|
||||
sf = SELECTED_FRAME ();
|
||||
if (XFRAME (WINDOW_FRAME (w)) != sf)
|
||||
{
|
||||
|
@ -500,7 +505,8 @@ select_window (Lisp_Object window, Lisp_Object norecord, int inhibit_point_swap)
|
|||
|
||||
select_window_1 (window, inhibit_point_swap);
|
||||
bset_last_selected_window (XBUFFER (w->contents), window);
|
||||
windows_or_buffers_changed = 24;
|
||||
if (NILP (norecord))
|
||||
wset_redisplay (w);
|
||||
|
||||
record_and_return:
|
||||
/* record_buffer can run QUIT, so make sure it is run only after we have
|
||||
|
@ -1577,8 +1583,7 @@ overriding motion of point in order to display at this exact start. */)
|
|||
/* Bug#15957. */
|
||||
w->window_end_valid = 0;
|
||||
if (w != XWINDOW (selected_window))
|
||||
/* Enforce full redisplay. FIXME: make it more selective. */
|
||||
windows_or_buffers_changed = 26;
|
||||
wset_redisplay (w);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
@ -2139,7 +2144,7 @@ add_window_to_list (struct window *w, void *user_data)
|
|||
Vwindow_list is a list, return that list. Otherwise, build a new
|
||||
list, cache it in Vwindow_list, and return that. */
|
||||
|
||||
static Lisp_Object
|
||||
Lisp_Object
|
||||
window_list (void)
|
||||
{
|
||||
if (!CONSP (Vwindow_list))
|
||||
|
@ -4138,8 +4143,9 @@ grow_mini_window (struct window *w, int delta)
|
|||
/* Grow the mini-window. */
|
||||
w->top_line = r->top_line + r->total_lines;
|
||||
w->total_lines -= XINT (value);
|
||||
/* Enforce full redisplay. FIXME: make it more selective. */
|
||||
windows_or_buffers_changed = 34;
|
||||
/* Enforce full redisplay of the frame. */
|
||||
/* FIXME: Shouldn't window--resize-root-window-vertically do it? */
|
||||
fset_redisplay (f);
|
||||
adjust_frame_glyphs (f);
|
||||
unblock_input ();
|
||||
}
|
||||
|
@ -4172,8 +4178,9 @@ shrink_mini_window (struct window *w)
|
|||
/* Shrink the mini-window. */
|
||||
w->top_line = r->top_line + r->total_lines;
|
||||
w->total_lines = 1;
|
||||
/* Enforce full redisplay. FIXME: make it more selective. */
|
||||
windows_or_buffers_changed = 35;
|
||||
/* Enforce full redisplay of the frame. */
|
||||
/* FIXME: Shouldn't window--resize-root-window-vertically do it? */
|
||||
fset_redisplay (f);
|
||||
adjust_frame_glyphs (f);
|
||||
unblock_input ();
|
||||
}
|
||||
|
|
53
src/window.h
53
src/window.h
|
@ -282,60 +282,63 @@ struct window
|
|||
int window_end_vpos;
|
||||
|
||||
/* Non-zero if this window is a minibuffer window. */
|
||||
unsigned mini : 1;
|
||||
bool mini : 1;
|
||||
|
||||
/* Meaningful only if contents is a window, non-zero if this
|
||||
internal window is used in horizontal combination. */
|
||||
unsigned horizontal : 1;
|
||||
bool horizontal : 1;
|
||||
|
||||
/* Non-zero means must regenerate mode line of this window. */
|
||||
unsigned update_mode_line : 1;
|
||||
bool update_mode_line : 1;
|
||||
|
||||
/* Non-nil if the buffer was "modified" when the window
|
||||
was last updated. */
|
||||
unsigned last_had_star : 1;
|
||||
bool last_had_star : 1;
|
||||
|
||||
/* Non-zero means current value of `start'
|
||||
was the beginning of a line when it was chosen. */
|
||||
unsigned start_at_line_beg : 1;
|
||||
bool start_at_line_beg : 1;
|
||||
|
||||
/* Non-zero means next redisplay must use the value of start
|
||||
set up for it in advance. Set by scrolling commands. */
|
||||
unsigned force_start : 1;
|
||||
bool force_start : 1;
|
||||
|
||||
/* Non-zero means we have explicitly changed the value of start,
|
||||
but that the next redisplay is not obliged to use the new value.
|
||||
This is used in Fdelete_other_windows to force a call to
|
||||
Vwindow_scroll_functions; also by Frecenter with argument. */
|
||||
unsigned optional_new_start : 1;
|
||||
bool optional_new_start : 1;
|
||||
|
||||
/* Non-zero means the cursor is currently displayed. This can be
|
||||
set to zero by functions overpainting the cursor image. */
|
||||
unsigned phys_cursor_on_p : 1;
|
||||
bool phys_cursor_on_p : 1;
|
||||
|
||||
/* 0 means cursor is logically on, 1 means it's off. Used for
|
||||
blinking cursor. */
|
||||
unsigned cursor_off_p : 1;
|
||||
bool cursor_off_p : 1;
|
||||
|
||||
/* Value of cursor_off_p as of the last redisplay. */
|
||||
unsigned last_cursor_off_p : 1;
|
||||
bool last_cursor_off_p : 1;
|
||||
|
||||
/* 1 means desired matrix has been build and window must be
|
||||
updated in update_frame. */
|
||||
unsigned must_be_updated_p : 1;
|
||||
bool must_be_updated_p : 1;
|
||||
|
||||
/* Flag indicating that this window is not a real one.
|
||||
Currently only used for menu bar windows of frames. */
|
||||
unsigned pseudo_window_p : 1;
|
||||
bool pseudo_window_p : 1;
|
||||
|
||||
/* Non-zero means fringes are drawn outside display margins.
|
||||
Otherwise draw them between margin areas and text. */
|
||||
unsigned fringes_outside_margins : 1;
|
||||
bool fringes_outside_margins : 1;
|
||||
|
||||
/* Nonzero if window_end_pos and window_end_vpos are truly valid.
|
||||
This is zero if nontrivial redisplay is preempted since in that case
|
||||
the frame image that window_end_pos did not get onto the frame. */
|
||||
unsigned window_end_valid : 1;
|
||||
bool window_end_valid : 1;
|
||||
|
||||
/* True if it needs to be redisplayed. */
|
||||
bool redisplay : 1;
|
||||
|
||||
/* Amount by which lines of this window are scrolled in
|
||||
y-direction (smooth scrolling). */
|
||||
|
@ -900,15 +903,32 @@ extern EMACS_INT command_loop_level;
|
|||
|
||||
extern EMACS_INT minibuf_level;
|
||||
|
||||
/* true if we should redraw the mode lines on the next redisplay. */
|
||||
/* Non-zero if we should redraw the mode lines on the next redisplay.
|
||||
Usually set to a unique small integer so we can track the main causes of
|
||||
full redisplays in `redisplay--mode-lines-cause'. */
|
||||
|
||||
extern int update_mode_lines;
|
||||
|
||||
/* Nonzero if window sizes or contents have changed since last
|
||||
redisplay that finished. */
|
||||
redisplay that finished. Usually set to a unique small integer so
|
||||
we can track the main causes of full redisplays in
|
||||
`redisplay--all-windows-cause'. */
|
||||
|
||||
extern int windows_or_buffers_changed;
|
||||
|
||||
/* The main redisplay routine usually only redisplays the selected-window,
|
||||
so when something's changed elsewhere, we call one of the functions below
|
||||
to indicate which other windows might also need to be redisplayed. */
|
||||
|
||||
extern void wset_redisplay (struct window *w);
|
||||
extern void fset_redisplay (struct frame *f);
|
||||
extern void bset_redisplay (struct buffer *b);
|
||||
extern void bset_update_mode_line (struct buffer *b);
|
||||
/* Call this to tell redisplay to look for other windows than selected-window
|
||||
that need to be redisplayed. Calling one of the *set_redisplay functions
|
||||
above already does it, so it's only needed in unusual cases. */
|
||||
extern void redisplay_other_windows (void);
|
||||
|
||||
/* If *ROWS or *COLS are too small a size for FRAME, set them to the
|
||||
minimum allowable size. */
|
||||
|
||||
|
@ -942,6 +962,7 @@ struct glyph *get_phys_cursor_glyph (struct window *w);
|
|||
extern Lisp_Object Qwindow_live_p;
|
||||
extern Lisp_Object Vwindow_list;
|
||||
|
||||
extern Lisp_Object window_list (void);
|
||||
extern struct window *decode_live_window (Lisp_Object);
|
||||
extern struct window *decode_any_window (Lisp_Object);
|
||||
extern bool compare_window_configurations (Lisp_Object, Lisp_Object, bool);
|
||||
|
|
316
src/xdisp.c
316
src/xdisp.c
|
@ -502,12 +502,20 @@ static Lisp_Object Vmessage_stack;
|
|||
|
||||
static bool message_enable_multibyte;
|
||||
|
||||
/* Nonzero if we should redraw the mode lines on the next redisplay. */
|
||||
/* Nonzero if we should redraw the mode lines on the next redisplay.
|
||||
If it has value REDISPLAY_SOME, then only redisplay the mode lines where
|
||||
the `redisplay' bit has been set. Otherwise, redisplay all mode lines
|
||||
(the number used is then only used to track down the cause for this
|
||||
full-redisplay). */
|
||||
|
||||
int update_mode_lines;
|
||||
|
||||
/* Nonzero if window sizes or contents have changed since last
|
||||
redisplay that finished. */
|
||||
/* Nonzero if window sizes or contents other than selected-window have changed
|
||||
since last redisplay that finished.
|
||||
If it has value REDISPLAY_SOME, then only redisplay the windows where
|
||||
the `redisplay' bit has been set. Otherwise, redisplay all windows
|
||||
(the number used is then only used to track down the cause for this
|
||||
full-redisplay). */
|
||||
|
||||
int windows_or_buffers_changed;
|
||||
|
||||
|
@ -599,6 +607,49 @@ bool help_echo_showing_p;
|
|||
CACHE = NULL; \
|
||||
} while (0)
|
||||
|
||||
/* Functions to mark elements as needing redisplay. */
|
||||
enum { REDISPLAY_SOME = 2}; /* Arbitrary choice. */
|
||||
|
||||
void redisplay_other_windows (void)
|
||||
{
|
||||
if (!windows_or_buffers_changed)
|
||||
windows_or_buffers_changed = REDISPLAY_SOME;
|
||||
}
|
||||
|
||||
void wset_redisplay (struct window *w)
|
||||
{
|
||||
redisplay_other_windows ();
|
||||
w->redisplay = true;
|
||||
}
|
||||
|
||||
void fset_redisplay (struct frame *f)
|
||||
{
|
||||
redisplay_other_windows ();
|
||||
f->redisplay = true;
|
||||
}
|
||||
|
||||
void bset_redisplay (struct buffer *b)
|
||||
{
|
||||
int count = buffer_window_count (b);
|
||||
if (count > 0)
|
||||
{
|
||||
/* ... it's visible in other window than selected, */
|
||||
if (count > 1 || b != XBUFFER (XWINDOW (selected_window)->contents))
|
||||
redisplay_other_windows ();
|
||||
/* Even if we don't set windows_or_buffers_changed, do set `redisplay'
|
||||
so that if we later set windows_or_buffers_changed, this buffer will
|
||||
not be omitted. */
|
||||
b->text->redisplay = true;
|
||||
}
|
||||
}
|
||||
|
||||
extern void bset_update_mode_line (struct buffer *b)
|
||||
{
|
||||
if (!update_mode_lines)
|
||||
update_mode_lines = REDISPLAY_SOME;
|
||||
b->text->redisplay = true;
|
||||
}
|
||||
|
||||
#ifdef GLYPH_DEBUG
|
||||
|
||||
/* Non-zero means print traces of redisplay if compiled with
|
||||
|
@ -9468,7 +9519,6 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
|
|||
ptrdiff_t point_at_end = 0;
|
||||
ptrdiff_t zv_at_end = 0;
|
||||
Lisp_Object old_deactivate_mark;
|
||||
bool shown;
|
||||
struct gcpro gcpro1;
|
||||
|
||||
old_deactivate_mark = Vdeactivate_mark;
|
||||
|
@ -9482,8 +9532,8 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
|
|||
|
||||
Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
|
||||
|
||||
if (newbuffer &&
|
||||
!NILP (Ffboundp (intern ("messages-buffer-mode"))))
|
||||
if (newbuffer
|
||||
&& !NILP (Ffboundp (intern ("messages-buffer-mode"))))
|
||||
call0 (intern ("messages-buffer-mode"));
|
||||
}
|
||||
|
||||
|
@ -9625,18 +9675,17 @@ message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
|
|||
unchain_marker (XMARKER (oldbegv));
|
||||
unchain_marker (XMARKER (oldzv));
|
||||
|
||||
shown = buffer_window_count (current_buffer) > 0;
|
||||
set_buffer_internal (oldbuf);
|
||||
/* We called insert_1_both above with its 5th argument (PREPARE)
|
||||
zero, which prevents insert_1_both from calling
|
||||
prepare_to_modify_buffer, which in turns prevents us from
|
||||
incrementing windows_or_buffers_changed even if *Messages* is
|
||||
shown in some window. So we must manually incrementing
|
||||
shown in some window. So we must manually set
|
||||
windows_or_buffers_changed here to make up for that. */
|
||||
if (shown)
|
||||
windows_or_buffers_changed = 41;
|
||||
else
|
||||
windows_or_buffers_changed = old_windows_or_buffers_changed;
|
||||
bset_redisplay (current_buffer);
|
||||
|
||||
set_buffer_internal (oldbuf);
|
||||
|
||||
message_log_need_newline = !nlflag;
|
||||
Vdeactivate_mark = old_deactivate_mark;
|
||||
}
|
||||
|
@ -10325,15 +10374,8 @@ resize_echo_area_exactly (void)
|
|||
&& WINDOWP (echo_area_window))
|
||||
{
|
||||
struct window *w = XWINDOW (echo_area_window);
|
||||
int resized_p;
|
||||
Lisp_Object resize_exactly;
|
||||
|
||||
if (minibuf_level == 0)
|
||||
resize_exactly = Qt;
|
||||
else
|
||||
resize_exactly = Qnil;
|
||||
|
||||
resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
|
||||
Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
|
||||
int resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
|
||||
(intptr_t) w, resize_exactly);
|
||||
if (resized_p)
|
||||
{
|
||||
|
@ -10714,7 +10756,6 @@ clear_garbaged_frames (void)
|
|||
if (frame_garbaged)
|
||||
{
|
||||
Lisp_Object tail, frame;
|
||||
int changed_count = 0;
|
||||
|
||||
FOR_EACH_FRAME (tail, frame)
|
||||
{
|
||||
|
@ -10726,15 +10767,13 @@ clear_garbaged_frames (void)
|
|||
redraw_frame (f);
|
||||
else
|
||||
clear_current_matrices (f);
|
||||
changed_count++;
|
||||
f->garbaged = 0;
|
||||
f->resized_p = 0;
|
||||
fset_redisplay (f);
|
||||
f->garbaged = false;
|
||||
f->resized_p = false;
|
||||
}
|
||||
}
|
||||
|
||||
frame_garbaged = 0;
|
||||
if (changed_count)
|
||||
windows_or_buffers_changed = 43;
|
||||
frame_garbaged = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10822,11 +10861,11 @@ echo_area_display (int update_frame_p)
|
|||
redisplay displays the minibuffer, so that the cursor will
|
||||
be replaced with what the minibuffer wants. */
|
||||
if (cursor_in_echo_area)
|
||||
windows_or_buffers_changed = 45;
|
||||
wset_redisplay (XWINDOW (mini_window));
|
||||
}
|
||||
}
|
||||
else if (!EQ (mini_window, selected_window))
|
||||
windows_or_buffers_changed = 46;
|
||||
wset_redisplay (XWINDOW (mini_window));
|
||||
|
||||
/* Last displayed message is now the current message. */
|
||||
echo_area_buffer[1] = echo_area_buffer[0];
|
||||
|
@ -10842,16 +10881,6 @@ echo_area_display (int update_frame_p)
|
|||
return window_height_changed_p;
|
||||
}
|
||||
|
||||
/* Nonzero if the current window's buffer is shown in more than one
|
||||
window and was modified since last redisplay. */
|
||||
|
||||
static int
|
||||
buffer_shared_and_changed (void)
|
||||
{
|
||||
return (buffer_window_count (current_buffer) > 1
|
||||
&& UNCHANGED_MODIFIED < MODIFF);
|
||||
}
|
||||
|
||||
/* Nonzero if W's buffer was changed but not saved. */
|
||||
|
||||
static int
|
||||
|
@ -11171,9 +11200,13 @@ x_consider_frame_title (Lisp_Object frame)
|
|||
static void
|
||||
prepare_menu_bars (void)
|
||||
{
|
||||
int all_windows;
|
||||
bool all_windows = windows_or_buffers_changed || update_mode_lines;
|
||||
bool some_windows
|
||||
= (windows_or_buffers_changed == 0
|
||||
|| windows_or_buffers_changed == REDISPLAY_SOME)
|
||||
&& (update_mode_lines == 0
|
||||
|| update_mode_lines == REDISPLAY_SOME);
|
||||
struct gcpro gcpro1, gcpro2;
|
||||
struct frame *f;
|
||||
Lisp_Object tooltip_frame;
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
|
@ -11182,17 +11215,45 @@ prepare_menu_bars (void)
|
|||
tooltip_frame = Qnil;
|
||||
#endif
|
||||
|
||||
if (FUNCTIONP (Vpre_redisplay_function))
|
||||
{
|
||||
Lisp_Object windows = all_windows ? Qt : Qnil;
|
||||
if (all_windows && some_windows)
|
||||
{
|
||||
Lisp_Object ws = window_list ();
|
||||
for (windows = Qnil; CONSP (ws); ws = XCDR (ws))
|
||||
{
|
||||
Lisp_Object this = XCAR (ws);
|
||||
struct window *w = XWINDOW (this);
|
||||
if (w->redisplay
|
||||
|| XFRAME (w->frame)->redisplay
|
||||
|| XBUFFER (w->contents)->text->redisplay)
|
||||
{
|
||||
windows = Fcons (this, windows);
|
||||
}
|
||||
}
|
||||
}
|
||||
safe_call1 (Vpre_redisplay_function, windows);
|
||||
}
|
||||
|
||||
/* Update all frame titles based on their buffer names, etc. We do
|
||||
this before the menu bars so that the buffer-menu will show the
|
||||
up-to-date frame titles. */
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
if (windows_or_buffers_changed || update_mode_lines)
|
||||
if (all_windows)
|
||||
{
|
||||
Lisp_Object tail, frame;
|
||||
|
||||
FOR_EACH_FRAME (tail, frame)
|
||||
{
|
||||
f = XFRAME (frame);
|
||||
struct frame *f = XFRAME (frame);
|
||||
struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
|
||||
if (some_windows
|
||||
&& !f->redisplay
|
||||
&& !w->redisplay
|
||||
&& !XBUFFER (w->contents)->text->redisplay)
|
||||
continue;
|
||||
|
||||
if (!EQ (frame, tooltip_frame)
|
||||
&& (FRAME_ICONIFIED_P (f)
|
||||
|| FRAME_VISIBLE_P (f) == 1
|
||||
|
@ -11213,12 +11274,6 @@ prepare_menu_bars (void)
|
|||
|
||||
/* Update the menu bar item lists, if appropriate. This has to be
|
||||
done before any actual redisplay or generation of display lines. */
|
||||
all_windows = (update_mode_lines
|
||||
|| buffer_shared_and_changed ()
|
||||
|| windows_or_buffers_changed);
|
||||
|
||||
if (FUNCTIONP (Vpre_redisplay_function))
|
||||
safe_call1 (Vpre_redisplay_function, all_windows ? Qt : Qnil);
|
||||
|
||||
if (all_windows)
|
||||
{
|
||||
|
@ -11232,12 +11287,19 @@ prepare_menu_bars (void)
|
|||
|
||||
FOR_EACH_FRAME (tail, frame)
|
||||
{
|
||||
f = XFRAME (frame);
|
||||
struct frame *f = XFRAME (frame);
|
||||
struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
|
||||
|
||||
/* Ignore tooltip frame. */
|
||||
if (EQ (frame, tooltip_frame))
|
||||
continue;
|
||||
|
||||
if (some_windows
|
||||
&& !f->redisplay
|
||||
&& !w->redisplay
|
||||
&& !XBUFFER (w->contents)->text->redisplay)
|
||||
continue;
|
||||
|
||||
/* If a window on this frame changed size, report that to
|
||||
the user and clear the size-change flag. */
|
||||
if (FRAME_WINDOW_SIZES_CHANGED (f))
|
||||
|
@ -12860,6 +12922,27 @@ reconsider_clip_changes (struct window *w)
|
|||
}
|
||||
}
|
||||
|
||||
void propagate_buffer_redisplay (void)
|
||||
{ /* Resetting b->text->redisplay is problematic!
|
||||
We can't just reset it in the case that some window that displays
|
||||
it has not been redisplayed; and such a window can stay
|
||||
unredisplayed for a long time if it's currently invisible.
|
||||
But we do want to reset it at the end of redisplay otherwise
|
||||
its displayed windows will keep being redisplayed over and over
|
||||
again.
|
||||
So we copy all b->text->redisplay flags up to their windows here,
|
||||
such that mark_window_display_accurate can safely reset
|
||||
b->text->redisplay. */
|
||||
Lisp_Object ws = window_list ();
|
||||
for (; CONSP (ws); ws = XCDR (ws))
|
||||
{
|
||||
struct window *thisw = XWINDOW (XCAR (ws));
|
||||
struct buffer *thisb = XBUFFER (thisw->contents);
|
||||
if (thisb->text->redisplay)
|
||||
thisw->redisplay = true;
|
||||
}
|
||||
}
|
||||
|
||||
#define STOP_POLLING \
|
||||
do { if (! polling_stopped_here) stop_polling (); \
|
||||
polling_stopped_here = 1; } while (0)
|
||||
|
@ -12956,7 +13039,6 @@ redisplay_internal (void)
|
|||
/* Since frames on a single ASCII terminal share the same
|
||||
display area, displaying a different frame means redisplay
|
||||
the whole thing. */
|
||||
windows_or_buffers_changed = 48;
|
||||
SET_FRAME_GARBAGED (sf);
|
||||
#ifndef DOS_NT
|
||||
set_tty_color_mode (FRAME_TTY (sf), sf);
|
||||
|
@ -13005,9 +13087,6 @@ redisplay_internal (void)
|
|||
if (NILP (Vmemory_full))
|
||||
prepare_menu_bars ();
|
||||
|
||||
if (windows_or_buffers_changed && !update_mode_lines)
|
||||
update_mode_lines = 32;
|
||||
|
||||
reconsider_clip_changes (w);
|
||||
|
||||
/* In most cases selected window displays current buffer. */
|
||||
|
@ -13016,27 +13095,12 @@ redisplay_internal (void)
|
|||
{
|
||||
/* Detect case that we need to write or remove a star in the mode line. */
|
||||
if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
|
||||
{
|
||||
w->update_mode_line = 1;
|
||||
if (buffer_shared_and_changed ())
|
||||
update_mode_lines = 33;
|
||||
}
|
||||
|
||||
if (mode_line_update_needed (w))
|
||||
w->update_mode_line = 1;
|
||||
}
|
||||
|
||||
consider_all_windows_p = (update_mode_lines
|
||||
|| buffer_shared_and_changed ());
|
||||
|
||||
/* If specs for an arrow have changed, do thorough redisplay
|
||||
to ensure we remove any arrow that should no longer exist. */
|
||||
if (overlay_arrows_changed_p ())
|
||||
{
|
||||
consider_all_windows_p = true;
|
||||
windows_or_buffers_changed = 49;
|
||||
}
|
||||
|
||||
/* Normally the message* functions will have already displayed and
|
||||
updated the echo area, but the frame may have been trashed, or
|
||||
the update may have been preempted, so display the echo area
|
||||
|
@ -13066,8 +13130,6 @@ redisplay_internal (void)
|
|||
|
||||
if (window_height_changed_p)
|
||||
{
|
||||
consider_all_windows_p = true;
|
||||
update_mode_lines = 34;
|
||||
windows_or_buffers_changed = 50;
|
||||
|
||||
/* If window configuration was changed, frames may have been
|
||||
|
@ -13083,13 +13145,6 @@ redisplay_internal (void)
|
|||
/* Resized active mini-window to fit the size of what it is
|
||||
showing if its contents might have changed. */
|
||||
must_finish = 1;
|
||||
/* FIXME: this causes all frames to be updated, which seems unnecessary
|
||||
since only the current frame needs to be considered. This function
|
||||
needs to be rewritten with two variables, consider_all_windows and
|
||||
consider_all_frames. */
|
||||
consider_all_windows_p = true;
|
||||
windows_or_buffers_changed = 51;
|
||||
update_mode_lines = 35;
|
||||
|
||||
/* If window configuration was changed, frames may have been
|
||||
marked garbaged. Clear them or we will experience
|
||||
|
@ -13097,23 +13152,29 @@ redisplay_internal (void)
|
|||
clear_garbaged_frames ();
|
||||
}
|
||||
|
||||
if (VECTORP (Vredisplay__all_windows_cause)
|
||||
&& windows_or_buffers_changed >= 0
|
||||
&& windows_or_buffers_changed < ASIZE (Vredisplay__all_windows_cause)
|
||||
&& INTEGERP (AREF (Vredisplay__all_windows_cause,
|
||||
windows_or_buffers_changed)))
|
||||
ASET (Vredisplay__all_windows_cause, windows_or_buffers_changed,
|
||||
make_number (1 + XINT (AREF (Vredisplay__all_windows_cause,
|
||||
windows_or_buffers_changed))));
|
||||
if (windows_or_buffers_changed && !update_mode_lines)
|
||||
/* Code that sets windows_or_buffers_changed doesn't distinguish whether
|
||||
only the windows's contents needs to be refreshed, or whether the
|
||||
mode-lines also need a refresh. */
|
||||
update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
|
||||
? REDISPLAY_SOME : 32);
|
||||
|
||||
if (VECTORP (Vredisplay__mode_lines_cause)
|
||||
&& update_mode_lines >= 0
|
||||
&& update_mode_lines < ASIZE (Vredisplay__mode_lines_cause)
|
||||
&& INTEGERP (AREF (Vredisplay__mode_lines_cause,
|
||||
update_mode_lines)))
|
||||
ASET (Vredisplay__mode_lines_cause, update_mode_lines,
|
||||
make_number (1 + XINT (AREF (Vredisplay__mode_lines_cause,
|
||||
update_mode_lines))));
|
||||
/* If specs for an arrow have changed, do thorough redisplay
|
||||
to ensure we remove any arrow that should no longer exist. */
|
||||
if (overlay_arrows_changed_p ())
|
||||
/* Apparently, this is the only case where we update other windows,
|
||||
without updating other mode-lines. */
|
||||
windows_or_buffers_changed = 49;
|
||||
|
||||
consider_all_windows_p = (update_mode_lines
|
||||
|| windows_or_buffers_changed);
|
||||
|
||||
#define AINC(a,i) \
|
||||
if (VECTORP (a) && i >= 0 && i < ASIZE (a) && INTEGERP (AREF (a, i))) \
|
||||
ASET (a, i, make_number (1 + XINT (AREF (a, i))))
|
||||
|
||||
AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
|
||||
AINC (Vredisplay__mode_lines_cause, update_mode_lines);
|
||||
|
||||
/* Optimize the case that only the line containing the cursor in the
|
||||
selected window has changed. Variables starting with this_ are
|
||||
|
@ -13330,6 +13391,8 @@ redisplay_internal (void)
|
|||
FOR_EACH_FRAME (tail, frame)
|
||||
XFRAME (frame)->updated_p = 0;
|
||||
|
||||
propagate_buffer_redisplay ();
|
||||
|
||||
FOR_EACH_FRAME (tail, frame)
|
||||
{
|
||||
struct frame *f = XFRAME (frame);
|
||||
|
@ -13344,9 +13407,12 @@ redisplay_internal (void)
|
|||
|
||||
if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
|
||||
{
|
||||
bool gcscrollbars
|
||||
/* Only GC scollbars when we redisplay the whole frame. */
|
||||
= f->redisplay || windows_or_buffers_changed != REDISPLAY_SOME;
|
||||
/* Mark all the scroll bars to be removed; we'll redeem
|
||||
the ones we want when we redisplay their windows. */
|
||||
if (FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
|
||||
if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
|
||||
FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
|
||||
|
||||
if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
|
||||
|
@ -13358,7 +13424,7 @@ redisplay_internal (void)
|
|||
|
||||
/* Any scroll bars which redisplay_windows should have
|
||||
nuked should now go away. */
|
||||
if (FRAME_TERMINAL (f)->judge_scroll_bars_hook)
|
||||
if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
|
||||
FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
|
||||
|
||||
if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
|
||||
|
@ -13413,6 +13479,7 @@ redisplay_internal (void)
|
|||
struct frame *f = XFRAME (frame);
|
||||
if (f->updated_p)
|
||||
{
|
||||
f->redisplay = false;
|
||||
mark_window_display_accurate (f->root_window, 1);
|
||||
if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
|
||||
FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
|
||||
|
@ -13502,6 +13569,11 @@ redisplay_internal (void)
|
|||
{
|
||||
/* This has already been done above if
|
||||
consider_all_windows_p is set. */
|
||||
if (XBUFFER (w->contents)->text->redisplay
|
||||
&& buffer_window_count (XBUFFER (w->contents)) > 1)
|
||||
/* This can happen if b->text->redisplay was set during
|
||||
jit-lock. */
|
||||
propagate_buffer_redisplay ();
|
||||
mark_window_display_accurate_1 (w, 1);
|
||||
|
||||
/* Say overlay arrows are up to date. */
|
||||
|
@ -13535,12 +13607,7 @@ redisplay_internal (void)
|
|||
|
||||
FOR_EACH_FRAME (tail, frame)
|
||||
{
|
||||
int this_is_visible = 0;
|
||||
|
||||
if (XFRAME (frame)->visible)
|
||||
this_is_visible = 1;
|
||||
|
||||
if (this_is_visible)
|
||||
new_count++;
|
||||
}
|
||||
|
||||
|
@ -13639,8 +13706,13 @@ mark_window_display_accurate_1 (struct window *w, int accurate_p)
|
|||
|
||||
if (accurate_p)
|
||||
{
|
||||
b->clip_changed = 0;
|
||||
b->prevent_redisplay_optimizations_p = 0;
|
||||
b->clip_changed = false;
|
||||
b->prevent_redisplay_optimizations_p = false;
|
||||
eassert (buffer_window_count (b) > 0);
|
||||
/* Resetting b->text->redisplay is problematic!
|
||||
In order to make it safer to do it here, redisplay_internal must
|
||||
have copied all b->text->redisplay to their respective windows. */
|
||||
b->text->redisplay = false;
|
||||
|
||||
BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
|
||||
BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
|
||||
|
@ -13659,9 +13731,11 @@ mark_window_display_accurate_1 (struct window *w, int accurate_p)
|
|||
else
|
||||
w->last_point = marker_position (w->pointm);
|
||||
|
||||
w->window_end_valid = 1;
|
||||
w->update_mode_line = 0;
|
||||
w->window_end_valid = true;
|
||||
w->update_mode_line = false;
|
||||
}
|
||||
|
||||
w->redisplay = !accurate_p;
|
||||
}
|
||||
|
||||
|
||||
|
@ -14314,9 +14388,9 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
|
|||
occlude point. Only set w->cursor if we found a better
|
||||
approximation to the cursor position than we have from previously
|
||||
examined candidate rows belonging to the same continued line. */
|
||||
if (/* we already have a candidate row */
|
||||
if (/* We already have a candidate row. */
|
||||
w->cursor.vpos >= 0
|
||||
/* that candidate is not the row we are processing */
|
||||
/* That candidate is not the row we are processing. */
|
||||
&& MATRIX_ROW (matrix, w->cursor.vpos) != row
|
||||
/* Make sure cursor.vpos specifies a row whose start and end
|
||||
charpos occlude point, and it is valid candidate for being a
|
||||
|
@ -14327,30 +14401,30 @@ set_cursor_from_row (struct window *w, struct glyph_row *row,
|
|||
&& pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
|
||||
&& cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
|
||||
{
|
||||
struct glyph *g1 =
|
||||
MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
|
||||
struct glyph *g1
|
||||
= MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
|
||||
|
||||
/* Don't consider glyphs that are outside TEXT_AREA. */
|
||||
if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
|
||||
return 0;
|
||||
/* Keep the candidate whose buffer position is the closest to
|
||||
point or has the `cursor' property. */
|
||||
if (/* previous candidate is a glyph in TEXT_AREA of that row */
|
||||
if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
|
||||
w->cursor.hpos >= 0
|
||||
&& w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
|
||||
&& ((BUFFERP (g1->object)
|
||||
&& (g1->charpos == pt_old /* an exact match always wins */
|
||||
&& (g1->charpos == pt_old /* An exact match always wins. */
|
||||
|| (BUFFERP (glyph->object)
|
||||
&& eabs (g1->charpos - pt_old)
|
||||
< eabs (glyph->charpos - pt_old))))
|
||||
/* previous candidate is a glyph from a string that has
|
||||
a non-nil `cursor' property */
|
||||
/* Previous candidate is a glyph from a string that has
|
||||
a non-nil `cursor' property. */
|
||||
|| (STRINGP (g1->object)
|
||||
&& (!NILP (Fget_char_property (make_number (g1->charpos),
|
||||
Qcursor, g1->object))
|
||||
/* previous candidate is from the same display
|
||||
/* Previous candidate is from the same display
|
||||
string as this one, and the display string
|
||||
came from a text property */
|
||||
came from a text property. */
|
||||
|| (EQ (g1->object, glyph->object)
|
||||
&& string_from_text_prop)
|
||||
/* this candidate is from newline and its
|
||||
|
@ -15329,6 +15403,16 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
|
|||
*w->desired_matrix->method = 0;
|
||||
#endif
|
||||
|
||||
if (!just_this_one_p
|
||||
&& (update_mode_lines == REDISPLAY_SOME
|
||||
|| update_mode_lines == 0)
|
||||
&& (windows_or_buffers_changed == REDISPLAY_SOME
|
||||
|| windows_or_buffers_changed == 0)
|
||||
&& !w->redisplay
|
||||
&& !f->redisplay
|
||||
&& !buffer->text->redisplay)
|
||||
return;
|
||||
|
||||
/* Make sure that both W's markers are valid. */
|
||||
eassert (XMARKER (w->start)->buffer == buffer);
|
||||
eassert (XMARKER (w->pointm)->buffer == buffer);
|
||||
|
|
|
@ -6202,7 +6202,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
|
|||
SET_FRAME_GARBAGED (f);
|
||||
|
||||
/* Check if fullscreen was specified before we where mapped the
|
||||
first time, i.e. from the command line. */
|
||||
first time, i.e. from the command line. */
|
||||
if (!f->output_data.x->has_been_visible)
|
||||
x_check_fullscreen (f);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue