]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0852: GTK: ligatures not correctly displayed v9.2.0852
authorFoxe Chen <chen.foxe@gmail.com>
Fri, 24 Jul 2026 20:51:52 +0000 (20:51 +0000)
committerChristian Brabandt <cb@256bit.org>
Fri, 24 Jul 2026 20:51:52 +0000 (20:51 +0000)
Problem:  GTK: ligatures not correctly displayed
          (thunderbird-1990)
Solution: Split ligatures at cursor location (Foxe Chen).

fixes:  #12901
closes: #20708

Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/gui.c
src/version.c

index 0e1306c868b5a3314875ed0ac83bb21925832c33..f3ba3705a9fa5872497faabd284f088a0059c52e 100644 (file)
--- a/src/gui.c
+++ b/src/gui.c
@@ -1196,6 +1196,9 @@ gui_update_cursor(
     int                cattr;          // cursor attributes
     int                attr;
     attrentry_T *aep = NULL;
+#if (defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MSWIN)) && !defined(USE_GTK4_SNAPSHOT)
+    bool       lig_left = false, lig_right = false;
+#endif
 
     // Don't update the cursor when halfway busy scrolling or the screen size
     // doesn't match 'columns' and 'lines.  ScreenLines[] isn't valid then.
@@ -1375,6 +1378,55 @@ gui_update_cursor(
     gui_redraw_block(gui.row, gui.col, gui.row, gui.col, GUI_MON_NOCLEAR);
     // gui_redraw_block() will invalidate the cursor
     gui.cursor_is_valid = true;
+#endif
+#if defined(FEAT_GUI_GTK) || defined(FEAT_GUI_MSWIN)
+    // If cursor is in the middle of a ligature, then split the ligature at
+    // the cursor boundaries by redrawing those cells again.
+    for (int c = gui.col - 1; c >= 0; c--)
+       if (!gui.ligatures_map[ScreenLines[LineOffset[gui.row] + c]])
+       {
+           if (c < gui.col - 1)
+           {
+               gui_redraw_block(gui.row, c + 1, gui.row, gui.col - 1,
+                       GUI_MON_NOCLEAR);
+# ifndef USE_GTK4_SNAPSHOT
+               lig_left = true;
+# endif
+           }
+           break;
+       }
+
+    for (int c = gui.col + 1; c < screen_Columns - 1; c++)
+       if (!gui.ligatures_map[ScreenLines[LineOffset[gui.row] + c]])
+       {
+           if (c > gui.col + 1)
+           {
+               gui_redraw_block(gui.row, gui.col + 1, gui.row, c - 1,
+                       GUI_MON_NOCLEAR);
+# ifndef USE_GTK4_SNAPSHOT
+               lig_right = true;
+# endif
+           }
+           break;
+       }
+    // gui_redraw_block() may invalidate the cursor, make sure to validate
+    // it again.
+    gui.cursor_is_valid = true;
+
+# ifndef USE_GTK4_SNAPSHOT
+    if ((lig_left || lig_right) && shape->shape != SHAPE_BLOCK)
+    {
+       // Because the cursor is not drawn with gui_screenchar(), must blit the
+       // cell again (with its background), so that old ligature does not
+       // remain on screen. Not needed for GtkSnapshot, because char beneath is
+       // always rerendered (see above ifdef).
+       int old = gui.col;
+       gui.highlight_mask = ScreenAttrs[LineOffset[gui.row] + gui.col];
+       (void)gui_screenchar(LineOffset[gui.row] + gui.col,
+               GUI_MON_NOCLEAR, (guicolor_T)0, (guicolor_T)0, 0);
+       gui.col = old;
+    }
+# endif
 #endif
 
     old_hl_mask = gui.highlight_mask;
index 422af5fda412809fdd36ccd9b69b72611db16535..c857374a9398116b598385bbde3661d7c3000b5d 100644 (file)
@@ -758,6 +758,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    852,
 /**/
     851,
 /**/