Recently there is a popular github repo called lsix, and it's using sixel graphics to display images inside a terminal. Currently I am using rxvt-unicode as my terminal emulator, but it seems not to work well with sixel.

Anyone know how to make it support sixel?

(I am using Ubuntu 18.04 LTS FYI)

  • sure - you modify the program, as suggested here. – Thomas Dickey Dec 31 '18 at 10:28
  • @ThomasDickey thx! But I wonder if there is any other way without modifying the source code? – tjysdsg Jan 1 at 9:22
  • Use a different program, then. Your choice. – Thomas Dickey Jan 1 at 10:13

Besides using the rxvt-unicode-sixel fork, it might be possible to implement sixel by writing a perl extension. Documentation for that is in the urxvtperl(3) manpage. I don't know much about sixel but I imagine it's a matter of:

  • intercepting the sixel escape sequences, interpreting them and not letting them pass through to the main escape sequence interpreter. You can replace the sequence with newline characters to displace the correct number of lines to fit the image's height, maybe scaled to fit the width.

  • drawing the image. You can get the correct window id via the API urxvt provides to extensions, and use regular xlib or xcb functions to draw the image if need be.

  • watch out for events like scrolling to redraw the image as needed.

I see many possibilities here that could be configurable, though I don't know if there are standards on sixel implementations. For example, what happens to images when resizing a terminal? Is it clipped? Is it scaled? only on creation or on every resize as well? what happens when the cursor is then moved over the image and one writes enough for text to wrap? what happens to the image and wrapped text when you resize then? etc.

I think the ideal would be to initially draw it at the scale of what's smaller between the terminal width and the image size, and set that as the maximum size of the image. Rescale the image on terminal resize, while respecting the maximum size set. With respect to text drawn over it, it might get a little complicated to keep that text over the image on redrawing the image...

Sorry, seems I got a little excited and got out of scope for your answer. Kind of wish I had the time to work on this.

EDIT: To answer to skepticism in the comments on the ability to work with pixels from a urxvt perl extension, here is a proof of concept. It sets a pixel the color white on coordinate (10, 10) from the top-left:

use strict;
use warnings;
use X11::Protocol;

my $X = X11::Protocol->new;

sub on_refresh_end {
  my $term = shift(@_);
  my $gc = $X->new_rsrc;
  $X->CreateGC($gc, $term->vt,
    foreground => $X->white_pixel);
  $X->PolyPoint($term->vt, $gc, 0, (10,10));

To install this extension, put it in ~/.urxvt/ext/sixel-proof-of-concept, add it to ~/.Xresources (or ~/.Xdefaults if you use that) by adding the line URxvt.perl-ext-common: sixel-proof-of-concept, load that by doing xrdb ~/.Xresources, and make sure you have the X11::Protocol perl module installed.

  • The perl interface won't get you there, since it is not able to work with pixels/drawing. – Thomas Dickey Mar 29 at 21:15
  • @ThomasDickey If I remember right, any program can draw to any X window. So even if urxvt's interface doesn't provide that, you should be able to use whatever perl libraries correspond with the Xlib or XCB C libraries. You just need to pass the terminal's window id as argument. – JoL Mar 29 at 22:25
  • Then your answer should show how to do this :-) – Thomas Dickey Mar 29 at 22:59
  • @ThomasDickey "should" is a strong word, but I guess I understand that you don't think this is a valid answer if for some reason it were impossible to work with pixels from a urxvt perl extension. I provided a proof of concept. – JoL Mar 30 at 0:00
  • Can the downvoter explain their downvote? – JoL Mar 30 at 1:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.