aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2022-10-25 19:50:57 +0800
committerPo Lu2022-10-25 19:51:08 +0800
commitb6097fe279b03e2fb50fc6af063d7c8f1e55fe8b (patch)
tree8d7a834c70cbb631fbdb086e9b4a2ba35a6b25c2
parentbb95e597a9adcba0080cba85b2270fdf80696b3a (diff)
downloademacs-b6097fe279b03e2fb50fc6af063d7c8f1e55fe8b.tar.gz
emacs-b6097fe279b03e2fb50fc6af063d7c8f1e55fe8b.zip
Fix drag-and-drop bugs on Lucid build
Also, optimize Fx_translate_coordinates to avoid excessive calls to _XReply. * lisp/x-dnd.el (x-dnd-get-drop-rectangle): Return empty drop rectangle if posn-area. * src/xfns.c (Fx_translate_coordinates): Accept arg `require_child'. If not set, allow optimizations based on cached position data. * src/xselect.c (x_handle_dnd_message): Use x_translate_coordinates. * src/xterm.c (x_translate_coordinates): Export function. (x_handle_translate_coordinates): New function. (handle_one_xevent): Fix coding style. * src/xterm.h: Update prototypes.
-rw-r--r--lisp/x-dnd.el10
-rw-r--r--src/xfns.c24
-rw-r--r--src/xselect.c7
-rw-r--r--src/xterm.c30
-rw-r--r--src/xterm.h4
5 files changed, 62 insertions, 13 deletions
diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el
index ee80e41a22e..058ab99f5cb 100644
--- a/lisp/x-dnd.el
+++ b/lisp/x-dnd.el
@@ -675,7 +675,15 @@ with coordinates relative to the root window."
675(defun x-dnd-get-drop-rectangle (window posn) 675(defun x-dnd-get-drop-rectangle (window posn)
676 "Return the drag-and-drop rectangle at POSN on WINDOW." 676 "Return the drag-and-drop rectangle at POSN on WINDOW."
677 (if (or dnd-scroll-margin 677 (if (or dnd-scroll-margin
678 (not (windowp window))) 678 (not (windowp window))
679 ;; Drops on the scroll bar aren't allowed, but the mouse
680 ;; rectangle can be set while still on the scroll bar,
681 ;; causing the drag initiator to never send an XdndPosition
682 ;; event that will an XdndStatus message with the accept
683 ;; flag set to be set, even after the mouse enters the
684 ;; window text area. To prevent that, simply don't generate
685 ;; a mouse rectangle when an area is set.
686 (posn-area posn))
679 '(0 0 0 0) 687 '(0 0 0 0)
680 (let ((window-rectangle (x-dnd-get-window-rectangle window)) 688 (let ((window-rectangle (x-dnd-get-window-rectangle window))
681 object-rectangle) 689 object-rectangle)
diff --git a/src/xfns.c b/src/xfns.c
index e8732986eb9..3ff7a8c2865 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -7913,7 +7913,7 @@ Otherwise, the return value is a vector with the following fields:
7913 7913
7914DEFUN ("x-translate-coordinates", Fx_translate_coordinates, 7914DEFUN ("x-translate-coordinates", Fx_translate_coordinates,
7915 Sx_translate_coordinates, 7915 Sx_translate_coordinates,
7916 1, 5, 0, doc: /* Translate coordinates from FRAME. 7916 1, 6, 0, doc: /* Translate coordinates from FRAME.
7917Translate the given coordinates SOURCE-X and SOURCE-Y from 7917Translate the given coordinates SOURCE-X and SOURCE-Y from
7918SOURCE-WINDOW's coordinate space to that of DEST-WINDOW, on FRAME. 7918SOURCE-WINDOW's coordinate space to that of DEST-WINDOW, on FRAME.
7919 7919
@@ -7929,16 +7929,21 @@ Return a list of (X Y CHILD) if the given coordinates are on the same
7929screen, or nil otherwise, where X and Y are the coordinates in 7929screen, or nil otherwise, where X and Y are the coordinates in
7930DEST-WINDOW's coordinate space, and CHILD is the window ID of any 7930DEST-WINDOW's coordinate space, and CHILD is the window ID of any
7931mapped child in DEST-WINDOW at those coordinates, or nil if there is 7931mapped child in DEST-WINDOW at those coordinates, or nil if there is
7932no such window. */) 7932no such window. If REQUIRE-CHILD is nil, avoid fetching CHILD if it
7933would result in an avoidable request to the X server, thereby
7934improving performance when the X connection is over a slow network.
7935Otherwise, always obtain the mapped child window from the X
7936server. */)
7933 (Lisp_Object frame, Lisp_Object source_window, 7937 (Lisp_Object frame, Lisp_Object source_window,
7934 Lisp_Object dest_window, Lisp_Object source_x, 7938 Lisp_Object dest_window, Lisp_Object source_x,
7935 Lisp_Object source_y) 7939 Lisp_Object source_y, Lisp_Object require_child)
7936{ 7940{
7937 struct x_display_info *dpyinfo; 7941 struct x_display_info *dpyinfo;
7938 struct frame *source_frame; 7942 struct frame *source_frame;
7939 int dest_x, dest_y; 7943 int dest_x, dest_y;
7940 Window child_return, src, dest; 7944 Window child_return, src, dest;
7941 Bool rc; 7945 Bool rc;
7946 Lisp_Object temp_result;
7942 7947
7943 dpyinfo = check_x_display_info (frame); 7948 dpyinfo = check_x_display_info (frame);
7944 dest_x = 0; 7949 dest_x = 0;
@@ -7956,6 +7961,8 @@ no such window. */)
7956 dest_y = XFIXNUM (source_y); 7961 dest_y = XFIXNUM (source_y);
7957 } 7962 }
7958 7963
7964 source_frame = NULL;
7965
7959 if (!NILP (source_window)) 7966 if (!NILP (source_window))
7960 CONS_TO_INTEGER (source_window, Window, src); 7967 CONS_TO_INTEGER (source_window, Window, src);
7961 else 7968 else
@@ -7964,6 +7971,17 @@ no such window. */)
7964 src = FRAME_X_WINDOW (source_frame); 7971 src = FRAME_X_WINDOW (source_frame);
7965 } 7972 }
7966 7973
7974 /* If require_child is nil, try to avoid an avoidable roundtrip to
7975 the X server. */
7976 if (NILP (require_child) && source_frame)
7977 {
7978 temp_result
7979 = x_handle_translate_coordinates (source_frame, dest_window, dest_x,
7980 dest_y);
7981 if (!NILP (temp_result))
7982 return temp_result;
7983 }
7984
7967 if (!src) 7985 if (!src)
7968 src = dpyinfo->root_window; 7986 src = dpyinfo->root_window;
7969 7987
diff --git a/src/xselect.c b/src/xselect.c
index 498c28af536..db5c7853e7f 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -2787,7 +2787,6 @@ x_handle_dnd_message (struct frame *f, const XClientMessageEvent *event,
2787 unsigned char *data = (unsigned char *) event->data.b; 2787 unsigned char *data = (unsigned char *) event->data.b;
2788 int idata[5]; 2788 int idata[5];
2789 ptrdiff_t i; 2789 ptrdiff_t i;
2790 Window child_return;
2791 2790
2792 for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i) 2791 for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i)
2793 if (dpyinfo->x_dnd_atoms[i] == event->message_type) break; 2792 if (dpyinfo->x_dnd_atoms[i] == event->message_type) break;
@@ -2822,11 +2821,7 @@ x_handle_dnd_message (struct frame *f, const XClientMessageEvent *event,
2822 if (!root_window_coords) 2821 if (!root_window_coords)
2823 x_relative_mouse_position (f, &x, &y); 2822 x_relative_mouse_position (f, &x, &y);
2824 else 2823 else
2825 XTranslateCoordinates (dpyinfo->display, 2824 x_translate_coordinates (f, root_x, root_y, &x, &y);
2826 dpyinfo->root_window,
2827 FRAME_X_WINDOW (f),
2828 root_x, root_y,
2829 &x, &y, &child_return);
2830 2825
2831 bufp->kind = DRAG_N_DROP_EVENT; 2826 bufp->kind = DRAG_N_DROP_EVENT;
2832 bufp->frame_or_window = frame; 2827 bufp->frame_or_window = frame;
diff --git a/src/xterm.c b/src/xterm.c
index 205c948c461..b061383a2ea 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1143,7 +1143,6 @@ static Window x_get_window_below (Display *, Window, int, int, int *, int *);
1143#ifndef USE_TOOLKIT_SCROLL_BARS 1143#ifndef USE_TOOLKIT_SCROLL_BARS
1144static void x_scroll_bar_redraw (struct scroll_bar *); 1144static void x_scroll_bar_redraw (struct scroll_bar *);
1145#endif 1145#endif
1146static void x_translate_coordinates (struct frame *, int, int, int *, int *);
1147 1146
1148/* Global state maintained during a drag-and-drop operation. */ 1147/* Global state maintained during a drag-and-drop operation. */
1149 1148
@@ -13658,7 +13657,7 @@ x_compute_root_window_offset (struct frame *f, int root_x, int root_y,
13658 many cases while handling events, which would otherwise result in 13657 many cases while handling events, which would otherwise result in
13659 slowdowns over slow network connections. */ 13658 slowdowns over slow network connections. */
13660 13659
13661static void 13660void
13662x_translate_coordinates (struct frame *f, int root_x, int root_y, 13661x_translate_coordinates (struct frame *f, int root_x, int root_y,
13663 int *x_out, int *y_out) 13662 int *x_out, int *y_out)
13664{ 13663{
@@ -13731,6 +13730,31 @@ x_translate_coordinates_to_root (struct frame *f, int x, int y,
13731 } 13730 }
13732} 13731}
13733 13732
13733/* Do x-translate-coordinates, but try to avoid a roundtrip to the X
13734 server at the cost of not returning `child', which most callers
13735 have no reason to use. */
13736
13737Lisp_Object
13738x_handle_translate_coordinates (struct frame *f, Lisp_Object dest_window,
13739 int source_x, int source_y)
13740{
13741 if (NILP (dest_window))
13742 {
13743 /* We are translating coordinates from a frame to the root
13744 window. Avoid a roundtrip if possible by using cached
13745 coordinates. */
13746
13747 if (!FRAME_X_OUTPUT (f)->window_offset_certain_p)
13748 return Qnil;
13749
13750 return list3 (make_fixnum (source_x + FRAME_X_OUTPUT (f)->root_x),
13751 make_fixnum (source_y + FRAME_X_OUTPUT (f)->root_y),
13752 Qnil);
13753 }
13754
13755 return Qnil;
13756}
13757
13734/* The same, but for an XIDeviceEvent. */ 13758/* The same, but for an XIDeviceEvent. */
13735 13759
13736#ifdef HAVE_XINPUT2 13760#ifdef HAVE_XINPUT2
@@ -20826,7 +20850,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
20826 event->xbutton.time); 20850 event->xbutton.time);
20827 } 20851 }
20828 else if (x_dnd_last_seen_window != None 20852 else if (x_dnd_last_seen_window != None
20829 && x_dnd_last_protocol_version != -1) 20853 && x_dnd_last_protocol_version != -1)
20830 { 20854 {
20831 x_dnd_pending_finish_target = x_dnd_last_seen_toplevel; 20855 x_dnd_pending_finish_target = x_dnd_last_seen_toplevel;
20832 x_dnd_waiting_for_finish_proto = x_dnd_last_protocol_version; 20856 x_dnd_waiting_for_finish_proto = x_dnd_last_protocol_version;
diff --git a/src/xterm.h b/src/xterm.h
index 2967d105ea2..537cabc9577 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1695,8 +1695,12 @@ extern void x_xr_apply_ext_clip (struct frame *, GC);
1695extern void x_xr_reset_ext_clip (struct frame *); 1695extern void x_xr_reset_ext_clip (struct frame *);
1696#endif 1696#endif
1697 1697
1698extern void x_translate_coordinates (struct frame *, int, int, int *, int *);
1698extern void x_translate_coordinates_to_root (struct frame *, int, int, 1699extern void x_translate_coordinates_to_root (struct frame *, int, int,
1699 int *, int *); 1700 int *, int *);
1701extern Lisp_Object x_handle_translate_coordinates (struct frame *, Lisp_Object,
1702 int, int);
1703
1700extern Bool x_query_pointer (Display *, Window, Window *, Window *, int *, 1704extern Bool x_query_pointer (Display *, Window, Window *, Window *, int *,
1701 int *, int *, int *, unsigned int *); 1705 int *, int *, int *, unsigned int *);
1702 1706