]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix mouse position handling for nested tty child frames
authorGerd Möllmann <gerd@gnu.org>
Sat, 25 Jan 2025 06:33:45 +0000 (07:33 +0100)
committerEshel Yaron <me@eshelyaron.com>
Sat, 25 Jan 2025 17:46:26 +0000 (18:46 +0100)
* src/dispnew.c (child_xy): New function.
* src/dispextern.h: Declare it.
* src/term.c (tty_frame_at): Return child-relative (x, y) in output
parameters.
(Ftty_frame_at): Return a list (FRAME CHILD-X CHILD-Y).
(handle_one_term_event): Adapt use of tty_frame_at.
* lisp/xt-mouse.el (xterm-mouse-event): Use new tty-frame-at.

(cherry picked from commit f37559a1ee035d184bc4db6e4f597281d3ac6879)

lisp/xt-mouse.el
src/dispextern.h
src/dispnew.c
src/term.c

index 19d688e4d1e35389b61424da6a7a15bf5e5f7e42..e395723d05c6824afdddc56646da3d556f3eccb6 100644 (file)
@@ -298,16 +298,11 @@ which is the \"1006\" extension implemented in Xterm >= 277."
              ;; FIXME: The test for running in batch mode is here solely
              ;; for the sake of xt-mouse-tests where the only frame is
              ;; the initial frame.
-             (frame (unless noninteractive (tty-frame-at x y)))
-             ;;(_ (message (format "*** %S" frame)))
-             (frame-pos (frame-position frame))
-             ;;(_ (message (format "*** %S" frame-pos)))
-             (x (- x (car frame-pos)))
-             (y (- y (cdr frame-pos)))
-             ;;(_ (message (format "*** %S %S" x y)))
+             (frame-and-xy (unless noninteractive (tty-frame-at x y)))
+             (frame (nth 0 frame-and-xy))
+             (x (nth 1 frame-and-xy))
+             (y (nth 2 frame-and-xy))
              (w (window-at x y frame))
-             ;;(_ (message (format "*** %S" w)))
-
              (ltrb (window-edges w))
              (left (nth 0 ltrb))
              (top (nth 1 ltrb))
index 9c193e79fd10492ec039c3d6276fd06abe14342f..e1214128e358c9f23f074db70a67f546a7e7cd42 100644 (file)
@@ -3959,6 +3959,7 @@ void combine_updates_for_frame (struct frame *f, bool inhibit_id_p);
 void tty_raise_lower_frame (struct frame *f, bool raise);
 int max_child_z_order (struct frame *parent);
 void root_xy (struct frame *f, int x, int y, int *rx, int *ry);
+void child_xy (struct frame *f, int x, int y, int *cx, int *cy);
 bool is_frame_ancestor (struct frame *f1, struct frame *f2);
 
 INLINE_HEADER_END
index c966df2ac5819bcf0a1d0b6bef2e6cb28eaf0572..ebca32ae30e580910d05321d57b353cf78783f62 100644 (file)
@@ -3325,6 +3325,17 @@ root_xy (struct frame *f, int x, int y, int *rx, int *ry)
     }
 }
 
+/* Translate absolute coordinates (X, Y) to coordinates relative to F's origin.  */
+
+void
+child_xy (struct frame *f, int x, int y, int *cx, int *cy)
+{
+  int rx, ry;
+  root_xy (f, 0, 0, &rx, &ry);
+  *cx = x - rx;
+  *cy = y - ry;
+}
+
 /* Return the rectangle frame F occupies.  X and Y are in absolute
    coordinates.  */
 
index 7397ee68347cfeb374cd5642010a7f404715c600..e13089af2bb16dad30f5409b114fe5255d73e8e5 100644 (file)
@@ -2595,7 +2595,7 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
 #endif
 
 static Lisp_Object
-tty_frame_at (int x, int y)
+tty_frame_at (int x, int y, int *cx, int *cy)
 {
   for (Lisp_Object frames = Ftty_frame_list_z_order (Qnil);
        !NILP (frames);
@@ -2606,24 +2606,33 @@ tty_frame_at (int x, int y)
       int fx, fy;
       root_xy (f, 0, 0, &fx, &fy);
 
-      if (fx <= x && x < fx + f->pixel_width
-         && fy <= y && y < fy + f->pixel_height)
-       return frame;
+      if ((fx <= x && x < fx + f->pixel_width)
+         && (fy <= y && y < fy + f->pixel_height))
+       {
+         child_xy (XFRAME (frame), x, y, cx, cy);
+         return frame;
+       }
     }
 
   return Qnil;
 }
 
-DEFUN ("tty-frame-at", Ftty_frame_at, Stty_frame_at,
-       2, 2, 0,
-       doc: /* Return tty frame containing pixel position X, Y.  */)
+DEFUN ("tty-frame-at", Ftty_frame_at, Stty_frame_at, 2, 2, 0,
+       doc : /* Return tty frame containing absolute pixel position (X, Y).
+Value is nil if no frame found.  Otherwise it is a list (FRAME CX CY),
+where FRAME is the frame containing (X, Y) and CX and CY are X and Y
+relative to FRAME.  */)
   (Lisp_Object x, Lisp_Object y)
 {
   if (! FIXNUMP (x) || ! FIXNUMP (y))
     /* Coordinates this big can not correspond to any frame.  */
     return Qnil;
 
-  return tty_frame_at (XFIXNUM (x), XFIXNUM (y));
+  int cx, cy;
+  Lisp_Object frame = tty_frame_at (XFIXNUM (x), XFIXNUM (y), &cx, &cy);
+  if (NILP (frame))
+    return Qnil;
+  return list3 (frame, make_fixnum (cx), make_fixnum (cy));
 }
 
 #ifdef HAVE_GPM
@@ -2756,11 +2765,9 @@ term_mouse_click (struct input_event *result, Gpm_Event *event,
 int
 handle_one_term_event (struct tty_display_info *tty, const Gpm_Event *event_in)
 {
-  Lisp_Object frame = tty_frame_at (event_in->x, event_in->y);
-  struct frame *f = decode_live_frame (frame);
   Gpm_Event event = *event_in;
-  event.x -= f->left_pos;
-  event.y -= f->top_pos;
+  Lisp_Object frame = tty_frame_at (event_in->x, event_in->y, &event.x, &event.y);
+  struct frame *f = decode_live_frame (frame);
 
   struct input_event ie;
   int count = 0;