Hi everyone!

I have attempted to write patches for some annoying behaviour in dvtm. Resizing 
a window while a full-screen application has enabled the alternate buffer can 
affect the normal buffer and its cursor in some unexpected ways. I think I 
understand what is happening and I have tried writing patches for it. Verbose 
explanation follows:

Issue #1: The cursor ends up in the middle of my shell output when I exit vis

This happens specifically when I start vis, increase the size of the window 
(usually by enabling full-screen layout with multiple windows in the master 
area) and then exit vis. It does not have to be vis, any full-screen 
application will do. Also, the normal screen buffer must be somewhat full.

I think the full-screen application enables the alternate buffer and saves the 
cursor position using escape sequences when it starts. When I increase the 
window size, the function vt_resize() calls buffer_resize() to increase the 
size of the normal screen buffer. In buffer_resize(), the backfill mechanism is 
triggered to scroll out content from the scrollback buffer. Now the cursor row 
is moved but the saved cursor position is not updated. When the application 
exits, it restores a cursor position that is no longer valid and the cursor 
ends up on a different row than before the application was started.

Updating the cursor position in the backfill mechanism fixes the issue [1]. 
Maybe it breaks compatibility with some applications? Another idea I had was to 
disable backfill for the buffer not in use but this restricts the backfill 
feature and requires more invasive changes to the source.

In general, any scrolling may invalidate a saved cursor position. But as I 
understand it, the cursor position is typically saved only for the normal 
buffer while the alternate buffer is enabled. As the only code that scrolls the 
normal buffer while the alternate buffer is enabled is the backfill mechanism, 
this problem is nicely isolated. My patch handles the case where the window 
size is increased. The backfill mechanism also scrolls content into the 
scrollback buffer when the window size is decreased, but I suspect this is not 
problematic because saved cursor positions are clamped after being restored. 
Maybe it would be a good idea to modify it anyway just to signify intent.

Issue #2: Empty lines are added in the middle of my shell output when I exit vis

This happens specifically when I start vis, decrease the size of the window and 
then increase the size of the window to the exact original size. The cursor 
must be located on a row in the lower half of the window.

After resizing the buffers, the function vt_resize() calls cursor_clamp() to 
clamp the cursor of the currently enabled buffer. However, the cursor of the 
other buffer is not clamped. I think it ends up on a row below the resized 
viewport. When the size of the normal buffer is increased to its original size 
the backfill mechanism uses the invalid cursor position to decide whether a 
backfill is needed; it makes the wrong decision and no content is scrolled out. 
The cursor ends up somewhere inside the region of empty rows created during the 
resize.

My suggested fix is to refactor cursor_clamp() to take the buffer to operate on 
as a parameter and update all ocurrences where it is used [2]. A second call is 
added to vt_resize() to clamp the cursor of both buffers on resize.

Should I post the patches to hackers using git --send-email? I need some 
confidence here, at least one person should approve. :-)

[1] attached file: update-saved-cursor-position-on-backfill.diff
[2] attached file: clamp-cursors-of-both-buffers-on-resize.diff

--
Audun Sutterud

Attachment: update-saved-cursor-position-on-backfill.diff
Description: Binary data

Attachment: clamp-cursors-of-both-buffers-on-resize.diff
Description: Binary data

Reply via email to