Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@jonathanj
Copy link
Contributor

@jonathanj jonathanj commented Sep 21, 2025

Magit has mouse support via emacs builtin mouse support, one particularly useful aspect of this is being able to jump around instantly instead of needing to navigate in a fashion like "next line, next line, … next line", such as when staging individual lines or moving to a particular commit/stash.

After using the mouse for a bit, I felt like perhaps there could be a few simple actions:

  • Left clicking an item will move the cursor there
  • Left clicking the item already at the cursor will toggle it if it's a section, or show it if not
  • Right clicking an item will move the cursor there and immediately show it
  • Scrolling the mouse wheel (or trackpad) scrolls the view up/down without moving the cursor position

I tried to use as much of what infrastructure was already there to support implementing this, but one thing I didn't do was make the mouse actions bindable. I looked at how this might be done, modifying the parser to accept mouse1_click, etc. seems very straightforward, but all of the parser functions return KeyCode and it seems like adjusting that might be it's own whole PR.

I added a config option general.mouse_support that defaults to false to preserve the existing behaviour, although it could be argued that since the mouse input is captured it would be more intuitive if it did something. This doesn't disable mouse reporting, but just ignores the mouse events. I briefly looked at trying to disable mouse reporting in TermWiz, but my initial attempts didn't work. I think I would need to dig into the TermWiz source and CSI modes more to understand how to do this.

There's definitely some trailblazing in here, and some less-than-stellar code, so please feel free to suggest improvements.

- Left clicking an item will move the cursor there
- Left clicking the item already at the cursor will toggle the section
- Right clicking an item will show it
@jonathanj
Copy link
Contributor Author

On macOS, which has momentum scrolling, I think there is a bug in termwiz handling of these events. If I flick the trackpad, the view scrolls and then suddenly I get the "Remote" menu (shortcut key "M") appearing. Logging out the events you can see that the mouse event appears as keyboard input for no reason, with the "M" key being the only one with a binding. This doesn't happen when scrolling normally (i.e. without momentum):

[00:00:04.593] (2018c60c0) DEBUG  Mouse input: x=35, y=20, buttons=MouseButtons(VERT_WHEEL), modifiers=NONE
[00:00:04.608] (2018c60c0) DEBUG  Mouse input: x=35, y=20, buttons=MouseButtons(VERT_WHEEL), modifiers=NONE
[00:00:04.623] (2018c60c0) DEBUG  Mouse input: x=35, y=20, buttons=MouseButtons(VERT_WHEEL), modifiers=NONE
[00:00:04.639] (2018c60c0) DEBUG  Key input: modifiers=ALT, key=Char('[')
[00:00:04.643] (2018c60c0) DEBUG  Key input: modifiers=NONE, key=Char('<')
[00:00:04.648] (2018c60c0) DEBUG  Key input: modifiers=NONE, key=Char('6')
[00:00:04.652] (2018c60c0) DEBUG  Key input: modifiers=NONE, key=Char('5')
[00:00:04.657] (2018c60c0) DEBUG  Key input: modifiers=NONE, key=Char(';')
[00:00:04.662] (2018c60c0) DEBUG  Key input: modifiers=NONE, key=Char('3')
[00:00:04.666] (2018c60c0) DEBUG  Key input: modifiers=NONE, key=Char('5')
[00:00:04.671] (2018c60c0) DEBUG  Key input: modifiers=NONE, key=Char(';')
[00:00:04.675] (2018c60c0) DEBUG  Key input: modifiers=NONE, key=Char('2')
[00:00:04.680] (2018c60c0) DEBUG  Key input: modifiers=NONE, key=Char('0')
[00:00:04.684] (2018c60c0) DEBUG  Key input: modifiers=NONE, key=Char('M')
[00:00:04.697] (2018c60c0) DEBUG  Mouse input: x=35, y=20, buttons=MouseButtons(VERT_WHEEL), modifiers=NONE
[00:00:04.712] (2018c60c0) DEBUG  Mouse input: x=35, y=20, buttons=MouseButtons(VERT_WHEEL), modifiers=NONE

I don't think this is particularly serious (unless you bind reset hard to < or something) but I wouldn't know how to fix it in termwiz. There is this commit which might help, but I don't think that's been published.

@altsem
Copy link
Owner

altsem commented Sep 21, 2025

Sweeeet!

Seems to occur sometimes on my Fedora/Alacritty/Tmux too.
If I scroll upon launching gitu, it seems to occur. Or even if just moving the mouse upon launch.

Would love to have this as a default, but it's a nice start even with the bug.

@codecov
Copy link

