GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
static bool set_cursor_from_row (struct window *, struct glyph_row *,
struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
int, int);
+static bool cursor_row_fully_visible_p (struct window *, bool, bool);
static bool update_menu_bar (struct frame *, bool, bool);
static bool try_window_reusing_current_matrix (struct window *);
static int try_window_id (struct window *);
character properties needed for reordering are not yet
available. */
it->bidi_p =
- NILP (Vpurify_flag)
+ !redisplay__inhibit_bidi
&& !NILP (BVAR (current_buffer, bidi_display_reordering))
&& it->multibyte_p;
loading loadup.el, as the necessary character property tables are
not yet available. */
it->bidi_p =
- NILP (Vpurify_flag)
+ !redisplay__inhibit_bidi
&& !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
if (s == NULL)
{
ptrdiff_t ignore;
int next_face_id;
+ bool text_from_string = false;
+ /* Normally, the next buffer location is stored in
+ IT->current.pos... */
struct text_pos pos = it->current.pos;
- /* For a string from a display property, the next
- buffer position is stored in the 'position'
+ /* ...but for a string from a display property, the
+ next buffer position is stored in the 'position'
member of the iteration stack slot below the
current one, see handle_single_display_spec. By
- contrast, it->current.pos was is not yet updated
- to point to that buffer position; that will
- happen in pop_it, after we finish displaying the
- current string. Note that we already checked
- above that it->sp is positive, so subtracting one
- from it is safe. */
+ contrast, it->current.pos was not yet updated to
+ point to that buffer position; that will happen
+ in pop_it, after we finish displaying the current
+ string. Note that we already checked above that
+ it->sp is positive, so subtracting one from it is
+ safe. */
if (it->from_disp_prop_p)
- pos = (it->stack + it->sp - 1)->position;
+ {
+ int stackp = it->sp - 1;
+
+ /* Find the stack level with data from buffer. */
+ while (stackp >= 0
+ && STRINGP ((it->stack + stackp)->string))
+ stackp--;
+ if (stackp < 0)
+ {
+ /* If no stack slot was found for iterating
+ a buffer, we are displaying text from a
+ string, most probably the mode line or
+ the header line, and that string has a
+ display string on some of its
+ characters. */
+ text_from_string = true;
+ pos = it->stack[it->sp - 1].position;
+ }
+ else
+ pos = (it->stack + stackp)->position;
+ }
else
INC_TEXT_POS (pos, it->multibyte_p);
- if (CHARPOS (pos) >= ZV)
+ if (text_from_string)
+ {
+ Lisp_Object base_string = it->stack[it->sp - 1].string;
+
+ if (CHARPOS (pos) >= SCHARS (base_string) - 1)
+ it->end_of_box_run_p = true;
+ else
+ {
+ next_face_id
+ = face_at_string_position (it->w, base_string,
+ CHARPOS (pos), 0,
+ &ignore, face_id, false);
+ it->end_of_box_run_p
+ = (FACE_FROM_ID (it->f, next_face_id)->box
+ == FACE_NO_BOX);
+ }
+ }
+ else if (CHARPOS (pos) >= ZV)
it->end_of_box_run_p = true;
else
{
- next_face_id = face_at_buffer_position
- (it->w, CHARPOS (pos), &ignore,
- CHARPOS (pos) + TEXT_PROP_DISTANCE_LIMIT, false, -1);
+ next_face_id =
+ face_at_buffer_position (it->w, CHARPOS (pos), &ignore,
+ CHARPOS (pos)
+ + TEXT_PROP_DISTANCE_LIMIT,
+ false, -1);
it->end_of_box_run_p
= (FACE_FROM_ID (it->f, next_face_id)->box
== FACE_NO_BOX);
suitable buffer from echo_buffer[] and clear it.
If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
- that the current message becomes the last displayed one, make
- choose a suitable buffer for echo_area_buffer[0], and clear it.
+ that the current message becomes the last displayed one, choose a
+ suitable buffer for echo_area_buffer[0], and clear it.
Value is what FN returns. */
echo_area_buffer[this_one] = Qnil;
}
- /* Choose a suitable buffer from echo_buffer[] is we don't
+ /* Choose a suitable buffer from echo_buffer[] if we don't
have one. */
if (NILP (echo_area_buffer[this_one]))
{
if (frame_garbaged)
{
Lisp_Object tail, frame;
+ struct frame *sf = SELECTED_FRAME ();
FOR_EACH_FRAME (tail, frame)
{
if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
{
- if (f->resized_p)
+ if (f->resized_p
+ /* It makes no sense to redraw a non-selected TTY
+ frame, since that will actually clear the
+ selected frame, and might leave the selected
+ frame with corrupted display, if it happens not
+ to be marked garbaged. */
+ && !(f != sf && (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))))
redraw_frame (f);
else
clear_current_matrices (f);
eassert (this_line_vpos == it.vpos);
eassert (this_line_y == it.current_y);
set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
+ if (cursor_row_fully_visible_p (w, false, true))
+ {
#ifdef GLYPH_DEBUG
- *w->desired_matrix->method = 0;
- debug_method_add (w, "optimization 3");
+ *w->desired_matrix->method = 0;
+ debug_method_add (w, "optimization 3");
#endif
- goto update;
+ goto update;
+ }
+ else
+ goto cancel;
}
else
goto cancel;
if (scroll_conservatively > SCROLL_LIMIT)
{
int window_total_lines
- = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height;
+ = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
int margin =
scroll_margin > 0
? min (scroll_margin, window_total_lines / 4)
ignore_mouse_drag_p = true;
#endif
}
+ ptrdiff_t count1 = SPECPDL_INDEX ();
+ /* x_consider_frame_title calls select-frame, which calls
+ resize_mini_window, which could resize the mini-window and by
+ that undo the effect of this redisplay cycle wrt minibuffer
+ and echo-area display. Binding inhibit-redisplay to t makes
+ the call to resize_mini_window a no-op, thus avoiding the
+ adverse side effects. */
+ specbind (Qinhibit_redisplay, Qt);
x_consider_frame_title (w->frame);
+ unbind_to (count1, Qnil);
#endif
}
|| NILP (BVAR (buf, enable_multibyte_characters))
/* When we are loading loadup.el, the character property tables
needed for bidi iteration are not yet available. */
- || !NILP (Vpurify_flag))
+ || redisplay__inhibit_bidi)
return Qleft_to_right;
else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
return BVAR (buf, bidi_paragraph_direction);
/* When we are loading loadup.el, the character property
tables needed for bidi iteration are not yet
available. */
- || !NILP (Vpurify_flag))
+ || redisplay__inhibit_bidi)
return Qnil;
validate_subarray (object, from, to, SCHARS (object), &from_pos, &to_pos);
/* When we are loading loadup.el, the character property
tables needed for bidi iteration are not yet
available. */
- || !NILP (Vpurify_flag))
+ || redisplay__inhibit_bidi)
return Qnil;
set_buffer_temp (buf);
glyph->object = it->object;
if (it->pixel_width > 0)
{
+ eassert (it->pixel_width <= SHRT_MAX);
glyph->pixel_width = it->pixel_width;
glyph->padding_p = false;
}
}
glyph->charpos = it->cmp_it.charpos;
glyph->object = it->object;
+ eassert (it->pixel_width <= SHRT_MAX);
glyph->pixel_width = it->pixel_width;
glyph->ascent = it->ascent;
glyph->descent = it->descent;
{
glyph->charpos = CHARPOS (it->position);
glyph->object = it->object;
- glyph->pixel_width = it->pixel_width;
+ glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
glyph->ascent = glyph_ascent;
glyph->descent = it->descent;
glyph->voffset = it->voffset;
{
glyph->charpos = CHARPOS (it->position);
glyph->object = it->object;
- glyph->pixel_width = it->pixel_width;
+ glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
glyph->ascent = glyph_ascent;
glyph->descent = it->descent;
glyph->voffset = it->voffset;
}
glyph->charpos = CHARPOS (it->position);
glyph->object = object;
- glyph->pixel_width = width;
+ /* FIXME: It would be better to use TYPE_MAX here, but
+ __typeof__ is not portable enough... */
+ glyph->pixel_width = clip_to_bounds (-1, width, SHRT_MAX);
glyph->ascent = ascent;
glyph->descent = height - ascent;
glyph->voffset = it->voffset;
}
glyph->charpos = CHARPOS (it->position);
glyph->object = it->object;
+ eassert (it->pixel_width <= SHRT_MAX);
glyph->pixel_width = it->pixel_width;
glyph->ascent = it->ascent;
glyph->descent = it->descent;
Vtruncate_partial_width_windows,
doc: /* Non-nil means truncate lines in windows narrower than the frame.
For an integer value, truncate lines in each window narrower than the
-full frame width, provided the window width is less than that integer;
-otherwise, respect the value of `truncate-lines'.
+full frame width, provided the total window width in column units is less
+than that integer; otherwise, respect the value of `truncate-lines'.
+The total width of the window is as returned by `window-total-width', it
+includes the fringes, the continuation and truncation glyphs, the
+display margins (if any), and the scroll bar
For any other non-nil value, truncate lines in all windows that do
not span the full frame width.
DEFVAR_LISP ("frame-title-format", Vframe_title_format,
doc: /* Template for displaying the title bar of visible frames.
-(Assuming the window manager supports this feature.)
+\(Assuming the window manager supports this feature.)
This variable has the same structure as `mode-line-format', except that
the %c and %l constructs are ignored. It is used only on frames for
DEFVAR_LISP ("icon-title-format", Vicon_title_format,
doc: /* Template for displaying the title bar of an iconified frame.
-(Assuming the window manager supports this feature.)
+\(Assuming the window manager supports this feature.)
This variable has the same structure as `mode-line-format' (which see),
and is used only on frames for which no explicit name has been set
-(see `modify-frame-parameters'). */);
+\(see `modify-frame-parameters'). */);
Vicon_title_format
= Vframe_title_format
= listn (CONSTYPE_PURE, 3,
A value of `grow-only', the default, means let mini-windows grow only;
they return to their normal size when the minibuffer is closed, or the
echo area becomes empty. */);
- Vresize_mini_windows = Qgrow_only;
+ /* Contrary to the doc string, we initialize this to nil, so that
+ loading loadup.el won't try to resize windows before loading
+ window.el, where some functions we need to call for this live.
+ We assign the 'grow-only' value right after loading window.el
+ during loadup. */
+ Vresize_mini_windows = Qnil;
DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
doc: /* Alist specifying how to blink the cursor off.
DEFVAR_LISP ("redisplay--variables", Vredisplay__variables,
doc: /* A hash-table of variables changing which triggers a thorough redisplay. */);
Vredisplay__variables = Qnil;
+
+ DEFVAR_BOOL ("redisplay--inhibit-bidi", redisplay__inhibit_bidi,
+ doc: /* Non-nil means it is not safe to attempt bidi reordering for display. */);
+ /* Initialize to t, since we need to disable reordering until
+ loadup.el successfully loads charprop.el. */
+ redisplay__inhibit_bidi = true;
}