[vim/vim] Render images inside popup windows via sixel and GDI (PR #20136)

33 views
Skip to first unread message

mattn

unread,
May 4, 2026, 12:51:25 PM (7 days ago) May 4
to vim/vim, Subscribed

Add an image attribute to popup_create() / popup_setoptions() that renders a pixel buffer inside the popup window. Terminal backends emit the buffer as DEC sixel DCS sequences (FEAT_IMAGE_SIXEL); on the MS-Windows GUI the same data is BitBlt'd through a GDI device bitmap (FEAT_IMAGE_GDI). The popup auto-sizes its cell box from the image's pixel dimensions, so the caller does not have to compute minwidth/maxwidth/minheight/maxheight by hand.

image.png (view on web)

Vim itself does not link against libpng, libjpeg, libwebp or any image-decoding library. The image attribute takes an already-decoded raw RGB / RGBA pixel buffer; format decoding is left to the script caller, who can pipe the file through any external tool (GraphicsMagick, ImageMagick, ffmpeg, custom converter, ...) and pass the resulting bytes via a Blob. This keeps Vim's build footprint unchanged while letting users render PNG, JPEG, GIF, WebP, AVIF or proprietary formats with whatever decoder they already have.

The image dict accepts data (a Blob of width*height*3 for RGB or width*height*4 for RGBA), width and height. RGBA buffers are composited over the popup's background. A companion script function getbgcolor() returns the current background colour as [r, g, b] (from the terminal's OSC 11 response, or the GUI's Normal highlight) so scripts that want to pre-composite their pixels can match the popup's actual backdrop -- handy when generating an image with anti-aliased edges that need to blend cleanly into the editor.

Minimal RGB example — a 4×4 red square popped at the cursor:

let pixels = repeat([0xff, 0x00, 0x00], 4 * 4)->list2blob()
call popup_create('', #{
      \ image: #{ data: pixels, width: 4, height: 4 },
      \ line: 'cursor+1', col: 'cursor',
      \ })

Real-world example — pipe a PNG through GraphicsMagick and pop the resulting raw RGB bytes:

let png = 'cat.png'
let dim = split(system('gm identify -format "%w %h" ' .. shellescape(png)))
let [w, h] = [str2nr(dim[0]), str2nr(dim[1])]
call system('gm convert ' .. shellescape(png) .. ' -depth 8 rgb:/tmp/cat.rgb')
let blob = readblob('/tmp/cat.rgb')
call popup_create('', #{
      \ image: #{ data: blob, width: w, height: h },
      \ line: 1, col: 1, border: [], padding: [0, 0, 0, 0],
      \ })

Sixel encoding is deferred to popup_adjust_position() so the encoder knows the final winrow and can crop the bottom row of the image to one cell above the screen edge, avoiding sixel-induced terminal scrolling. popup_getoptions() returns the same dict back -- data is a fresh blob copy independent of the popup's internal buffer.

Other refinements:

  • Hidden popups skip image re-emission so the cached sixel is not re-blitted at its old position after the textprop scrolls out of view.
  • A few small redraw/cursor fixes around sixel emit, so terminal cells previously covered by the image are re-rendered cleanly when the popup hides on scroll.
  • has('image'), has('image_sixel'), has('image_gdi') are registered as known feature names so the test framework's CheckFeature works and has('image') is no longer a runtime no-op.

