New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: option to not scroll cursor with iTerm2 images #1228
Comments
Where "do not move cursor" means "do not scroll" or actually keep cursor where the image started so the next image or text will overlap it? |
Yep, some TUI apps, like Yazi, fix the right sidebar as the preview area and take over the clearing of all previewed content -- because it's not just images that are previewed, but also codes, directories, and so on. At this point the extra cursor movement is not only unnecessary, but also conflicts with the TUI itself.
I think it would be more flexible to be able to control it for each image, and if another image doesn't want to render in a fixed area, the scrolling may need to be restored. Another reason is that WezTerm is implemented in this way, that it would be easier for TUI devs to adapt if the format is kept the same, without having to take into account different standards for different terminals. |
I have a few concerns about a quick go:
|
I don't know much about the implementation behind iTerm2, but I tested at macOS that it works fine even without this parameter. But on Windows both WezTerm and mintty require this parameter, maybe it has something to do with the platform difference.
Currently only WezTerm extends this parameter, this is its documentation https://github.com/wez/wezterm/blob/main/docs/imgcat.md
It's the literal "do not move cursor" for this parameter. When a TUI app moves the cursor at the same time as the terminal, it can lead to unexpected results, scrolling the screen being the most common one. |
I guess what you mainly need is to prevent scrolling by graphics output. Implementation is easy and I guess I'll make that a new private mode DECSET 7780. |
Sounds good! let me know if you need testers. |
The new feature is now in the repository. |
Thanks for your work! I tested the latest code TUI was corrupted, and could not receive Here is a reproduction video: 388.mp4 |
What's wrong in the video? |
When building with fa33000 (Aug 7, first 25 seconds of the video), the TUI is messed up, tabs float to the top left corner and no key input is recognized, on zoom the whole screen disappears. Use its previous commit f61f9d5 (Aug 4) everything works fine. It seems that the debug code messes up the TUI app, I'm not sure how to turn it off. |
The debug code isn't even active as it's #ifdef'ed out. There must be something else going on. |
I noticed that Lines 894 to 897 in fe4430d
|
Oh! Quite embarassing. That happens if you work on multiple issues in one file. Fixed. |
Thanks, all is well with TUI now. I tested the new DECSET 7780 mode and it works fine, now my screen doesn't get scrolled. But I also found another issue when adapting Mintty, there seems no way to get the iTerm2 image anchored at the current cursor position like Sixel, is there anything I missed? |
It works but it does not work? I don't understand. |
For the clarification:
Here is the ANSI escape code to send:
Also have a video to explain it (note the bottom right corner): 133.mp4 |
If I output an image with your escape sequences, it appears in the rightmost column of line 2 (near the top), properly corresponding to the 2;99 coordinates. |
1111.mp4I made a minimal replication and tested it in WezTerm and Mintty, WezTerm works fine (first 15 seconds of the video), but Mintty doesn't correctly respect the cursor position. |
I have no rust. Please |
The test case img.txt confirms that positioning works properly. |
You used Save Cursor and Restore Cursor sequences to "keep" the cursor position. That could be a problem in the context of your application if it happens to be using them already, as these sequences cannot be nested. |
Nope, the reproduction code above only has one Save Cursor and Restore Cursor, which doesn't work properly. This log.txt is what I logged using I'm not sure if this is related to ConPTY, but the same code works without issues in WezTerm. |
Yes, there is no Save/Restore Cursor sequence in the log. Please report that to the cygwin mailing list. |
I'm not familiar with Cygwin and Windows, how do I describe the issue? Is the Save/Restore Cursor not visible to Mintty because Mintty is using Cygwin as a dependency library but Cygwin isn't providing Mintty with the correct escape code results? |
Your previous suspicion, ConPTY, is more likely. Anyway, I see in the log that the save/restore sequences do not arrive at mintty, so mintty behaviour is correct. So the issue should be taken to the cygwin mailing list. |
Can you replace the Save/Restore with absolute cursor placement in that application? It should be knowing where the next output is supposed to go. Or is "do not move cursor" behaviour needed in addition to "do not scroll"? And if so, does it make sense to combine them both in mode 7780? |
I don't understand this. Do you mean that after displaying the image, the cursor position is no longer restored after the move and the TUI app uses the absolute position for the next time it draws? If so, that's hard to do, since the TUI library I'm using, ratatui, doesn't have a corresponding API to do this. Are there any TUI projects that use Mintty with iTerm2 to display images? I'd like to use it as a reference to see how they are implemented.
I need to do more tests to see if they make sense, at the moment Mintty doesn't display images properly, I found that |
Please be careful about how you describe the issue, as others reading this might get confused. Mintty does display images properly as I demonstrated. Your application with your library does not display properly in mintty. The reason is ESC 7/8 being filtered out, perhaps by ConPTY. So we can look for an alternative. If you display an image, using that library, don't you know your own current cursor position? If you do, you can simply set the same position to refresh it after image display. |
Sorry, maybe I worded it wrong, I have to clarify: The reproduction I provided above implements the iTerm2 image protocol correctly, but I can't get the correct result in Mintty, I don't think it can be called "Mintty does display images properly".
Yes, it may be a ConPTY issue, but WezTerm, which is also based on ConPTY and works fine, I'm not sure why.
I didn't understand this, could you please give an escape code example like #1228 (comment), it would be helpful for both of us to explain the issue more clearly. |
I think what @mintty may mean is that the Cygwin console interface dealing with running native Windows programs via |
\x1b[2;10H place cursor |
It's hard to do that. The UI library I'm using, ratatui, provides a higher level of abstraction for components, and I can't predict its next cursor position, and it's not portable :( |
You are writing the application, right? So you are preparing an image for output and somehow get it written. Then you should be knowing where to place that image, right? That's how I understood the scenario but maybe it's different. |
Just FYI, something like that is almost certainly not going to work over conpty. When conhost sees the In general, if you're using an escape sequence that conhost doesn't understand, there's a good chance it won't work correctly. |
Ah, that might be the problem. ConPTY apparently also transforms Save/Restore Cursor into absolute positioning (CUP). So I assume Restore Cursor is also dropped because of that. Maybe it would help to set the cursor explicitly to a wrong position, then back. |
Windows Rust crate |
@BrianInglis Hey, the reproduction I provided above just writes the escape sequences to stdout, without using libraries like ratatui, crossterm, to control the assumptions. I've only tested in Mintty and WezTerm, which are the only 2 emulators I know of that support displaying images on Windows. |
@mintty If that works at all, it's likely to be flaky. Depending on the timing, conpty may only trigger a refresh after you've moved the cursor back to the original position. And in that case, it's again likely to think there's nothing to update. You could try inserting a delay between the two moves, but even then conpty will sometimes optimize the cursor movement with relative operations, e.g. using What I don't understand is why it would work any better on WezTerm, assuming it's also using conpty. It's possible they're bundling a more recent version, which could make a difference, but I'd still expect it to have issues. |
Yes, WezTerm is using the more recent version from May 19, wez/wezterm@43a8b44
FYI, I use the same code with 234.mp4 |
OK, so the clarifications suggest that you need more support from mintty. I had asked before, but let's get that clearer: there are a few options to deal with the two features "do not scroll" and "do not move cursor":
Which of these (or other) options is preferable and most likely to be portable? |
As I said, mode 7780 is already working as expected and the screen really doesn't get scrolled anymore. Now the issue is that it's not possible to move the cursor to the specified position before the image is rendered, due to the Whether implementing mode 7780 as "do not move cursor" at the same time would help, depending on whether the missing Is it possible to create a git patch for "mode 7780 could imply also "do not move cursor", so enabling both at once", I'll provide further information after testing it out. |
I guess you are misinterpreting something about this, maybe because you are writing multiple images in sequence? Anyway, I've implemented "do not move cursor" for mode 7780 and uploaded it to the repository. Please test. |
Yes, I need to write multiple images. When starting the next image, I need to use I have tested the new code and it behaves the same as the last version. But I finally found a way to get the image preview to work, which was prompted by @j4james, I added a I'm not sure if there's a better way to do it, and while it works now, it's still unstable, and occasionally the picture gets washed out at the screen bottom. 1112.mp4 |
I'm puzzled. If you write two subsequent images, and I assume you do not write them to the same position, there would be a positioning sequence (CUP) between them, with different coordinates. What would make ConPTY suppress the proper positioning for the second image? |
Sorry I don't know more details behind ConPTY, but the issue can be reproduced using the following code: fn main() -> anyhow::Result<()> {
let img = fs::read(Path::new("./demo.jpg"))?;
let mut stdout = std::io::stdout().lock();
write!(stdout, "\x1b[?25h\x1b7\x1b[2;20H")?;
stdout.flush()?;
thread::sleep(Duration::from_millis(100)); // to switch this
write!(
stdout,
"\x1b[?7780h\x1b]1337;File=inline=1;size={};width={}px;height={}px:{}\x07",
img.len(),
400,
240,
general_purpose::STANDARD.encode(&img)
)?;
write!(stdout, "\x1b8\x1b[?25l")?;
write!(stdout, "\x1b[?25h\x1b7\x1b[20;20H")?;
stdout.flush()?;
thread::sleep(Duration::from_millis(100)); // to switch this
write!(
stdout,
"\x1b[?7780h\x1b]1337;File=inline=1;size={};width={}px;height={}px:{}\x07",
img.len(),
400,
240,
general_purpose::STANDARD.encode(&img)
)?;
write!(stdout, "\x1b8\x1b[?25l")?;
Ok(())
} The video to demonstrate it: 111.mp4And should this issue be closed? it seems gotten too far away from its original goal, and the |
We should check whether the ...20;20 comes through to the terminal. |
Initially adapting WezTerm had the same issue as Mintty, the image didn't follow the cursor, no matter what the cursor was set to, after two nights of testing I realized that WezTerm has to show the cursor before drawing the image, and then hide it, which is very strange... I filed an issue with them and the answer I got was because of ConPTY, I'm not sure, it's just a huge black box for me, so agonizing... |
The new behaviour is now also supported case-by-case by image parameter doNotMoveCursor as you requested. |
Thanks, it's now consistent with WezTerm behavior. |
Release 3.6.5. |
Hi, I'm working on a terminal file manager, limited by ConPTY, in Windows it can only use the inline images protocol, the current behavior moves the cursor while the image is rendering, which can cause the TUI to scroll and get broken.
It would be great if a new parameter
doNotMoveCursor=1
could be added to disable cursor movement, I've tested it inWezTerm -- the only one I know of that implements this protocol besides iTerm2/Mintty, and it works fine, here's the proposal: wez/wezterm#1424
The text was updated successfully, but these errors were encountered: