[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 6e2d3bc: Correct mouse handling when window origin changes betwee
From: |
Alan Mackenzie |
Subject: |
master 6e2d3bc: Correct mouse handling when window origin changes between down and up events |
Date: |
Mon, 31 May 2021 06:34:07 -0400 (EDT) |
branch: master
commit 6e2d3bce087d30a535b1f01715d7820576ffe390
Author: Alan Mackenzie <acm@muc.de>
Commit: Alan Mackenzie <acm@muc.de>
Correct mouse handling when window origin changes between down and up events
Do this by using frame relative positions rather than window relative ones,
which gave rise to spurious drag events when the origin of the window
changed
between the mouse down and up events. This fixes bug #48409.
* keyboard.c (frame_relative_event_pos): New static variable.
(make_lispy_event): Record frame relative position of down event. When the
up
event is in the same position, "move" this event into the window of the down
event when this window (typically a mini-window) is no longer under the
mouse.
Call make_lispy_position a second time to generate this changed event.
(syms_of_keyboard): Declare Qwindow_edges. static_pro
frame_relative_event_pos.
---
src/keyboard.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 51 insertions(+), 13 deletions(-)
diff --git a/src/keyboard.c b/src/keyboard.c
index c855d45..4433cfa 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5018,6 +5018,10 @@ static short const internal_border_parts[] = {
static Lisp_Object button_down_location;
+/* A cons recording the original frame-relative x and y coordinates of
+ the down mouse event. */
+static Lisp_Object frame_relative_event_pos;
+
/* Information about the most recent up-going button event: Which
button, what location, and what time. */
@@ -5669,6 +5673,7 @@ make_lispy_event (struct input_event *event)
double_click_count = 1;
button_down_time = event->timestamp;
*start_pos_ptr = Fcopy_alist (position);
+ frame_relative_event_pos = Fcons (event->x, event->y);
ignore_mouse_drag_p = false;
}
@@ -5691,20 +5696,12 @@ make_lispy_event (struct input_event *event)
ignore_mouse_drag_p = false;
else
{
- Lisp_Object new_down, down;
intmax_t xdiff = double_click_fuzz, ydiff = double_click_fuzz;
- /* The third element of every position
- should be the (x,y) pair. */
- down = Fcar (Fcdr (Fcdr (start_pos)));
- new_down = Fcar (Fcdr (Fcdr (position)));
-
- if (CONSP (down)
- && FIXNUMP (XCAR (down)) && FIXNUMP (XCDR (down)))
- {
- xdiff = XFIXNUM (XCAR (new_down)) - XFIXNUM (XCAR (down));
- ydiff = XFIXNUM (XCDR (new_down)) - XFIXNUM (XCDR (down));
- }
+ xdiff = XFIXNUM (event->x)
+ - XFIXNUM (XCAR (frame_relative_event_pos));
+ ydiff = XFIXNUM (event->y)
+ - XFIXNUM (XCDR (frame_relative_event_pos));
if (! (0 < double_click_fuzz
&& - double_click_fuzz < xdiff
@@ -5721,12 +5718,51 @@ make_lispy_event (struct input_event *event)
a click. But mouse-drag-region completely ignores
this case and it hasn't caused any real problem, so
it's probably OK to ignore it as well. */
- && EQ (Fcar (Fcdr (start_pos)), Fcar (Fcdr (position)))))
+ && (EQ (Fcar (Fcdr (start_pos)),
+ Fcar (Fcdr (position))) /* Same buffer pos */
+ || !EQ (Fcar (start_pos),
+ Fcar (position))))) /* Different window */
{
/* Mouse has moved enough. */
button_down_time = 0;
click_or_drag_modifier = drag_modifier;
}
+ else if (((!EQ (Fcar (start_pos), Fcar (position)))
+ || (!EQ (Fcar (Fcdr (start_pos)),
+ Fcar (Fcdr (position)))))
+ /* Was the down event in a window body? */
+ && FIXNUMP (Fcar (Fcdr (start_pos)))
+ && WINDOW_LIVE_P (Fcar (start_pos))
+ && Ffboundp (Qwindow_edges))
+ /* If the window (etc.) at the mouse position has
+ changed between the down event and the up event,
+ we assume there's been a redisplay between the
+ two events, and we pretend the mouse is still in
+ the old window to prevent a spurious drag event
+ being generated. */
+ {
+ Lisp_Object edges
+ = call4 (Qwindow_edges, Fcar (start_pos), Qt, Qnil, Qt);
+ int new_x = XFIXNUM (Fcar (frame_relative_event_pos));
+ int new_y = XFIXNUM (Fcdr (frame_relative_event_pos));
+
+ /* If the up-event is outside the down-event's
+ window, use coordinates that are within it. */
+ if (new_x < XFIXNUM (Fcar (edges)))
+ new_x = XFIXNUM (Fcar (edges));
+ else if (new_x >= XFIXNUM (Fcar (Fcdr (Fcdr (edges)))))
+ new_x = XFIXNUM (Fcar (Fcdr (Fcdr (edges)))) - 1;
+ if (new_y < XFIXNUM (Fcar (Fcdr (edges))))
+ new_y = XFIXNUM (Fcar (Fcdr (edges)));
+ else if (new_y
+ >= XFIXNUM (Fcar (Fcdr (Fcdr (Fcdr (edges))))))
+ new_y = XFIXNUM (Fcar (Fcdr (Fcdr (Fcdr (edges))))) - 1;
+
+ position = make_lispy_position
+ (XFRAME (event->frame_or_window),
+ make_fixnum (new_x), make_fixnum (new_y),
+ event->timestamp);
+ }
}
/* Don't check is_double; treat this as multiple if the
@@ -11645,6 +11681,7 @@ syms_of_keyboard (void)
DEFSYM (Qmake_frame_visible, "make-frame-visible");
DEFSYM (Qselect_window, "select-window");
DEFSYM (Qselection_request, "selection-request");
+ DEFSYM (Qwindow_edges, "window-edges");
{
int i;
@@ -11661,6 +11698,7 @@ syms_of_keyboard (void)
button_down_location = make_nil_vector (5);
staticpro (&button_down_location);
+ staticpro (&frame_relative_event_pos);
mouse_syms = make_nil_vector (5);
staticpro (&mouse_syms);
wheel_syms = make_nil_vector (ARRAYELTS (lispy_wheel_names));
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 6e2d3bc: Correct mouse handling when window origin changes between down and up events,
Alan Mackenzie <=