diff options
| author | Po Lu | 2022-05-28 10:09:19 +0800 |
|---|---|---|
| committer | Po Lu | 2022-05-28 10:09:19 +0800 |
| commit | 73237458ba305506d42293beb88d26054f8a353c (patch) | |
| tree | b1f54eb7cd0daaff2b0c3921837d0795ac11ca37 /src | |
| parent | ac13957b86ad699a76a0b248063551f971c4cef9 (diff) | |
| download | emacs-73237458ba305506d42293beb88d26054f8a353c.tar.gz emacs-73237458ba305506d42293beb88d26054f8a353c.zip | |
Improve safety of various DND callbacks
* src/xterm.c (x_dnd_begin_drag_and_drop): Restore selection
events if DND is no longer in progress and don't call
x-dnd-movement-function.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/src/xterm.c b/src/xterm.c index 94c996a11dc..5c591134692 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -10646,7 +10646,12 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 10646 | /* FIXME: how come this can end up with movement frames | 10646 | /* FIXME: how come this can end up with movement frames |
| 10647 | from other displays on GTK builds? */ | 10647 | from other displays on GTK builds? */ |
| 10648 | && (FRAME_X_DISPLAY (x_dnd_movement_frame) | 10648 | && (FRAME_X_DISPLAY (x_dnd_movement_frame) |
| 10649 | == FRAME_X_DISPLAY (f))) | 10649 | == FRAME_X_DISPLAY (f)) |
| 10650 | /* If both those variables are false, then F is no | ||
| 10651 | longer protected from deletion by Lisp code. This | ||
| 10652 | can only happen during the final iteration of the DND | ||
| 10653 | event loop. */ | ||
| 10654 | && (x_dnd_in_progress || x_dnd_waiting_for_finish)) | ||
| 10650 | { | 10655 | { |
| 10651 | XSETFRAME (frame_object, x_dnd_movement_frame); | 10656 | XSETFRAME (frame_object, x_dnd_movement_frame); |
| 10652 | XSETINT (x, x_dnd_movement_x); | 10657 | XSETINT (x, x_dnd_movement_x); |
| @@ -10677,14 +10682,24 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 10677 | { | 10682 | { |
| 10678 | if (hold_quit.kind == SELECTION_REQUEST_EVENT) | 10683 | if (hold_quit.kind == SELECTION_REQUEST_EVENT) |
| 10679 | { | 10684 | { |
| 10680 | x_dnd_old_window_attrs = root_window_attrs; | 10685 | /* It's not safe to run Lisp inside this function if |
| 10681 | x_dnd_unwind_flag = true; | 10686 | x_dnd_in_progress and x_dnd_waiting_for_finish |
| 10687 | are unset, so push it back into the event queue. */ | ||
| 10688 | |||
| 10689 | if (!x_dnd_in_progress && !x_dnd_waiting_for_finish) | ||
| 10690 | kbd_buffer_store_event (&hold_quit); | ||
| 10691 | else | ||
| 10692 | { | ||
| 10693 | x_dnd_old_window_attrs = root_window_attrs; | ||
| 10694 | x_dnd_unwind_flag = true; | ||
| 10695 | |||
| 10696 | ref = SPECPDL_INDEX (); | ||
| 10697 | record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f); | ||
| 10698 | x_handle_selection_event ((struct selection_input_event *) &hold_quit); | ||
| 10699 | x_dnd_unwind_flag = false; | ||
| 10700 | unbind_to (ref, Qnil); | ||
| 10701 | } | ||
| 10682 | 10702 | ||
| 10683 | ref = SPECPDL_INDEX (); | ||
| 10684 | record_unwind_protect_ptr (x_dnd_cleanup_drag_and_drop, f); | ||
| 10685 | x_handle_selection_event ((struct selection_input_event *) &hold_quit); | ||
| 10686 | x_dnd_unwind_flag = false; | ||
| 10687 | unbind_to (ref, Qnil); | ||
| 10688 | continue; | 10703 | continue; |
| 10689 | } | 10704 | } |
| 10690 | 10705 | ||