codecov bot commented Sep 21, 2025

Codecov Report

❌ Patch coverage is 87.37374% with 25 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.50%. Comparing base (b3492a8) to head (1f285f7).

Files with missing lines Patch % Lines
src/app.rs 76.08% 11 Missing ⚠️
src/term.rs 44.44% 5 Missing ⚠️
src/lib.rs 0.00% 3 Missing ⚠️
src/ops/editor.rs 72.72% 3 Missing ⚠️
src/screen/mod.rs 91.17% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #422      +/-   ##
==========================================
+ Coverage   86.48%   86.50%   +0.02%     
==========================================
  Files          71       71              
  Lines        7116     7314     +198     
==========================================
+ Hits         6154     6327     +173     
- Misses        962      987      +25     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jonathanj
Copy link
Contributor Author

Seems to occur sometimes on my Fedora/Alacritty/Tmux too. If I scroll upon launching gitu, it seems to occur. Or even if just moving the mouse upon launch.

Ugh, that's unfortunate. Is it possible to try out the HEAD of termwiz somehow to see if this has been fixed, or if I should report it?

Would love to have this as a default, but it's a nice start even with the bug.

Do you think I should change the default to be true, or maybe best to leave it off until the bug is resolved? I'd be a bit worried about triggering some unpleasant git actions for users who have customised their bindings.

