Skip to content
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

Always reset cursor correctly on exit. #7931

Merged
merged 1 commit into from Aug 15, 2023

Conversation

dilr
Copy link
Contributor

@dilr dilr commented Aug 13, 2023

This is intended to be a fix for #7404. I was able to replicate on MacOS by setting Terminal.app's default cursor to something other than Block, and then binding a key to :quit as described in the issue. Via debugging, I found that Terminal::restore actually does reset the cursor correctly regardless of if a keybind is used or if :quit is used.
However, the cursor gets set back to CursorKind::Block when the process exits if a keybinding was used.

It turns out that the Drop impl for Terminal will put the cursor back in block mode if terminal.cursor_kind is Hidden. Via debugging, I found that this was not the case if :quit was used but was the case if the keybind was used.

My understanding is that either Terminal::restore or TerminalBackend::force_restore will be called before exit, and both reset the cursor. Thus it seems to me that the Drop impl for Terminal is redundant and does not have the information needed to do the reset properly. Thus this PR removes the Drop impl.

When Application::run is exiting, either Terminal::restore or
Terminal::force_restore will be called depending
on if a panic occured or not.
Both of these functions will reset the cursor to terminal's default.

After this is done, Terminal::drop will be called.
If terminal.cursor_kind == Hidden, then
the cursor will be reset to a CursorKind::Block,
undoing the work of restore or force_restore.

This commit just removes the drop implementation,
as its job is already better handled in restore and force_restore.
Copy link
Member

@the-mikedavis the-mikedavis left a comment

Choose a reason for hiding this comment

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

Good catch!

For context: we use the terminal's (block) cursor in the Prompt component used to enter typable commands, so when you use :quit you're exiting from the prompt with Terminal.cursor_kind == Block. With a keybind you can exit from normal mode where the cursor is hidden (done by default, so we can color the cursor), so the Drop calls show_cursor. restore and force_restore should always be called even if we panic so no need to reset the cursor in the Drop anyways.

@the-mikedavis the-mikedavis added C-bug Category: This is a bug S-waiting-on-review Status: Awaiting review from a maintainer. labels Aug 15, 2023
@archseer archseer merged commit ea88677 into helix-editor:master Aug 15, 2023
6 checks passed
@dilr dilr deleted the no_override_term_reset branch August 15, 2023 13:10
dgkf pushed a commit to dgkf/helix that referenced this pull request Jan 30, 2024
…-editor#7931)

When Application::run is exiting, either Terminal::restore or
Terminal::force_restore will be called depending
on if a panic occured or not.
Both of these functions will reset the cursor to terminal's default.

After this is done, Terminal::drop will be called.
If terminal.cursor_kind == Hidden, then
the cursor will be reset to a CursorKind::Block,
undoing the work of restore or force_restore.

This commit just removes the drop implementation,
as its job is already better handled in restore and force_restore.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug S-waiting-on-review Status: Awaiting review from a maintainer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Using a keypress to :quit fails to restore terminals cursor style
3 participants