X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/f01684313faa9803ddc69e71b66d9a469f955348..20038f8ab75dd1551412a43cd58520c483c22921:/src/xdisp.c diff --git a/src/xdisp.c b/src/xdisp.c index d589080ac4..b8dcdcec41 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -1321,6 +1321,11 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, if (CHARPOS (top) > ZV) SET_TEXT_POS (top, BEGV, BEGV_BYTE); + /* If the top of the window is after CHARPOS, the latter is surely + not visible. */ + if (charpos >= 0 && CHARPOS (top) > charpos) + return visible_p; + /* Compute exact mode line heights. */ if (WINDOW_WANTS_MODELINE_P (w)) w->mode_line_height @@ -1813,7 +1818,7 @@ estimate_mode_line_height (struct frame *f, enum face_id face_id) cache and mode line face are not yet initialized. */ if (FRAME_FACE_CACHE (f)) { - struct face *face = FACE_OPT_FROM_ID (f, face_id); + struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); if (face) { if (face->font) @@ -2836,11 +2841,7 @@ init_iterator (struct it *it, struct window *w, frames when the fringes are turned off. But leave the dimensions zero for tooltip frames, as these glyphs look ugly there and also sabotage calculations of tooltip dimensions in x-show-tip. */ -#ifdef HAVE_WINDOW_SYSTEM - if (!(FRAME_WINDOW_P (it->f) - && FRAMEP (tip_frame) - && it->f == XFRAME (tip_frame))) -#endif + if (!FRAME_TOOLTIP_P (it->f)) { if (it->line_wrap == TRUNCATE) { @@ -2918,7 +2919,7 @@ init_iterator (struct it *it, struct window *w, /* If we have a boxed mode line, make the first character appear with a left box line. */ - face = FACE_OPT_FROM_ID (it->f, remapped_base_face_id); + face = FACE_FROM_ID_OR_NULL (it->f, remapped_base_face_id); if (face && face->box != FACE_NO_BOX) it->start_of_box_run_p = true; } @@ -3877,9 +3878,9 @@ handle_face_prop (struct it *it) { struct face *new_face = FACE_FROM_ID (it->f, new_face_id); /* If it->face_id is -1, old_face below will be NULL, see - the definition of FACE_OPT_FROM_ID. This will happen if this - is the initial call that gets the face. */ - struct face *old_face = FACE_OPT_FROM_ID (it->f, it->face_id); + the definition of FACE_FROM_ID_OR_NULL. This will happen + if this is the initial call that gets the face. */ + struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); /* If the value of face_id of the iterator is -1, we have to look in front of IT's position and see whether there is a @@ -3888,7 +3889,7 @@ handle_face_prop (struct it *it) { int prev_face_id = face_before_it_pos (it); - old_face = FACE_OPT_FROM_ID (it->f, prev_face_id); + old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id); } /* If the new face has a box, but the old face does not, @@ -3988,7 +3989,7 @@ handle_face_prop (struct it *it) if (new_face_id != it->face_id) { struct face *new_face = FACE_FROM_ID (it->f, new_face_id); - struct face *old_face = FACE_OPT_FROM_ID (it->f, it->face_id); + struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); /* If new face has a box but old face hasn't, this is the start of a run of characters with box, i.e. it has a @@ -5017,8 +5018,6 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, || EQ (XCAR (spec), Qright_fringe)) && CONSP (XCDR (spec))) { - int fringe_bitmap; - if (it) { if (!FRAME_WINDOW_P (it->f)) @@ -5043,8 +5042,8 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object, #ifdef HAVE_WINDOW_SYSTEM value = XCAR (XCDR (spec)); - if (!SYMBOLP (value) - || !(fringe_bitmap = lookup_fringe_bitmap (value))) + int fringe_bitmap = SYMBOLP (value) ? lookup_fringe_bitmap (value) : 0; + if (! fringe_bitmap) /* If we return here, POSITION has been advanced across the text with this property. */ { @@ -6097,7 +6096,7 @@ pop_it (struct it *it) break; case GET_FROM_STRING: { - struct face *face = FACE_OPT_FROM_ID (it->f, it->face_id); + struct face *face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); /* Restore the face_box_p flag, since it could have been overwritten by the face of the object that we just finished @@ -6778,7 +6777,8 @@ static next_element_function const get_next_element[NUM_IT_METHODS] = || ((IT)->cmp_it.stop_pos == (CHARPOS) \ && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \ END_CHARPOS, (IT)->w, \ - FACE_OPT_FROM_ID ((IT)->f, (IT)->face_id), \ + FACE_FROM_ID_OR_NULL ((IT)->f, \ + (IT)->face_id), \ (IT)->string))) @@ -7207,7 +7207,7 @@ get_next_display_element (struct it *it) if (it->method == GET_FROM_STRING && it->sp) { int face_id = underlying_face_id (it); - struct face *face = FACE_OPT_FROM_ID (it->f, face_id); + struct face *face = FACE_FROM_ID_OR_NULL (it->f, face_id); if (face) { @@ -7740,8 +7740,8 @@ next_element_from_display_vector (struct it *it) /* Glyphs in the display vector could have the box face, so we need to set the related flags in the iterator, as appropriate. */ - this_face = FACE_OPT_FROM_ID (it->f, it->face_id); - prev_face = FACE_OPT_FROM_ID (it->f, prev_face_id); + this_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); + prev_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id); /* Is this character the first character of a box-face run? */ it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX @@ -7766,7 +7766,7 @@ next_element_from_display_vector (struct it *it) it->saved_face_id); } } - next_face = FACE_OPT_FROM_ID (it->f, next_face_id); + next_face = FACE_FROM_ID_OR_NULL (it->f, next_face_id); it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX && (!next_face || next_face->box == FACE_NO_BOX)); @@ -8610,8 +8610,7 @@ move_it_in_display_line_to (struct it *it, && it->dpvec + it->current.dpvec_index + 1 >= it->dpend))) /* If there's a line-/wrap-prefix, handle it. */ - if (it->hpos == 0 && it->method == GET_FROM_BUFFER - && it->current_y < it->last_visible_y) + if (it->hpos == 0 && it->method == GET_FROM_BUFFER) handle_line_prefix (it); if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) @@ -9038,6 +9037,11 @@ move_it_in_display_line_to (struct it *it, } else result = MOVE_NEWLINE_OR_CR; + /* If we've processed the newline, make sure this flag is + reset, as it must only be set when the newline itself is + processed. */ + if (result == MOVE_NEWLINE_OR_CR) + it->constrain_row_ascent_descent_p = false; break; } @@ -9976,18 +9980,21 @@ include the height of both, if present, in the return value. */) it.last_visible_x = max_x; /* Actually, we never want move_it_to stop at to_x. But to make sure that move_it_in_display_line_to always moves far enough, - we set it to INT_MAX and specify MOVE_TO_X. Also bound width - value by X-LIMIT. */ - x = min (move_it_to (&it, end, INT_MAX, max_y, -1, - MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y), - max_x); + we set it to INT_MAX and specify MOVE_TO_X. */ + x = move_it_to (&it, end, INT_MAX, max_y, -1, + MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); + /* Don't return more than X-LIMIT. */ + if (x > max_x) + x = max_x; } /* Subtract height of header-line which was counted automatically by start_display. */ - y = min (it.current_y + it.max_ascent + it.max_descent - - WINDOW_HEADER_LINE_HEIGHT (w), - max_y); + y = it.current_y + it.max_ascent + it.max_descent + - WINDOW_HEADER_LINE_HEIGHT (w); + /* Don't return more than Y-LIMIT. */ + if (y > max_y) + y = max_y; if (EQ (mode_and_header_line, Qheader_line) || EQ (mode_and_header_line, Qt)) @@ -11702,7 +11709,7 @@ x_consider_frame_title (Lisp_Object frame) if ((FRAME_WINDOW_P (f) || FRAME_MINIBUF_ONLY_P (f) || f->explicit_name) - && NILP (Fframe_parameter (frame, Qtooltip))) + && !FRAME_TOOLTIP_P (f)) { /* Do we have more than one visible frame on this X display? */ Lisp_Object tail, other_frame, fmt; @@ -11719,7 +11726,7 @@ x_consider_frame_title (Lisp_Object frame) if (tf != f && FRAME_KBOARD (tf) == FRAME_KBOARD (f) && !FRAME_MINIBUF_ONLY_P (tf) - && !EQ (other_frame, tip_frame) + && !FRAME_TOOLTIP_P (tf) && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf))) break; } @@ -11782,13 +11789,6 @@ prepare_menu_bars (void) { bool all_windows = windows_or_buffers_changed || update_mode_lines; bool some_windows = REDISPLAY_SOME_P (); - Lisp_Object tooltip_frame; - -#ifdef HAVE_WINDOW_SYSTEM - tooltip_frame = tip_frame; -#else - tooltip_frame = Qnil; -#endif if (FUNCTIONP (Vpre_redisplay_function)) { @@ -11829,7 +11829,7 @@ prepare_menu_bars (void) && !XBUFFER (w->contents)->text->redisplay) continue; - if (!EQ (frame, tooltip_frame) + if (!FRAME_TOOLTIP_P (f) && (FRAME_ICONIFIED_P (f) || FRAME_VISIBLE_P (f) == 1 /* Exclude TTY frames that are obscured because they @@ -11866,7 +11866,7 @@ prepare_menu_bars (void) struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f)); /* Ignore tooltip frame. */ - if (EQ (frame, tooltip_frame)) + if (FRAME_TOOLTIP_P (f)) continue; if (some_windows @@ -15506,12 +15506,14 @@ try_scrolling (Lisp_Object window, bool just_this_one_p, The new window start will be computed, based on W's width, starting from the start of the continued line. It is the start of the - screen line with the minimum distance from the old start W->start. */ + screen line with the minimum distance from the old start W->start, + which is still before point (otherwise point will definitely not + be visible in the window). */ static bool compute_window_start_on_continuation_line (struct window *w) { - struct text_pos pos, start_pos; + struct text_pos pos, start_pos, pos_before_pt; bool window_start_changed_p = false; SET_TEXT_POS_FROM_MARKER (start_pos, w->start); @@ -15539,10 +15541,14 @@ compute_window_start_on_continuation_line (struct window *w) reseat_at_previous_visible_line_start (&it); /* If the line start is "too far" away from the window start, - say it takes too much time to compute a new window start. */ - if (CHARPOS (start_pos) - IT_CHARPOS (it) - /* PXW: Do we need upper bounds here? */ - < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w)) + say it takes too much time to compute a new window start. + Also, give up if the line start is after point, as in that + case point will not be visible with any window start we + compute. */ + if (IT_CHARPOS (it) <= PT + || (CHARPOS (start_pos) - IT_CHARPOS (it) + /* PXW: Do we need upper bounds here? */ + < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))) { int min_distance, distance; @@ -15552,12 +15558,14 @@ compute_window_start_on_continuation_line (struct window *w) decreased, the new window start will be < the old start. So, we're looking for the display line start with the minimum distance from the old window start. */ - pos = it.current.pos; + pos_before_pt = pos = it.current.pos; min_distance = INFINITY; while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))), distance < min_distance) { min_distance = distance; + if (CHARPOS (pos) <= PT) + pos_before_pt = pos; pos = it.current.pos; if (it.line_wrap == WORD_WRAP) { @@ -15580,6 +15588,13 @@ compute_window_start_on_continuation_line (struct window *w) move_it_by_lines (&it, 1); } + /* It makes very little sense to make the new window start + after point, as point won't be visible. If that's what + the loop above finds, fall back on the candidate before + or at point that is closest to the old window start. */ + if (CHARPOS (pos) > PT) + pos = pos_before_pt; + /* Set the window start there. */ SET_MARKER_FROM_TEXT_POS (w->start, pos); window_start_changed_p = true; @@ -19509,7 +19524,6 @@ append_space_for_newline (struct it *it, bool default_face_p) struct text_pos saved_pos; Lisp_Object saved_object; struct face *face; - struct glyph *g; saved_object = it->object; saved_pos = it->position; @@ -19545,7 +19559,7 @@ append_space_for_newline (struct it *it, bool default_face_p) /* Make sure this space glyph has the right ascent and descent values, or else cursor at end of line will look funny, and height of empty lines will be incorrect. */ - g = it->glyph_row->glyphs[TEXT_AREA] + n; + struct glyph *g = it->glyph_row->glyphs[TEXT_AREA] + n; struct font *font = face->font ? face->font : FRAME_FONT (it->f); if (n == 0) { @@ -19670,14 +19684,15 @@ extend_face_to_end_of_line (struct it *it) return; /* The default face, possibly remapped. */ - default_face = FACE_OPT_FROM_ID (f, lookup_basic_face (f, DEFAULT_FACE_ID)); + default_face = FACE_FROM_ID_OR_NULL (f, + lookup_basic_face (f, DEFAULT_FACE_ID)); /* Face extension extends the background and box of IT->face_id to the end of the line. If the background equals the background of the frame, we don't have to do anything. */ - face = FACE_OPT_FROM_ID (f, (it->face_before_selective_p - ? it->saved_face_id - : it->face_id)); + face = FACE_FROM_ID (f, (it->face_before_selective_p + ? it->saved_face_id + : it->face_id)); if (FRAME_WINDOW_P (f) && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row) @@ -21843,7 +21858,6 @@ Value is the new character position of point. */) } /* Move to the target X coordinate. */ -#ifdef HAVE_WINDOW_SYSTEM /* On GUI frames, as we don't know the X coordinate of the character to the left of point, moving point to the left requires walking, one grapheme cluster at a time, until we @@ -21900,9 +21914,7 @@ Value is the new character position of point. */) new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos); it.current.pos = new_pos; } - else -#endif - if (it.current_x != target_x) + else if (it.current_x != target_x) move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X); /* If we ended up in a display string that covers point, move to @@ -24782,7 +24794,7 @@ fill_gstring_glyph_string (struct glyph_string *s, int face_id, s->cmp_id = glyph->u.cmp.id; s->cmp_from = glyph->slice.cmp.from; s->cmp_to = glyph->slice.cmp.to + 1; - s->face = FACE_OPT_FROM_ID (s->f, face_id); + s->face = FACE_FROM_ID (s->f, face_id); lgstring = composition_gstring_from_id (s->cmp_id); s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring)); glyph++; @@ -25375,7 +25387,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p) #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \ do { \ int face_id = (row)->glyphs[area][START].face_id; \ - struct face *base_face = FACE_OPT_FROM_ID (f, face_id); \ + struct face *base_face = FACE_FROM_ID (f, face_id); \ ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \ struct composition *cmp = composition_table[cmp_id]; \ XChar2b *char2b; \ @@ -26692,12 +26704,8 @@ calc_line_height_property (struct it *it, Lisp_Object val, struct font *font, struct face *face; face_id = lookup_named_face (it->f, face_name, false); - if (face_id < 0) - return make_number (-1); - - face = FACE_FROM_ID (it->f, face_id); - font = face->font; - if (font == NULL) + face = FACE_FROM_ID_OR_NULL (it->f, face_id); + if (face == NULL || ((font = face->font) == NULL)) return make_number (-1); boff = font->baseline_offset; if (font->vertical_centering) @@ -27350,8 +27358,8 @@ x_produce_glyphs (struct it *it) eassume (0 < glyph_len); /* See Bug#8512. */ do - c = COMPOSITION_GLYPH (cmp, --glyph_len); - while (c == '\t' && 0 < glyph_len); + c = COMPOSITION_GLYPH (cmp, glyph_len - 1); + while (c == '\t' && 0 < --glyph_len); bool right_padded = glyph_len < cmp->glyph_len; for (i = 0; i < glyph_len; i++) @@ -28681,12 +28689,12 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw) } } -#ifdef HAVE_WINDOW_SYSTEM /* When we've written over the cursor, arrange for it to be displayed again. */ if (FRAME_WINDOW_P (f) && phys_cursor_on_p && !w->phys_cursor_on_p) { +#ifdef HAVE_WINDOW_SYSTEM int hpos = w->phys_cursor.hpos; /* When the window is hscrolled, cursor hpos can legitimately be @@ -28701,8 +28709,8 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw) display_and_set_cursor (w, true, hpos, w->phys_cursor.vpos, w->phys_cursor.x, w->phys_cursor.y); unblock_input (); - } #endif /* HAVE_WINDOW_SYSTEM */ + } } #ifdef HAVE_WINDOW_SYSTEM @@ -29642,12 +29650,17 @@ Returns the alist element for the first matching AREA in MAP. */) clip_to_bounds (INT_MIN, XINT (x), INT_MAX), clip_to_bounds (INT_MIN, XINT (y), INT_MAX)); } +#endif /* HAVE_WINDOW_SYSTEM */ /* Display frame CURSOR, optionally using shape defined by POINTER. */ static void define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer) { +#ifdef HAVE_WINDOW_SYSTEM + if (!FRAME_WINDOW_P (f)) + return; + /* Do not change cursor shape while dragging mouse. */ if (EQ (do_mouse_tracking, Qdragging)) return; @@ -29664,10 +29677,10 @@ define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer) cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor; else if (EQ (pointer, intern ("nhdrag"))) cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor; -#ifdef HAVE_X_WINDOWS +# ifdef HAVE_X_WINDOWS else if (EQ (pointer, intern ("vdrag"))) cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor; -#endif +# endif else if (EQ (pointer, intern ("hourglass"))) cursor = FRAME_X_OUTPUT (f)->hourglass_cursor; else if (EQ (pointer, Qmodeline)) @@ -29678,10 +29691,9 @@ define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer) if (cursor != No_Cursor) FRAME_RIF (f)->define_frame_cursor (f, cursor); +#endif } -#endif /* HAVE_WINDOW_SYSTEM */ - /* Take proper action when mouse has moved to the mode or header line or marginal area AREA of window W, x-position X and y-position Y. X is relative to the start of the text display area of W, so the @@ -29995,10 +30007,7 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y, if ((area == ON_MODE_LINE || area == ON_HEADER_LINE) && !mouse_face_shown) clear_mouse_face (hlinfo); -#ifdef HAVE_WINDOW_SYSTEM - if (FRAME_WINDOW_P (f)) - define_frame_cursor1 (f, cursor, pointer); -#endif + define_frame_cursor1 (f, cursor, pointer); } @@ -30203,15 +30212,15 @@ note_mouse_highlight (struct frame *f, int x, int y) { if (clear_mouse_face (hlinfo)) cursor = No_Cursor; -#ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (f) && NILP (pointer)) { +#ifdef HAVE_WINDOW_SYSTEM if (area != TEXT_AREA) cursor = FRAME_X_OUTPUT (f)->nontext_cursor; else pointer = Vvoid_text_area_pointer; - } #endif + } goto set_cursor; } @@ -30523,15 +30532,7 @@ note_mouse_highlight (struct frame *f, int x, int y) } set_cursor: - -#ifdef HAVE_WINDOW_SYSTEM - if (FRAME_WINDOW_P (f)) - define_frame_cursor1 (f, cursor, pointer); -#else - /* This is here to prevent a compiler error, about "label at end of - compound statement". */ - return; -#endif + define_frame_cursor1 (f, cursor, pointer); }