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 input does not work correctly on urxvt: Moving the cursor always claims the mouse button is clicked. #791

Closed
psychon opened this issue Dec 15, 2023 · 4 comments
Assignees

Comments

@psychon
Copy link

psychon commented Dec 15, 2023

Hi,

running the print_key_press example in urxvt and moving the mouse around produces e.g.

( 27 91 60 51 50 59 56 53 59 52 50 77 ) -> mouse_left_pressed_control(84,9)

Notice that this incorrectly claims that the left mouse button is pressed.

The same thing in xterm:

( 27 91 60 51 53 59 55 57 59 49 53 77 ) -> mouse_none_pressed_control(78,13)

This issue makes basically anything interactive unusable. E.g. button will trigger every time the cursor moves slightly across it.

@ArthurSonzogni
Copy link
Owner

ArthurSonzogni commented Dec 15, 2023

Hello @psychon

Thanks for reporting this

I think this was improved ~30 days ago with:
#774

Every builtin components have been updated.
A new API for custom on is available

  bool Mouse::IsPressed(Button button) const;
  bool Mouse::IsHeld(Button button) const;
  bool Mouse::IsReleased(Button button) const;

Does the new version satisfies you, or do we need something different?

That being said, the example print_key_press would still report the same kind of result.

@psychon
Copy link
Author

psychon commented Dec 15, 2023

Ah, you are right. I was initially experimenting with the latest release and then switched to latest main before reporting this issue.

However, "things" still don't seem to work correctly. I switched to the component/dropdown example. My instructions:

  1. click an entry (to open the dropdown)
  2. move the mouse to an item
  3. click
  4. move the mouse

With xterm, the dropdown closes at step 3 and the mouse move has no effect. With urxvt, the mouse click has no effect and only at step 4 does "something" happen.

Put differently: Yes, I can now interact with the dropdown via the mouse, but things still behave weird / unexpected.

I checked out git at c31aecf2edde81d20f4f4bc8c97af053026483a6^ (= before #774) and there things indeed behave as I described out. That's a lot worse than the current state of things.

@psychon
Copy link
Author

psychon commented Dec 16, 2023

I found http://pod.tst.eu/http://cvs.schmorp.de/rxvt-unicode/doc/rxvt.7.pod#Mouse_Reporting and the following sub-sections. ftxui seems to enable 1000, 1003, 1015, and 1016.

I did some more tests showing the raw input that was received in a human readable form:

diff --git a/examples/component/print_key_press.cpp b/examples/component/print_key_press.cpp
index c481271..221f93a 100644
--- a/examples/component/print_key_press.cpp
+++ b/examples/component/print_key_press.cpp
@@ -22,6 +22,9 @@ std::string Stringify(Event event) {
   std::string out;
   for (auto& it : event.input())
     out += " " + std::to_string((unsigned int)it);
+  out += " ";
+  for (auto& it : event.input())
+    out += it;
 
   out = "(" + out + " ) -> ";
   if (event.is_character()) {

I am just showing the printable part of the above output.

  • Mouse move: [<31;94;30M
  • Button 1 press: [<0;98;29M
  • Button 1 release: [<0;98;29m
  • Mouse move after the above button business: [<32;67;40M
  • Button 2 and 3 work the same with numbers 1 and 2.
  • Mouse moves always indicate the last button.
    • After I pressed button 1, mouse moves use 32 as the first argument
    • After button 2, it's 33
    • After button 3, it's 34

So... the moves are the last button that was pressed with 32 added?

With the following proof-of-concept patch, the print_key_press example seems to produce sane output.

diff --git a/src/ftxui/component/terminal_input_parser.cpp b/src/ftxui/component/terminal_input_parser.cpp
index 3ba0e69..ec3cc3c 100644
--- a/src/ftxui/component/terminal_input_parser.cpp
+++ b/src/ftxui/component/terminal_input_parser.cpp
@@ -401,6 +401,10 @@ TerminalInputParser::Output TerminalInputParser::ParseMouse(  // NOLINT
   output.mouse.meta = bool(arguments[0] & 8);                       // NOLINT
   output.mouse.x = arguments[1];                                    // NOLINT
   output.mouse.y = arguments[2];                                    // NOLINT
+  if (arguments[0] & 32) {
+    // DECMode::kMouseSgrExtMode: This is a move and not a press
+    output.mouse.button = Mouse::Button::None;
+  }
   return output;
 }
 

How did I come up with the above? The following part of the urxvt docs (but ignoring the offset since mode 1015 does not include one):

Bit 5 of b is set for motion events or double clicks (rxvt extension, disabled by default):

Motion = (b - SPACE) & 32

However, if I open a new terminal, newer press a button and move the mouse, I get e.g. [<31;78;45M. Button -1 pressed?!?

I also dug into urxvt's source code. The mouse reporting "stuff" is generated here: http://cvs.schmorp.de/rxvt-unicode/src/command.C?revision=1.603&view=markup#l1353

So... since ftxui enables mode 1006 (kMouseSgrExtMode / PrivMode_ExtMouseSGR), all the docs for urxvt mode do not apply. And I could have actually noticed that the escape sequences above have [< and the < would not be present in urxvt mode...
Besides that, I have not found anything helpful in this source code. I am now trying to figure out how this code remembers the last button that was pressed?!?

Edit: Found it. MEvent is a member variable of the class and is used to track this. The button_number is calculated at MEvent.button - Button1. At startup, MEvent.button is initialised to AnyButton and AnyButton - Button1 is -1. I'll report a bug to urxvt.

@ArthurSonzogni I hope some of this helps you help me. I never dug into escape sequences before.

@ArthurSonzogni
Copy link
Owner

Thanks you very much!

You made me realize 3 things:

  • I forgot to record the mouse.control modified.
  • Terminal do report "movement". I can simplify ftxui!
  • urxvt behave a bit differently than other terminals.

I start working on something. I will send you a PR.

@ArthurSonzogni ArthurSonzogni self-assigned this Dec 16, 2023
ArthurSonzogni added a commit that referenced this issue Dec 16, 2023
- Record whether the mouse moved. Suppress the previous alternative
  implementation.
- Record mouse.control modifier.

Fixed:#791
ArthurSonzogni added a commit that referenced this issue Dec 16, 2023
- Record whether the mouse moved. Suppress the previous alternative
  implementation.
- Record mouse.control modifier.

Fixed:#791
ArthurSonzogni added a commit that referenced this issue Dec 16, 2023
- Record whether the mouse moved. Suppress the previous alternative
  implementation.
- Record mouse.control modifier.

Fixed:#791
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

2 participants