diff options
| -rw-r--r-- | etc/NEWS | 16 | ||||
| -rw-r--r-- | lisp/mouse.el | 13 | ||||
| -rw-r--r-- | lisp/mwheel.el | 21 | ||||
| -rw-r--r-- | lisp/xt-mouse.el | 20 | ||||
| -rw-r--r-- | src/keyboard.c | 13 | ||||
| -rw-r--r-- | src/xterm.c | 53 |
6 files changed, 90 insertions, 46 deletions
| @@ -68,6 +68,12 @@ more details. | |||
| 68 | 68 | ||
| 69 | * Incompatible Changes in Emacs 30.1 | 69 | * Incompatible Changes in Emacs 30.1 |
| 70 | 70 | ||
| 71 | ** Mouse wheel events should now always be 'wheel-up/down/left/right'. | ||
| 72 | At those places where the old 'mouse-4/5/6/7' events could still occur | ||
| 73 | (i.e. X11 input in the absence of XInput2, and 'xterm-mouse-mode'), | ||
| 74 | we remap them to the corresponding 'wheel-up/down/left/right' event, | ||
| 75 | according to the new variable 'mouse-wheel-buttons'. | ||
| 76 | |||
| 71 | ** Tree-Sitter modes are now declared as submodes of the non-TS modes. | 77 | ** Tree-Sitter modes are now declared as submodes of the non-TS modes. |
| 72 | In order to help the use of those Tree-Sitter modes, they are now | 78 | In order to help the use of those Tree-Sitter modes, they are now |
| 73 | declared to have the corresponding non-Tree-Sitter mode as an | 79 | declared to have the corresponding non-Tree-Sitter mode as an |
| @@ -520,15 +526,15 @@ In batch mode, tracing now sends the trace to stdout. | |||
| 520 | ** Mwheel | 526 | ** Mwheel |
| 521 | The 'wheel-up/down/left/right' events are now bound unconditionally, | 527 | The 'wheel-up/down/left/right' events are now bound unconditionally, |
| 522 | and the 'mouse-wheel-up/down/left/right-event' variables are thus used | 528 | and the 'mouse-wheel-up/down/left/right-event' variables are thus used |
| 523 | only to specify the 'mouse-4/5/6/7' events generated by older | 529 | only to specify the 'mouse-4/5/6/7' events that might still |
| 524 | configurations such as X11 when the X server does not support at least | 530 | happen to be generated by some old packages (or if 'mouse-wheel-buttons' |
| 525 | version 2.1 of the X Input Extension, and 'xterm-mouse-mode'. | 531 | has been set to nil). |
| 526 | 532 | ||
| 527 | ** 'xterm-mouse-mode' | 533 | ** 'xterm-mouse-mode' |
| 528 | This mode now emits 'wheel-up/down/right/left' events instead of | 534 | This mode now emits 'wheel-up/down/right/left' events instead of |
| 529 | 'mouse-4/5/6/7' events for the mouse wheel. | 535 | 'mouse-4/5/6/7' events for the mouse wheel. |
| 530 | It uses the 'mouse-wheel-up/down/left/right-event' | 536 | It uses the new variable 'mouse-wheel-buttons' to decide which button |
| 531 | variables to decide which button maps to which wheel event (if any). | 537 | maps to which wheel event (if any). |
| 532 | 538 | ||
| 533 | ** Info | 539 | ** Info |
| 534 | 540 | ||
diff --git a/lisp/mouse.el b/lisp/mouse.el index cef88dede8a..410e52b2ecb 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el | |||
| @@ -133,6 +133,19 @@ or macOS)." | |||
| 133 | :type 'boolean | 133 | :type 'boolean |
| 134 | :version "29.1") | 134 | :version "29.1") |
| 135 | 135 | ||
| 136 | (defcustom mouse-wheel-buttons | ||
| 137 | '((4 . wheel-up) (5 . wheel-down) (6 . wheel-left) (7 . wheel-right)) | ||
| 138 | "How to remap mouse button numbers to wheel events. | ||
| 139 | This is an alist of (NUMBER . SYMBOL) used to remap old-style mouse wheel | ||
| 140 | events represented as mouse button events. It remaps mouse button | ||
| 141 | NUMBER to the event SYMBOL. SYMBOL must be one of `wheel-up', `wheel-down', | ||
| 142 | `wheel-left', or `wheel-right'. | ||
| 143 | This is used only for events that come from sources known to generate such | ||
| 144 | events, such as X11 events when XInput2 is not used, or events coming from | ||
| 145 | a text terminal." | ||
| 146 | :type '(alist) | ||
| 147 | :version "30.1") | ||
| 148 | |||
| 136 | (defvar mouse--last-down nil) | 149 | (defvar mouse--last-down nil) |
| 137 | 150 | ||
| 138 | (defun mouse--down-1-maybe-follows-link (&optional _prompt) | 151 | (defun mouse--down-1-maybe-follows-link (&optional _prompt) |
diff --git a/lisp/mwheel.el b/lisp/mwheel.el index 66a1fa1a706..9fc922eebc9 100644 --- a/lisp/mwheel.el +++ b/lisp/mwheel.el | |||
| @@ -56,20 +56,17 @@ | |||
| 56 | (bound-and-true-p mouse-wheel-mode)) | 56 | (bound-and-true-p mouse-wheel-mode)) |
| 57 | (mouse-wheel-mode 1))) | 57 | (mouse-wheel-mode 1))) |
| 58 | 58 | ||
| 59 | (defvar mouse-wheel-obey-old-style-wheel-buttons t | 59 | (make-obsolete-variable 'mouse-wheel-up-event 'mouse-wheel-buttons "30.1") |
| 60 | "If non-nil, treat mouse-4/5/6/7 events as mouse wheel events. | 60 | (make-obsolete-variable 'mouse-wheel-down-event 'mouse-wheel-buttons "30.1") |
| 61 | These are the event names used historically in X11 before XInput2. | 61 | (make-obsolete-variable 'mouse-wheel-left-event 'mouse-wheel-buttons "30.1") |
| 62 | They are sometimes generated by things like text-terminals as well.") | 62 | (make-obsolete-variable 'mouse-wheel-right-event 'mouse-wheel-buttons "30.1") |
| 63 | 63 | ||
| 64 | (defcustom mouse-wheel-down-event | 64 | (defcustom mouse-wheel-down-event 'mouse-4 |
| 65 | (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-4) | ||
| 66 | "Event used for scrolling down, beside `wheel-up', if any." | 65 | "Event used for scrolling down, beside `wheel-up', if any." |
| 67 | :group 'mouse | 66 | :group 'mouse |
| 68 | :type 'symbol | 67 | :type 'symbol |
| 69 | :set #'mouse-wheel-change-button) | 68 | :set #'mouse-wheel-change-button) |
| 70 | 69 | (defcustom mouse-wheel-up-event 'mouse-5 | |
| 71 | (defcustom mouse-wheel-up-event | ||
| 72 | (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-5) | ||
| 73 | "Event used for scrolling up, beside `wheel-down', if any." | 70 | "Event used for scrolling up, beside `wheel-down', if any." |
| 74 | :group 'mouse | 71 | :group 'mouse |
| 75 | :type 'symbol | 72 | :type 'symbol |
| @@ -223,12 +220,10 @@ Also see `mouse-wheel-tilt-scroll'." | |||
| 223 | (defvar mwheel-scroll-right-function 'scroll-right | 220 | (defvar mwheel-scroll-right-function 'scroll-right |
| 224 | "Function that does the job of scrolling right.") | 221 | "Function that does the job of scrolling right.") |
| 225 | 222 | ||
| 226 | (defvar mouse-wheel-left-event | 223 | (defvar mouse-wheel-left-event 'mouse-6 |
| 227 | (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-6) | ||
| 228 | "Event used for scrolling left, beside `wheel-left', if any.") | 224 | "Event used for scrolling left, beside `wheel-left', if any.") |
| 229 | 225 | ||
| 230 | (defvar mouse-wheel-right-event | 226 | (defvar mouse-wheel-right-event 'mouse-7 |
| 231 | (if mouse-wheel-obey-old-style-wheel-buttons 'mouse-7) | ||
| 232 | "Event used for scrolling right, beside `wheel-right', if any.") | 227 | "Event used for scrolling right, beside `wheel-right', if any.") |
| 233 | 228 | ||
| 234 | (defun mouse-wheel--get-scroll-window (event) | 229 | (defun mouse-wheel--get-scroll-window (event) |
diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el index 081b8f32456..c27dee7e249 100644 --- a/lisp/xt-mouse.el +++ b/lisp/xt-mouse.el | |||
| @@ -40,8 +40,6 @@ | |||
| 40 | 40 | ||
| 41 | ;;; Code: | 41 | ;;; Code: |
| 42 | 42 | ||
| 43 | (require 'mwheel) | ||
| 44 | |||
| 45 | (defvar xterm-mouse-debug-buffer nil) | 43 | (defvar xterm-mouse-debug-buffer nil) |
| 46 | 44 | ||
| 47 | (defun xterm-mouse-translate (_event) | 45 | (defun xterm-mouse-translate (_event) |
| @@ -195,12 +193,6 @@ single byte." | |||
| 195 | (cons n c)) | 193 | (cons n c)) |
| 196 | (cons (- (setq c (xterm-mouse--read-coordinate)) 32) c)))) | 194 | (cons (- (setq c (xterm-mouse--read-coordinate)) 32) c)))) |
| 197 | 195 | ||
| 198 | (defun xterm-mouse--button-p (event btn) | ||
| 199 | (and (symbolp event) | ||
| 200 | (string-prefix-p "mouse-" (symbol-name event)) | ||
| 201 | (eq btn (car (read-from-string (symbol-name event) | ||
| 202 | (length "mouse-")))))) | ||
| 203 | |||
| 204 | ;; XTerm reports mouse events as | 196 | ;; XTerm reports mouse events as |
| 205 | ;; <EVENT-CODE> <X> <Y> in default mode, and | 197 | ;; <EVENT-CODE> <X> <Y> in default mode, and |
| 206 | ;; <EVENT-CODE> ";" <X> ";" <Y> <"M" or "m"> in extended mode. | 198 | ;; <EVENT-CODE> ";" <X> ";" <Y> <"M" or "m"> in extended mode. |
| @@ -246,14 +238,10 @@ single byte." | |||
| 246 | (if meta "M-" "") | 238 | (if meta "M-" "") |
| 247 | (if shift "S-" "") | 239 | (if shift "S-" "") |
| 248 | (if down "down-" "") | 240 | (if down "down-" "") |
| 249 | (cond | 241 | (let ((remap (alist-get btn mouse-wheel-buttons))) |
| 250 | ;; BEWARE: `mouse-wheel-UP-event' corresponds to | 242 | (if remap |
| 251 | ;; `wheel-DOWN' events and vice versa!! | 243 | (symbol-name remap) |
| 252 | ((xterm-mouse--button-p mouse-wheel-down-event btn) "wheel-up") | 244 | (format "mouse-%d" btn)))))))) |
| 253 | ((xterm-mouse--button-p mouse-wheel-up-event btn) "wheel-down") | ||
| 254 | ((xterm-mouse--button-p mouse-wheel-left-event btn) "wheel-left") | ||
| 255 | ((xterm-mouse--button-p mouse-wheel-right-event btn) "wheel-right") | ||
| 256 | (t (format "mouse-%d" btn)))))))) | ||
| 257 | (list sym (1- x) (1- y)))) | 245 | (list sym (1- x) (1- y)))) |
| 258 | 246 | ||
| 259 | (defun xterm-mouse--set-click-count (event click-count) | 247 | (defun xterm-mouse--set-click-count (event click-count) |
diff --git a/src/keyboard.c b/src/keyboard.c index 91faf4582fa..a06c9116d24 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -6639,8 +6639,17 @@ make_lispy_event (struct input_event *event) | |||
| 6639 | 6639 | ||
| 6640 | if (CONSP (event->arg)) | 6640 | if (CONSP (event->arg)) |
| 6641 | return list5 (head, position, make_fixnum (double_click_count), | 6641 | return list5 (head, position, make_fixnum (double_click_count), |
| 6642 | XCAR (event->arg), Fcons (XCAR (XCDR (event->arg)), | 6642 | XCAR (event->arg), |
| 6643 | XCAR (XCDR (XCDR (event->arg))))); | 6643 | /* FIXME: When a mouse-click on a tab-bar is |
| 6644 | converted into a wheel-event we get here something | ||
| 6645 | of an unexpected shape... */ | ||
| 6646 | (CONSP (XCDR (event->arg)) | ||
| 6647 | && CONSP (XCDR (XCDR (event->arg)))) | ||
| 6648 | ? Fcons (XCAR (XCDR (event->arg)), | ||
| 6649 | XCAR (XCDR (XCDR (event->arg)))) | ||
| 6650 | /* ... not knowing what this "unexpected shape" means, | ||
| 6651 | we just use nil. */ | ||
| 6652 | : Qnil); | ||
| 6644 | else if (NUMBERP (event->arg)) | 6653 | else if (NUMBERP (event->arg)) |
| 6645 | return list4 (head, position, make_fixnum (double_click_count), | 6654 | return list4 (head, position, make_fixnum (double_click_count), |
| 6646 | event->arg); | 6655 | event->arg); |
diff --git a/src/xterm.c b/src/xterm.c index c0aef65ab66..5e5eb6269e4 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -14551,18 +14551,19 @@ x_query_pointer (Display *dpy, Window w, Window *root_return, | |||
| 14551 | `x', `y', `x_root' and `y_root'. This function should not access | 14551 | `x', `y', `x_root' and `y_root'. This function should not access |
| 14552 | any other fields in EVENT without also initializing the | 14552 | any other fields in EVENT without also initializing the |
| 14553 | corresponding fields in `bv' under the XI_ButtonPress and | 14553 | corresponding fields in `bv' under the XI_ButtonPress and |
| 14554 | XI_ButtonRelease labels inside `handle_one_xevent'. */ | 14554 | XI_ButtonRelease labels inside `handle_one_xevent'. |
| 14555 | |||
| 14556 | XI2 indicates that this click comes from XInput2 rather than core | ||
| 14557 | event. */ | ||
| 14555 | 14558 | ||
| 14556 | static Lisp_Object | 14559 | static Lisp_Object |
| 14557 | x_construct_mouse_click (struct input_event *result, | 14560 | x_construct_mouse_click (struct input_event *result, |
| 14558 | const XButtonEvent *event, | 14561 | const XButtonEvent *event, |
| 14559 | struct frame *f) | 14562 | struct frame *f, bool xi2) |
| 14560 | { | 14563 | { |
| 14561 | int x = event->x; | 14564 | int x = event->x; |
| 14562 | int y = event->y; | 14565 | int y = event->y; |
| 14563 | 14566 | ||
| 14564 | /* Make the event type NO_EVENT; we'll change that when we decide | ||
| 14565 | otherwise. */ | ||
| 14566 | result->kind = MOUSE_CLICK_EVENT; | 14567 | result->kind = MOUSE_CLICK_EVENT; |
| 14567 | result->code = event->button - Button1; | 14568 | result->code = event->button - Button1; |
| 14568 | result->timestamp = event->time; | 14569 | result->timestamp = event->time; |
| @@ -14572,6 +14573,29 @@ x_construct_mouse_click (struct input_event *result, | |||
| 14572 | ? up_modifier | 14573 | ? up_modifier |
| 14573 | : down_modifier)); | 14574 | : down_modifier)); |
| 14574 | 14575 | ||
| 14576 | /* Convert pre-XInput2 wheel events represented as mouse-clicks. */ | ||
| 14577 | if (!xi2) | ||
| 14578 | { | ||
| 14579 | Lisp_Object base | ||
| 14580 | = Fcdr_safe (Fassq (make_fixnum (result->code + 1), | ||
| 14581 | Fsymbol_value (Qmouse_wheel_buttons))); | ||
| 14582 | int wheel | ||
| 14583 | = (NILP (base) ? -1 | ||
| 14584 | : BASE_EQ (base, Qwheel_down) ? 0 | ||
| 14585 | : BASE_EQ (base, Qwheel_up) ? 1 | ||
| 14586 | : BASE_EQ (base, Qwheel_left) ? 2 | ||
| 14587 | : BASE_EQ (base, Qwheel_right) ? 3 | ||
| 14588 | : -1); | ||
| 14589 | if (wheel >= 0) | ||
| 14590 | { | ||
| 14591 | result->kind = (event->type != ButtonRelease ? NO_EVENT | ||
| 14592 | : wheel & 2 ? HORIZ_WHEEL_EVENT : WHEEL_EVENT); | ||
| 14593 | result->code = 0; /* Not used. */ | ||
| 14594 | result->modifiers &= ~(up_modifier || down_modifier); | ||
| 14595 | result->modifiers |= wheel & 1 ? up_modifier : down_modifier; | ||
| 14596 | } | ||
| 14597 | } | ||
| 14598 | |||
| 14575 | /* If result->window is not the frame's edit widget (which can | 14599 | /* If result->window is not the frame's edit widget (which can |
| 14576 | happen with GTK+ scroll bars, for example), translate the | 14600 | happen with GTK+ scroll bars, for example), translate the |
| 14577 | coordinates so they appear at the correct position. */ | 14601 | coordinates so they appear at the correct position. */ |
| @@ -21881,13 +21905,14 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 21881 | && event->xbutton.time > ignore_next_mouse_click_timeout) | 21905 | && event->xbutton.time > ignore_next_mouse_click_timeout) |
| 21882 | { | 21906 | { |
| 21883 | ignore_next_mouse_click_timeout = 0; | 21907 | ignore_next_mouse_click_timeout = 0; |
| 21884 | x_construct_mouse_click (&inev.ie, &event->xbutton, f); | 21908 | x_construct_mouse_click (&inev.ie, &event->xbutton, |
| 21909 | f, false); | ||
| 21885 | } | 21910 | } |
| 21886 | if (event->type == ButtonRelease) | 21911 | if (event->type == ButtonRelease) |
| 21887 | ignore_next_mouse_click_timeout = 0; | 21912 | ignore_next_mouse_click_timeout = 0; |
| 21888 | } | 21913 | } |
| 21889 | else | 21914 | else |
| 21890 | x_construct_mouse_click (&inev.ie, &event->xbutton, f); | 21915 | x_construct_mouse_click (&inev.ie, &event->xbutton, f, false); |
| 21891 | 21916 | ||
| 21892 | *finish = X_EVENT_DROP; | 21917 | *finish = X_EVENT_DROP; |
| 21893 | goto OTHER; | 21918 | goto OTHER; |
| @@ -21957,13 +21982,15 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 21957 | && event->xbutton.time > ignore_next_mouse_click_timeout) | 21982 | && event->xbutton.time > ignore_next_mouse_click_timeout) |
| 21958 | { | 21983 | { |
| 21959 | ignore_next_mouse_click_timeout = 0; | 21984 | ignore_next_mouse_click_timeout = 0; |
| 21960 | x_construct_mouse_click (&inev.ie, &event->xbutton, f); | 21985 | x_construct_mouse_click (&inev.ie, &event->xbutton, |
| 21986 | f, false); | ||
| 21961 | } | 21987 | } |
| 21962 | if (event->type == ButtonRelease) | 21988 | if (event->type == ButtonRelease) |
| 21963 | ignore_next_mouse_click_timeout = 0; | 21989 | ignore_next_mouse_click_timeout = 0; |
| 21964 | } | 21990 | } |
| 21965 | else | 21991 | else |
| 21966 | x_construct_mouse_click (&inev.ie, &event->xbutton, f); | 21992 | x_construct_mouse_click (&inev.ie, &event->xbutton, |
| 21993 | f, false); | ||
| 21967 | 21994 | ||
| 21968 | if (!NILP (tab_bar_arg)) | 21995 | if (!NILP (tab_bar_arg)) |
| 21969 | inev.ie.arg = tab_bar_arg; | 21996 | inev.ie.arg = tab_bar_arg; |
| @@ -23740,13 +23767,13 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 23740 | && xev->time > ignore_next_mouse_click_timeout) | 23767 | && xev->time > ignore_next_mouse_click_timeout) |
| 23741 | { | 23768 | { |
| 23742 | ignore_next_mouse_click_timeout = 0; | 23769 | ignore_next_mouse_click_timeout = 0; |
| 23743 | x_construct_mouse_click (&inev.ie, &bv, f); | 23770 | x_construct_mouse_click (&inev.ie, &bv, f, true); |
| 23744 | } | 23771 | } |
| 23745 | if (xev->evtype == XI_ButtonRelease) | 23772 | if (xev->evtype == XI_ButtonRelease) |
| 23746 | ignore_next_mouse_click_timeout = 0; | 23773 | ignore_next_mouse_click_timeout = 0; |
| 23747 | } | 23774 | } |
| 23748 | else | 23775 | else |
| 23749 | x_construct_mouse_click (&inev.ie, &bv, f); | 23776 | x_construct_mouse_click (&inev.ie, &bv, f, true); |
| 23750 | 23777 | ||
| 23751 | if (!NILP (tab_bar_arg)) | 23778 | if (!NILP (tab_bar_arg)) |
| 23752 | inev.ie.arg = tab_bar_arg; | 23779 | inev.ie.arg = tab_bar_arg; |
| @@ -32452,6 +32479,12 @@ syms_of_xterm (void) | |||
| 32452 | DEFSYM (Qexpose, "expose"); | 32479 | DEFSYM (Qexpose, "expose"); |
| 32453 | DEFSYM (Qdont_save, "dont-save"); | 32480 | DEFSYM (Qdont_save, "dont-save"); |
| 32454 | 32481 | ||
| 32482 | DEFSYM (Qmouse_wheel_buttons, "mouse-wheel-buttons"); | ||
| 32483 | DEFSYM (Qwheel_up, "wheel-up"); | ||
| 32484 | DEFSYM (Qwheel_down, "wheel-down"); | ||
| 32485 | DEFSYM (Qwheel_left, "wheel-left"); | ||
| 32486 | DEFSYM (Qwheel_right, "wheel-right"); | ||
| 32487 | |||
| 32455 | #ifdef USE_GTK | 32488 | #ifdef USE_GTK |
| 32456 | xg_default_icon_file = build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg"); | 32489 | xg_default_icon_file = build_pure_c_string ("icons/hicolor/scalable/apps/emacs.svg"); |
| 32457 | staticpro (&xg_default_icon_file); | 32490 | staticpro (&xg_default_icon_file); |