jdtsmith / mlscroll

Lightweight scrollbar for the Emacs mode line
GNU General Public License v3.0
94 stars 7 forks source link

mlscroll + mouse on terminal? #14

Open AkibAzmain opened 1 year ago

AkibAzmain commented 1 year ago

mlscroll doesn't work properly on terminal with gpm-mouse-mode or xterm-mouse-mode. It would be great to have that.

jdtsmith commented 1 year ago

I don't really use it on the terminal and am not familiar with these modes, so "doesn't work" isn't really enough info. Can you narrow down the problem and recommend a fix?

Update: I tried xterm-mouse-mode and mouse clicks in buffer work fine. Are you referring to clicking on the mlscroll bar itself?

AkibAzmain commented 1 year ago

At a quick glance, I see that mlscroll uses (read-event) to get mouse events. That doesn't work in terminal, because the terminal escape codes (e.g. "\e[<0;3;5m"). These escape codes are interpreted by xterm-mouse-mode, which generates the mouse event. When mlscroll encounters such event, dragging terminates and the escape code get inserted in the buffer. I recommend to use a transient keymap, which will call your dragging command when the mouse moves, and process all other event as usual.

jdtsmith commented 1 year ago

Thanks. It's my understanding that xterm-mouse only delivers press events, not motion. Another problem I found on investigating: posn-object-x-y does not function correctly for specified space with this mode, always returning 0. If you want to look into it and open a PR I'm open to it. The current graphical term functionality needs to remain.

I am considering putting some of the size calculations behind terminal parameters to better customize for mixed graphical/terminal uses, if that would be helpful to you.

AkibAzmain commented 1 year ago

It's my understanding that xterm-mouse only delivers press events, not motion.

xterm-mouse-mode delivers motion events, and you can select with mouse.

I am considering putting some of the size calculations behind terminal parameters to better customize for mixed graphical/terminal uses, if that would be helpful to you.

To be honest, I really don't need a scroll bar. Just wanted to inform you about the issue.

and open a PR I'm open to it

I'm afraid, because the code doesn't match with my coding style, so I'll do a lot of changes.

jdtsmith commented 1 year ago

`xterm-mouse-mode delivers motion events, and you can select with mouse.

This may not be available in all terminals.

In a terminal emulator which is compatible with xterm, you can use M-x xterm-mouse-mode to give Emacs control over simple uses of the mouse—basically, only non-modified single clicks are supported. Newer versions of xterm also support mouse-tracking.

I'm afraid, because the code doesn't match with my coding style, so I'll do a lot of changes.

Well, alternatively if interested, you can craft a new standalone terminal-only mouse handler function which does what you suggest (just for xterm-mouse and the other) and I can translate/integrate it. As long as you don't add library dependencies it shouldn't be too much of a problem. But if it's not something you'd use don't worry about it.

A bigger issue is that in xterm-mouse-mode, posn-object-x-y with specified space always returns 0. If you could test this recipe to confirm that, I'd appreciate:

(defun my/report-mouse (ev)
  (interactive "e")
  (let* ((posn (event-start ev))
     (rel (posn-object-x-y posn)))
    (message "Got Relative Position %S" rel)))

(insert "\n\n  ----  "
        (propertize " "
                    'extend nil
                    'display '(space :width (48))
                    'keymap '(keymap (down-mouse-1 . my/report-mouse))
                    'font-lock-face 'underline)
        "  ----  ")

Mouse 1 click positions relative to the extended-width space (underlined for visibility) are reported correctly in graphical emacs, in screen pixel units. With xterm-mouse-mode, however, relative positions are always reported as (0 . 0) for me, no matter where you click. Is something wrong with my assumption that posn-object-x-y should work similarly in graphical as well as terminal emacs with xterm-mouse-mode (modulo the larger “pixel” size)?

BTW, I just added a simple guard to prevent the track-mouse if in xterm-mouse-mode, so at least you won't get escape codes in buffer any longer.

AkibAzmain commented 1 year ago

Hmm, that's indeed a problem, since you're using specified width. Is it possible to get the start position of the clicked object or the scroll bar? If it is, we can get the object relative position from that. Or maybe, you can use plain space characters on terminal (though I don't know what would be the performance impact).

jdtsmith commented 1 year ago

Been experimenting and discussing on emacs-devel; apparently this is not really possible on TTY. posn-point, which would work if the scrollbar were in the buffer instead, returns nil in the modeline (since presumably point can't go there). So we'd need to calculate the position of the scrollbar ourselves, which can move if dynamic elements are placed in front of it. One way I thought of would be (on TTY only) to get a copy of the current mode-line with format-mode-line, then search for the mlscroll text property that I set on the scroll spaces. Not ideal to say the least, and so far not working (due to: specified space!). posn-string sometimes has much of full modeline (e.g. if you place it in place of the percentage indicator), so you can search in that, but other times (e.g. right-aligned) you get just the three (stretched) spaces.

I bet the number of people who want a clickable scrollbar in a TTY is small.

AkibAzmain commented 1 year ago

I bet the number of people who want a clickable scrollbar in a TTY is small.

Indeed.

Or maybe, you can use plain space characters on terminal (though I don't know what would be the performance impact).

jdtsmith commented 1 year ago

I'll leave this open in case anyone wants to look into a simple way to treat mouse clicks (/motion) on the mlscrollbar in TTY-mouse modes like xterm-mouse-mode.