Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@andy29485
Copy link

Implements #1765

Changes

  • allow content outside sixel region (extra text from previewer scripts)
  • fix extra text from sixel to appear in preview box
  • remove sixel dimension calculations as they are no longer needed

Motivation

Prior to #1943 I was able to add extra info to previews containing sixels (e.g. show both cover art and song title for music files) using workarounds. My hacks (workarounds) were somewhat broken by the recent sixel changes in r36 (output was effectively restricted to just the area of the sixel itself); so I decided that it's probably time to open a PR (or at least maintain a personal fork).

Other

I'm not a go developer, so any comments are appreciated.

@CatsDeservePets
Copy link
Collaborator

Just to be clear, my review is purely cosmetic and not about the changes itself.

@andy29485
Copy link
Author

Just to be clear, my review is purely cosmetic and not about the changes itself.

Will fix once I'm off work.

sixel := reAnsiShift.ReplaceAllString(*reg.sixel, xShift)

screen.LockRegion(win.x, win.y, (iw+cw-1)/cw, (ih+ch-1)/ch, true)
screen.LockRegion(win.x, win.y, win.w, win.h, true)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Locking the entire preview region isn't good because it will continue to show the part of the previous image that is not covered by the new one. You can refer to #1943 to see why the implementation is done the way it currently is.

If you want to print additional text with the sixel image, you will have to do the following in the previewer script:

  1. Manually print out blank characters to wipe the preview area
  2. Write the sixel data and text to a temp file
  3. Change the size reported in the sixel data to reflect the size of the entire preview window
  4. Output the updated contents

The downside is that there will now be flickering since you are clearing the previous image and then drawing the new image afterwards, which is what #1943 is trying to prevent in the first place. Of course it would be nice if chafa could directly support printing additional text, but if not then someone else would have to write a tool that is capable of doing so.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe I understand the issue (and should have a fix that doesn't flicker).

I think that the flicked used to happen in <=r35 due to the clearing of the screen and the drawing of the new sixel happening at different times (clear gets called on switch, well before preview is called, and only then can printSixel get called).

This is easily fixed by printing out the wall of spaces (to clear the old sixel) in printSixel right before drawing the new sixel. Only concern is if the screen is resized and the new sixel is smaller than the old one. But this shouldn't be an issue since the extra bits of the old one are outside the locked region, which gets gets overwritten by other parts of the lf ui (we only need to care about the parts of the locked region not covered by the new sixel - which is easy, just clear the entire to-be-locked region).

My, admittedly untrained, eye doesn't see a difference between this approach and the approach done by #1943 (using wezterm; I usually use konsole which has other sixel issues, but no flickering).

Copy link
Collaborator

@joelim-work joelim-work Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is easily fixed by printing out the wall of spaces (to clear the old sixel) in printSixel right before drawing the new sixel.

Explicitly clearing out the preview area before drawing the new image will temporarily show nothing, as opposed to just drawing the new image directly over the old one. This is actually quite noticeable when I tried it using Windows Terminal (there seems to be another issue with some residue on the right hand side, but that is because Windows does things differently and doesn't have a cell size).

Current behavior:

original.mp4

Behavior after these changes:

pullreq.mp4

I was wondering if you could instead try to solve this by changing the output of your previewer script so that it contains:

  • A blank sixel image (to indicate that the output contains sixel data, should also contain the size for the entire preview window)
  • Escape sequences to clear the preview area
  • The actual sixel image
  • Additional text you want to display

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, I'm not able to reproduce this behavior (even with large images in a zoomed out terminal) in konsole or wezterm (and I don't have a windows machine to test this), but that is an issue.

After some experimenting, I realized that I don't actually need to clear out the screen with spaces -- at least in the two terminals I tested, there was no difference.

If this doesn't work, I'm out of ideas for now. Alternatives:

  • As you suggested we(or the preview script) could change the size of the reported sixel. But I don't like this approach: lf isn't the final consumer of the sixel, the terminal is and it's not like lf will fix the corrupted sixel data.
  • We could also do proper parsing of sixels and put them in reg.lines, tweak printSixel to know what line to print at, and tweak printReg to know how many lines to skip over before printing real lines after a sixel. But that will likely run into the same issues that my other approaches ran into, the attempts I've made so far are just simpler versions of this more general (and probably slower) solution.

Copy link
Collaborator

@joelim-work joelim-work Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I tested, I found that the spaces were necessary if the entire preview region was locked. Locking the preview region means that tcell cannot update it, and without anything else to clear that region, parts of the previous image will still be shown if not covered by the new image (e.g. drawing an image in portrait orientation over an image in landscape orientation). Maybe other terminals are intelligent enough to track the size of a sixel image, and clear it entirely if part of it is overwritten - I do not know.

I guess you could try generalizing the parsing logic to detect and store combinations of sixels and text (it would have to be able to detect different cases like sixel followed by text, or multiple sixels, or text followed by sixel followed by more text, etc.). And then lock the region for each sixel or line of text separately. But it does result in more complex code, which is why we just accounted for one sixel image and have lf lock a single region.


EDIT: So I ended up getting this working myself: https://github.com/joelim-work/lf/tree/sixel2. It uses a generic implementation for reading files that can handle both newlines and sixel images, so there is no longer any need for the sixel option, or the previewer output to start with ESC+P. Hopefully it works for you.

@andy29485 andy29485 force-pushed the master branch 2 times, most recently from 80ccfc6 to 37dbef1 Compare August 13, 2025 23:33
- allow content outside sixel region (extra text from previewer scripts)
- fix extra text from sixel to appear in preview box
- remove sixel dimension calculations as they are no longer needed
@joelim-work
Copy link
Collaborator

This is implemented by #2109

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants