Main technical thrust: Modify Screen to recognize scrollwheel events and handle it in the Frame
I will begin work on this soon and submit a PR when I get it working.
=======================
Jeff Wright
@jeffwright13
Feb 06 06:35
@peterbrittain - is there a way to modify the scrolling behavior? When I use the scroll wheel on my mouse, it seems to want to scroll an entire page at a time, instead of what I have come to expect in a normal GUI: N lines at a time. The result is a very jumpy experience. I didn't see anything in the docs about configuring scroll behavior.
peterbrittain
@peterbrittain
Feb 06 06:46
That's because asciimatics doesn't support scroll wheels (due to patchy support in Linux). I suspect what you're seeing is the terminal intercepting the event and scrolling the whole buffer.
You'll be able to tell if this is the case, because asciimatics will still only draw on the original screen that was visible when you started the app.
Jeff Wright
@jeffwright13
Feb 06 06:55
So nothing to be done then?
peterbrittain
@peterbrittain
Feb 06 07:08
Mouse support has improved in ncurses 6. Do you know what version your system uses? We'd also need to see if there is a setting on your terminal to force it to pass the input to the running app (instead of consuming it itself).
Jeff Wright
@jeffwright13
Feb 06 07:14
I am running (currently) on a Macbook Pro (2019/Intel). Latest version of OSX. I usually run Pytest (and hence Asciimatics) out of iTerm2, although sometimes also from my IDE (VSCode, with Integrated Terminal). My shell is latest zsh.
peterbrittain
@peterbrittain
Feb 06 08:02
Ok... with a newer version of ncurses, you then need to enable scroll wheel reporting. Looks like there's a setting in iterm2: https://iterm2.com/documentation-preferences-profiles-terminal.html
Finally, we'd need to tweak asciimatics Screen to recognize the events and handle it in the Frame.
All pretty self-contained changes, so I can explain them to you if you're up for submitting a PR.
Jeff Wright
@jeffwright13
Feb 06 09:16
Screen Shot 2022-02-06 at 9.16.13 AM.png
Screen Shot 2022-02-06 at 9.16.38 AM.png
Looks like I already had that setting enabled ("Enable mouse reporting")
Sure, I could submit a PR. Would need some guidance on where in the code to make changes.
peterbrittain
@peterbrittain
Feb 06 14:57
Ok... There are 2 basic changes. First is to _CursesScreen.get_event(). There's already logic to handle other buttons in there. We just need to find what events fire when you scroll the mouse wheel. You could either add some logging to the function, or use something like this: https://stackoverflow.com/questions/11893034/mouse-wheel-in-python-curses.
According to the curses maintainer, it should look like mouse buttons 4 and 5. See https://stackoverflow.com/questions/42356352/mouse-scroll-up-ncurses-c
Once you have those events translated into equivalent asciimatics MouseEvents, you just need to act on them in the scrollbar. That's in scrollbar.py. simply get the current position and add/subtract a percentage to the position on the relevant button.
Jeff Wright
@jeffwright13
Feb 06 20:54
I made the following changes to screen.py.
# Some Linux modes only report clicks, so check for any
# button down or click events.
if (bstate & curses.BUTTON1_PRESSED != 0 or
bstate & curses.BUTTON1_CLICKED != 0):
buttons |= MouseEvent.LEFT_CLICK
if (bstate & curses.BUTTON3_PRESSED != 0 or
bstate & curses.BUTTON3_CLICKED != 0):
buttons |= MouseEvent.RIGHT_CLICK
if bstate & curses.BUTTON1_DOUBLE_CLICKED != 0:
buttons |= MouseEvent.DOUBLE_CLICK
if bstate & curses.BUTTON4_PRESSED != 0:
print("BUTTON4_PRESSED")
if bstate & curses.BUTTON5_PRESSED != 0:
print("BUTTON5_PRESSED")
if bstate & curses.BUTTON4_CLICKED != 0:
print("BUTTON4_CLICKED")
if bstate & curses.BUTTON5_CLICKED != 0:
print("BUTTON5_CLICKED")
return MouseEvent(x, y, buttons)
This resulted in an exception when the scroll wheel was rolled:
Traceback (most recent call last):
File "/Users/jwr003/coding/pytest-fold/pytest_fold/tui.py", line 186, in
main()
File "/Users/jwr003/coding/pytest-fold/pytest_fold/tui.py", line 179, in main
Screen.wrapper(demo, catch_interrupt=True, arguments=[last_scene])
File "/Users/jwr003/coding/pytest-fold/venv/lib/python3.9/site-packages/asciimatics/screen.py", line 1393, in wrapper
return func(screen, *arguments)
File "/Users/jwr003/coding/pytest-fold/pytest_fold/tui.py", line 166, in demo
screen.play(
File "/Users/jwr003/coding/pytest-fold/venv/lib/python3.9/site-packages/asciimatics/screen.py", line 1566, in play
self.draw_next_frame(repeat=repeat)
File "/Users/jwr003/coding/pytest-fold/venv/lib/python3.9/site-packages/asciimatics/screen.py", line 1649, in draw_next_frame
event = self.get_event()
File "/Users/jwr003/coding/pytest-fold/venv/lib/python3.9/site-packages/asciimatics/screen.py", line 2494, in get_event
if bstate & curses.BUTTON5_PRESSED != 0:
AttributeError: module 'curses' has no attribute 'BUTTON5_PRESSED'
I am on a Mac. I saw the following comment in _curses.py:
# Darwin ncurses doesn't provide BUTTON5_* constants
Maybe that's the issue with the crash above.
peterbrittain
@peterbrittain
Feb 07 00:58
Yeah - I wondered if we'd start hitting issue like this. We can create the constants ourselves if needed. For now, I suggest you just log the bstate in hex and compare it to https://github.com/mirror/ncurses/blob/d30f99439fcc8d4bb4c38e5c4afb4f6555fc6ad4/include/curses.tail
Note that print doesn't work in alternate screens (like asciimatics uses). Also, if you don't like doing the bit maths, you can probably use this definition instead: https://github.com/mattn/pdcurses/blob/master/curses.h
Jeff Wright
@jeffwright13
Feb 07 11:14
The print was meant for initial diagnosis to see what button the system registered when I scrolled. Definitely will remove before issuing a PR!
peterbrittain
@peterbrittain
Feb 07 11:57
:-)
As per our conversation 2022-02-06 at https://gitter.im/asciimatics/Lobby, I am requesting scrollwheel support in Asciimatics.
Main technical thrust: Modify Screen to recognize scrollwheel events and handle it in the Frame
I will begin work on this soon and submit a PR when I get it working.
=======================
Jeff Wright @jeffwright13 Feb 06 06:35 @peterbrittain - is there a way to modify the scrolling behavior? When I use the scroll wheel on my mouse, it seems to want to scroll an entire page at a time, instead of what I have come to expect in a normal GUI: N lines at a time. The result is a very jumpy experience. I didn't see anything in the docs about configuring scroll behavior. peterbrittain @peterbrittain Feb 06 06:46 That's because asciimatics doesn't support scroll wheels (due to patchy support in Linux). I suspect what you're seeing is the terminal intercepting the event and scrolling the whole buffer. You'll be able to tell if this is the case, because asciimatics will still only draw on the original screen that was visible when you started the app. Jeff Wright @jeffwright13 Feb 06 06:55 So nothing to be done then? peterbrittain @peterbrittain Feb 06 07:08 Mouse support has improved in ncurses 6. Do you know what version your system uses? We'd also need to see if there is a setting on your terminal to force it to pass the input to the running app (instead of consuming it itself). Jeff Wright @jeffwright13 Feb 06 07:14
I am running (currently) on a Macbook Pro (2019/Intel). Latest version of OSX. I usually run Pytest (and hence Asciimatics) out of iTerm2, although sometimes also from my IDE (VSCode, with Integrated Terminal). My shell is latest zsh.
$ tic -V ncurses 5.7.20081102
BUT:
$ brew upgrade ncurses Running
brew update --preinstall
... ==> Auto-updated Homebrew! Updated 2 taps (homebrew/core and homebrew/cask). ==> Updated Formulae Updated 84 formulae. ==> Updated Casks Updated 36 casks.Warning: ncurses 6.3 already installed
peterbrittain @peterbrittain Feb 06 08:02 Ok... with a newer version of ncurses, you then need to enable scroll wheel reporting. Looks like there's a setting in iterm2: https://iterm2.com/documentation-preferences-profiles-terminal.html Finally, we'd need to tweak asciimatics Screen to recognize the events and handle it in the Frame. All pretty self-contained changes, so I can explain them to you if you're up for submitting a PR. Jeff Wright @jeffwright13 Feb 06 09:16 Screen Shot 2022-02-06 at 9.16.13 AM.png Screen Shot 2022-02-06 at 9.16.38 AM.png Looks like I already had that setting enabled ("Enable mouse reporting") Sure, I could submit a PR. Would need some guidance on where in the code to make changes. peterbrittain @peterbrittain Feb 06 14:57 Ok... There are 2 basic changes. First is to _CursesScreen.get_event(). There's already logic to handle other buttons in there. We just need to find what events fire when you scroll the mouse wheel. You could either add some logging to the function, or use something like this: https://stackoverflow.com/questions/11893034/mouse-wheel-in-python-curses. According to the curses maintainer, it should look like mouse buttons 4 and 5. See https://stackoverflow.com/questions/42356352/mouse-scroll-up-ncurses-c Once you have those events translated into equivalent asciimatics MouseEvents, you just need to act on them in the scrollbar. That's in scrollbar.py. simply get the current position and add/subtract a percentage to the position on the relevant button. Jeff Wright @jeffwright13 Feb 06 20:54
I made the following changes to screen.py.
This resulted in an exception when the scroll wheel was rolled:
Traceback (most recent call last): File "/Users/jwr003/coding/pytest-fold/pytest_fold/tui.py", line 186, in
main()
File "/Users/jwr003/coding/pytest-fold/pytest_fold/tui.py", line 179, in main
Screen.wrapper(demo, catch_interrupt=True, arguments=[last_scene])
File "/Users/jwr003/coding/pytest-fold/venv/lib/python3.9/site-packages/asciimatics/screen.py", line 1393, in wrapper
return func(screen, *arguments)
File "/Users/jwr003/coding/pytest-fold/pytest_fold/tui.py", line 166, in demo
screen.play(
File "/Users/jwr003/coding/pytest-fold/venv/lib/python3.9/site-packages/asciimatics/screen.py", line 1566, in play
self.draw_next_frame(repeat=repeat)
File "/Users/jwr003/coding/pytest-fold/venv/lib/python3.9/site-packages/asciimatics/screen.py", line 1649, in draw_next_frame
event = self.get_event()
File "/Users/jwr003/coding/pytest-fold/venv/lib/python3.9/site-packages/asciimatics/screen.py", line 2494, in get_event
if bstate & curses.BUTTON5_PRESSED != 0:
AttributeError: module 'curses' has no attribute 'BUTTON5_PRESSED'
I am on a Mac. I saw the following comment in _curses.py:
Maybe that's the issue with the crash above. peterbrittain @peterbrittain Feb 07 00:58 Yeah - I wondered if we'd start hitting issue like this. We can create the constants ourselves if needed. For now, I suggest you just log the bstate in hex and compare it to https://github.com/mirror/ncurses/blob/d30f99439fcc8d4bb4c38e5c4afb4f6555fc6ad4/include/curses.tail Note that print doesn't work in alternate screens (like asciimatics uses). Also, if you don't like doing the bit maths, you can probably use this definition instead: https://github.com/mattn/pdcurses/blob/master/curses.h Jeff Wright @jeffwright13 Feb 07 11:14 The print was meant for initial diagnosis to see what button the system registered when I scrolled. Definitely will remove before issuing a PR! peterbrittain @peterbrittain Feb 07 11:57 :-)