[dev] [dvtm] unexpected cursor behavior when resizing the alternate buffer

From: Audunsu <audunsu_AT_protonmail.com>
Date: Thu, 24 Aug 2017 03:14:50 -0400

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

Received on Thu Aug 24 2017 - 09:14:50 CEST

This archive was generated by hypermail 2.3.0 : Thu Aug 24 2017 - 09:24:20 CEST