emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 907f3a4f8d: Use coordinates provided by DND messages if available


From: Po Lu
Subject: master 907f3a4f8d: Use coordinates provided by DND messages if available
Date: Mon, 13 Jun 2022 21:57:19 -0400 (EDT)

branch: master
commit 907f3a4f8d83c228a3be3772a3cb7d5079261752
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Use coordinates provided by DND messages if available
    
    This avoids an extra sync, which matters when dropping onto
    Emacs running over a slow connection.
    
    * src/xselect.c (x_handle_dnd_message): New args
    `root_window_coords', `root_x' and `root_y'.
    * src/xterm.c (x_coords_from_dnd_message): New function.
    (handle_one_xevent): Pass root window coordinates to
    x_handle_dnd_message.
    * src/xterm.h: Update prototypes.
---
 src/xselect.c | 14 ++++++++++++--
 src/xterm.c   | 40 +++++++++++++++++++++++++++++++++++++++-
 src/xterm.h   |  3 ++-
 3 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/src/xselect.c b/src/xselect.c
index 490a008dfc..96c1e9830f 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -2522,7 +2522,8 @@ FRAME is on.  If FRAME is nil, the selected frame is 
used.  */)
 
 bool
 x_handle_dnd_message (struct frame *f, const XClientMessageEvent *event,
-                      struct x_display_info *dpyinfo, struct input_event *bufp)
+                      struct x_display_info *dpyinfo, struct input_event *bufp,
+                     bool root_window_coords, int root_x, int root_y)
 {
   Lisp_Object vec;
   Lisp_Object frame;
@@ -2532,6 +2533,7 @@ x_handle_dnd_message (struct frame *f, const 
XClientMessageEvent *event,
   unsigned char *data = (unsigned char *) event->data.b;
   int idata[5];
   ptrdiff_t i;
+  Window child_return;
 
   for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i)
     if (dpyinfo->x_dnd_atoms[i] == event->message_type) break;
@@ -2563,7 +2565,15 @@ x_handle_dnd_message (struct frame *f, const 
XClientMessageEvent *event,
                                         event->format,
                                         size));
 
-  x_relative_mouse_position (f, &x, &y);
+  if (!root_window_coords)
+    x_relative_mouse_position (f, &x, &y);
+  else
+    XTranslateCoordinates (dpyinfo->display,
+                          dpyinfo->root_window,
+                          FRAME_X_WINDOW (f),
+                          root_x, root_y,
+                          &x, &y, &child_return);
+
   bufp->kind = DRAG_N_DROP_EVENT;
   bufp->frame_or_window = frame;
   bufp->timestamp = CurrentTime;
diff --git a/src/xterm.c b/src/xterm.c
index d9dd29ca12..d79871e021 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -15762,6 +15762,31 @@ x_monitors_changed_cb (GdkScreen *gscr, gpointer 
user_data)
 }
 #endif
 
+/* Extract the root window coordinates from the client message EVENT
+   if it is a message that we already understand.  Return false if the
+   event was not understood.  */
+static bool
+x_coords_from_dnd_message (struct x_display_info *dpyinfo,
+                          XEvent *event, int *x_out, int *y_out)
+{
+  if (event->type != ClientMessage)
+    return false;
+
+  if (event->xclient.message_type == dpyinfo->Xatom_XdndPosition)
+    {
+      if (event->xclient.format != 32)
+       return false;
+
+      *x_out = (((unsigned long) event->xclient.data.l[2]) >> 16
+               & 0xffff);
+      *y_out = (event->xclient.data.l[2] & 0xffff);
+
+      return true;
+    }
+
+  return false;
+}
+
 /* Handles the XEvent EVENT on display DPYINFO.
 
    *FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
@@ -15804,6 +15829,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
   GdkEvent *copy = NULL;
   GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
 #endif
+  int dx, dy;
   USE_SAFE_ALLOCA;
 
   *finish = X_EVENT_NORMAL;
@@ -15835,6 +15861,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
     {
     case ClientMessage:
       {
+       int rc;
+
        if (x_dnd_in_progress
            && FRAME_DISPLAY_INFO (x_dnd_frame) == dpyinfo
            && event->xclient.message_type == dpyinfo->Xatom_XdndStatus)
@@ -16211,7 +16239,17 @@ handle_one_xevent (struct x_display_info *dpyinfo,
        f = any;
        if (!f)
          goto OTHER;
-       if (x_handle_dnd_message (f, &event->xclient, dpyinfo, &inev.ie))
+
+       /* These values are always used initialized, but GCC doesn't
+          know that.  */
+       dx = 0;
+       dy = 0;
+
+       rc = x_coords_from_dnd_message (dpyinfo, (XEvent *) event,
+                                       &dx, &dy);
+
+       if (x_handle_dnd_message (f, &event->xclient, dpyinfo, &inev.ie,
+                                 rc, dx, dy))
          *finish = X_EVENT_DROP;
       }
       break;
diff --git a/src/xterm.h b/src/xterm.h
index 25c2453ee7..82b4308041 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1540,7 +1540,8 @@ extern Lisp_Object x_atom_to_symbol (struct 
x_display_info *, Atom);
 extern bool x_handle_dnd_message (struct frame *,
                                  const XClientMessageEvent *,
                                  struct x_display_info *,
-                                 struct input_event *);
+                                 struct input_event *,
+                                 bool, int, int);
 extern int x_check_property_data (Lisp_Object);
 extern void x_fill_property_data (Display *,
                                   Lisp_Object,



reply via email to

[Prev in Thread] Current Thread [Next in Thread]