Hi, Thank you for your prompt response! On 3/26/25 7:47 AM, Eli Zaretskii wrote: > I think the problem is not in vertical-motion at all. The problem is > that the "normal" display of embedded images allows us to get into a > situation with layout which vertical-motion doesn't expect to happen, > when these two minor modes are turned on. Please try the patch below > and see if it gives good results. > > diff --git a/src/xdisp.c b/src/xdisp.c > index 4e8bb7d..7afa64d 100644 > --- a/src/xdisp.c > +++ b/src/xdisp.c > @@ -31956,12 +31956,13 @@ produce_image_glyph (struct it *it) > word-wrap, unless the image starts at column zero, because > wrapping correctly needs the real pixel width of the image. */ > if ((it->line_wrap != WORD_WRAP > - || it->hpos == 0 > + || it->hpos == 0 + (it->lnum_width ? it->lnum_width + 2 : 0) > /* Always crop images larger than the window-width, minus 1 space. */ > || it->pixel_width > it->last_visible_x - FRAME_COLUMN_WIDTH (it->f)) > && (crop = it->pixel_width - (it->last_visible_x - it->current_x), > crop > 0) > - && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4)) > + && (it->hpos == 0 + (it->lnum_width ? it->lnum_width + 2 : 0) > + || it->pixel_width > it->last_visible_x / 4)) > { > it->pixel_width -= crop; > slice.width -= crop; Unfortunately with this patch, I could still get the cursor stuck. See stuck.png and following gdb logs when it gets stuck: +bt #0  produce_image_glyph (it=0x7fff258031d0) at xdisp.c:31958 #1  0x000057ba672d79e1 in gui_produce_glyphs (it=0x7fff258031d0) at xdisp.c:33672 #2  0x000057ba672bcb18 in display_line (it=0x7fff258031d0, cursor_vpos=6) at xdisp.c:25720 #3  0x000057ba672aeb0a in try_window (window=0x57baa27b9c2d, pos=..., flags=1) at xdisp.c:21413 #4  0x000057ba672abaa3 in redisplay_window (window=0x57baa27b9c2d, just_this_one_p=true) at xdisp.c:20784 #5  0x000057ba672a2fa9 in redisplay_window_1 (window=0x57baa27b9c2d) at xdisp.c:18268 #6  0x000057ba67460bf1 in internal_condition_case_1 (bfun=0x57ba672a2f67 , arg=0x57baa27b9c2d, handlers=0x710b5b9a7d33, hfun=0x57ba672a2df7 ) at eval.c:1644 #7  0x000057ba672a207d in redisplay_internal () at xdisp.c:17774 #8  0x000057ba6729fb21 in redisplay () at xdisp.c:16802 #9  0x000057ba6739a0cb in read_char (commandflag=1, map=0x57baa32452f3, prev_event=0x0, used_mouse_menu=0x7fff2580871a, end_time=0x0) at keyboard.c:2672 #10 0x000057ba673ad0fb in read_key_sequence (keybuf=0x7fff25808990, prompt=0x0, dont_downcase_last=false, can_return_switch_frame=true, fix_current_buffer=true, prevent_redisplay=false, disable_text_conversion_p=false) at keyboard.c:10848 #11 0x000057ba67396751 in command_loop_1 () at keyboard.c:1424 #12 0x000057ba67460b4a in internal_condition_case (bfun=0x57ba67396343 , handlers=0x90, hfun=0x57ba67395874 ) at eval.c:1620 #13 0x000057ba67395f90 in command_loop_2 (handlers=0x90) at keyboard.c:1163 #14 0x000057ba6746009f in internal_catch (tag=0x11f40, func=0x57ba67395f66 , arg=0x90) at eval.c:1300 #15 0x000057ba67395f22 in command_loop () at keyboard.c:1141 #16 0x000057ba67395416 in recursive_edit_1 () at keyboard.c:749 #17 0x000057ba673955c2 in Frecursive_edit () at keyboard.c:832 #18 0x000057ba6739167f in main (argc=3, argv=0x7fff25808e78) at emacs.c:2560 +p *it $11 = {window = 0x57baa27b9c2d, w = 0x57baa27b9c28, f = 0x57baa27b99d0, method = GET_FROM_IMAGE, stop_charpos = 127, prev_stop = 126, base_level_stop = 126, end_charpos = 302, medium_narrowing_begv = 0, medium_narrowing_zv = 0, large_narrowing_begv = 0, large_narrowing_zv = 0, s = 0x0, string_nchars = 0, multibyte_p = true, tab_line_p = false, header_line_p = false, string_from_display_prop_p = false, string_from_prefix_prop_p = false, from_disp_prop_p = true, ellipsis_p = false, avoid_cursor_p = false, dp = 0x0, dpvec = 0x0, dpend = 0x0, dpvec_char_len = 0, dpvec_face_id = 0, saved_face_id = 34, ctl_chars = {0x0 }, start = {pos = {charpos = 121, bytepos = 121}, overlay_string_index = -1, string_pos = {charpos = -1, bytepos = -1}, dpvec_index = -1}, current = {pos = {charpos = 126, bytepos = 126}, overlay_string_index = -1, string_pos = {charpos = -1, bytepos = -1}, dpvec_index = -1}, n_overlay_strings = 0, overlay_strings_charpos = 126, overlay_strings = {0x0 }, string_overlays = {0x0 }, string = 0x0, from_overlay = 0x0, stack = {{string = 0x0, string_nchars = 0, end_charpos = 302, stop_charpos = 127, prev_stop = 126, base_level_stop = 126, cmp_it = {stop_pos = 129, id = -1, ch = -2, rule_idx = 0, lookback = 0, nglyphs = 0, reversed_p = false, parent_it = 0x7fff258031d0, charpos = 0, nchars = 0, nbytes = 0, from = 0, to = 0, width = 0}, face_id = 34, u = {image = {object = 0x0, slice = {x = 0x0, y = 0x0, width = 0x0, height = 0x0}, image_id = 0}, stretch = {object = 0x0}, xwidget = {object = 0x0}}, position = {charpos = 127, bytepos = 127}, current = {pos = {charpos = 127, bytepos = 127}, overlay_string_index = -1, string_pos = {charpos = -1, bytepos = -1}, dpvec_index = -1}, from_overlay = 0x0, area = TEXT_AREA, method = GET_FROM_BUFFER, paragraph_embedding = NEUTRAL_DIR, multibyte_p = true, string_from_display_prop_p = false, string_from_prefix_prop_p = false, display_ellipsis_p = false, avoid_cursor_p = false, bidi_p = true, from_disp_prop_p = false, line_wrap = WORD_WRAP, voffset = 0, space_width = 0x0, font_height = 0x0}, {string = 0x0, string_nchars = 0, end_charpos = 0, stop_charpos = 0, prev_stop = 0, base_level_stop = 0, cmp_it = {stop_pos = 0, id = 0, ch = 0, rule_idx = 0, lookback = 0, nglyphs = 0, reversed_p = false, parent_it = 0x0, charpos = 0, nchars = 0, nbytes = 0, from = 0, to = 0, width = 0}, face_id = 0, u = {image = {object = 0x0, slice = {x = 0x0, y = 0x0, width = 0x0, height = 0x0}, image_id = 0}, stretch = {object = 0x0}, xwidget = {object = 0x0}}, position = {charpos = 0, bytepos = 0}, current = {pos = {charpos = 0, bytepos = 0}, overlay_string_index = 0, string_pos = {charpos = 0, bytepos = 0}, dpvec_index = 0}, from_overlay = 0x0, area = LEFT_MARGIN_AREA, method = GET_FROM_BUFFER, paragraph_embedding = NEUTRAL_DIR, multibyte_p = false, string_from_display_prop_p = false, string_from_prefix_prop_p = false, display_ellipsis_p = false, avoid_cursor_p = false, bidi_p = false, from_disp_prop_p = false, line_wrap = TRUNCATE, voffset = 0, space_width = 0x0, font_height = 0x0}, {string = 0x0, string_nchars = 0, end_charpos = 0, stop_charpos = 0, prev_stop = 0, base_level_stop = 0, cmp_it = {stop_pos = 0, id = 0, ch = 0, rule_idx = 0, lookback = 0, nglyphs = 0, reversed_p = false, parent_it = 0x0, charpos = 0, nchars = 0, nbytes = 0, from = 0, to = 0, width = 0}, face_id = 0, u = {image = {object = 0x0, slice = {x = 0x0, y = 0x0, width = 0x0, height = 0x0}, image_id = 0}, stretch = {object = 0x0}, xwidget = {object = 0x0}}, position = {charpos = 0, bytepos = 0}, current = {pos = {charpos = 0, bytepos = 0}, overlay_string_index = 0, string_pos = {charpos = 0, bytepos = 0}, dpvec_index = 0}, from_overlay = 0x0, area = LEFT_MARGIN_AREA, method = GET_FROM_BUFFER, paragraph_embedding = NEUTRAL_DIR, multibyte_p = false, string_from_display_prop_p = false, string_from_prefix_prop_p = false, display_ellipsis_p = false, avoid_cursor_p = false, bidi_p = false, from_disp_prop_p = false, line_wrap = TRUNCATE, voffset = 0, space_width = 0x0, font_height = 0x0}, {string = 0x0, string_nchars = 0, end_charpos = 0, stop_charpos = 0, prev_stop = 0, base_level_stop = 0, cmp_it = {stop_pos = 0, id = 0, ch = 0, rule_idx = 0, lookback = 0, nglyphs = 0, reversed_p = false, parent_it = 0x0, charpos = 0, nchars = 0, nbytes = 0, from = 0, to = 0, width = 0}, face_id = 0, u = {image = {object = 0x0, slice = {x = 0x0, y = 0x0, width = 0x0, height = 0x0}, image_id = 0}, stretch = {object = 0x0}, xwidget = {object = 0x0}}, position = {charpos = 0, bytepos = 0}, current = {pos = {charpos = 0, bytepos = 0}, overlay_string_index = 0, string_pos = {charpos = 0, bytepos = 0}, dpvec_index = 0}, from_overlay = 0x0, area = LEFT_MARGIN_AREA, method = GET_FROM_BUFFER, paragraph_embedding = NEUTRAL_DIR, multibyte_p = false, string_from_display_prop_p = false, string_from_prefix_prop_p = false, display_ellipsis_p = false, avoid_cursor_p = false, bidi_p = false, from_disp_prop_p = false, line_wrap = TRUNCATE, voffset = 0, space_width = 0x0, font_height = 0x0}, {string = 0x0, string_nchars = 0, end_charpos = 0, stop_charpos = 0, prev_stop = 0, base_level_stop = 0, cmp_it = {stop_pos = 0, id = 0, ch = 0, rule_idx = 0, lookback = 0, nglyphs = 0, reversed_p = false, parent_it = 0x0, charpos = 0, nchars = 0, nbytes = 0, from = 0, to = 0, width = 0}, face_id = 0, u = {image = {object = 0x0, slice = {x = 0x0, y = 0x0, width = 0x0, height = 0x0}, image_id = 0}, stretch = {object = 0x0}, xwidget = {object = 0x0}}, position = {charpos = 0, bytepos = 0}, current = {pos = {charpos = 0, bytepos = 0}, overlay_string_index = 0, string_pos = {charpos = 0, bytepos = 0}, dpvec_index = 0}, from_overlay = 0x0, area = LEFT_MARGIN_AREA, method = GET_FROM_BUFFER, paragraph_embedding = NEUTRAL_DIR, multibyte_p = false, string_from_display_prop_p = false, string_from_prefix_prop_p = false, display_ellipsis_p = false, avoid_cursor_p = false, bidi_p = false, from_disp_prop_p = false, line_wrap = TRUNCATE, voffset = 0, space_width = 0x0, font_height = 0x0}}, sp = 1, selective = 0, what = IT_IMAGE, face_id = 34, selective_display_ellipsis_p = true, ctl_arrow_p = true, face_box_p = false, start_of_box_run_p = false, end_of_box_run_p = false, overlay_strings_at_end_processed_p = false, ignore_overlay_strings_at_pos_p = false, glyph_not_available_p = false, starts_in_middle_of_char_p = false, face_before_selective_p = false, constrain_row_ascent_descent_p = false, line_number_produced_p = true, align_visually_p = false, line_wrap = WORD_WRAP, base_face_id = 34, c = 101, len = 1, cmp_it = {stop_pos = 129, id = -1, ch = -2, rule_idx = 0, lookback = 0, nglyphs = 0, reversed_p = false, parent_it = 0x7fff258031d0, charpos = 0, nchars = 0, nbytes = 0, from = 0, to = 0, width = 0}, char_to_display = 101, glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE, image_id = 13, xwidget = 0x0, slice = {x = 0x0, y = 0x0, width = 0x0, height = 0x0}, space_width = 0x0, voffset = 0, tab_width = 8, font_height = 0x0, object = 0x57baa2a18f9d, position = {charpos = 126, bytepos = 126}, truncation_pixel_width = 0, continuation_pixel_width = 20, first_visible_x = 0, last_visible_x = 1012, last_visible_y = 918, extra_line_spacing = 0, max_extra_line_spacing = 0, override_ascent = -1, override_descent = 0, override_boff = 0, glyph_row = 0x57baa2af4120, area = TEXT_AREA, nglyphs = 1, pixel_width = 948, ascent = 20, descent = 20, max_ascent = 36, max_descent = 10, phys_ascent = 20, phys_descent = 20, max_phys_ascent = 25, max_phys_descent = 8, current_x = 180, wrap_prefix_width = 0, continuation_lines_width = 0, eol_pos = {charpos = 0, bytepos = 0}, current_y = 230, first_vpos = 0, vpos = 5, hpos = 9, lnum = 3, lnum_bytepos = 121, lnum_width = 2, lnum_pixel_width = 80, pt_lnum = 0, stretch_adjust = 0, left_user_fringe_bitmap = 0, right_user_fringe_bitmap = 0, left_user_fringe_face_id = 0, right_user_fringe_face_id = 0, bidi_p = true, bidi_it = {bytepos = 126, charpos = 126, ch = 65532, nchars = 1, ch_len = 1, type = STRONG_L, type_after_wn = NEUTRAL_ON, orig_type = NEUTRAL_ON, resolved_level = 0 '\000', isolate_level = 0 '\000', invalid_levels = 0, invalid_isolates = 0, prev = {charpos = 125, type = STRONG_L, orig_type = STRONG_L}, last_strong = {charpos = 125, type = STRONG_L, orig_type = STRONG_L}, next_for_neutral = {charpos = -1, type = UNKNOWN_BT, orig_type = UNKNOWN_BT}, prev_for_neutral = {charpos = 125, type = STRONG_L, orig_type = STRONG_L}, next_for_ws = {charpos = -1, type = UNKNOWN_BT, orig_type = UNKNOWN_BT}, bracket_pairing_pos = -1, bracket_enclosed_type = UNKNOWN_BT, next_en_pos = 0, next_en_type = UNKNOWN_BT, sos = L2R, scan_dir = 1, disp_pos = 302, disp_prop = 0, stack_idx = 0, level_stack = {{next_for_neutral_pos = 0, next_for_neutral_type = 0, last_strong_type = 0, prev_for_neutral_type = 0, level = 0 '\000', flags = 0 '\000'} }, string = {lstring = 0x0, s = 0x0, schars = 0, bufpos = 0, from_disp_str = false, unibyte = false}, w = 0x57baa27b9c28, paragraph_dir = L2R, separator_limit = -1, first_elt = false, new_paragraph = false, frame_window_p = true}, paragraph_embedding = NEUTRAL_DIR, min_width_property = 0x0, min_width_start = 0} An updated patch resolves the issue (also attached): diff --git a/src/xdisp.c b/src/xdisp.c index 4e8bb7d9b97..c6b87b08ae9 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -31956,12 +31956,14 @@ produce_image_glyph (struct it *it)       word-wrap, unless the image starts at column zero, because       wrapping correctly needs the real pixel width of the image. */    if ((it->line_wrap != WORD_WRAP -       || it->hpos == 0 +       || it->hpos == (it->lnum_width ? it->lnum_width + 2 : 0)         /* Always crop images larger than the window-width, minus 1 space.  */ -       || it->pixel_width > it->last_visible_x - FRAME_COLUMN_WIDTH (it->f)) +       || it->pixel_width > it->last_visible_x - FRAME_COLUMN_WIDTH (it->f) +                                - it->lnum_pixel_width)        && (crop = it->pixel_width - (it->last_visible_x - it->current_x), -         crop > 0) -      && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4)) +          crop > 0) +      && (it->hpos == (it->lnum_width ? it->lnum_width + 2 : 0) +          || it->pixel_width > it->last_visible_x / 4))      {        it->pixel_width -= crop;        slice.width -= crop; However, I think that images wider than the line should always start on a new line, instead of being almost clipped on the current line. E.g., see bad_clipping.png. Do you think I should file a separate bug report for this?