* mouse-face and help echo support for xterm mouse
@ 2020-11-01 5:46 Jared Finder via Emacs development discussions.
2020-11-01 13:39 ` Stefan Monnier
0 siblings, 1 reply; 24+ messages in thread
From: Jared Finder via Emacs development discussions. @ 2020-11-01 5:46 UTC (permalink / raw)
To: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 395 bytes --]
Attached is a patch that makes the xterm-mouse properly support
mouse-face and help echo text. It simply adds a new function to call
from Lisp that does what the existing event handlers
(handle_one_term_event for GPM, w32_read_socket for Windows, etc.) when
they notice mouse movement.
I think with this the xterm-mouse is now at parity with other terminal
mouse support. Yay!
-- MJF
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Face-changing-text-properties-and-help-echo-now-work.patch --]
[-- Type: text/x-diff; name=0001-Face-changing-text-properties-and-help-echo-now-work.patch, Size: 3296 bytes --]
From b7eb78397bc96c0e1bc2d280bd6660bbaa779790 Mon Sep 17 00:00:00 2001
From: Jared Finder <jared@finder.org>
Date: Sat, 31 Oct 2020 21:25:47 -0800
Subject: [PATCH] Face-changing text properties and help-echo now work with
xterm-mouse.
* src/term.c (handle-lisp-mouse-motion): New function like
handle_one_term_event but only for mouse motion and with no GPM code.
* lisp/xt-mouse.el (xterm-mouse--handle-mouse-motion): New function that
calls 'handle-lisp-mouse-motion'.
(xterm-mouse-translate-1): Call 'xterm-mouse--handle-mouse-motion'.
---
lisp/xt-mouse.el | 9 +++++++++
src/term.c | 28 ++++++++++++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el
index f9c08f9a17..37550276f8 100644
--- a/lisp/xt-mouse.el
+++ b/lisp/xt-mouse.el
@@ -77,6 +77,7 @@ xterm-mouse-translate-1
(copy-sequence event))
vec)
(is-move
+ (xterm-mouse--handle-mouse-motion)
(if track-mouse vec
;; Mouse movement events are currently supposed to be
;; suppressed. Return no event.
@@ -106,8 +107,16 @@ xterm-mouse-translate-1
(if (null track-mouse)
(vector drag)
(push drag unread-command-events)
+ (xterm-mouse--handle-mouse-motion)
(vector (list 'mouse-movement ev-data))))))))))))
+(defun xterm-mouse--handle-mouse-motion ()
+ "Handle mouse motion that was just generated for XTerm mouse."
+ (let ((frame (selected-frame)))
+ (handle-lisp-mouse-motion frame
+ (terminal-parameter frame 'xterm-mouse-x)
+ (terminal-parameter frame 'xterm-mouse-y))))
+
;; These two variables have been converted to terminal parameters.
;;
;;(defvar xterm-mouse-x 0
diff --git a/src/term.c b/src/term.c
index ff1aabfed2..710b00e32f 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2617,6 +2617,33 @@ handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event,
return count;
}
+DEFUN ("handle-lisp-mouse-motion", Fhandle_lisp_mouse_motion,
+ Shandle_lisp_mouse_motion, 3, 3, 0,
+ doc: /* Handle mouse motion 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
+not rely on input events such as updating display for mouse-face
+proprties or updating the help echo text. */)
+ (Lisp_Object frame, Lisp_Object mouse_x, Lisp_Object mouse_y)
+{
+ if (NILP (frame))
+ frame = selected_frame;
+
+ previous_help_echo_string = help_echo_string;
+ help_echo_string = Qnil;
+
+ note_mouse_highlight(XFRAME(frame), XFIXNUM (mouse_x), XFIXNUM (mouse_y));
+
+ if (!NILP (help_echo_string)
+ || !NILP (previous_help_echo_string))
+ {
+ gen_help_event (help_echo_string, frame, help_echo_window,
+ help_echo_object, help_echo_pos);
+ }
+ return Qnil;
+}
+
DEFUN ("gpm-mouse-start", Fgpm_mouse_start, Sgpm_mouse_start,
0, 0, 0,
doc: /* Open a connection to Gpm.
@@ -4568,6 +4595,7 @@ syms_of_term (void)
defsubr (&Stty_top_frame);
defsubr (&Ssuspend_tty);
defsubr (&Sresume_tty);
+ defsubr (&Shandle_lisp_mouse_motion);
#ifdef HAVE_GPM
defsubr (&Sgpm_mouse_start);
defsubr (&Sgpm_mouse_stop);
--
2.20.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-01 5:46 mouse-face and help echo support for xterm mouse Jared Finder via Emacs development discussions.
@ 2020-11-01 13:39 ` Stefan Monnier
2020-11-01 15:56 ` Jared Finder via Emacs development discussions.
2020-11-05 8:15 ` Jared Finder via Emacs development discussions.
0 siblings, 2 replies; 24+ messages in thread
From: Stefan Monnier @ 2020-11-01 13:39 UTC (permalink / raw)
To: Jared Finder via Emacs development discussions.; +Cc: Jared Finder
Hi Jared,
I really like this new feature but have just one comment/question?
> + previous_help_echo_string = help_echo_string;
> + help_echo_string = Qnil;
> +
> + note_mouse_highlight(XFRAME(frame), XFIXNUM (mouse_x), XFIXNUM (mouse_y));
> +
> + if (!NILP (help_echo_string)
> + || !NILP (previous_help_echo_string))
> + {
> + gen_help_event (help_echo_string, frame, help_echo_window,
> + help_echo_object, help_echo_pos);
> + }
I see this exact same code in other C files.
Could we move it to a file where we can share it instead of having
N copies?
Stefan
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-01 13:39 ` Stefan Monnier
@ 2020-11-01 15:56 ` Jared Finder via Emacs development discussions.
2020-11-04 6:54 ` Jared Finder via Emacs development discussions.
2020-11-05 8:15 ` Jared Finder via Emacs development discussions.
1 sibling, 1 reply; 24+ messages in thread
From: Jared Finder via Emacs development discussions. @ 2020-11-01 15:56 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Jared Finder via "Emacs development discussions."
On 2020-11-01 5:39 am, Stefan Monnier wrote:
> Hi Jared,
>
> I really like this new feature but have just one comment/question?
>
>> + previous_help_echo_string = help_echo_string;
>> + help_echo_string = Qnil;
>> +
>> + note_mouse_highlight(XFRAME(frame), XFIXNUM (mouse_x), XFIXNUM
>> (mouse_y));
>> +
>> + if (!NILP (help_echo_string)
>> + || !NILP (previous_help_echo_string))
>> + {
>> + gen_help_event (help_echo_string, frame, help_echo_window,
>> + help_echo_object, help_echo_pos);
>> + }
>
> I see this exact same code in other C files.
> Could we move it to a file where we can share it instead of having
> N copies?
I completely agree, not just for this code but also for mouse handling
in general. I think there should be a shared mouse interface with
individual C functions for each type of mouse event: mouse move, mouse
click, etc. Translating OS-specific events to this shared functionality
would continue to be OS-specific, but the actual handling of these
events, such as this logic, would be fully shared. For example, this
would unify the different codepaths between TTY menus for GPM,
xterm-mouse, and NT Emacs.
I would be happy to help with this next. However I need some help. I
can only locally build and test for Linux terminal with xterm-mouse or
GPM handling the mouse. Is there someone who can help for other
platforms? And should the GUI platforms be included as well? (I
suspect yes is the right answer.)
-- MJF
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-01 15:56 ` Jared Finder via Emacs development discussions.
@ 2020-11-04 6:54 ` Jared Finder via Emacs development discussions.
2020-11-04 14:13 ` Stefan Monnier
2020-11-04 15:19 ` Eli Zaretskii
0 siblings, 2 replies; 24+ messages in thread
From: Jared Finder via Emacs development discussions. @ 2020-11-04 6:54 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Jared Finder via "Emacs development discussions."
[-- Attachment #1: Type: text/plain, Size: 2245 bytes --]
On 2020-11-01 7:56 am, Jared Finder wrote:
> On 2020-11-01 5:39 am, Stefan Monnier wrote:
>> Hi Jared,
>>
>> I really like this new feature but have just one comment/question?
>>
>>> + previous_help_echo_string = help_echo_string;
>>> + help_echo_string = Qnil;
>>> +
>>> + note_mouse_highlight(XFRAME(frame), XFIXNUM (mouse_x), XFIXNUM
>>> (mouse_y));
>>> +
>>> + if (!NILP (help_echo_string)
>>> + || !NILP (previous_help_echo_string))
>>> + {
>>> + gen_help_event (help_echo_string, frame, help_echo_window,
>>> + help_echo_object, help_echo_pos);
>>> + }
>>
>> I see this exact same code in other C files.
>> Could we move it to a file where we can share it instead of having
>> N copies?
>
> I completely agree, not just for this code but also for mouse handling
> in general. I think there should be a shared mouse interface with
> individual C functions for each type of mouse event: mouse move, mouse
> click, etc. Translating OS-specific events to this shared
> functionality would continue to be OS-specific, but the actual
> handling of these events, such as this logic, would be fully shared.
> For example, this would unify the different codepaths between TTY
> menus for GPM, xterm-mouse, and NT Emacs.
>
> I would be happy to help with this next. However I need some help. I
> can only locally build and test for Linux terminal with xterm-mouse or
> GPM handling the mouse. Is there someone who can help for other
> platforms? And should the GUI platforms be included as well? (I
> suspect yes is the right answer.)
Toward proving that the code could be shared, I refactored the GPM mouse
logic so that it was clearly apparent how to share it with
handle-lisp-mouse-motion. That patch is attached. I'd like to make
sure this looks like an appropriate change to make. If so, I will
finish up the patch.
Two specific questions:
1. To enable sharing logic, I need to encode a handful of assumptions
that I believe are true today (example: no need to handle quit-char in
GPM handling). Do these assumptions look reasonable?
2. In what file should such a shared function go? My initial thought is
a new file "mouse.c" as it would hold shared mouse logic.
-- MJF
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-WIP-Simplifying-the-code-in-handle_one_term_event.patch --]
[-- Type: text/x-diff; name=0001-WIP-Simplifying-the-code-in-handle_one_term_event.patch, Size: 4872 bytes --]
From 186983baf6d316aeef964c5e84485bb8964eb891 Mon Sep 17 00:00:00 2001
From: Jared Finder <jared@finder.org>
Date: Tue, 3 Nov 2020 22:15:36 -0800
Subject: [PATCH] WIP: Simplifying the code in handle_one_term_event.
Simplifying things so that the mouse movement code looks similar to
handle-lisp-mouse-motion. Specifically:
1) Removing hold_quit from handle_one_term_event. GPM only ever
reports click events or move events, so no need to hold quit events
until later.
2) do_help is only ever set for mouse movement events, so directly
inline that branch.
3) f is guaranteed to be non-null, so remove branches that check.
4) ie is only ever set to GPM_CLICK_EVENT, so directly inline that
branch.
---
src/keyboard.c | 8 +-------
src/term.c | 53 ++++++++++++++++++++-----------------------------
src/termhooks.h | 2 +-
3 files changed, 23 insertions(+), 40 deletions(-)
diff --git a/src/keyboard.c b/src/keyboard.c
index 403f583689..598e86e2a5 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -7025,12 +7025,8 @@ tty_read_avail_input (struct terminal *terminal,
if (gpm_tty == tty)
{
Gpm_Event event;
- struct input_event gpm_hold_quit;
int gpm, fd = gpm_fd;
- EVENT_INIT (gpm_hold_quit);
- gpm_hold_quit.kind = NO_EVENT;
-
/* gpm==1 if event received.
gpm==0 if the GPM daemon has closed the connection, in which case
Gpm_GetEvent closes gpm_fd and clears it to -1, which is why
@@ -7038,13 +7034,11 @@ tty_read_avail_input (struct terminal *terminal,
select masks.
gpm==-1 if a protocol error or EWOULDBLOCK; the latter is normal. */
while (gpm = Gpm_GetEvent (&event), gpm == 1) {
- nread += handle_one_term_event (tty, &event, &gpm_hold_quit);
+ nread += handle_one_term_event (tty, &event);
}
if (gpm == 0)
/* Presumably the GPM daemon has closed the connection. */
close_gpm (fd);
- if (gpm_hold_quit.kind != NO_EVENT)
- kbd_buffer_store_event (&gpm_hold_quit);
if (nread)
return nread;
}
diff --git a/src/term.c b/src/term.c
index b6fa93bb62..f40cae4efd 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2550,18 +2550,11 @@ term_mouse_click (struct input_event *result, Gpm_Event *event,
}
int
-handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event,
- struct input_event *hold_quit)
+handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event)
{
struct frame *f = XFRAME (tty->top_frame);
- struct input_event ie;
- bool do_help = 0;
int count = 0;
- EVENT_INIT (ie);
- ie.kind = NO_EVENT;
- ie.arg = Qnil;
-
if (event->type & (GPM_MOVE | GPM_DRAG)) {
previous_help_echo_string = help_echo_string;
help_echo_string = Qnil;
@@ -2575,11 +2568,22 @@ handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event,
has changed, generate a HELP_EVENT. */
if (!NILP (help_echo_string)
|| !NILP (previous_help_echo_string))
- do_help = 1;
+ {
+ Lisp_Object frame;
- goto done;
+ XSETFRAME (frame, f);
+ gen_help_event (help_echo_string, frame, help_echo_window,
+ help_echo_object, help_echo_pos);
+ count++;
+ }
}
else {
+ struct input_event ie;
+
+ EVENT_INIT (ie);
+ ie.kind = NO_EVENT;
+ ie.arg = Qnil;
+
f->mouse_moved = 0;
term_mouse_click (&ie, event, f);
if (tty_handle_tab_bar_click (f, event->x, event->y,
@@ -2590,29 +2594,14 @@ handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event,
count += 2;
return count;
}
- }
- done:
- if (ie.kind != NO_EVENT)
- {
- kbd_buffer_store_event_hold (&ie, hold_quit);
- count++;
- }
-
- if (do_help
- && !(hold_quit && hold_quit->kind != NO_EVENT))
- {
- 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++;
- }
+ /* ie can only be of the event type GPM_CLICK_EVENT., it could
+ never be a quit-char keystroke event. Therefore, there is no
+ need to queue quit events. */
+ eassert (ie.kind == GPM_CLICK_EVENT);
+ kbd_buffer_store_event_hold (&ie, NULL);
+ count++;
+ }
return count;
}
diff --git a/src/termhooks.h b/src/termhooks.h
index d18b750c3a..6ab06ceff9 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -370,7 +370,7 @@ #define EVENT_INIT(event) memset (&(event), 0, sizeof (struct input_event))
#ifdef HAVE_GPM
#include <gpm.h>
-extern int handle_one_term_event (struct tty_display_info *, Gpm_Event *, struct input_event *);
+extern int handle_one_term_event (struct tty_display_info *, Gpm_Event *);
#ifndef HAVE_WINDOW_SYSTEM
extern void term_mouse_moveto (int, int);
#endif
--
2.20.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-04 6:54 ` Jared Finder via Emacs development discussions.
@ 2020-11-04 14:13 ` Stefan Monnier
2020-11-04 15:46 ` Eli Zaretskii
2020-11-04 15:19 ` Eli Zaretskii
1 sibling, 1 reply; 24+ messages in thread
From: Stefan Monnier @ 2020-11-04 14:13 UTC (permalink / raw)
To: Jared Finder; +Cc: Jared Finder via "Emacs development discussions."
> Toward proving that the code could be shared, I refactored the GPM mouse
> logic so that it was clearly apparent how to share it with
> handle-lisp-mouse-motion. That patch is attached. I'd like to make sure
> this looks like an appropriate change to make. If so, I will finish up
> the patch.
Hmm... this `handle_one_term_event` seems weirdly complex.
I don't understand it enough to judge if your rewrite is OK.
> 1. To enable sharing logic, I need to encode a handful of assumptions that
> I believe are true today (example: no need to handle quit-char in GPM
> handling). Do these assumptions look reasonable?
I don't know. I don't even know why `hold_quit` is called that way:
I can't see any reason why it should hold "quit" events more than
anything else.
In the patch below I slightly tweaked the code to simplify the control
flow a tiny bit and to follow our coding convention on placement of
braces, and more importantly I added assertions which I believe always
hold along with comments pointing out things I don't understand.
Could someone help me clarify what's going on?
> 2. In what file should such a shared function go? My initial thought is
> a new file "mouse.c" as it would hold shared mouse logic.
I suspect it would end up being fairly empty, and while I hate the
monster xdisp.c file, I also don't really like tiny files, so I'd prefer
if we could find a better home for it.
Stefan
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-04 6:54 ` Jared Finder via Emacs development discussions.
2020-11-04 14:13 ` Stefan Monnier
@ 2020-11-04 15:19 ` Eli Zaretskii
1 sibling, 0 replies; 24+ messages in thread
From: Eli Zaretskii @ 2020-11-04 15:19 UTC (permalink / raw)
To: Jared Finder; +Cc: monnier, emacs-devel
> Date: Tue, 03 Nov 2020 22:54:32 -0800
> Cc: "Jared Finder via \"Emacs development discussions.\"" <emacs-devel@gnu.org>
> From: Jared Finder via "Emacs development discussions." <emacs-devel@gnu.org>
>
> Toward proving that the code could be shared, I refactored the GPM mouse
> logic so that it was clearly apparent how to share it with
> handle-lisp-mouse-motion. That patch is attached. I'd like to make
> sure this looks like an appropriate change to make. If so, I will
> finish up the patch.
Thanks, see below.
> Two specific questions:
>
> 1. To enable sharing logic, I need to encode a handful of assumptions
> that I believe are true today (example: no need to handle quit-char in
> GPM handling). Do these assumptions look reasonable?
Not sure why is this important. You want to remove the hold_quit
stuff from the code? I don't see that it complicates the code, so I'd
suggest not to waste your time on worrying about it. Just leave it
alone.
> 2. In what file should such a shared function go? My initial thought is
> a new file "mouse.c" as it would hold shared mouse logic.
No, new file for a single function is too much. dispnew.c, I guess.
> while (gpm = Gpm_GetEvent (&event), gpm == 1) {
> - nread += handle_one_term_event (tty, &event, &gpm_hold_quit);
> + nread += handle_one_term_event (tty, &event);
As explained above, I'd leave the signature alone, because it is not
guaranteed that every subroutine we call here doesn't need to use it.
> - if (ie.kind != NO_EVENT)
I also don't think it's a good idea to remove this test. The
functions you call don't guarantee to always return a meaningful
event, and the assertion you leave instead is too drastic: imagine
that it happens to some innocent user.
> + kbd_buffer_store_event_hold (&ie, NULL);
If we eventually decide not to use the hold_quit stuff, you can just
call kbd_buffer_store_event here.
Thanks.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-04 14:13 ` Stefan Monnier
@ 2020-11-04 15:46 ` Eli Zaretskii
2020-11-04 15:56 ` Stefan Monnier
0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2020-11-04 15:46 UTC (permalink / raw)
To: Stefan Monnier; +Cc: jared, emacs-devel
> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Wed, 04 Nov 2020 09:13:07 -0500
> Cc: "Jared Finder via \"Emacs development discussions.\"" <emacs-devel@gnu.org>
>
> In the patch below I slightly tweaked the code
What patch?
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-04 15:46 ` Eli Zaretskii
@ 2020-11-04 15:56 ` Stefan Monnier
2020-11-04 17:54 ` Jared Finder via Emacs development discussions.
0 siblings, 1 reply; 24+ messages in thread
From: Stefan Monnier @ 2020-11-04 15:56 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: jared, emacs-devel
>> In the patch below I slightly tweaked the code
> What patch?
Hmm... *the* patch, of course.
Stefan
diff --git a/src/term.c b/src/term.c
index ff1aabfed2..a03a246415 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2562,7 +2562,8 @@
ie.kind = NO_EVENT;
ie.arg = Qnil;
- if (event->type & (GPM_MOVE | GPM_DRAG)) {
+ if (event->type & (GPM_MOVE | GPM_DRAG))
+ {
previous_help_echo_string = help_echo_string;
help_echo_string = Qnil;
@@ -2577,29 +2578,45 @@
|| !NILP (previous_help_echo_string))
do_help = 1;
- goto done;
+ eassert (ie.kind == NO_EVENT);
}
- else {
+ else
+ {
f->mouse_moved = 0;
+ eassert (ie.kind == NO_EVENT);
term_mouse_click (&ie, event, f);
+ eassert (ie.kind == GPM_CLICK_EVENT);
if (tty_handle_tab_bar_click (f, event->x, event->y,
(ie.modifiers & down_modifier) != 0, &ie))
{
+ eassert (ie.kind == GPM_CLICK_EVENT
+ || ie.kind == TAB_BAR_EVENT);
/* tty_handle_tab_bar_click stores 2 events in the event
queue, so we are done here. */
+ /* FIXME: Actually, `tty_handle_tab_bar_click` returns true
+ without storing any events, when
+ (ie.modifiers & down_modifier) != 0 */
count += 2;
return count;
}
+ eassert (ie.kind == GPM_CLICK_EVENT);
}
- done:
- if (ie.kind != NO_EVENT)
+ if (ie.kind != NO_EVENT) /* FIXME: We retest the previous if's condition! */
{
+ /* FIXME: `hold_quit` could already hold a previous event,
+ so it risks crushing that previous event.
+ What am I missing? */
kbd_buffer_store_event_hold (&ie, hold_quit);
count++;
}
if (do_help
+ /* FIXME: `hold_quit` is never NULL?! */
+ /* FIXME: Why do we test `hold_quit->kind != NO_EVENT` here?
+ This either comes from `ie` (via kbd_buffer_store_event_hold above)
+ or from an earlier call to us (tty_read_avail_input calls us in a
+ loop with the same `hold_quit` struct). */
&& !(hold_quit && hold_quit->kind != NO_EVENT))
{
Lisp_Object frame;
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-04 15:56 ` Stefan Monnier
@ 2020-11-04 17:54 ` Jared Finder via Emacs development discussions.
2020-11-04 18:47 ` Stefan Monnier
0 siblings, 1 reply; 24+ messages in thread
From: Jared Finder via Emacs development discussions. @ 2020-11-04 17:54 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel
On 2020-11-04 7:56 am, Stefan Monnier wrote:
>
> diff --git a/src/term.c b/src/term.c
> index ff1aabfed2..a03a246415 100644
> --- a/src/term.c
> +++ b/src/term.c
> @@ -2562,7 +2562,8 @@
> ie.kind = NO_EVENT;
> ie.arg = Qnil;
>
> - if (event->type & (GPM_MOVE | GPM_DRAG)) {
> + if (event->type & (GPM_MOVE | GPM_DRAG))
> + {
Old code style is OLD. Apparently this formatting is from when the
function was first added in 2007. :)
> @@ -2577,29 +2578,45 @@
> || !NILP (previous_help_echo_string))
> do_help = 1;
>
> - goto done;
> + eassert (ie.kind == NO_EVENT);
This is the assert for the mouse movement path. Please remember this
value.
> }
> - else {
> + else
> + {
> f->mouse_moved = 0;
> + eassert (ie.kind == NO_EVENT);
> term_mouse_click (&ie, event, f);
> + eassert (ie.kind == GPM_CLICK_EVENT);
> if (tty_handle_tab_bar_click (f, event->x, event->y,
> (ie.modifiers & down_modifier) != 0,
> &ie))
> {
> + eassert (ie.kind == GPM_CLICK_EVENT
> + || ie.kind == TAB_BAR_EVENT);
> /* tty_handle_tab_bar_click stores 2 events in the event
> queue, so we are done here. */
> + /* FIXME: Actually, `tty_handle_tab_bar_click` returns true
> + without storing any events, when
> + (ie.modifiers & down_modifier) != 0 */
> count += 2;
> return count;
> }
> + eassert (ie.kind == GPM_CLICK_EVENT);
This assert is for the mouse click path, please remember this value.
> }
>
> - done:
> - if (ie.kind != NO_EVENT)
> + if (ie.kind != NO_EVENT) /* FIXME: We retest the previous if's
> condition! */
> {
> + /* FIXME: `hold_quit` could already hold a previous event,
> + so it risks crushing that previous event.
> + What am I missing? */
> kbd_buffer_store_event_hold (&ie, hold_quit);
This is the meat of the refactor.
Given the current code hold_quit will never hold a previous event.
tty_read_avail_input initializes hold_quit right before calling
handle_one_term_event and and sets kind to NO_EVENT. This is the first
and only time in this function hold_quit is passed to any other
function.
Because it is the first time passed, we can safely deduce that
hold_quit->kind will still be NO_EVENT *unless* a previous loop
iteration changed it.
Because it is the only time passed, we can safely deduce that
hold_quit->kind can only changed in a previous loop iteration by this
function storing a quit event. However, this can not happen. hold_quit
would get set by kbd_buffer_store_buffered_event which
kbd_buffer_store_event_hold calls. To get set, the following must all
be true:
1. An event of kind ASCII_KEYSTROKE_EVENT must be processed.
2. And that event's character code must be quit_char.
3. And that event must be on the current frame's KBOARD (not quite sure
what this means).
However, 1 will never be true as the only events that ever reach this
point are of kind GPM_CLICK_EVENT, as deduced from the above asserts.
> count++;
> }
>
> if (do_help
> + /* FIXME: `hold_quit` is never NULL?! */
Agreed.
> + /* FIXME: Why do we test `hold_quit->kind != NO_EVENT` here?
> + This either comes from `ie` (via kbd_buffer_store_event_hold
> above)
> + or from an earlier call to us (tty_read_avail_input calls us
> in a
> + loop with the same `hold_quit` struct). */
And from above reasoning, we know that hold_quit is always non-NULL and
hold_quit->kind is always NO_EVENT.
-- MJF
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-04 17:54 ` Jared Finder via Emacs development discussions.
@ 2020-11-04 18:47 ` Stefan Monnier
2020-11-04 18:51 ` Eli Zaretskii
0 siblings, 1 reply; 24+ messages in thread
From: Stefan Monnier @ 2020-11-04 18:47 UTC (permalink / raw)
To: Jared Finder; +Cc: Eli Zaretskii, emacs-devel
>> - done:
>> - if (ie.kind != NO_EVENT)
>> + if (ie.kind != NO_EVENT) /* FIXME: We retest the previous if's
>> condition! */
>> {
>> + /* FIXME: `hold_quit` could already hold a previous event,
>> + so it risks crushing that previous event.
>> + What am I missing? */
>> kbd_buffer_store_event_hold (&ie, hold_quit);
>
> This is the meat of the refactor.
>
> Given the current code hold_quit will never hold a previous
> event. tty_read_avail_input initializes hold_quit right before calling
> handle_one_term_event and and sets kind to NO_EVENT. This is the first and
> only time in this function hold_quit is passed to any other function.
The way I read it:
EVENT_INIT (gpm_hold_quit);
gpm_hold_quit.kind = NO_EVENT;
[...]
while (gpm = Gpm_GetEvent (&event), gpm == 1) {
nread += handle_one_term_event (tty, &event, &gpm_hold_quit);
}
`gpm_hold_quit->kind` could hold a different value from `NO_EVENT` on the
second iteration (and subsequent ones) of the loop.
> Because it is the first time passed, we can safely deduce that
> hold_quit->kind will still be NO_EVENT *unless* a previous loop iteration
> changed it.
That's right.
> Because it is the only time passed, we can safely deduce that
> hold_quit->kind can only changed in a previous loop iteration by this
> function storing a quit event. However, this can not happen. hold_quit
> would get set by kbd_buffer_store_buffered_event which
> kbd_buffer_store_event_hold calls. To get set, the following must all be
> true:
>
> 1. An event of kind ASCII_KEYSTROKE_EVENT must be processed.
> 2. And that event's character code must be quit_char.
> 3. And that event must be on the current frame's KBOARD (not quite sure what
> this means).
>
> However, 1 will never be true as the only events that ever reach this point
> are of kind GPM_CLICK_EVENT, as deduced from the above asserts.
Oh, I see, indeed.
So we have the following:
if (event->type & (GPM_MOVE | GPM_DRAG))
{
[...]
eassert (ie.kind == NO_EVENT);
}
else
{
[...]
eassert (ie.kind == GPM_CLICK_EVENT);
}
if (ie.kind != NO_EVENT) /* FIXME: We retest the previous if's condition! */
{
kbd_buffer_store_event_hold (&ie, hold_quit);
count++;
}
where we can move the second `if` into the first (according to the FIXME)
if (event->type & (GPM_MOVE | GPM_DRAG))
{
[...]
eassert (ie.kind == NO_EVENT);
}
else
{
[...]
eassert (ie.kind == GPM_CLICK_EVENT);
kbd_buffer_store_event_hold (&ie, hold_quit);
count++;
}
and then we know that `hold_quit` starts at NO_EVENT and can only be
changed via this call to `kbd_buffer_store_event_hold`, but this call
will never change it because `ie.kind == GPM_CLICK_EVENT` and
kbd_buffer_store_event_hold would only ever touch it if the kind was
ASCII_KEYSTROKE_EVENT, so we know that `hold_quit->kind == NO_EVENT`
always holds and we can drop it.
The code is now (with added context):
if (event->type & (GPM_MOVE | GPM_DRAG))
{
[...]
eassert (ie.kind == NO_EVENT);
}
else
{
[...]
eassert (ie.kind == GPM_CLICK_EVENT);
kbd_buffer_store_event (&ie);
count++;
}
if (do_help
/* FIXME: `hold_quit` is never NULL?! */
&& !(hold_quit && hold_quit->kind != NO_EVENT))
{ ... }
and the last if's condition can now be simplified:
bool do_help = false;
[...]
if (event->type & (GPM_MOVE | GPM_DRAG))
{
[...]
if (!NILP (help_echo_string)
|| !NILP (previous_help_echo_string))
do_help = true;
eassert (ie.kind == NO_EVENT);
}
else
{
[...]
eassert (ie.kind == GPM_CLICK_EVENT);
kbd_buffer_store_event (&ie);
count++;
}
if (do_help)
{ ... }
and now we can again fold the second move into the tail of the first:
bool do_help = false;
[...]
if (event->type & (GPM_MOVE | GPM_DRAG))
{
[...]
if (!NILP (help_echo_string)
|| !NILP (previous_help_echo_string))
do_help = true;
eassert (ie.kind == NO_EVENT);
if (do_help)
{ ... }
}
else
{
[...]
eassert (ie.kind == GPM_CLICK_EVENT);
kbd_buffer_store_event (&ie);
count++;
}
and get rid of `do_help` altogether.
[...]
if (event->type & (GPM_MOVE | GPM_DRAG))
{
[...]
if (!NILP (help_echo_string)
|| !NILP (previous_help_echo_string))
{ ... }
}
else
{
[...]
eassert (ie.kind == GPM_CLICK_EVENT);
kbd_buffer_store_event (&ie);
count++;
}
So, I installed the patch below.
Stefan
diff --git a/src/keyboard.c b/src/keyboard.c
index 2e0143379a..49a0a8bd23 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -7005,12 +7005,8 @@ tty_read_avail_input (struct terminal *terminal,
if (gpm_tty == tty)
{
Gpm_Event event;
- struct input_event gpm_hold_quit;
int gpm, fd = gpm_fd;
- EVENT_INIT (gpm_hold_quit);
- gpm_hold_quit.kind = NO_EVENT;
-
/* gpm==1 if event received.
gpm==0 if the GPM daemon has closed the connection, in which case
Gpm_GetEvent closes gpm_fd and clears it to -1, which is why
@@ -7018,13 +7014,11 @@ tty_read_avail_input (struct terminal *terminal,
select masks.
gpm==-1 if a protocol error or EWOULDBLOCK; the latter is normal. */
while (gpm = Gpm_GetEvent (&event), gpm == 1) {
- nread += handle_one_term_event (tty, &event, &gpm_hold_quit);
+ nread += handle_one_term_event (tty, &event);
}
if (gpm == 0)
/* Presumably the GPM daemon has closed the connection. */
close_gpm (fd);
- if (gpm_hold_quit.kind != NO_EVENT)
- kbd_buffer_store_event (&gpm_hold_quit);
if (nread)
return nread;
}
diff --git a/src/term.c b/src/term.c
index ff1aabfed2..3a13da165e 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2550,67 +2550,63 @@ term_mouse_click (struct input_event *result, Gpm_Event *event,
}
int
-handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event,
- struct input_event *hold_quit)
+handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event)
{
struct frame *f = XFRAME (tty->top_frame);
struct input_event ie;
- bool do_help = 0;
int count = 0;
EVENT_INIT (ie);
ie.kind = NO_EVENT;
ie.arg = Qnil;
- if (event->type & (GPM_MOVE | GPM_DRAG)) {
- previous_help_echo_string = help_echo_string;
- help_echo_string = Qnil;
+ 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));
+ Gpm_DrawPointer (event->x, event->y, fileno (tty->output));
- if (!term_mouse_movement (f, event))
- help_echo_string = previous_help_echo_string;
+ 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))
- do_help = 1;
+ /* 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;
- goto done;
- }
- else {
- f->mouse_moved = 0;
- term_mouse_click (&ie, event, f);
- if (tty_handle_tab_bar_click (f, event->x, event->y,
- (ie.modifiers & down_modifier) != 0, &ie))
- {
- /* tty_handle_tab_bar_click stores 2 events in the event
- queue, so we are done here. */
- count += 2;
- return count;
- }
- }
+ if (f)
+ XSETFRAME (frame, f);
+ else
+ frame = Qnil;
- done:
- if (ie.kind != NO_EVENT)
- {
- kbd_buffer_store_event_hold (&ie, hold_quit);
- count++;
+ gen_help_event (help_echo_string, frame, help_echo_window,
+ help_echo_object, help_echo_pos);
+ count++;
+ }
}
-
- if (do_help
- && !(hold_quit && hold_quit->kind != NO_EVENT))
+ else
{
- 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);
+ f->mouse_moved = 0;
+ term_mouse_click (&ie, event, f);
+ /* eassert (ie.kind == GPM_CLICK_EVENT); */
+ if (tty_handle_tab_bar_click (f, event->x, event->y,
+ (ie.modifiers & down_modifier) != 0, &ie))
+ {
+ /* eassert (ie.kind == GPM_CLICK_EVENT
+ * || ie.kind == TAB_BAR_EVENT); */
+ /* tty_handle_tab_bar_click stores 2 events in the event
+ queue, so we are done here. */
+ /* FIXME: Actually, `tty_handle_tab_bar_click` returns true
+ without storing any events, when
+ (ie.modifiers & down_modifier) != 0 */
+ count += 2;
+ return count;
+ }
+ /* eassert (ie.kind == GPM_CLICK_EVENT); */
+ kbd_buffer_store_event (&ie);
count++;
}
diff --git a/src/termhooks.h b/src/termhooks.h
index d18b750c3a..6ab06ceff9 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -370,7 +370,7 @@ #define EVENT_INIT(event) memset (&(event), 0, sizeof (struct input_event))
#ifdef HAVE_GPM
#include <gpm.h>
-extern int handle_one_term_event (struct tty_display_info *, Gpm_Event *, struct input_event *);
+extern int handle_one_term_event (struct tty_display_info *, Gpm_Event *);
#ifndef HAVE_WINDOW_SYSTEM
extern void term_mouse_moveto (int, int);
#endif
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-04 18:47 ` Stefan Monnier
@ 2020-11-04 18:51 ` Eli Zaretskii
2020-11-04 19:05 ` Stefan Monnier
0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2020-11-04 18:51 UTC (permalink / raw)
To: Stefan Monnier; +Cc: jared, emacs-devel
> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: Eli Zaretskii <eliz@gnu.org>, emacs-devel@gnu.org
> Date: Wed, 04 Nov 2020 13:47:29 -0500
>
> `gpm_hold_quit->kind` could hold a different value from `NO_EVENT` on the
> second iteration (and subsequent ones) of the loop.
>
> > Because it is the first time passed, we can safely deduce that
> > hold_quit->kind will still be NO_EVENT *unless* a previous loop iteration
> > changed it.
>
> That's right.
>
> > Because it is the only time passed, we can safely deduce that
> > hold_quit->kind can only changed in a previous loop iteration by this
> > function storing a quit event. However, this can not happen. hold_quit
> > would get set by kbd_buffer_store_buffered_event which
> > kbd_buffer_store_event_hold calls. To get set, the following must all be
> > true:
> >
> > 1. An event of kind ASCII_KEYSTROKE_EVENT must be processed.
> > 2. And that event's character code must be quit_char.
> > 3. And that event must be on the current frame's KBOARD (not quite sure what
> > this means).
> >
> > However, 1 will never be true as the only events that ever reach this point
> > are of kind GPM_CLICK_EVENT, as deduced from the above asserts.
>
> Oh, I see, indeed.
Are you guys taking into consideration the fact that this is a TTY,
where C-g causes a SIGINT, so it can come in at any time?
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-04 18:51 ` Eli Zaretskii
@ 2020-11-04 19:05 ` Stefan Monnier
2020-11-04 19:10 ` Jared Finder via Emacs development discussions.
0 siblings, 1 reply; 24+ messages in thread
From: Stefan Monnier @ 2020-11-04 19:05 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: jared, emacs-devel
> Are you guys taking into consideration the fact that this is a TTY,
> where C-g causes a SIGINT, so it can come in at any time?
I believe so, yes.
Stefan
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-04 19:05 ` Stefan Monnier
@ 2020-11-04 19:10 ` Jared Finder via Emacs development discussions.
0 siblings, 0 replies; 24+ messages in thread
From: Jared Finder via Emacs development discussions. @ 2020-11-04 19:10 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel
On 2020-11-04 11:05 am, Stefan Monnier wrote:
>> Are you guys taking into consideration the fact that this is a TTY,
>> where C-g causes a SIGINT, so it can come in at any time?
>
> I believe so, yes.
I agree. All of the reasoning was done by reasoning about local
variables in C functions. I do not see any code in the signal handling
code that reaches into arbitrary local variables of another C function.
-- MJF
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-01 13:39 ` Stefan Monnier
2020-11-01 15:56 ` Jared Finder via Emacs development discussions.
@ 2020-11-05 8:15 ` Jared Finder via Emacs development discussions.
2020-11-05 14:45 ` Stefan Monnier
1 sibling, 1 reply; 24+ messages in thread
From: Jared Finder via Emacs development discussions. @ 2020-11-05 8:15 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Jared Finder via "Emacs development discussions."
[-- Attachment #1: Type: text/plain, Size: 1144 bytes --]
On 2020-11-01 5:39 am, Stefan Monnier wrote:
> Hi Jared,
>
> I really like this new feature but have just one comment/question?
>
>> + previous_help_echo_string = help_echo_string;
>> + help_echo_string = Qnil;
>> +
>> + note_mouse_highlight(XFRAME(frame), XFIXNUM (mouse_x), XFIXNUM
>> (mouse_y));
>> +
>> + if (!NILP (help_echo_string)
>> + || !NILP (previous_help_echo_string))
>> + {
>> + gen_help_event (help_echo_string, frame, help_echo_window,
>> + help_echo_object, help_echo_pos);
>> + }
>
> I see this exact same code in other C files.
> Could we move it to a file where we can share it instead of having
> N copies?
With the code simplification in, this logic is now sharable between
xterm-mouse and GPM. Attached is an updated patch.
This patch does have one actual logic change: Previously
handle_one_term_event might call gen_help_event if a GPM_MOVE_EVENT or
GPM_DRAG_EVENT happened but the mouse position did not change. With
this patch, this is no longer the case. From testing locally with
running GPM mouse, this seems to not cause any user-visible change.
-- MJF
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Face-changing-text-properties-and-help-echo-now-work.patch --]
[-- Type: text/x-diff; name=0001-Face-changing-text-properties-and-help-echo-now-work.patch, Size: 6680 bytes --]
From 98e18207726ddeb1f922e9b95f1fd4822502a66a Mon Sep 17 00:00:00 2001
From: Jared Finder <jared@finder.org>
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 should be shared across GPM and
xterm-mouse.
(handle-lisp-mouse-motion): New lisp function, call it.
* lisp/xt-mouse.el (xterm-mouse--handle-mouse-motion): New function that
calls 'handle-lisp-mouse-motion'.
(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 | 9 +++++++++
src/dispextern.h | 1 +
src/dispnew.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
src/term.c | 46 ++++++++--------------------------------------
4 files changed, 65 insertions(+), 38 deletions(-)
diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el
index f9c08f9a17..37550276f8 100644
--- a/lisp/xt-mouse.el
+++ b/lisp/xt-mouse.el
@@ -77,6 +77,7 @@ xterm-mouse-translate-1
(copy-sequence event))
vec)
(is-move
+ (xterm-mouse--handle-mouse-motion)
(if track-mouse vec
;; Mouse movement events are currently supposed to be
;; suppressed. Return no event.
@@ -106,8 +107,16 @@ xterm-mouse-translate-1
(if (null track-mouse)
(vector drag)
(push drag unread-command-events)
+ (xterm-mouse--handle-mouse-motion)
(vector (list 'mouse-movement ev-data))))))))))))
+(defun xterm-mouse--handle-mouse-motion ()
+ "Handle mouse motion that was just generated for XTerm mouse."
+ (let ((frame (selected-frame)))
+ (handle-lisp-mouse-motion frame
+ (terminal-parameter frame 'xterm-mouse-x)
+ (terminal-parameter frame '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 848d3bcd20..da51772b37 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3606,6 +3606,7 @@ #define IMAGE_BACKGROUND_TRANSPARENT(img, f, mask) \
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 3f2ae3e6ad..545cae628f 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -3323,6 +3323,52 @@ 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 ("handle-lisp-mouse-motion", Fhandle_lisp_mouse_motion,
+ Shandle_lisp_mouse_motion, 3, 3, 0,
+ doc: /* Handle mouse motion 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
+not rely on input events such as updating display for mouse-face
+proprties or updating the help echo text. */)
+ (Lisp_Object frame, Lisp_Object mouse_x, Lisp_Object mouse_y)
+{
+ if (NILP (frame))
+ frame = selected_frame;
+
+ update_mouse_position (XFRAME (frame), XFIXNUM (mouse_x), XFIXNUM (mouse_y));
+ return Qnil;
+}
+
\f
/************************************************************************
Window-based updates
@@ -6490,6 +6536,7 @@ syms_of_display (void)
{
defsubr (&Sredraw_frame);
defsubr (&Sredraw_display);
+ defsubr (&Shandle_lisp_mouse_motion);
defsubr (&Sframe_or_buffer_changed_p);
defsubr (&Sopen_termscript);
defsubr (&Sding);
diff --git a/src/term.c b/src/term.c
index 3a13da165e..df34983344 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,16 @@ 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)
+ {
+ 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.20.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-05 8:15 ` Jared Finder via Emacs development discussions.
@ 2020-11-05 14:45 ` Stefan Monnier
2020-11-05 19:58 ` Jared Finder via Emacs development discussions.
0 siblings, 1 reply; 24+ messages in thread
From: Stefan Monnier @ 2020-11-05 14:45 UTC (permalink / raw)
To: Jared Finder; +Cc: Jared Finder via "Emacs development discussions."
> With the code simplification in, this logic is now sharable between
> xterm-mouse and GPM. Attached is an updated patch.
Thanks.
> This patch does have one actual logic change: Previously
> handle_one_term_event might call gen_help_event if a GPM_MOVE_EVENT or
> GPM_DRAG_EVENT happened but the mouse position did not change. With this
> patch, this is no longer the case. From testing locally with running GPM
> mouse, this seems to not cause any user-visible change.
I wouldn't worry about that, indeed. It's typically the kind of minor
discrepancies that accrue when code is duplicated and which make merging
them back "fun". You just have to choose which of the two behaviors is
preferable and I think here the better choice is to refrain from
generating an event when the position didn't actually change.
Further comments below.
Stefan
> diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el
> index f9c08f9a17..37550276f8 100644
> --- a/lisp/xt-mouse.el
> +++ b/lisp/xt-mouse.el
> @@ -77,6 +77,7 @@ xterm-mouse-translate-1
> (copy-sequence event))
> vec)
> (is-move
> + (xterm-mouse--handle-mouse-motion)
> (if track-mouse vec
> ;; Mouse movement events are currently supposed to be
> ;; suppressed. Return no event.
> @@ -106,8 +107,16 @@ xterm-mouse-translate-1
> (if (null track-mouse)
> (vector drag)
> (push drag unread-command-events)
> + (xterm-mouse--handle-mouse-motion)
> (vector (list 'mouse-movement ev-data))))))))))))
Hmm... `ev-data` includes the X/Y position, right?
Could we arrange to pass *that* data directly to
`xterm-mouse--handle-mouse-motion` rather than go through
(terminal-parameter frame 'xterm-mouse-x/y)? It likely won't make
much difference in practice, but it would make the data flow more clear,
I think.
> +(defun xterm-mouse--handle-mouse-motion ()
> + "Handle mouse motion that was just generated for XTerm mouse."
> + (let ((frame (selected-frame)))
> + (handle-lisp-mouse-motion frame
> + (terminal-parameter frame 'xterm-mouse-x)
> + (terminal-parameter frame 'xterm-mouse-y))))
This is the only caller to `handle-lisp-mouse-motion` and that function
has a "default frame to selected-frame" feature, so you could pass nil
instead of `frame`. Better yet, drop that frame argument altogether.
And I think the function's name should make it clear it's for internal
use only, or otherwise try to use some prefix that indicates it's
related to the display. Like `display-update-for-mouse-motion`?
[ I'm reminded here of the tension between using "mouse-motion" because it's
shorter and using "mouse-movement" because that's the name of the
event. ]
> +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
> +not rely on input events such as updating display for mouse-face
"not not"
> +proprties or updating the help echo text. */)
^^
e
> + (Lisp_Object frame, Lisp_Object mouse_x, Lisp_Object mouse_y)
> +{
> + if (NILP (frame))
> + frame = selected_frame;
> +
> + update_mouse_position (XFRAME (frame), XFIXNUM (mouse_x), XFIXNUM (mouse_y));
> + return Qnil;
> +}
This will crash and burn if `frame` is an integer (and the XFIXNUM won't
crash and burn but they should also be preceded by CHECK_FIXNUMs).
> if (event->type & (GPM_MOVE | GPM_DRAG))
> {
[...]
> + /* 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)
> + {
> + last_mouse_x = event->x;
> + last_mouse_y = event->y;
> + f->mouse_moved = 1;
Would it make sense to try and add this test to the "generic" part of
the code?
Stefan
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-05 14:45 ` Stefan Monnier
@ 2020-11-05 19:58 ` Jared Finder via Emacs development discussions.
2020-11-05 20:18 ` Stefan Monnier
0 siblings, 1 reply; 24+ messages in thread
From: Jared Finder via Emacs development discussions. @ 2020-11-05 19:58 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Jared Finder via "Emacs development discussions."
On 2020-11-05 6:45 am, Stefan Monnier wrote:
>>
>> diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el
>> index f9c08f9a17..37550276f8 100644
>> --- a/lisp/xt-mouse.el
>> +++ b/lisp/xt-mouse.el
>> @@ -77,6 +77,7 @@ xterm-mouse-translate-1
>> (copy-sequence event))
>> vec)
>> (is-move
>> + (xterm-mouse--handle-mouse-motion)
>> (if track-mouse vec
>> ;; Mouse movement events are currently supposed to be
>> ;; suppressed. Return no event.
>> @@ -106,8 +107,16 @@ xterm-mouse-translate-1
>> (if (null track-mouse)
>> (vector drag)
>> (push drag unread-command-events)
>> + (xterm-mouse--handle-mouse-motion)
>> (vector (list 'mouse-movement ev-data))))))))))))
>
> Hmm... `ev-data` includes the X/Y position, right?
> Could we arrange to pass *that* data directly to
> `xterm-mouse--handle-mouse-motion` rather than go through
> (terminal-parameter frame 'xterm-mouse-x/y)? It likely won't make
> much difference in practice, but it would make the data flow more
> clear,
> I think.
Using ev-data's x,y would add significant complexity. ev-data is a
posn, which is window part relative, not frame relative.
>> +(defun xterm-mouse--handle-mouse-motion ()
>> + "Handle mouse motion that was just generated for XTerm mouse."
>> + (let ((frame (selected-frame)))
>> + (handle-lisp-mouse-motion frame
>> + (terminal-parameter frame
>> 'xterm-mouse-x)
>> + (terminal-parameter frame
>> 'xterm-mouse-y))))
>
> This is the only caller to `handle-lisp-mouse-motion` and that function
> has a "default frame to selected-frame" feature, so you could pass nil
> instead of `frame`. Better yet, drop that frame argument altogether.
> And I think the function's name should make it clear it's for internal
> use only, or otherwise try to use some prefix that indicates it's
> related to the display. Like `display-update-for-mouse-motion`?
Is there a way I can name it that makes it clear this is an internal
function and we may change the arguments in the future? I was hoping
that this function would work with background frames across different
TTYs in case I can figure out how to get that working.
> [ I'm reminded here of the tension between using "mouse-motion" because
> it's
> shorter and using "mouse-movement" because that's the name of the
> event. ]
I squared this circle by using "mouse motion" for the concept and "mouse
movement" for the event. I could rename to mouse-movement if you'd
prefer.
>> +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
>> +not rely on input events such as updating display for mouse-face
>
> "not not"
Done.
>> +proprties or updating the help echo text. */)
> ^^
> e
Done.
>> + (Lisp_Object frame, Lisp_Object mouse_x, Lisp_Object mouse_y)
>> +{
>> + if (NILP (frame))
>> + frame = selected_frame;
>> +
>> + update_mouse_position (XFRAME (frame), XFIXNUM (mouse_x), XFIXNUM
>> (mouse_y));
>> + return Qnil;
>> +}
>
> This will crash and burn if `frame` is an integer (and the XFIXNUM
> won't
> crash and burn but they should also be preceded by CHECK_FIXNUMs).
Done.
>> if (event->type & (GPM_MOVE | GPM_DRAG))
>> {
> [...]
>> + /* 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)
>> + {
>> + last_mouse_x = event->x;
>> + last_mouse_y = event->y;
>> + f->mouse_moved = 1;
>
> Would it make sense to try and add this test to the "generic" part of
> the code?
This is not possible without much further work. These are all tied with
the C mouse event path: last_mouse_x, last_mouse_y, and
frame.mouse_moved are all used by the mouse position hook and integrated
with keyboard.c's mouse event generation.
Making this shared would require changing the way xterm-mouse currently
reports all mouse events to not return data through input-decode-map and
instead creating a Lisp interface to the C mouse event generation logic.
I tried playing around with this locally and it did seem like there is
a path to make it work, but it would be a much bigger effort.
As there's no logic changes, I'll wait for my questions above to get
addressed before sending an updated patch.
-- MJF
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-05 19:58 ` Jared Finder via Emacs development discussions.
@ 2020-11-05 20:18 ` Stefan Monnier
2020-11-06 5:23 ` Jared Finder via Emacs development discussions.
0 siblings, 1 reply; 24+ messages in thread
From: Stefan Monnier @ 2020-11-05 20:18 UTC (permalink / raw)
To: Jared Finder; +Cc: Jared Finder via "Emacs development discussions."
> Using ev-data's x,y would add significant complexity. ev-data is a posn,
> which is window part relative, not frame relative.
Fair enough.
>>> +(defun xterm-mouse--handle-mouse-motion ()
>>> + "Handle mouse motion that was just generated for XTerm mouse."
>>> + (let ((frame (selected-frame)))
>>> + (handle-lisp-mouse-motion frame
>>> + (terminal-parameter frame 'xterm-mouse-x)
>>> + (terminal-parameter frame
>>> 'xterm-mouse-y))))
>> This is the only caller to `handle-lisp-mouse-motion` and that function
>> has a "default frame to selected-frame" feature, so you could pass nil
>> instead of `frame`. Better yet, drop that frame argument altogether.
>> And I think the function's name should make it clear it's for internal
>> use only, or otherwise try to use some prefix that indicates it's
>> related to the display. Like `display-update-for-mouse-motion`?
> Is there a way I can name it that makes it clear this is an internal
> function and we may change the arguments in the future?
I'd suggest `display--update-for-mouse-action`, then.
> I was hoping that this function would work with background frames
> across different TTYs in case I can figure out how to get
> that working.
Not sure why that would require a frame that's not `selected_frame`.
>> [ I'm reminded here of the tension between using "mouse-motion"
>> because it's shorter and using "mouse-movement" because that's the
>> name of the event. ]
> I squared this circle by using "mouse motion" for the concept and "mouse
> movement" for the event.
Sounds good.
>> Would it make sense to try and add this test to the "generic" part of
>> the code?
> This is not possible without much further work. These are all tied with the
> C mouse event path: last_mouse_x, last_mouse_y, and frame.mouse_moved are
> all used by the mouse position hook and integrated with keyboard.c's mouse
> event generation.
Fair enough. Maybe you can add a brief FIXME comment explaining just
that (or pointing to this discussion).
Stefan
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-05 20:18 ` Stefan Monnier
@ 2020-11-06 5:23 ` Jared Finder via Emacs development discussions.
2020-11-06 6:00 ` Eli Zaretskii
0 siblings, 1 reply; 24+ messages in thread
From: Jared Finder via Emacs development discussions. @ 2020-11-06 5:23 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Jared Finder via "Emacs development discussions."
[-- Attachment #1: Type: text/plain, Size: 127 bytes --]
All points addressed. New patch attached.
I also attached a fix for mode-line-highlight that I noticed from this.
-- MJF
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Face-changing-text-properties-and-help-echo-now-work.patch --]
[-- Type: text/x-diff; name=0001-Face-changing-text-properties-and-help-echo-now-work.patch, Size: 6992 bytes --]
From db70354d2282b7a03295d49ffbfdeca12e45d1b5 Mon Sep 17 00:00:00 2001
From: Jared Finder <jared@finder.org>
Date: Sat, 31 Oct 2020 21:25:47 -0800
Subject: [PATCH 1/2] 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 f9c08f9a17..9301476e81 100644
--- a/lisp/xt-mouse.el
+++ b/lisp/xt-mouse.el
@@ -77,6 +77,7 @@ xterm-mouse-translate-1
(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 @@ xterm-mouse-translate-1
(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 848d3bcd20..da51772b37 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3606,6 +3606,7 @@ #define IMAGE_BACKGROUND_TRANSPARENT(img, f, mask) \
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 3f2ae3e6ad..f51ed2709a 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 (XFRAME (selected_frame), XFIXNUM (mouse_x),
+ XFIXNUM (mouse_y));
+ return Qnil;
+}
+
\f
/************************************************************************
Window-based updates
@@ -6490,6 +6537,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 3a13da165e..a0738594bf 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.20.1
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-lisp-faces.el-mode-line-highlight-Use-box-only-on-no.patch --]
[-- Type: text/x-diff; name=0002-lisp-faces.el-mode-line-highlight-Use-box-only-on-no.patch, Size: 730 bytes --]
From bc569c9cc18072fa943afea4d4dafdf8655b997d Mon Sep 17 00:00:00 2001
From: Jared Finder <jared@finder.org>
Date: Thu, 5 Nov 2020 21:15:08 -0800
Subject: [PATCH 2/2] * lisp/faces.el (mode-line-highlight): Use :box only on
non-TTYs.
---
lisp/faces.el | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lisp/faces.el b/lisp/faces.el
index 728f8b0fe6..875bee9910 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2578,7 +2578,7 @@ mode-line-inactive
:group 'basic-faces)
(defface mode-line-highlight
- '((((class color) (min-colors 88))
+ '((((type graphic) (class color) (min-colors 88))
:box (:line-width 2 :color "grey40" :style released-button))
(t
:inherit highlight))
--
2.20.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-06 5:23 ` Jared Finder via Emacs development discussions.
@ 2020-11-06 6:00 ` Eli Zaretskii
2020-11-06 6:46 ` Jared Finder via Emacs development discussions.
0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2020-11-06 6:00 UTC (permalink / raw)
To: Jared Finder; +Cc: monnier, emacs-devel
> Date: Thu, 05 Nov 2020 21:23:26 -0800
> Cc: "Jared Finder via \"Emacs development discussions.\"" <emacs-devel@gnu.org>
> From: Jared Finder via "Emacs development discussions." <emacs-devel@gnu.org>
>
> All points addressed. New patch attached.
Thanks.
> * 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.
Nitpicking: the lines in the change log are too long, they will
overflow 80 columns when indented by TABs (which happens when we
generate a ChangeLog file from Git log). Please use one of the Emacs
commands available for generating ChangeLog entries, they will keep
you from making these mistakes.
> + XSETFRAME(frame, f);
^
Please leave a space before the opening parenthesis, to conform to our
coding conventsions.
> + update_mouse_position (XFRAME (selected_frame), XFIXNUM (mouse_x),
^^^^^^^^^^^^^^^^^^^^^^^
A.k.a. SELECTED_FRAME().
> (defface mode-line-highlight
> - '((((class color) (min-colors 88))
> + '((((type graphic) (class color) (min-colors 88))
> :box (:line-width 2 :color "grey40" :style released-button))
I don't think I understand the rationale. With TTYs supporting many
colors nowadays, and mode-line-highlight available on TTYs, what is
the problem you tried to fix here?
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-06 6:00 ` Eli Zaretskii
@ 2020-11-06 6:46 ` Jared Finder via Emacs development discussions.
2020-11-06 7:39 ` Eli Zaretskii
2020-11-14 12:35 ` Eli Zaretskii
0 siblings, 2 replies; 24+ messages in thread
From: Jared Finder via Emacs development discussions. @ 2020-11-06 6:46 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: monnier, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 2223 bytes --]
On 2020-11-05 10:00 pm, Eli Zaretskii wrote:
>> Date: Thu, 05 Nov 2020 21:23:26 -0800
>> Cc: "Jared Finder via \"Emacs development discussions.\""
>> <emacs-devel@gnu.org>
>> From: Jared Finder via "Emacs development discussions."
>> <emacs-devel@gnu.org>
>>
>> All points addressed. New patch attached.
>
> Thanks.
>
>> * 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.
>
> Nitpicking: the lines in the change log are too long, they will
> overflow 80 columns when indented by TABs (which happens when we
> generate a ChangeLog file from Git log). Please use one of the Emacs
> commands available for generating ChangeLog entries, they will keep
> you from making these mistakes.
Oops, sorry. I hand-verified each row was 72 or less characters just
now. I will try to learn the Emacs commands for dealing with
changelogs.
>> + XSETFRAME(frame, f);
> ^
> Please leave a space before the opening parenthesis, to conform to our
> coding conventsions.
Done.
>> + update_mouse_position (XFRAME (selected_frame), XFIXNUM (mouse_x),
> ^^^^^^^^^^^^^^^^^^^^^^^
> A.k.a. SELECTED_FRAME().
Done.
>> (defface mode-line-highlight
>> - '((((class color) (min-colors 88))
>> + '((((type graphic) (class color) (min-colors 88))
>> :box (:line-width 2 :color "grey40" :style released-button))
>
> I don't think I understand the rationale. With TTYs supporting many
> colors nowadays, and mode-line-highlight available on TTYs, what is
> the problem you tried to fix here?
Are there any TTYs that support :box? None of the platforms I tested
locally on do, they instead just ignore the :box aspect of any face.
Updated patches attached.
-- MJF
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Face-changing-text-properties-and-help-echo-now-work.patch --]
[-- Type: text/x-diff; name=0001-Face-changing-text-properties-and-help-echo-now-work.patch, Size: 6987 bytes --]
From 039c399a5078a9e95d9f49cb8b5a9a941494bf57 Mon Sep 17 00:00:00 2001
From: Jared Finder <jared@finder.org>
Date: Sat, 31 Oct 2020 21:25:47 -0800
Subject: [PATCH 1/2] 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 f9c08f9a17..9301476e81 100644
--- a/lisp/xt-mouse.el
+++ b/lisp/xt-mouse.el
@@ -77,6 +77,7 @@ xterm-mouse-translate-1
(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 @@ xterm-mouse-translate-1
(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 848d3bcd20..da51772b37 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3606,6 +3606,7 @@ #define IMAGE_BACKGROUND_TRANSPARENT(img, f, mask) \
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 3f2ae3e6ad..2e40d458d1 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;
+}
+
\f
/************************************************************************
Window-based updates
@@ -6490,6 +6537,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 3a13da165e..a0738594bf 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.20.1
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-lisp-faces.el-mode-line-highlight-Use-box-only-on-no.patch --]
[-- Type: text/x-diff; name=0002-lisp-faces.el-mode-line-highlight-Use-box-only-on-no.patch, Size: 730 bytes --]
From dcf2b7070f48676960fd99f497df6bcb1035ce2a Mon Sep 17 00:00:00 2001
From: Jared Finder <jared@finder.org>
Date: Thu, 5 Nov 2020 21:15:08 -0800
Subject: [PATCH 2/2] * lisp/faces.el (mode-line-highlight): Use :box only on
non-TTYs.
---
lisp/faces.el | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lisp/faces.el b/lisp/faces.el
index 728f8b0fe6..875bee9910 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2578,7 +2578,7 @@ mode-line-inactive
:group 'basic-faces)
(defface mode-line-highlight
- '((((class color) (min-colors 88))
+ '((((type graphic) (class color) (min-colors 88))
:box (:line-width 2 :color "grey40" :style released-button))
(t
:inherit highlight))
--
2.20.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-06 6:46 ` Jared Finder via Emacs development discussions.
@ 2020-11-06 7:39 ` Eli Zaretskii
2020-11-07 1:22 ` Jared Finder via Emacs development discussions.
2020-11-14 12:35 ` Eli Zaretskii
1 sibling, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2020-11-06 7:39 UTC (permalink / raw)
To: Jared Finder; +Cc: monnier, emacs-devel
> Date: Thu, 05 Nov 2020 22:46:32 -0800
> From: Jared Finder <jared@finder.org>
> Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org
>
> >> (defface mode-line-highlight
> >> - '((((class color) (min-colors 88))
> >> + '((((type graphic) (class color) (min-colors 88))
> >> :box (:line-width 2 :color "grey40" :style released-button))
> >
> > I don't think I understand the rationale. With TTYs supporting many
> > colors nowadays, and mode-line-highlight available on TTYs, what is
> > the problem you tried to fix here?
>
> Are there any TTYs that support :box? None of the platforms I tested
> locally on do, they instead just ignore the :box aspect of any face.
That's true, but having conditions where they aren't necessary is not
good for maintenance, because they aren't future-proof: they will need
changes should someone implement the :box attribute for TTYs. We've
bumped into such problems many times during the last two decades: as
more and more display features (colors, menus, mouse) became supported
on TTYs, we time after time found them not working in some package,
because someone arbitrarily disabled that for TTYs on the assumption
that "TTYs cannot possibly do that". So attributes that are silently
and harmlessly ignored should not in general be disabled.
If you want, we can add a more reasonable condition, using the
'supports' keyword, requesting specifically support for the :box
attribute.
Thanks.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-06 7:39 ` Eli Zaretskii
@ 2020-11-07 1:22 ` Jared Finder via Emacs development discussions.
2020-11-14 12:38 ` Eli Zaretskii
0 siblings, 1 reply; 24+ messages in thread
From: Jared Finder via Emacs development discussions. @ 2020-11-07 1:22 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: monnier, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 621 bytes --]
On 2020-11-05 11:39 pm, Eli Zaretskii wrote:
>> Date: Thu, 05 Nov 2020 22:46:32 -0800
>> From: Jared Finder <jared@finder.org>
>> Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org
>>
>> Are there any TTYs that support :box? None of the platforms I tested
>> locally on do, they instead just ignore the :box aspect of any face.
>
> [...]
>
> If you want, we can add a more reasonable condition, using the
> 'supports' keyword, requesting specifically support for the :box
> attribute.
Thank you!
I was not aware of the supports keyword for defface and it certainly is
better here. Updated patch attached.
-- MJF
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0002-lisp-faces.el-mode-line-highlight-Use-box-only-when-.patch --]
[-- Type: text/x-diff; name=0002-lisp-faces.el-mode-line-highlight-Use-box-only-when-.patch, Size: 736 bytes --]
From 7787c5370f2bdc4c56a7afd92b524445a3b713d3 Mon Sep 17 00:00:00 2001
From: Jared Finder <jared@finder.org>
Date: Thu, 5 Nov 2020 21:15:08 -0800
Subject: [PATCH 2/2] * lisp/faces.el (mode-line-highlight): Use :box only when
supported.
---
lisp/faces.el | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lisp/faces.el b/lisp/faces.el
index 728f8b0fe6..7355e1dd0a 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2578,7 +2578,7 @@ mode-line-inactive
:group 'basic-faces)
(defface mode-line-highlight
- '((((class color) (min-colors 88))
+ '((((supports :box t) (class color) (min-colors 88))
:box (:line-width 2 :color "grey40" :style released-button))
(t
:inherit highlight))
--
2.20.1
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-06 6:46 ` Jared Finder via Emacs development discussions.
2020-11-06 7:39 ` Eli Zaretskii
@ 2020-11-14 12:35 ` Eli Zaretskii
1 sibling, 0 replies; 24+ messages in thread
From: Eli Zaretskii @ 2020-11-14 12:35 UTC (permalink / raw)
To: Jared Finder; +Cc: monnier, emacs-devel
> Date: Thu, 05 Nov 2020 22:46:32 -0800
> From: Jared Finder <jared@finder.org>
> Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org
>
> Updated patches attached.
Thanks, I pushed the first one to the master branch.
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: mouse-face and help echo support for xterm mouse
2020-11-07 1:22 ` Jared Finder via Emacs development discussions.
@ 2020-11-14 12:38 ` Eli Zaretskii
0 siblings, 0 replies; 24+ messages in thread
From: Eli Zaretskii @ 2020-11-14 12:38 UTC (permalink / raw)
To: Jared Finder; +Cc: monnier, emacs-devel
> Date: Fri, 06 Nov 2020 17:22:57 -0800
> From: Jared Finder <jared@finder.org>
> Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org
>
> > If you want, we can add a more reasonable condition, using the
> > 'supports' keyword, requesting specifically support for the :box
> > attribute.
>
> Thank you!
>
> I was not aware of the supports keyword for defface and it certainly is
> better here. Updated patch attached.
Thanks, pushed to the master branch.
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2020-11-14 12:38 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-11-01 5:46 mouse-face and help echo support for xterm mouse Jared Finder via Emacs development discussions.
2020-11-01 13:39 ` Stefan Monnier
2020-11-01 15:56 ` Jared Finder via Emacs development discussions.
2020-11-04 6:54 ` Jared Finder via Emacs development discussions.
2020-11-04 14:13 ` Stefan Monnier
2020-11-04 15:46 ` Eli Zaretskii
2020-11-04 15:56 ` Stefan Monnier
2020-11-04 17:54 ` Jared Finder via Emacs development discussions.
2020-11-04 18:47 ` Stefan Monnier
2020-11-04 18:51 ` Eli Zaretskii
2020-11-04 19:05 ` Stefan Monnier
2020-11-04 19:10 ` Jared Finder via Emacs development discussions.
2020-11-04 15:19 ` Eli Zaretskii
2020-11-05 8:15 ` Jared Finder via Emacs development discussions.
2020-11-05 14:45 ` Stefan Monnier
2020-11-05 19:58 ` Jared Finder via Emacs development discussions.
2020-11-05 20:18 ` Stefan Monnier
2020-11-06 5:23 ` Jared Finder via Emacs development discussions.
2020-11-06 6:00 ` Eli Zaretskii
2020-11-06 6:46 ` Jared Finder via Emacs development discussions.
2020-11-06 7:39 ` Eli Zaretskii
2020-11-07 1:22 ` Jared Finder via Emacs development discussions.
2020-11-14 12:38 ` Eli Zaretskii
2020-11-14 12:35 ` Eli Zaretskii
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).