]> git.eshelyaron.com Git - emacs.git/commitdiff
Implement `drag-source' values of `track-mouse' on PGTK.
authorPo Lu <luangruo@yahoo.com>
Sun, 3 Apr 2022 11:33:52 +0000 (19:33 +0800)
committerPo Lu <luangruo@yahoo.com>
Sun, 3 Apr 2022 11:34:06 +0000 (19:34 +0800)
* src/frame.c (Fmouse_position, mouse_position)
(Fmouse_pixel_position): Fix crashes when mouse_position_hook
stores nil.

* src/pgtkterm.c (pgtk_mouse_position): Behave appropriately.

src/frame.c
src/pgtkterm.c

index e531891a8a35fcb99e2139fa7db7c82535cf913f..7a9ed3302e405280bd8fc73858aa8153b90ab4ec 100644 (file)
@@ -2505,9 +2505,12 @@ vertical offset, measured in units of the frame's default character size.
 If Emacs is running on a mouseless terminal or hasn't been programmed
 to read the mouse position, it returns the selected frame for FRAME
 and nil for X and Y.
-If `mouse-position-function' is non-nil, `mouse-position' calls it,
-passing the normal return value to that function as an argument,
-and returns whatever that function returns.  */)
+
+FRAME might be nil if `track-mouse' is set to `drag-source'.  This
+means there is no frame under the mouse.  If `mouse-position-function'
+is non-nil, `mouse-position' calls it, passing the normal return value
+to that function as an argument, and returns whatever that function
+returns.  */)
   (void)
 {
   return mouse_position (true);
@@ -2534,7 +2537,7 @@ mouse_position (bool call_mouse_position_function)
                                                  &time_dummy);
     }
 
-  if (! NILP (x))
+  if (! NILP (x) && f)
     {
       int col = XFIXNUM (x);
       int row = XFIXNUM (y);
@@ -2542,7 +2545,10 @@ mouse_position (bool call_mouse_position_function)
       XSETINT (x, col);
       XSETINT (y, row);
     }
-  XSETFRAME (lispy_dummy, f);
+  if (f)
+    XSETFRAME (lispy_dummy, f);
+  else
+    lispy_dummy = Qnil;
   retval = Fcons (lispy_dummy, Fcons (x, y));
   if (call_mouse_position_function && !NILP (Vmouse_position_function))
     retval = call1 (Vmouse_position_function, retval);
@@ -2555,9 +2561,11 @@ DEFUN ("mouse-pixel-position", Fmouse_pixel_position,
 The position is given in pixel units, where (0, 0) is the
 upper-left corner of the frame, X is the horizontal offset, and Y is
 the vertical offset.
-If Emacs is running on a mouseless terminal or hasn't been programmed
-to read the mouse position, it returns the selected frame for FRAME
-and nil for X and Y.  */)
+FRAME might be nil if `track-mouse' is set to `drag-source'.  This
+means there is no frame under the mouse.  If Emacs is running on a
+mouseless terminal or hasn't been programmed to read the mouse
+position, it returns the selected frame for FRAME and nil for X and
+Y.  */)
   (void)
 {
   struct frame *f;
@@ -2578,7 +2586,11 @@ and nil for X and Y.  */)
                                                  &time_dummy);
     }
 
-  XSETFRAME (lispy_dummy, f);
+  if (f)
+    XSETFRAME (lispy_dummy, f);
+  else
+    lispy_dummy = Qnil;
+
   retval = Fcons (lispy_dummy, Fcons (x, y));
   if (!NILP (Vmouse_position_function))
     retval = call1 (Vmouse_position_function, retval);
index 216b5ee7dd5c636cd568cf2c6f91f57520c08d60..94587381424df9d59277b18ed51ada65e7271064 100644 (file)
@@ -3329,8 +3329,8 @@ pgtk_frame_up_to_date (struct frame *f)
 
 static void
 pgtk_mouse_position (struct frame **fp, int insist, Lisp_Object * bar_window,
-                    enum scroll_bar_part *part, Lisp_Object * x,
-                    Lisp_Object * y, Time * timestamp)
+                    enum scroll_bar_part *part, Lisp_Object *x,
+                    Lisp_Object *y, Time *timestamp)
 {
   struct frame *f1;
   struct pgtk_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp);
@@ -3339,6 +3339,7 @@ pgtk_mouse_position (struct frame **fp, int insist, Lisp_Object * bar_window,
   GdkDevice *device;
   GdkModifierType mask;
   GdkWindow *win;
+  bool return_frame_flag = false;
 
   block_input ();
 
@@ -3352,30 +3353,37 @@ pgtk_mouse_position (struct frame **fp, int insist, Lisp_Object * bar_window,
 
   dpyinfo->last_mouse_scroll_bar = NULL;
 
-  if (gui_mouse_grabbed (dpyinfo))
+  if (gui_mouse_grabbed (dpyinfo)
+      && (!EQ (track_mouse, Qdropping)
+         && !EQ (track_mouse, Qdrag_source)))
     {
-      /* 1.1. use last_mouse_frame as frame where the pointer is on. */
+      /* 1.1. use last_mouse_frame as frame where the pointer is
+        on.  */
       f1 = dpyinfo->last_mouse_frame;
     }
   else
     {
       f1 = *fp;
-      /* 1.2. get frame where the pointer is on. */
+      /* 1.2. get frame where the pointer is on.  */
       win = gtk_widget_get_window (FRAME_GTK_WIDGET (*fp));
       seat = gdk_display_get_default_seat (dpyinfo->gdpy);
       device = gdk_seat_get_pointer (seat);
-      win =
-       gdk_window_get_device_position (win, device, &win_x, &win_y, &mask);
+      win = gdk_window_get_device_position (win, device, &win_x,
+                                           &win_y, &mask);
       if (win != NULL)
        f1 = pgtk_any_window_to_frame (win);
       else
        {
-         /* crossing display server? */
          f1 = SELECTED_FRAME ();
+
+         if (!FRAME_PGTK_P (f1))
+           f1 = dpyinfo->last_mouse_frame;
+
+         return_frame_flag = EQ (track_mouse, Qdrag_source);
        }
     }
 
-  /* f1 can be a terminal frame. Bug#50322 */
+  /* F1 can be a terminal frame.  (Bug#50322) */
   if (f1 == NULL || !FRAME_PGTK_P (f1))
     {
       unblock_input ();
@@ -3399,7 +3407,7 @@ pgtk_mouse_position (struct frame **fp, int insist, Lisp_Object * bar_window,
 
       *bar_window = Qnil;
       *part = 0;
-      *fp = f1;
+      *fp = !return_frame_flag ? f1 : NULL;
       XSETINT (*x, win_x);
       XSETINT (*y, win_y);
       *timestamp = dpyinfo->last_mouse_movement_time;