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

Mouse movement control sequences leak to terminal at app shutdown #4418

Open
slawek-es opened this issue Apr 15, 2024 · 10 comments
Open

Mouse movement control sequences leak to terminal at app shutdown #4418

slawek-es opened this issue Apr 15, 2024 · 10 comments

Comments

@slawek-es
Copy link

If the user is moving the mouse while the textual application exits, terminal control sequences from the mouse movement may leak from the application and get into the terminal.

This happens on all terminals I have tested: gnome-terminal and Terminator on Ubuntu Linux, and the Terminal on macOS. The issue can be easily reproduced using the examples from the textual repository. Here's a reproduction with five_by_five.py, where I press q on the keyboard while moving the mouse around the terminal:

control-seq-leak-2024-04-15_10.56.24.mp4

Please find the diagnostics output below:

textual diagnose output
<!-- This is valid Markdown, please paste the following directly in to a GitHub issue -->
# Textual Diagnostics

## Versions

| Name    | Value  |
|---------|--------|
| Textual | 0.56.4 |
| Rich    | 13.7.1 |

## Python

| Name           | Value                                        |
|----------------|----------------------------------------------|
| Version        | 3.11.7                                       |
| Implementation | CPython                                      |
| Compiler       | GCC 9.4.0                                    |
| Executable     | /home/saf/code/misc/textual/.venv/bin/python |

## Operating System

| Name    | Value                                        |
|---------|----------------------------------------------|
| System  | Linux                                        |
| Release | 5.4.0-176-generic                            |
| Version | #196-Ubuntu SMP Fri Mar 22 16:46:39 UTC 2024 |

## Terminal

| Name                 | Value          |
|----------------------|----------------|
| Terminal Application | Terminator     |
| TERM                 | xterm-256color |
| COLORTERM            | truecolor      |
| FORCE_COLOR          | *Not set*      |
| NO_COLOR             | *Not set*      |

## Rich Console options

| Name           | Value                |
|----------------|----------------------|
| size           | width=167, height=45 |
| legacy_windows | False                |
| min_width      | 1                    |
| max_width      | 167                  |
| is_terminal    | False                |
| encoding       | utf-8                |
| max_height     | 45                   |
| justify        | None                 |
| overflow       | None                 |
| no_wrap        | False                |
| highlight      | None                 |
| markup         | None                 |
| height         | None                 |

Copy link

We found the following entries in the FAQ which you may find helpful:

Feel free to close this issue if you found an answer in the FAQ. Otherwise, please give us a little time to review.

This is an automated reply, generated by FAQtory

@slawek-es
Copy link
Author

I took a shot at diagnosing this issue, and the issue disappears if we modify the shutdown sequence of the input thread to loop a few times more to drain the mouse movement sequences out from the input descriptor:

class LinuxDriver(Driver):
    ...
    def run_input_thread(self) -> None:
        ...
        countdown = 3

        try:
            with open("/tmp/textual_out", "a") as f:
                while not self.exit_event.is_set() or countdown > 0:
                    selector_events = selector.select(0.1)
                    for _selector_key, mask in selector_events:
                        if mask & EVENT_READ:
                            rdd = read(fileno, 1024)
                            unicode_data = decode(rdd, final=self.exit_event.is_set())
                            for event in feed(unicode_data):
                                self.process_event(event)
                    if self.exit_event.is_set():
                        print(
                            f"Exit event set, countdown: {countdown}, data: {rdd if mask & EVENT_READ else None}",
                            file=f,
                        )
                        termios.tcflush(fileno, termios.TCIFLUSH)
                        rdd = ""
                        countdown -= 1
        finally:
            selector.close()

I'm getting the following output in /tmp/textual_out if I move the mouse while quitting the application:

Exit event set, countdown: 3, data: b'\x1b[<35;101;46M'
Exit event set, countdown: 2, data: b'\x1b[<35;111;45M'
Exit event set, countdown: 1, data: 

so it looks like new mouse movement control sequences may appear on the linux driver's terminal file descriptor, even though the control sequence for disabling mouse support is already sent by disable_input, and the descriptor's input queue is flushed. I'm not sure how to proceed from here: this "draining" mechanism works to resolve this issue, but it looks very odd that we would have to do it.

@TomJGooding
Copy link
Contributor

TomJGooding commented Apr 15, 2024

This issue does seem specific to certain terminal emulators, at least from running quick tests with:

  • xterm
  • urxvt
  • alacritty
  • terminator
  • wezterm
  • Xfce Terminal

@davep
Copy link
Collaborator

davep commented Apr 15, 2024

FWIW I couldn't reproduce it with kitty on macOS.

@TomJGooding
Copy link
Contributor

@davep How about with macOS Terminal (just for confirmation as not one I'm able to check)?

@davep
Copy link
Collaborator

davep commented Apr 15, 2024

Didn't test with anything else; I'll try and remember to have a look the next time I'm at a machine.

@TomJGooding
Copy link
Contributor

I've also now tested with Xfce Terminal which shows the same issue, which makes me wonder if perhaps specific to VTE-based terminal emulators? (Though this wouldn't explain issues with macOS terminals.)

@piankma
Copy link

piankma commented May 6, 2024

for more macOS terminal emulators:
issue can be reproduced on Hyper, but not on iTerm2 and Terminal.app

@willmcgugan
Copy link
Collaborator

I can't seem to reproduce it at all with the latest Textual (on macOS).

@willmcgugan
Copy link
Collaborator

Actually, I did manage to reproduce it after a few attempt on Hyper. This should help me track it down!

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

No branches or pull requests

5 participants