summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2022-10-25 14:59:39 +0300
committerEli Zaretskii <eliz@gnu.org>2022-10-25 14:59:39 +0300
commit92ec31a48c7fa2a700eb3a5c618fe015843e6875 (patch)
treed206f9cad15ef94b1d26ffa1a091c294f8142f1b
parent095dadf27781b5f7916db0b5d669d7ced8f76d7e (diff)
parentb6097fe279b03e2fb50fc6af063d7c8f1e55fe8b (diff)
downloademacs-92ec31a48c7fa2a700eb3a5c618fe015843e6875.tar.gz
emacs-92ec31a48c7fa2a700eb3a5c618fe015843e6875.tar.bz2
emacs-92ec31a48c7fa2a700eb3a5c618fe015843e6875.zip
Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs
-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."
(defun x-dnd-get-drop-rectangle (window posn)
"Return the drag-and-drop rectangle at POSN on WINDOW."
(if (or dnd-scroll-margin
- (not (windowp window)))
+ (not (windowp window))
+ ;; Drops on the scroll bar aren't allowed, but the mouse
+ ;; rectangle can be set while still on the scroll bar,
+ ;; causing the drag initiator to never send an XdndPosition
+ ;; event that will an XdndStatus message with the accept
+ ;; flag set to be set, even after the mouse enters the
+ ;; window text area. To prevent that, simply don't generate
+ ;; a mouse rectangle when an area is set.
+ (posn-area posn))
'(0 0 0 0)
(let ((window-rectangle (x-dnd-get-window-rectangle window))
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:
DEFUN ("x-translate-coordinates", Fx_translate_coordinates,
Sx_translate_coordinates,
- 1, 5, 0, doc: /* Translate coordinates from FRAME.
+ 1, 6, 0, doc: /* Translate coordinates from FRAME.
Translate the given coordinates SOURCE-X and SOURCE-Y from
SOURCE-WINDOW's coordinate space to that of DEST-WINDOW, on FRAME.
@@ -7929,16 +7929,21 @@ Return a list of (X Y CHILD) if the given coordinates are on the same
screen, or nil otherwise, where X and Y are the coordinates in
DEST-WINDOW's coordinate space, and CHILD is the window ID of any
mapped child in DEST-WINDOW at those coordinates, or nil if there is
-no such window. */)
+no such window. If REQUIRE-CHILD is nil, avoid fetching CHILD if it
+would result in an avoidable request to the X server, thereby
+improving performance when the X connection is over a slow network.
+Otherwise, always obtain the mapped child window from the X
+server. */)
(Lisp_Object frame, Lisp_Object source_window,
Lisp_Object dest_window, Lisp_Object source_x,
- Lisp_Object source_y)
+ Lisp_Object source_y, Lisp_Object require_child)
{
struct x_display_info *dpyinfo;
struct frame *source_frame;
int dest_x, dest_y;
Window child_return, src, dest;
Bool rc;
+ Lisp_Object temp_result;
dpyinfo = check_x_display_info (frame);
dest_x = 0;
@@ -7956,6 +7961,8 @@ no such window. */)
dest_y = XFIXNUM (source_y);
}
+ source_frame = NULL;
+
if (!NILP (source_window))
CONS_TO_INTEGER (source_window, Window, src);
else
@@ -7964,6 +7971,17 @@ no such window. */)
src = FRAME_X_WINDOW (source_frame);
}
+ /* If require_child is nil, try to avoid an avoidable roundtrip to
+ the X server. */
+ if (NILP (require_child) && source_frame)
+ {
+ temp_result
+ = x_handle_translate_coordinates (source_frame, dest_window, dest_x,
+ dest_y);
+ if (!NILP (temp_result))
+ return temp_result;
+ }
+
if (!src)
src = dpyinfo->root_window;
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,
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;
@@ -2822,11 +2821,7 @@ x_handle_dnd_message (struct frame *f, const XClientMessageEvent *event,
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);
+ x_translate_coordinates (f, root_x, root_y, &x, &y);
bufp->kind = DRAG_N_DROP_EVENT;
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 *);
#ifndef USE_TOOLKIT_SCROLL_BARS
static void x_scroll_bar_redraw (struct scroll_bar *);
#endif
-static void x_translate_coordinates (struct frame *, int, int, int *, int *);
/* Global state maintained during a drag-and-drop operation. */
@@ -13658,7 +13657,7 @@ x_compute_root_window_offset (struct frame *f, int root_x, int root_y,
many cases while handling events, which would otherwise result in
slowdowns over slow network connections. */
-static void
+void
x_translate_coordinates (struct frame *f, int root_x, int root_y,
int *x_out, int *y_out)
{
@@ -13731,6 +13730,31 @@ x_translate_coordinates_to_root (struct frame *f, int x, int y,
}
}
+/* Do x-translate-coordinates, but try to avoid a roundtrip to the X
+ server at the cost of not returning `child', which most callers
+ have no reason to use. */
+
+Lisp_Object
+x_handle_translate_coordinates (struct frame *f, Lisp_Object dest_window,
+ int source_x, int source_y)
+{
+ if (NILP (dest_window))
+ {
+ /* We are translating coordinates from a frame to the root
+ window. Avoid a roundtrip if possible by using cached
+ coordinates. */
+
+ if (!FRAME_X_OUTPUT (f)->window_offset_certain_p)
+ return Qnil;
+
+ return list3 (make_fixnum (source_x + FRAME_X_OUTPUT (f)->root_x),
+ make_fixnum (source_y + FRAME_X_OUTPUT (f)->root_y),
+ Qnil);
+ }
+
+ return Qnil;
+}
+
/* The same, but for an XIDeviceEvent. */
#ifdef HAVE_XINPUT2
@@ -20826,7 +20850,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
event->xbutton.time);
}
else if (x_dnd_last_seen_window != None
- && x_dnd_last_protocol_version != -1)
+ && x_dnd_last_protocol_version != -1)
{
x_dnd_pending_finish_target = x_dnd_last_seen_toplevel;
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);
extern void x_xr_reset_ext_clip (struct frame *);
#endif
+extern void x_translate_coordinates (struct frame *, int, int, int *, int *);
extern void x_translate_coordinates_to_root (struct frame *, int, int,
int *, int *);
+extern Lisp_Object x_handle_translate_coordinates (struct frame *, Lisp_Object,
+ int, int);
+
extern Bool x_query_pointer (Display *, Window, Window *, Window *, int *,
int *, int *, int *, unsigned int *);