I have some code that runs in a hook that I want to change to only execute only if the left mouse button is not currently held down. I don't see any obvious functions or variables that let me directly query the mouse button state. What's the easiest way to do this?
Asked
Active
Viewed 428 times
5
-
1I don't think there's a way to detect the mouse button state directly. However, Emacs allows the user to handle [mouse events](https://www.gnu.org/software/emacs/manual/html_node/elisp/Mouse-Events.html#Mouse-Events) like [clicking](https://www.gnu.org/software/emacs/manual/html_node/elisp/Click-Events.html#Click-Events) and [dragging](https://www.gnu.org/software/emacs/manual/html_node/elisp/Drag-Events.html#Drag-Events). Can you provide more information as to what you're trying to do, so we can see if it can be done by handling these events? – Tianxiang Xiong Dec 14 '16 at 01:45
-
@Tianxiang_Xiong I have some code that recenters the view of the buffer everytime the cursor moves, but it's annoying when it runs while I'm trying to drag to highlight text for copying and pasting. – Joseph Garvin Dec 14 '16 at 01:53
-
Hmm, maybe a knowledgeable user like [@Drew](http://emacs.stackexchange.com/users/105/drew) will be able to provide a solution. – Tianxiang Xiong Dec 14 '16 at 02:00
2 Answers
3
This seems to do what you want:
(defun mouse-button-pressed-p ()
"Return non-nil if last event is a mouse-button down event."
(run-hooks 'mouse-leave-buffer-hook)
(and (consp last-input-event)
(string-match-p "down-mouse-" (format "%s" (car last-input-event)))))
You can test it using M-x bar
. That will give you 2 seconds to perform an action that issues an event and then call mouse-button-pressed-p
to test whether the last event was a mouse-button down event. After 2 seconds it tells you whether at the time mouse-button-pressed-p
was called a mouse-button was depressed (held down).
(defun bar ()
(interactive)
(run-with-timer 2 nil 'foo))
(defun foo ()
(message (if (mouse-button-pressed-p)
"Button is pressed now"
"No button is pressed now")))
See the Elisp manual, node Button-Down Events.

Drew
- 75,699
- 9
- 109
- 225
-
doesn't appear to work for me, I run this function in order to re- center the screen: https://gist.github.com/jgarvin/70d747a9ee9b4b0b5683035d9080643d when I drag text it still recenters – Joseph Garvin Oct 16 '17 at 15:56
-
1Strangely I also think it breaks hitting c-s repeatedly to cycle through results from incremental search -- as soon as a search item is found it leaves incremental search mode. – Joseph Garvin Oct 16 '17 at 17:45
-
Your code works for me. When I depress a mouse button the `recenter` does not happen. When I release the button the `recenter` happens. – Drew Oct 16 '17 at 19:57
-
what OS and emacs are you on? I'm on Linux and a recent checkout – Joseph Garvin Oct 16 '17 at 23:09
-
I'm using MS Windows, with several releases, the most recent being 25.3.1. – Drew Oct 17 '17 at 00:28
0
Maybe a simple solution is to check:
(defun mouse-button-pressed-p ()
track-mouse)
This is a hack, but in practice I think track-mouse
is only set while handling some kind of "mouse drag".

Stefan
- 26,154
- 3
- 46
- 84