emacs-which-key
emacs-which-key copied to clipboard
[WIP] Basic mouse support
Hi,
This pull request adds really basic mouse support
- The
which-keypop-up is not hidden if the mouse events happen inside the pop-up - The mouse wheel can be used to navigate to the next and previous pages
I still have to figure out how to make this work with the minibuffer, minibuffer is always hidden by Emacs on mouse events, I need to see if Emacs provides a way to temporarily change this behavior, any ideas?
Interesting. I just tried it and it doesn't seem to work with my trackpad. That could be something I'm overlooking right now.
Were you thinking about this issue?
Yes, #159 is what this pull request attempts to solve. I did not get a chance to try this on a trackpad, but I am surprised it is not working with trackpad, it seems Emacs handles it differently from the mouse wheel.
Hi @justbur, I tried this with trackpad and it worked, except that the popup would be hidden certain unhandled mouse events, I have pushed a fix to handle them. Could you try it?
Also in case it does not work, could you help me debug this, I debug the the issues by changing which-key--hide-popup to the following to log the events that cause the popup to be hidden
(defun which-key--hide-popup ()
"This function is called to hide the which-key buffer."
(unless (or (member real-this-command which-key--paging-functions)
;; Do not hide the popup the if the last event was a mouse
;; event and was inside which-key popup
(and (or (mouse-event-p last-command-event)
;; 'mwheel-scroll events are not recognized as mouse
;; events
(equal real-this-command 'mwheel-scroll))
(which-key--mouse-event-inside-which-key-p last-command-event))
;; The mouse event was not handled by Emacs
(and (not this-command)
(string-prefix-p "mouse-"
;; Using prin1-to-string since it can handle
;; all kinds of values returned by `event-basic-type'
(prin1-to-string (event-basic-type last-command-event)))))
(message "%s - %s" this-command last-command-event)
(setq which-key--current-page-n nil
which-key--current-prefix nil
which-key--using-top-level nil
which-key--using-show-keymap nil
which-key--using-show-operator-keymap nil
which-key--current-show-keymap-name nil
which-key--prior-show-keymap-args nil
which-key--on-last-page nil)
(when (and which-key-idle-secondary-delay
which-key--secondary-timer-active)
(which-key--start-timer))
(cl-case which-key-popup-type
;; Not necessary to hide minibuffer
;; (minibuffer (which-key--hide-buffer-minibuffer))
(side-window (which-key--hide-buffer-side-window))
(frame (which-key--hide-buffer-frame))
(custom (funcall which-key-custom-hide-popup-function)))))
Hi @iqbalansari, I haven't dug into the code yet, but I just tried it. The popup is not getting hidden on the mouse wheel events, but not all of them are being handled. If I scroll the wheel quickly, it seems like every third step or so triggers the page turn but the rest show up as something like C-x <mouse-4> is undefined.
You are right, it seems Emacs treats the scroll event as part of ongoing key sequence. It did not happen for me because I was testing it for toplevel binding (how stupid of me :man_facepalming:). I wonder why it works for some scroll events though. Let me investigate a bit more.
I think the issue with undefined mouse bindings can be solved by adding keybinding for prefix + mouse[1-5], not sure we want to go that route though, would be incredibly hacky.
I realized why it works for alternate keybindings, the first scroll fails with undefined error and returns to the toplevel, but the which key popup is not hid and the which key state is not destroyed, since the mouse event was on the popup.
The next scroll event works since it is essentially invokes the global keybinding for mouse scroll, which causes the page to scroll using the preserved state from previous invocation and reloads whatever the key prefix was.
So this thing worked only by chance on non-toplevel popups. Sorry for the noise :pensive:
The only solution I can think at this point is adding extra keybinding for mouse events on the keymaps (like which-key does to support which-key-paging-key). We can create a local keymap for the popup buffer while displaying the popup, so that it does not affect rest of the system, not sure it would work just a thought. What do you think?
The only solution I can think at this point is adding extra keybinding for mouse events on the keymaps (like which-key does to support which-key-paging-key).
This seems like the only option. which-key-define-key-recursively works pretty well for this purpose, but it's still a little cumbersome.
We can create a local keymap for the popup buffer while displaying the popup, so that it does not affect rest of the system, not sure it would work just a thought. What do you think?
I believe the local keymap will only work when you are not already in the middle of a key sequence (ie at the top level)
I believe the local keymap will only work when you are not already in the middle of a key sequence (ie at the top level)
I just did a quick test, using the following snippet
(progn
;; Make sure there is no keybinding for C-x left-click
(global-set-key (kbd "C-x <mouse-1>") nil)
;; Set keybinding after 1 second, so that the keybinding is set after the C-x
;; input
(run-at-time 1 nil
(lambda ()
(message "Setup the binding, now click ...")
(global-set-key (kbd "C-x <mouse-1>") (lambda (&rest ignored)
(interactive "e")
(message "Worked")))))
;; Fake 'C-x' input
(setq unread-command-events (listify-key-sequence (kbd "C-x"))))
Now doing a left click after the message "Setup the binding, now click ..." echoes "Worked" as expected, so I guess this can work, am I missing something?
Maybe it will I guess. My experience with stuff like this in the past suggested that Emacs won't pick up the modified keymaps until after a new key sequence is started, but your example suggests otherwise.
On Tue, Apr 18, 2017 at 8:49 AM Iqbal Ansari [email protected] wrote:
I believe the local keymap will only work when you are not already in the middle of a key sequence (ie at the top level)
I just did a quick test, using the following snippet
(progn ;; Make sure there is no keybinding for C-x (global-set-key (kbd "C-x
") nil) ;; Set keybinding after 1 second, so that the keybinding is set after the C-x ;; input (run-at-time 1 nil (lambda () (message "Setup the binding, now click ...") (global-set-key (kbd "C-x ") (lambda (&rest ignored) (interactive "e") (message "Worked"))))) ;; Fake 'C-x' input (setq unread-command-events (listify-key-sequence (kbd "C-x")))) Now doing a left click after the message "Setup the binding, now click ..." echoes "Worked" as expected, so I guess this can work, am I missing something?
— You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/justbur/emacs-which-key/pull/166#issuecomment-294828088, or mute the thread https://github.com/notifications/unsubscribe-auth/ACGyft14-iUdwk8HPY7gC99XlSLfw4TPks5rxLFbgaJpZM4M4Grn .
You seem to be right, I have hit some wierd issue, even though example above works for me (changes to global as well as local keymap are picked up), Emacs does not seem to be picking up the modified binding, if I do it after/while the which-key popup is displayed (there are some nuances, I will post later), any ideas?
Also assuming the strategy of updating the keybindings does not work, what other options do we have?
I think just pre-populating the keys. I've not thought of a (reasonable) alternative.
On Fri, Apr 21, 2017 at 1:38 PM Iqbal Ansari [email protected] wrote:
You seem to be right, I have hit some wierd issue, even though example above works for me (changes to global as well as local keymap are picked up), Emacs does not seem to be picking up the modified binding, if I do it after/while the which-key popup is displayed (there are some nuances, I will post later), any ideas?
Also assuming the strategy of updating the keybindings does not work, what other options do we have?
— You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub https://github.com/justbur/emacs-which-key/pull/166#issuecomment-296255889, or mute the thread https://github.com/notifications/unsubscribe-auth/ACGyfiwf345izTm6s6D4jDoDyYYcaTrkks5ryOmjgaJpZM4M4Grn .
I am not an elisp guy but I can suggest a thing. Don't know whether it will work or not. Whenever which-key is triggered can the mode line be changed? If that is a yes then backward and forward buttons on the model-ine can be placed to scroll the page instead of using the mouse wheel or trackpad. And another button for undo can also be placed IMO. Can this be done?
Any updates on this?
If I understand correctly this hasn't been resolved in the end? It would be really useful though - quite often there are more keybindings than you can fit in the side-window, often C-h is bound to something else, so you can't "unroll" the list. An option to scroll the list with a mouse would be really helpful.