]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0820: GUI: hidden popup image is displayed and not erased v9.2.0820
authorHirohito Higashi <h.east.727@gmail.com>
Mon, 20 Jul 2026 17:50:06 +0000 (17:50 +0000)
committerChristian Brabandt <cb@256bit.org>
Mon, 20 Jul 2026 17:50:06 +0000 (17:50 +0000)
Problem:  In the GUI a popup image is drawn even when the popup is
          hidden, and hiding a popup leaves part of the image on the
          screen (Bakudankun).
Solution: Skip hidden popups when repainting images after the cursor is
          undrawn or the window is exposed.  Redraw the area the image
          covered when the popup is hidden or closed, also for the GDI
          backend (Hirohito Higashi).

fixes:  #20796
closes: #20798

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/popupwin.c
src/version.c

index cd3fe80dab80a8fbe8a22412de8ea6d3f7c4f80c..0acb7453df95d54b587692d7c64668e4207e98d6 100644 (file)
@@ -120,11 +120,20 @@ static void redraw_overlapped_opacity_popups(int winrow, int wincol,
 #ifdef FEAT_IMAGE_KITTY
 static void popup_image_clear_kitty(win_T *wp);
 #endif
+// GDI and cairo paint the image straight into the window, so the area has to
+// be redrawn when the popup goes away.  GTK4 keeps a list of images to render
+// instead, there gui_gtk4_remove_image() does the job.
+#ifdef FEAT_IMAGE_GDI
+# define POPUP_IMAGE_CLEAR_GUI
+#endif
 #if defined(FEAT_GUI_GTK) && defined(FEAT_IMAGE_CAIRO)
 # if !GTK_CHECK_VERSION(4,0,0)
-static void popup_image_clear_cairo(win_T *wp);
+#  define POPUP_IMAGE_CLEAR_GUI
 # endif
 #endif
+#ifdef POPUP_IMAGE_CLEAR_GUI
+static void popup_image_clear_gui(win_T *wp);
+#endif
 #ifdef FEAT_IMAGE
 static bool popup_image_composites_frames(void);
 #endif
@@ -4314,10 +4323,8 @@ popup_hide(win_T *wp)
 
     wp->w_popup_flags |= POPF_HIDDEN;
 
-#if defined(FEAT_GUI_GTK) && defined(FEAT_IMAGE_CAIRO)
-# if !GTK_CHECK_VERSION(4,0,0)
-    popup_image_clear_cairo(wp);
-# endif
+#ifdef POPUP_IMAGE_CLEAR_GUI
+    popup_image_clear_gui(wp);
 #endif
 
     // Do not decrement b_nwindows, we still reference the buffer.
@@ -4523,10 +4530,8 @@ popup_free(win_T *wp)
     if (gui.in_use)
        gui_gtk4_remove_image(wp);
 #endif
-#if defined(FEAT_GUI_GTK) && defined(FEAT_IMAGE_CAIRO)
-# if !GTK_CHECK_VERSION(4,0,0)
-    popup_image_clear_cairo(wp);
-# endif
+#ifdef POPUP_IMAGE_CLEAR_GUI
+    popup_image_clear_gui(wp);
 #endif
     sign_undefine_by_name(popup_get_sign_name(wp), FALSE);
     wp->w_buffer->b_locked = FALSE;
@@ -7162,10 +7167,12 @@ popup_image_clear_kitty(win_T *wp)
 }
 # endif
 
-# if defined(FEAT_GUI_GTK) && defined(FEAT_IMAGE_CAIRO)
-#  if !GTK_CHECK_VERSION(4,0,0)
+# ifdef POPUP_IMAGE_CLEAR_GUI
+/*
+ * Redraw the area the image of "wp" was drawn in, the popup goes away.
+ */
     static void
-popup_image_clear_cairo(win_T *wp)
+popup_image_clear_gui(win_T *wp)
 {
     if (!gui.in_use
            || wp->w_popup_image_emit_cells_w <= 0
@@ -7181,7 +7188,6 @@ popup_image_clear_cairo(win_T *wp)
     wp->w_popup_image_emit_cells_w = 0;
     wp->w_popup_image_emit_cells_h = 0;
 }
-#  endif
 # endif
 
 # if defined(FEAT_IMAGE_SIXEL) || defined(FEAT_IMAGE_KITTY)
@@ -7245,7 +7251,10 @@ popup_maybe_emit_image_rect(
     int img_left, img_top, img_right, img_bottom;
     int src_x, src_y, draw_w, draw_h;
 
-    if (!gui.in_use || wp->w_popup_image_data == NULL
+    // This is called for every popup, also the hidden ones: the cursor undraw
+    // and WM_PAINT paths do not go through find_next_popup().
+    if (!gui.in_use || (wp->w_popup_flags & POPF_HIDDEN)
+           || wp->w_popup_image_data == NULL
            || wp->w_popup_image_w <= 0 || wp->w_popup_image_h <= 0)
        return;
 
index ae605f243146776711cd1694d94eeb64c89b007e..4031cd24ca23d8bb9147ffafbf8cb31b42c2e697 100644 (file)
@@ -759,6 +759,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    820,
 /**/
     819,
 /**/