Improve drag-and-drop emulation time handling

* src/xselect.c (x_handle_selection_request): Use
display-specific pending DND time.
(x_set_pending_dnd_time): Delete function.
* src/xterm.c (x_dnd_do_unsupported_drop, handle_one_xevent):
Set dpyinfo->pending_dnd_time instead.
* src/xterm.h (struct x_display_info): New field
`pending_dnd_time'.  Make handling pending drops
display-specific to avoid interference when there are multiple
displays.
This commit is contained in:
Po Lu 2022-07-09 16:18:35 +08:00
parent edabfe4ff6
commit bab449f034
3 changed files with 32 additions and 49 deletions

View file

@ -40,8 +40,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <X11/Xproto.h>
static Time pending_dnd_time;
struct prop_location;
struct selection_data;
@ -265,7 +263,7 @@ x_atom_to_symbol (struct x_display_info *dpyinfo, Atom atom)
TIMESTAMP should be the timestamp where selection ownership will be
assumed.
DND_DATA is the local value that will be used for selection requests
with `pending_dnd_time'.
with `dpyinfo->pending_dnd_time'.
Update the Vselection_alist so that we can reply to later requests for
our selection. */
@ -855,8 +853,11 @@ x_handle_selection_request (struct selection_input_event *event)
/* This is how the XDND protocol recommends dropping text onto a
target that doesn't support XDND. */
if (SELECTION_EVENT_TIME (event) == pending_dnd_time + 1
|| SELECTION_EVENT_TIME (event) == pending_dnd_time + 2)
if (dpyinfo->pending_dnd_time
&& ((SELECTION_EVENT_TIME (event)
== dpyinfo->pending_dnd_time + 1)
|| (SELECTION_EVENT_TIME (event)
== dpyinfo->pending_dnd_time + 2)))
use_alternate = true;
block_input ();
@ -2884,12 +2885,6 @@ x_timestamp_for_selection (struct x_display_info *dpyinfo,
return value;
}
void
x_set_pending_dnd_time (Time time)
{
pending_dnd_time = time;
}
static void syms_of_xselect_for_pdumper (void);
void

View file

@ -3873,8 +3873,10 @@ x_dnd_do_unsupported_drop (struct x_display_info *dpyinfo,
&& child_return != None)
child = child_return;
x_uncatch_errors ();
if (!CONSP (value))
goto cancel;
return;
current_value = assq_no_quit (QPRIMARY,
dpyinfo->terminal->Vselection_alist);
@ -3891,9 +3893,7 @@ x_dnd_do_unsupported_drop (struct x_display_info *dpyinfo,
from generating events that will insert something else. */
if (owner != FRAME_X_WINDOW (f))
goto cancel;
x_uncatch_errors ();
return;
event.xbutton.window = child;
event.xbutton.subwindow = None;
@ -3903,7 +3903,7 @@ x_dnd_do_unsupported_drop (struct x_display_info *dpyinfo,
event.xbutton.button = 2;
event.xbutton.same_screen = True;
x_set_pending_dnd_time (before);
dpyinfo->pending_dnd_time = before;
event.xbutton.type = ButtonPress;
event.xbutton.time = before + 1;
@ -3924,9 +3924,6 @@ x_dnd_do_unsupported_drop (struct x_display_info *dpyinfo,
x_dnd_action_symbol = QXdndActionPrivate;
return;
cancel:
x_uncatch_errors ();
}
static void
@ -18934,23 +18931,17 @@ handle_one_xevent (struct x_display_info *dpyinfo,
}
}
else
{
x_set_pending_dnd_time (event->xbutton.time);
x_dnd_send_unsupported_drop (dpyinfo, (x_dnd_last_seen_toplevel != None
? x_dnd_last_seen_toplevel
: x_dnd_last_seen_window),
event->xbutton.x_root, event->xbutton.y_root,
event->xbutton.time);
}
x_dnd_send_unsupported_drop (dpyinfo, (x_dnd_last_seen_toplevel != None
? x_dnd_last_seen_toplevel
: x_dnd_last_seen_window),
event->xbutton.x_root, event->xbutton.y_root,
event->xbutton.time);
}
else if (x_dnd_last_seen_toplevel != None)
{
x_set_pending_dnd_time (event->xbutton.time);
x_dnd_send_unsupported_drop (dpyinfo, x_dnd_last_seen_toplevel,
event->xbutton.x_root,
event->xbutton.y_root,
event->xbutton.time);
}
x_dnd_send_unsupported_drop (dpyinfo, x_dnd_last_seen_toplevel,
event->xbutton.x_root,
event->xbutton.y_root,
event->xbutton.time);
x_dnd_last_protocol_version = -1;
@ -20352,22 +20343,16 @@ handle_one_xevent (struct x_display_info *dpyinfo,
}
}
else
{
x_set_pending_dnd_time (xev->time);
x_dnd_send_unsupported_drop (dpyinfo, (x_dnd_last_seen_toplevel != None
? x_dnd_last_seen_toplevel
: x_dnd_last_seen_window),
xev->root_x, xev->root_y, xev->time);
}
x_dnd_send_unsupported_drop (dpyinfo, (x_dnd_last_seen_toplevel != None
? x_dnd_last_seen_toplevel
: x_dnd_last_seen_window),
xev->root_x, xev->root_y, xev->time);
}
else if (x_dnd_last_seen_toplevel != None)
{
x_set_pending_dnd_time (xev->time);
x_dnd_send_unsupported_drop (dpyinfo,
x_dnd_last_seen_toplevel,
xev->root_x, xev->root_y,
xev->time);
}
x_dnd_send_unsupported_drop (dpyinfo,
x_dnd_last_seen_toplevel,
xev->root_x, xev->root_y,
xev->time);
x_dnd_last_protocol_version = -1;
x_dnd_last_motif_style = XM_DRAG_STYLE_NONE;

View file

@ -765,6 +765,10 @@ struct x_display_info
/* Pointer to the next request in `failable_requests'. */
struct x_failable_request *next_failable_request;
/* The pending drag-and-drop time for middle-click based
drag-and-drop emulation. */
Time pending_dnd_time;
};
#ifdef HAVE_X_I18N
@ -1617,7 +1621,6 @@ extern void x_clipboard_manager_save_all (void);
extern Lisp_Object x_timestamp_for_selection (struct x_display_info *,
Lisp_Object);
extern void x_set_pending_dnd_time (Time);
extern void x_own_selection (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object, Time);
extern Atom x_intern_cached_atom (struct x_display_info *, const char *,