From 91d5edd9d10db30418cb32f5734d496d76ef56f3 Mon Sep 17 00:00:00 2001 From: Jared Finder Date: Sat, 31 Oct 2020 21:25:47 -0800 Subject: [PATCH] Face-changing text properties and help-echo now work with xterm-mouse. * src/dispnew.c (update_mouse_position): New function for mouse movement logic in 'handle_one_term_event' that can be shared across different mouse backends. (display--update-for-mouse-movement): New lisp function, call it. * lisp/xt-mouse.el (xterm-mouse--handle-mouse-movement): New function that calls 'display--update-for-mouse-movement'. (xterm-mouse-translate-1): Call it. * src/term.c (handle_one_term_event): Inline logic from 'term_mouse_movement' and call 'update_mouse_position'. (term_mouse_movement): Delete. --- lisp/xt-mouse.el | 7 +++++++ src/dispextern.h | 1 + src/dispnew.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ src/term.c | 52 +++++++++++++----------------------------------- 4 files changed, 70 insertions(+), 38 deletions(-) diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el index f9c08f9a174..9301476e815 100644 --- a/lisp/xt-mouse.el +++ b/lisp/xt-mouse.el @@ -77,6 +77,7 @@ https://invisible-island.net/xterm/ctlseqs/ctlseqs.html)." (copy-sequence event)) vec) (is-move + (xterm-mouse--handle-mouse-movement) (if track-mouse vec ;; Mouse movement events are currently supposed to be ;; suppressed. Return no event. @@ -106,8 +107,14 @@ https://invisible-island.net/xterm/ctlseqs/ctlseqs.html)." (if (null track-mouse) (vector drag) (push drag unread-command-events) + (xterm-mouse--handle-mouse-movement) (vector (list 'mouse-movement ev-data)))))))))))) +(defun xterm-mouse--handle-mouse-movement () + "Handle mouse motion that was just generated for XTerm mouse." + (display--update-for-mouse-movement (terminal-parameter nil 'xterm-mouse-x) + (terminal-parameter nil 'xterm-mouse-y))) + ;; These two variables have been converted to terminal parameters. ;; ;;(defvar xterm-mouse-x 0 diff --git a/src/dispextern.h b/src/dispextern.h index 848d3bcd20e..da51772b37a 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3606,6 +3606,7 @@ extern Lisp_Object marginal_area_string (struct window *, enum window_part, extern void redraw_frame (struct frame *); extern bool update_frame (struct frame *, bool, bool); extern void update_frame_with_menu (struct frame *, int, int); +extern int update_mouse_position (struct frame *, int, int); extern void bitch_at_user (void); extern void adjust_frame_glyphs (struct frame *); void free_glyphs (struct frame *); diff --git a/src/dispnew.c b/src/dispnew.c index 48a36f2006c..479fccb45e0 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -3323,6 +3323,53 @@ update_frame_with_menu (struct frame *f, int row, int col) display_completed = !paused_p; } +/* Update the mouse position for a frame F. This handles both + updating the display for mouse-face propreties and updating the + help echo text. + + Returns the number of events generated. */ +int +update_mouse_position (struct frame *f, int x, int y) +{ + previous_help_echo_string = help_echo_string; + help_echo_string = Qnil; + + note_mouse_highlight (f, x, y); + + /* If the contents of the global variable help_echo_string + has changed, generate a HELP_EVENT. */ + if (!NILP (help_echo_string) + || !NILP (previous_help_echo_string)) + { + Lisp_Object frame; + XSETFRAME (frame, f); + + gen_help_event (help_echo_string, frame, help_echo_window, + help_echo_object, help_echo_pos); + return 1; + } + + return 0; +} + +DEFUN ("display--update-for-mouse-movement", Fdisplay__update_for_mouse_movement, + Sdisplay__update_for_mouse_movement, 2, 2, 0, + doc: /* Handle mouse movement detected by Lisp code. + +This function should be called when Lisp code detects the mouse has +moved, even if `track-mouse' is nil. This handles updates that do not +rely on input events such as updating display for mouse-face +properties or updating the help echo text. */) + (Lisp_Object mouse_x, Lisp_Object mouse_y) +{ + CHECK_FIXNUM (mouse_x); + CHECK_FIXNUM (mouse_y); + + update_mouse_position (SELECTED_FRAME (), XFIXNUM (mouse_x), + XFIXNUM (mouse_y)); + return Qnil; +} + /************************************************************************ Window-based updates @@ -6494,6 +6541,7 @@ syms_of_display (void) { defsubr (&Sredraw_frame); defsubr (&Sredraw_display); + defsubr (&Sdisplay__update_for_mouse_movement); defsubr (&Sframe_or_buffer_changed_p); defsubr (&Sopen_termscript); defsubr (&Sding); diff --git a/src/term.c b/src/term.c index 3a13da165e5..a0738594bfc 100644 --- a/src/term.c +++ b/src/term.c @@ -2430,22 +2430,6 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row, cursor_to (f, save_y, save_x); } -static bool -term_mouse_movement (struct frame *frame, Gpm_Event *event) -{ - /* Has the mouse moved off the glyph it was on at the last sighting? */ - if (event->x != last_mouse_x || event->y != last_mouse_y) - { - frame->mouse_moved = 1; - note_mouse_highlight (frame, event->x, event->y); - /* Remember which glyph we're now on. */ - last_mouse_x = event->x; - last_mouse_y = event->y; - return 1; - } - return 0; -} - /* Return the current time, as a Time value. Wrap around on overflow. */ static Time current_Time (void) @@ -2562,30 +2546,22 @@ handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event) if (event->type & (GPM_MOVE | GPM_DRAG)) { - previous_help_echo_string = help_echo_string; - help_echo_string = Qnil; - Gpm_DrawPointer (event->x, event->y, fileno (tty->output)); - if (!term_mouse_movement (f, event)) - help_echo_string = previous_help_echo_string; - - /* If the contents of the global variable help_echo_string - has changed, generate a HELP_EVENT. */ - if (!NILP (help_echo_string) - || !NILP (previous_help_echo_string)) - { - Lisp_Object frame; - - if (f) - XSETFRAME (frame, f); - else - frame = Qnil; - - gen_help_event (help_echo_string, frame, help_echo_window, - help_echo_object, help_echo_pos); - count++; - } + /* Has the mouse moved off the glyph it was on at the last + sighting? */ + if (event->x != last_mouse_x || event->y != last_mouse_y) + { + /* FIXME: These three lines can not be moved into + update_mouse_position unless xterm-mouse gets updated to + generate mouse events via C code. See + https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg00163.html */ + last_mouse_x = event->x; + last_mouse_y = event->y; + f->mouse_moved = 1; + + count += update_mouse_position (f, event->x, event->y); + } } else { -- 2.39.2