I wondered if implementing a workaround where seeing meta-[ as a keypress and then eating keystrokes for the next 50ms would alleviate it.

@jonathanj
Copy link
Contributor Author

It didn’t occur to me before now that I could probably put the show/open logic into the left click logic, and just check if the item is expandable to figure out which to do. Might be a bit more intuitive?

@jonathanj
Copy link
Contributor Author

It didn’t occur to me before now that I could probably put the show/open logic into the left click logic, and just check if the item is expandable to figure out which to do. Might be a bit more intuitive?

I pushed a commit to do this, it feels a lot more natural. I kept the right-click thing, so you can show files in the staged/unstaged for example.

Termwiz will sometimes not handle mouse scroll events, and instead they
are sent as key events of the escape sequence. This causes issues
because it triggers the app bindings, which could be harmful to users.
@jonathanj
Copy link
Contributor Author

jonathanj commented Sep 21, 2025

I added a workaround for the Termwiz bug, it just ignores key events for the next 75ms (a totally arbitrary number that felt like "not too long and not too short") every time it encounters ALT+[. Not the best thing to have to implement but it does seem to work reliably, and hopefully it can be removed in the near future.

Maybe now enabling mouse support by default is okay?

@jonathanj
Copy link
Contributor Author

I added code to directly disable mouse reporting in unix terminals if general.mouse_support is disabled, which means you can select text without needing a modifier. Which would address #409.

I ended up having to directly write the escape sequences to the terminal, since Termwiz doesn't seem to expose anything to do this and will always enable mouse reporting if the terminal has the capability.

@altsem
Copy link
Owner

altsem commented Sep 22, 2025

If it works smoothly, then having it as default would be nice.

I seemed to notice a problem though, it seems that if I move the mouse around over the terminal, my CPU will spike (albeit in debug mode: cargo run). This also freezes the UI for a bit, rendering me unable to do anything for a short period. Of course, this only occurs if the terminal window is sufficiently big. Eehhh what.

Moving the mouse slowly, no weirdness:

[00:00:09.687] (7fc6d24bdd80) INFO   event Mouse(MouseEvent { x: 30, y: 12, mouse_buttons: MouseButtons(0x0), modifiers: NONE })
[00:00:09.688] (7fc6d24bdd80) INFO   event Mouse(MouseEvent { x: 30, y: 13, mouse_buttons: MouseButtons(0x0), modifiers: NONE })
[00:00:09.690] (7fc6d24bdd80) INFO   event Mouse(MouseEvent { x: 31, y: 13, mouse_buttons: MouseButtons(0x0), modifiers: NONE })
[00:00:09.692] (7fc6d24bdd80) INFO   event Mouse(MouseEvent { x: 32, y: 13, mouse_buttons: MouseButtons(0x0), modifiers: NONE })
[00:00:09.695] (7fc6d24bdd80) INFO   event Mouse(MouseEvent { x: 33, y: 13, mouse_buttons: MouseButtons(0x0), modifiers: NONE })
[00:00:09.698] (7fc6d24bdd80) INFO   event Mouse(MouseEvent { x: 34, y: 13, mouse_buttons: MouseButtons(0x0), modifiers: NONE })
[00:00:09.700] (7fc6d24bdd80) INFO   event Mouse(MouseEvent { x: 35, y: 13, mouse_buttons: MouseButtons(0x0), modifiers: NONE })

Moving the mouse fast / big terminal window:

[00:00:08.282] (7f9394f27d80) INFO   event Mouse(MouseEvent { x: 77, y: 37, mouse_buttons: MouseButtons(0x0), modifiers: NONE })
[00:00:08.285] (7f9394f27d80) INFO   event Mouse(MouseEvent { x: 76, y: 37, mouse_buttons: MouseButtons(0x0), modifiers: NONE })
[00:00:08.289] (7f9394f27d80) INFO   event Mouse(MouseEvent { x: 75, y: 37, mouse_buttons: MouseButtons(0x0), modifiers: NONE })
[00:00:08.293] (7f9394f27d80) INFO   event Mouse(MouseEvent { x: 75, y: 38, mouse_buttons: MouseButtons(0x0), modifiers: NONE })
[00:00:08.297] (7f9394f27d80) INFO   event Key(KeyEvent { key: Char('['), modifiers: ALT })
[00:00:08.301] (7f9394f27d80) INFO   event Key(KeyEvent { key: Char('<'), modifiers: NONE })
[00:00:08.305] (7f9394f27d80) INFO   event Key(KeyEvent { key: Char('3'), modifiers: NONE })
[00:00:08.309] (7f9394f27d80) INFO   event Key(KeyEvent { key: Char('5'), modifiers: NONE })
[00:00:08.313] (7f9394f27d80) INFO   event Key(KeyEvent { key: Char(';'), modifiers: NONE })
[00:00:08.317] (7f9394f27d80) INFO   event Key(KeyEvent { key: Char('7'), modifiers: NONE })
[00:00:08.321] (7f9394f27d80) INFO   event Key(KeyEvent { key: Char('4'), modifiers: NONE })
[00:00:08.325] (7f9394f27d80) INFO   event Key(KeyEvent { key: Char(';'), modifiers: NONE })
[00:00:08.328] (7f9394f27d80) INFO   event Key(KeyEvent { key: Char('3'), modifiers: NONE })
[00:00:08.332] (7f9394f27d80) INFO   event Key(KeyEvent { key: Char('8'), modifiers: NONE })
[00:00:08.336] (7f9394f27d80) INFO   event Key(KeyEvent { key: Char('M'), modifiers: NONE })

Must be the same symptoms you experienced while scrolling.
There is something weird going on...

@altsem
Copy link
Owner

altsem commented Sep 22, 2025

Perhaps swapping back over to Crossterm is a good idea. There's small issues with rendering that occur ever since the switch to Termwiz as well.
It was done with this PR: #352

Update: I started on it. #423. I'll continue another time, but feel free to continue on it if you feel like!

@jonathanj
Copy link
Contributor Author

Perhaps swapping back over to Crossterm is a good idea. There's small issues with rendering that occur ever since the switch to Termwiz as well. It was done with this PR: #352

Update: I started on it. #423. I'll continue another time, but feel free to continue on it if you feel like!

I’d be interested to see if the mouse stuff works better on crossterm, could I just make a temp branch and rebase on top of yours to try it out? I assume the event types and other small things will be broken since they’re currently termwiz events.

@altsem
Copy link
Owner

altsem commented Sep 22, 2025

I think I got the majority of it fixed, but I think trying it out is a good idea. Feel free to steal the one I started on.

This avoids a lot of CPU usage for just moving the mouse around.
@jonathanj
Copy link
Contributor Author

I seemed to notice a problem though, it seems that if I move the mouse around over the terminal, my CPU will spike (albeit in debug mode: cargo run). This also freezes the UI for a bit, rendering me unable to do anything for a short period. Of course, this only occurs if the terminal window is sufficiently big. Eehhh what.

Looking at your log, these events are spaced a few ms apart and there are quite a few that happen over the space of just a few milliseconds, obviously almost none of these are going to impact the UI since there are no clicks.

I pushed a commit to avoid calling stage_redraw in cases where the mouse event wasn't actually handled which seems to solve the CPU usage.

@altsem
Copy link
Owner

altsem commented Sep 24, 2025

@jonathanj I can actually reproduce this bug in master, by moving the mouse.
But I feel this is ready to go then. There's just a linter error. I'll fix that :)

@altsem altsem merged commit 562d2eb into altsem:master Sep 24, 2025
2 of 3 checks passed
@jonathanj
Copy link
Contributor Author

Hooray, thanks! I’m looking forward to enjoying mouse support.

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

Successfully merging this pull request may close these issues.

2 participants