Tests in test_popupwin.vim cover image acceptance for both RGB and RGBA, blob round-trip through popup_getoptions, the validation paths (wrong data length / missing keys), and the existing dimension-update case (whose blob lengths were corrected -- the previous test silently no-op'd because has('image') returned 0).

With this in place, Vim's expressive range grows considerably: anything that can be rendered to an RGB/RGBA buffer can now sit next to your text, anchored to a textprop and tracking the buffer as it scrolls. A few demos of what this enables straight from a markdown buffer:

PlantUML diagram preview, anchored to a fenced ```plantuml block:

https://github.com/user-attachments/assets/8c6e3973-ff16-4605-91be-51bfe77e4308

LaTeX math rendered through the CodeCogs API and pinned next to the formula:

image.png (view on web)

QR code generated for the URL under the cursor, ready to scan with a phone:

https://github.com/user-attachments/assets/352c8398-78b0-4331-8aca-a8d6c010b85e

And -- because the popup just consumes a raw pixel buffer -- you can generate each frame yourself in Vim script and feed it back via popup_setoptions() on a timer. That alone is enough to build an xeyes-style dynamic application, drawn pixel by pixel and updated in place, running entirely inside Vim.

https://github.com/user-attachments/assets/de5ca08a-b0f0-47db-9ac3-ad9ae9d7c89a


You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/20136

Commit Summary

  • 8fbd8d3 feat: support image attribute in popup_create() via sixel
  • 2152944 feat: add GDI backend for popup image, generalize FEAT_SIXEL
  • c8f5c5a fix popup image redraw after paint and cursor updates
  • a063970 defer sixel encoding and crop to fit screen
  • 2bd224f force full redraw when textprop popup hides on scroll
  • 021672e add RGBA alpha support for popup images
  • 305d90f fix cursor flicker after popup sixel emit
  • 89eb20e skip image emit for hidden popups
  • 89e4f00 expose popup image via popup_getoptions and add tests

File Changes

(24 files)

Patch Links:


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136@github.com>

mattn

unread,
May 4, 2026, 12:58:29 PM (7 days ago) May 4
to vim/vim, Push

@mattn pushed 1 commit.

  • 6e9501f fix CI: list sixel files and avoid -Wcomment on term.c


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/89e4f00ebdb290e866e7c0f5ac66bb98a95e18f0/after/6e9501f7d14135713bb27f1b8b2bf270e72139e4@github.com>

mattn

unread,
May 4, 2026, 1:03:57 PM (7 days ago) May 4
to vim/vim, Push

@mattn pushed 1 commit.

  • 4bf7c8b fix CI: scope GDI-only locals inside FEAT_IMAGE_GDI block in gui_undraw_cursor


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/6e9501f7d14135713bb27f1b8b2bf270e72139e4/after/4bf7c8b6cef4dc5f8af8f7fb3655cc4ef1d20552@github.com>

mattn

unread,
May 4, 2026, 1:16:02 PM (7 days ago) May 4
to vim/vim, Push

@mattn pushed 1 commit.

  • 791dd69 fix CI: list getbgcolor() in :help function-list


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/4bf7c8b6cef4dc5f8af8f7fb3655cc4ef1d20552/after/791dd69691eca154f6aed87178cd52c58481ccbb@github.com>

mattn

unread,
May 4, 2026, 1:33:55 PM (7 days ago) May 4
to vim/vim, Push

@mattn pushed 1 commit.


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/791dd69691eca154f6aed87178cd52c58481ccbb/after/4a9a053dc102f4acb42abaff81cdeb82c90bda99@github.com>

mattn

unread,
May 4, 2026, 2:04:57 PM (7 days ago) May 4
to vim/vim, Push

@mattn pushed 1 commit.

  • 34e8959 fix CI: accept empty list in Test_getcellpixels_for_unix


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/4a9a053dc102f4acb42abaff81cdeb82c90bda99/after/34e8959560b575ad1605f82f69dbb5f4d32ab717@github.com>

Foxe Chen

unread,
May 4, 2026, 4:55:54 PM (7 days ago) May 4
to vim/vim, Subscribed
64-bitman left a comment (vim/vim#20136)

Wow, this is amazing work

do you plan on supporting the kitty graphics protocol? Thanks


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/c4374415506@github.com>

mattn

unread,
May 5, 2026, 8:23:47 AM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • a5cbf63 Revert "fix popup image redraw after paint and cursor updates"


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/34e8959560b575ad1605f82f69dbb5f4d32ab717/after/a5cbf63df501207c1b15d4f0d9c1b0d0972caffa@github.com>

mattn

unread,
May 5, 2026, 8:45:09 AM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • e3a0d49 Revert "fix cursor flicker after popup sixel emit"


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/a5cbf63df501207c1b15d4f0d9c1b0d0972caffa/after/e3a0d49dcd05a25a68f5426dabd2fe62b1df0c2c@github.com>

mattn

unread,
May 5, 2026, 9:02:51 AM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 2 commits.

  • 7a6d99d Revert "skip image emit for hidden popups"
  • 4bb2959 Revert "force full redraw when textprop popup hides on scroll"


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/e3a0d49dcd05a25a68f5426dabd2fe62b1df0c2c/after/4bb29599d45f1bf631d7aa304bb67b7177f123f9@github.com>

mattn

unread,
May 5, 2026, 9:27:22 AM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • 1de6211 Revert "expose popup image via popup_getoptions and add tests"


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/4bb29599d45f1bf631d7aa304bb67b7177f123f9/after/1de6211c69fb27a5f611889aac36f109f132a939@github.com>

mattn

unread,
May 5, 2026, 10:11:45 AM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • 7cabcc6 fix CI: do not call mch_calc_cell_size() from mch_report_winsize


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/1de6211c69fb27a5f611889aac36f109f132a939/after/7cabcc68aa9726b2aec54661b806fff5a128c253@github.com>

mattn

unread,
May 5, 2026, 10:32:39 AM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • 5f80ff7 add kitty graphics protocol backend for popup images


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/7cabcc68aa9726b2aec54661b806fff5a128c253/after/5f80ff72f53b0a9d821419d3b8831cfeb048b667@github.com>

mattn

unread,
May 5, 2026, 11:02:47 AM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • 4868064 broaden kitty backend auto-detection


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/5f80ff72f53b0a9d821419d3b8831cfeb048b667/after/486806495a8b71baa8d2f3d9a24c2cc726e8fd9f@github.com>

mattn

unread,
May 5, 2026, 11:09:36 AM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • 72fcda4 delete kitty placement when popup hides or closes


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/486806495a8b71baa8d2f3d9a24c2cc726e8fd9f/after/72fcda48620bd58ffe445a5455d75fb10cca6026@github.com>

mattn

unread,
May 5, 2026, 11:13:29 AM (6 days ago) May 5
to vim/vim, Subscribed
mattn left a comment (vim/vim#20136)

@64-bitman Now supported kitty renderer.

https://github.com/user-attachments/assets/fe2b6354-d13c-4b78-883d-aecaee368cef


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/c4380582687@github.com>

mattn

unread,
May 5, 2026, 11:16:30 AM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • 337c766 fix CI: indent IMAGE_BACKEND_* defines under outer #ifdef


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/72fcda48620bd58ffe445a5455d75fb10cca6026/after/337c766553b05c1f5e92c35fde8188a0ec075d0d@github.com>

Foxe Chen

unread,
May 5, 2026, 11:23:25 AM (6 days ago) May 5
to vim/vim, Subscribed
64-bitman left a comment (vim/vim#20136)

I just took a quick look at the commits, but it seems that detection for the kitty graphics protocol is done via environment variables. However support for it can be queried from the terminal: https://sw.kovidgoyal.net/kitty/graphics-protocol/#querying-support-and-available-transmission-mediums. Not sure if that is feasible though


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/c4380666838@github.com>

mattn

unread,
May 5, 2026, 11:31:50 AM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • fe94dc0 add active probe for kitty graphics support


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/337c766553b05c1f5e92c35fde8188a0ec075d0d/after/fe94dc0327631bb4730c95258d25923065d63d28@github.com>

mattn

unread,
May 5, 2026, 11:38:45 AM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • abd67d8 implement mch_calc_cell_size() on Windows console


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/fe94dc0327631bb4730c95258d25923065d63d28/after/abd67d8a959eb265e1cbb185ddd672deedd81281@github.com>

mattn

unread,
May 5, 2026, 11:44:24 AM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • 5f41d73 add CSI 14 t fallback to mch_calc_cell_size() on Windows


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/abd67d8a959eb265e1cbb185ddd672deedd81281/after/5f41d7385debaf204c5e131a2ed76f7bdfac5f3c@github.com>

mattn

unread,
May 5, 2026, 12:18:22 PM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/5f41d7385debaf204c5e131a2ed76f7bdfac5f3c/after/f6004a4c09d3a935c2b9cdeb31e3817eddbf287d@github.com>

mattn

unread,
May 5, 2026, 12:58:45 PM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • 14d939e fix CI: indent kitty probe preprocessor directives under FEAT_IMAGE_SIXEL


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/f6004a4c09d3a935c2b9cdeb31e3817eddbf287d/after/14d939e5ddf71819ff20f4f18c82d0357094a185@github.com>

mattn

unread,
May 5, 2026, 1:24:59 PM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • daf69b0 add Cairo image backend for popup_image (GTK2/3)


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/14d939e5ddf71819ff20f4f18c82d0357094a185/after/daf69b03cc42317c049279a3c95e3382f5be2d47@github.com>

mattn

unread,
May 5, 2026, 1:28:15 PM (6 days ago) May 5
to vim/vim, Subscribed
mattn left a comment (vim/vim#20136)

Now supported cairo renderer (gtk3)
image.png (view on web)


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/c4381535028@github.com>

mattn

unread,
May 5, 2026, 1:43:13 PM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/daf69b03cc42317c049279a3c95e3382f5be2d47/after/68f81ef8555b7210acf7919e479780c74b526e19@github.com>

mattn

unread,
May 5, 2026, 1:59:59 PM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.


View it on GitHub or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/68f81ef8555b7210acf7919e479780c74b526e19/after/68ce9240f69a8c480224014cbe9b3546c486f4d2@github.com>

mattn

unread,
May 5, 2026, 3:09:41 PM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • 8d83f5c document popup_create() image attribute and image_* features


View it on GitHub or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/68ce9240f69a8c480224014cbe9b3546c486f4d2/after/8d83f5ced3c928550b771c272c11fa564144af40@github.com>

mattn

unread,
May 5, 2026, 9:09:04 PM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 28 commits.

  • 1f5174d feat: support image attribute in popup_create() via sixel
  • 57756a7 feat: add GDI backend for popup image, generalize FEAT_SIXEL
  • 229eacc fix popup image redraw after paint and cursor updates
  • a6c31f4 defer sixel encoding and crop to fit screen
  • 812c37e force full redraw when textprop popup hides on scroll
  • 37606da add RGBA alpha support for popup images
  • a634a58 fix cursor flicker after popup sixel emit
  • 128af88 skip image emit for hidden popups
  • 0fe8685 expose popup image via popup_getoptions and add tests
  • bf7b06b fix CI: list sixel files and avoid -Wcomment on term.c
  • dcd1da7 fix CI: scope GDI-only locals inside FEAT_IMAGE_GDI block in gui_undraw_cursor
  • 518bae1 fix CI: list getbgcolor() in :help function-list
  • 307439f fix CI: regenerate proto/popupwin.pro and proto/gui_w32.pro
  • 1c0c6c3 fix CI: accept empty list in Test_getcellpixels_for_unix
  • 1c00439 fix CI: do not call mch_calc_cell_size() from mch_report_winsize
  • f5a3315 add kitty graphics protocol backend for popup images
  • 79f7155 broaden kitty backend auto-detection
  • 9e2623a delete kitty placement when popup hides or closes
  • e29c212 fix CI: indent IMAGE_BACKEND_* defines under outer #ifdef
  • 9be1d3d add active probe for kitty graphics support
  • 0f8d363 implement mch_calc_cell_size() on Windows console
  • d111a64 add CSI 14 t fallback to mch_calc_cell_size() on Windows
  • c863beb fix CI: regenerate proto/os_win32.pro for Windows mch_calc_cell_size
  • fab8e94 fix CI: indent kitty probe preprocessor directives under FEAT_IMAGE_SIXEL
  • 11ddbf1 add Cairo image backend for popup_image (GTK2/3)
  • 4cde41e fix CI: add popup_image wrappers to proto/gui_gtk_x11.pro
  • 4b228af fix CI: match cproto order in proto/gui_gtk_x11.pro
  • 845d639 document popup_create() image attribute and image_* features


View it on GitHub or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/8d83f5ced3c928550b771c272c11fa564144af40/after/845d6397fc26742f117154a07bb3b5a12b153277@github.com>

mattn

unread,
May 5, 2026, 10:55:49 PM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • 2ac7849 fix CI: don't wrap external API names in |...| in popup.txt


View it on GitHub or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/845d6397fc26742f117154a07bb3b5a12b153277/after/2ac7849c4c3f94b3bacbcebada8a8f192f964684@github.com>

Foxe Chen

unread,
May 5, 2026, 11:12:37 PM (6 days ago) May 5
to vim/vim, Subscribed

@64-bitman commented on this pull request.


In src/os_unix.c:

> @@ -4527,6 +4527,76 @@ mch_get_shellsize(void)
     return OK;
 }
 
+/*
+ * Synchronously ask the terminal for its window pixel dimensions via the
+ * xterm CSI 14 t query and parse the CSI 4 ; H ; W t response.  Returns OK
+ * and fills *win_w and *win_h on success.  Returns FAIL on any error
+ * (non-tty, no response within ~200ms, malformed reply).
+ */
+    static int
+query_terminal_pixel_size(int *win_w, int *win_h)

Is it possible to do this asynchronously? Although I'm guessing it will be very complicated


Reply to this email directly, view it on GitHub, or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/review/4232915688@github.com>

Foxe Chen

unread,
May 5, 2026, 11:15:51 PM (6 days ago) May 5
to vim/vim, Subscribed

@64-bitman commented on this pull request.


In src/os_unix.c:

> +    }
+    buf[n] = 0;
+    tcsetattr(fd_in, TCSANOW, &old_t);
+
+    // expected: ESC [ 4 ; H ; W t
+    p = (char *)vim_strchr((char_u *)buf, '\033');
+    if (p == NULL || p[1] != '[' || p[2] != '4' || p[3] != ';')
+	return FAIL;
+    p += 4;
+    semi = (char *)vim_strchr((char_u *)p, ';');
+    if (semi == NULL)
+	return FAIL;
+    end = (char *)vim_strchr((char_u *)semi, 't');
+    if (end == NULL)
+	return FAIL;
+    hpx = atoi(p);

maybe use strtol instead of atoi?


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/review/4232923174@github.com>

Foxe Chen

unread,
May 5, 2026, 11:20:41 PM (6 days ago) May 5
to vim/vim, Subscribed

@64-bitman commented on this pull request.


In src/popupwin.c:

> +	return FALSE;
+    new_t = old_t;
+    new_t.c_lflag &= ~(ICANON | ECHO);
+    new_t.c_cc[VMIN]  = 0;
+    new_t.c_cc[VTIME] = 3;	    // 300ms grace per read()
+    if (tcsetattr(fd_in, TCSANOW, &new_t) != 0)
+	return FALSE;
+
+    if (write(fd_out, query, sizeof(query) - 1) != sizeof(query) - 1)
+    {
+	tcsetattr(fd_in, TCSANOW, &old_t);
+	return FALSE;
+    }
+
+    // Read until the DA1 reply (`\e[?...c`) lands or we time out.
+    while (n < (int)sizeof(buf) - 1)

Is it possible to check for the response later when it is received, and during the meantime just make it so that kitty graphics protocol isn't available?


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/review/4232935619@github.com>

Foxe Chen

unread,
May 5, 2026, 11:30:41 PM (6 days ago) May 5
to vim/vim, Subscribed

@64-bitman commented on this pull request.


In src/popupwin.c:

> +    return ok;
+}
+# endif
+
+/*
+ * Pick a terminal image backend.  Cached on first call.  Returns
+ * IMAGE_BACKEND_KITTY when the host terminal advertises kitty graphics
+ * support, otherwise IMAGE_BACKEND_SIXEL.
+ *
+ * Detection order:
+ *   1. $VIM_IMAGE_BACKEND override ("kitty" | "sixel")
+ *   2. $KITTY_WINDOW_ID                (kitty itself)
+ *   3. $GHOSTTY_BIN_DIR / $GHOSTTY_RESOURCES_DIR  (Ghostty)
+ *   4. $WEZTERM_EXECUTABLE / $WEZTERM_PANE        (WezTerm)
+ *   5. $TERM contains "kitty" / "ghostty" / "wezterm"
+ *   6. $TERM_PROGRAM equals one of the above

I don't think detecting backends based on environment variables is a good idea. Either we can add an option like 'keyprotocol' or just rely on querying the terminal instead. It also seems like Konsole supports the kitty graphics protocol as well.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/review/4232968025@github.com>

mattn

unread,
May 5, 2026, 11:57:57 PM (6 days ago) May 5
to vim/vim, Push

@mattn pushed 1 commit.

  • 7b8b08a use strtol for CSI 14 t pixel size response


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/9330c4f84016e657463d18984839b8cd06347f7c/after/7b8b08a9681f7e4dfe3ea3f1b8fa6e3147236fc8@github.com>

mattn

unread,
May 6, 2026, 12:01:06 AM (5 days ago) May 6
to vim/vim, Push

@mattn pushed 1 commit.

  • bbbdfc3 rely on terminal probe for kitty backend detection


View it on GitHub or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/7b8b08a9681f7e4dfe3ea3f1b8fa6e3147236fc8/after/bbbdfc3e5f0868fe90dcc61d7829725ec994394b@github.com>

mattn

unread,
May 6, 2026, 12:07:42 AM (5 days ago) May 6
to vim/vim, Subscribed

@mattn commented on this pull request.


In src/os_unix.c:

> @@ -4527,6 +4527,76 @@ mch_get_shellsize(void)
     return OK;
 }
 
+/*
+ * Synchronously ask the terminal for its window pixel dimensions via the
+ * xterm CSI 14 t query and parse the CSI 4 ; H ; W t response.  Returns OK
+ * and fills *win_w and *win_h on success.  Returns FAIL on any error
+ * (non-tty, no response within ~200ms, malformed reply).
+ */
+    static int
+query_terminal_pixel_size(int *win_w, int *win_h)

The query is lazy and cached — it only runs the first time something asks for cell pixel size, and the 200 ms timeout bounds the worst case, so it's a one-time cost on the first image popup.


Reply to this email directly, view it on GitHub, or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/review/4233095198@github.com>

mattn

unread,
May 6, 2026, 12:08:30 AM (5 days ago) May 6
to vim/vim, Subscribed

@mattn commented on this pull request.


In src/popupwin.c:

> +	return FALSE;
+    new_t = old_t;
+    new_t.c_lflag &= ~(ICANON | ECHO);
+    new_t.c_cc[VMIN]  = 0;
+    new_t.c_cc[VTIME] = 3;	    // 300ms grace per read()
+    if (tcsetattr(fd_in, TCSANOW, &new_t) != 0)
+	return FALSE;
+
+    if (write(fd_out, query, sizeof(query) - 1) != sizeof(query) - 1)
+    {
+	tcsetattr(fd_in, TCSANOW, &old_t);
+	return FALSE;
+    }
+
+    // Read until the DA1 reply (`\e[?...c`) lands or we time out.
+    while (n < (int)sizeof(buf) - 1)

Same answer as the CSI 14 t one — the probe is lazy and one-shot per session, cached on first call to popup_image_backend(). Async would be a worthwhile follow-up if the cost actually shows up.


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/review/4233097429@github.com>

mattn

unread,
May 10, 2026, 9:26:37 AM (yesterday) May 10
to vim/vim, Push

@mattn pushed 19 commits.

  • bfb6921 feat: support image attribute in popup_create() via sixel
  • c3f9140 feat: add GDI backend for popup image, generalize FEAT_SIXEL
  • 74b4f37 fix popup image redraw after paint and cursor updates
  • 86822ad defer sixel encoding and crop to fit screen
  • e806cab force full redraw when textprop popup hides on scroll
  • 6d725ff add RGBA alpha support for popup images
  • 7e2f531 fix cursor flicker after popup sixel emit
  • e41d02f skip image emit for hidden popups
  • 2d2fe68 expose popup image via popup_getoptions and add tests
  • 5980570 add kitty graphics protocol backend for popup images
  • de71e2a broaden kitty backend auto-detection
  • 9e5cad1 delete kitty placement when popup hides or closes
  • f0d7d9a add active probe for kitty graphics support
  • e985b55 implement mch_calc_cell_size() on Windows console
  • f1fe523 add CSI 14 t fallback to mch_calc_cell_size() on Windows
  • 1b328ba add Cairo image backend for popup_image (GTK2/3)
  • 058a68b document popup_create() image attribute and image_* features
  • 4aaa201 use strtol for CSI 14 t pixel size response
  • 9f1c28f rely on terminal probe for kitty backend detection


View it on GitHub or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/bbbdfc3e5f0868fe90dcc61d7829725ec994394b/after/9f1c28fec617a23363a72ece89f862aa5ef38556@github.com>

mattn

unread,
May 10, 2026, 11:56:31 AM (yesterday) May 10
to vim/vim, Push

@mattn pushed 1 commit.

  • 403c959 cache sixel encoder buffers across calls


View it on GitHub or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/9f1c28fec617a23363a72ece89f862aa5ef38556/after/403c959eedd62593fa805f7f1ecd5e6f6a45aac9@github.com>

mattn

unread,
May 10, 2026, 7:25:06 PM (17 hours ago) May 10
to vim/vim, Push

@mattn pushed 20 commits.

  • 0f18c5f feat: support image attribute in popup_create() via sixel
  • 39c95d2 feat: add GDI backend for popup image, generalize FEAT_SIXEL
  • 4cd0532 fix popup image redraw after paint and cursor updates
  • 949656d defer sixel encoding and crop to fit screen
  • 48f2456 force full redraw when textprop popup hides on scroll
  • 953461b add RGBA alpha support for popup images
  • 2264d35 fix cursor flicker after popup sixel emit
  • b3b2b9f skip image emit for hidden popups
  • 0550ff7 expose popup image via popup_getoptions and add tests
  • 51cfce4 add kitty graphics protocol backend for popup images
  • 91693a8 broaden kitty backend auto-detection
  • 431b2b8 delete kitty placement when popup hides or closes
  • 8d4b5b2 add active probe for kitty graphics support
  • 3b0678c implement mch_calc_cell_size() on Windows console
  • a7664be add CSI 14 t fallback to mch_calc_cell_size() on Windows
  • e14daa5 add Cairo image backend for popup_image (GTK2/3)
  • 1b5841e document popup_create() image attribute and image_* features
  • 0c4fa81 use strtol for CSI 14 t pixel size response
  • c501598 rely on terminal probe for kitty backend detection
  • 80c5034 cache sixel encoder buffers across calls


View it on GitHub or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/403c959eedd62593fa805f7f1ecd5e6f6a45aac9/after/80c503487af817bcc5991ea7db8888b616d10387@github.com>

mattn

unread,
May 10, 2026, 9:16:41 PM (15 hours ago) May 10
to vim/vim, Push

@mattn pushed 5 commits.

  • 4048696 crop popup image to clipwindow visible region
  • 03f168f reuse popup_compute_clip() for popup image clipping
  • d4f1a9b emit clipped popup image when origin is above host top
  • 09dfa1a emit popup image after topoff shift is restored
  • dcf27c3 keep popup sixel image off the host status line


View it on GitHub or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/before/80c503487af817bcc5991ea7db8888b616d10387/after/dcf27c3f8c9bb9e2efbca76f56ce71326ad168e7@github.com>

mattn

unread,
May 10, 2026, 9:23:17 PM (15 hours ago) May 10
to vim/vim, Subscribed
mattn left a comment (vim/vim#20136)

Now popup image support clipwindow

https://github.com/user-attachments/assets/2dbe7168-52de-41ff-9a25-d269b1d2f7e5


Reply to this email directly, view it on GitHub, or unsubscribe.


Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/c4416917707@github.com>

github-advanced-security[bot]

unread,
May 10, 2026, 9:28:46 PM (15 hours ago) May 10
to vim/vim, Subscribed

@github-advanced-security[bot] commented on this pull request.


In src/popupwin.c:

> +
+    VIM_CLEAR(wp->w_popup_image_seq);
+
+    // The sixel/kitty encoders read data tightly packed as width*height
+    // pixels.  When the source row width changes (left or right clipped),
+    // or when rows must be skipped from the top, build a contiguous cropped
+    // buffer.  A pure bottom crop (target_h reduced, full source width) can
+    // reuse the source buffer as-is.
+    if (crop_left_px > 0 || crop_right_px > 0 || crop_top_px > 0)
+    {
+	int bpp = wp->w_popup_image_alpha ? 4 : 3;
+	int src_stride = wp->w_popup_image_w * bpp;
+	int dst_stride = target_w * bpp;
+	int y;
+
+	crop_buf = alloc(target_h * dst_stride);

CodeQL / Multiplication result converted to larger type

Multiplication result may overflow 'int' before it is converted to 'size_t'.

Show more details


Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications on the go with GitHub Mobile for iOS or Android.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/20136/review/4260271822@github.com>

Reply all
Reply to author
Forward
0 new messages