diff options
| author | Po Lu | 2022-05-30 09:25:03 +0800 |
|---|---|---|
| committer | Po Lu | 2022-05-30 09:25:03 +0800 |
| commit | 5b770b60f4f9d7d157774b999b0574aee133e7cb (patch) | |
| tree | 1a76392e1b58a636e4799013ff459d295cc00f53 /src | |
| parent | e2e232933c6f944b1dda7c578425b34f1e160e7f (diff) | |
| download | emacs-5b770b60f4f9d7d157774b999b0574aee133e7cb.tar.gz emacs-5b770b60f4f9d7d157774b999b0574aee133e7cb.zip | |
Further clean up DND target handling
* src/xfns.c (Fx_begin_drag): Alloca target list.
* src/xterm.c (x_set_dnd_targets): Copy the given targets list.
(x_dnd_begin_drag_and_drop): Record freeing the targets list on
the specpdl.
(handle_one_xevent, x_dnd_cleanup_drag_and_drop)
(x_connection_closed, x_delete_terminal): Stop calling
`x_set_dnd_targets' manually to free the targets list.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfns.c | 2 | ||||
| -rw-r--r-- | src/xterm.c | 40 |
2 files changed, 27 insertions, 15 deletions
diff --git a/src/xfns.c b/src/xfns.c index 8237e8870cd..259034861ab 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -6932,7 +6932,7 @@ that mouse buttons are being held down, such as immediately after a | |||
| 6932 | else | 6932 | else |
| 6933 | signal_error ("Invalid drag-and-drop action", action); | 6933 | signal_error ("Invalid drag-and-drop action", action); |
| 6934 | 6934 | ||
| 6935 | target_atoms = xmalloc (ntargets * sizeof *target_atoms); | 6935 | target_atoms = SAFE_ALLOCA (ntargets * sizeof *target_atoms); |
| 6936 | 6936 | ||
| 6937 | block_input (); | 6937 | block_input (); |
| 6938 | XInternAtoms (FRAME_X_DISPLAY (f), target_names, | 6938 | XInternAtoms (FRAME_X_DISPLAY (f), target_names, |
diff --git a/src/xterm.c b/src/xterm.c index 996e1949260..eee888f6fe6 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -3907,8 +3907,24 @@ x_set_dnd_targets (Atom *targets, int ntargets) | |||
| 3907 | if (x_dnd_targets) | 3907 | if (x_dnd_targets) |
| 3908 | xfree (x_dnd_targets); | 3908 | xfree (x_dnd_targets); |
| 3909 | 3909 | ||
| 3910 | x_dnd_targets = targets; | 3910 | block_input (); |
| 3911 | x_dnd_targets = xmalloc (sizeof *targets * ntargets); | ||
| 3911 | x_dnd_n_targets = ntargets; | 3912 | x_dnd_n_targets = ntargets; |
| 3913 | |||
| 3914 | memcpy (x_dnd_targets, targets, | ||
| 3915 | sizeof *targets * ntargets); | ||
| 3916 | unblock_input (); | ||
| 3917 | } | ||
| 3918 | |||
| 3919 | static void | ||
| 3920 | x_free_dnd_targets (void) | ||
| 3921 | { | ||
| 3922 | if (!x_dnd_targets) | ||
| 3923 | return; | ||
| 3924 | |||
| 3925 | xfree (x_dnd_targets); | ||
| 3926 | x_dnd_targets = NULL; | ||
| 3927 | x_dnd_n_targets = 0; | ||
| 3912 | } | 3928 | } |
| 3913 | 3929 | ||
| 3914 | static void | 3930 | static void |
| @@ -3962,7 +3978,6 @@ x_dnd_cleanup_drag_and_drop (void *frame) | |||
| 3962 | x_dnd_in_progress = false; | 3978 | x_dnd_in_progress = false; |
| 3963 | } | 3979 | } |
| 3964 | 3980 | ||
| 3965 | x_set_dnd_targets (NULL, 0); | ||
| 3966 | x_dnd_waiting_for_finish = false; | 3981 | x_dnd_waiting_for_finish = false; |
| 3967 | 3982 | ||
| 3968 | if (x_dnd_use_toplevels) | 3983 | if (x_dnd_use_toplevels) |
| @@ -10332,7 +10347,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 10332 | struct frame *any; | 10347 | struct frame *any; |
| 10333 | char *atom_name, *ask_actions; | 10348 | char *atom_name, *ask_actions; |
| 10334 | Lisp_Object action, ltimestamp; | 10349 | Lisp_Object action, ltimestamp; |
| 10335 | specpdl_ref ref, count; | 10350 | specpdl_ref ref, count, base; |
| 10336 | ptrdiff_t i, end, fill; | 10351 | ptrdiff_t i, end, fill; |
| 10337 | XTextProperty prop; | 10352 | XTextProperty prop; |
| 10338 | xm_drop_start_message dmsg; | 10353 | xm_drop_start_message dmsg; |
| @@ -10348,6 +10363,8 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 10348 | int n_events; | 10363 | int n_events; |
| 10349 | struct frame *event_frame; | 10364 | struct frame *event_frame; |
| 10350 | 10365 | ||
| 10366 | base = SPECPDL_INDEX (); | ||
| 10367 | |||
| 10351 | /* Before starting drag-and-drop, walk through the keyboard buffer | 10368 | /* Before starting drag-and-drop, walk through the keyboard buffer |
| 10352 | to see if there are any UNSUPPORTED_DROP_EVENTs, and run them now | 10369 | to see if there are any UNSUPPORTED_DROP_EVENTs, and run them now |
| 10353 | if they exist, to prevent race conditions from happening due to | 10370 | if they exist, to prevent race conditions from happening due to |
| @@ -10427,6 +10444,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 10427 | if (popup_activated ()) | 10444 | if (popup_activated ()) |
| 10428 | error ("Trying to drag-and-drop from within a menu-entry"); | 10445 | error ("Trying to drag-and-drop from within a menu-entry"); |
| 10429 | 10446 | ||
| 10447 | record_unwind_protect_void (x_free_dnd_targets); | ||
| 10430 | x_set_dnd_targets (target_atoms, ntargets); | 10448 | x_set_dnd_targets (target_atoms, ntargets); |
| 10431 | 10449 | ||
| 10432 | ltimestamp = x_timestamp_for_selection (FRAME_DISPLAY_INFO (f), | 10450 | ltimestamp = x_timestamp_for_selection (FRAME_DISPLAY_INFO (f), |
| @@ -10738,7 +10756,6 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 10738 | x_dnd_frame = NULL; | 10756 | x_dnd_frame = NULL; |
| 10739 | } | 10757 | } |
| 10740 | 10758 | ||
| 10741 | x_set_dnd_targets (NULL, 0); | ||
| 10742 | x_dnd_waiting_for_finish = false; | 10759 | x_dnd_waiting_for_finish = false; |
| 10743 | 10760 | ||
| 10744 | if (x_dnd_use_toplevels) | 10761 | if (x_dnd_use_toplevels) |
| @@ -10810,7 +10827,6 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 10810 | x_dnd_frame = NULL; | 10827 | x_dnd_frame = NULL; |
| 10811 | } | 10828 | } |
| 10812 | 10829 | ||
| 10813 | x_set_dnd_targets (NULL, 0); | ||
| 10814 | x_dnd_waiting_for_finish = false; | 10830 | x_dnd_waiting_for_finish = false; |
| 10815 | 10831 | ||
| 10816 | if (x_dnd_use_toplevels) | 10832 | if (x_dnd_use_toplevels) |
| @@ -10850,7 +10866,6 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 10850 | #endif | 10866 | #endif |
| 10851 | } | 10867 | } |
| 10852 | 10868 | ||
| 10853 | x_set_dnd_targets (NULL, 0); | ||
| 10854 | x_dnd_waiting_for_finish = false; | 10869 | x_dnd_waiting_for_finish = false; |
| 10855 | 10870 | ||
| 10856 | #ifdef USE_GTK | 10871 | #ifdef USE_GTK |
| @@ -10887,7 +10902,8 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 10887 | 10902 | ||
| 10888 | XSETFRAME (action, x_dnd_return_frame_object); | 10903 | XSETFRAME (action, x_dnd_return_frame_object); |
| 10889 | x_dnd_return_frame_object = NULL; | 10904 | x_dnd_return_frame_object = NULL; |
| 10890 | return action; | 10905 | |
| 10906 | return unbind_to (base, action); | ||
| 10891 | } | 10907 | } |
| 10892 | 10908 | ||
| 10893 | x_dnd_return_frame_object = NULL; | 10909 | x_dnd_return_frame_object = NULL; |
| @@ -10903,7 +10919,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 10903 | && (any = x_any_window_to_frame (FRAME_DISPLAY_INFO (f), | 10919 | && (any = x_any_window_to_frame (FRAME_DISPLAY_INFO (f), |
| 10904 | x_dnd_end_window)) | 10920 | x_dnd_end_window)) |
| 10905 | && (allow_current_frame || any != f)) | 10921 | && (allow_current_frame || any != f)) |
| 10906 | return QXdndActionPrivate; | 10922 | return unbind_to (base, QXdndActionPrivate); |
| 10907 | 10923 | ||
| 10908 | if (x_dnd_action != None) | 10924 | if (x_dnd_action != None) |
| 10909 | { | 10925 | { |
| @@ -10928,10 +10944,10 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 10928 | action = Qnil; | 10944 | action = Qnil; |
| 10929 | unblock_input (); | 10945 | unblock_input (); |
| 10930 | 10946 | ||
| 10931 | return action; | 10947 | return unbind_to (base, action); |
| 10932 | } | 10948 | } |
| 10933 | 10949 | ||
| 10934 | return Qnil; | 10950 | return unbind_to (base, Qnil); |
| 10935 | } | 10951 | } |
| 10936 | 10952 | ||
| 10937 | /* The focus may have changed. Figure out if it is a real focus change, | 10953 | /* The focus may have changed. Figure out if it is a real focus change, |
| @@ -17334,7 +17350,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17334 | x_dnd_last_seen_window = None; | 17350 | x_dnd_last_seen_window = None; |
| 17335 | x_dnd_last_seen_toplevel = None; | 17351 | x_dnd_last_seen_toplevel = None; |
| 17336 | x_dnd_frame = NULL; | 17352 | x_dnd_frame = NULL; |
| 17337 | x_set_dnd_targets (NULL, 0); | ||
| 17338 | } | 17353 | } |
| 17339 | } | 17354 | } |
| 17340 | 17355 | ||
| @@ -18653,7 +18668,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 18653 | x_dnd_last_seen_window = None; | 18668 | x_dnd_last_seen_window = None; |
| 18654 | x_dnd_last_seen_toplevel = None; | 18669 | x_dnd_last_seen_toplevel = None; |
| 18655 | x_dnd_frame = NULL; | 18670 | x_dnd_frame = NULL; |
| 18656 | x_set_dnd_targets (NULL, 0); | ||
| 18657 | 18671 | ||
| 18658 | goto XI_OTHER; | 18672 | goto XI_OTHER; |
| 18659 | } | 18673 | } |
| @@ -21459,7 +21473,6 @@ x_connection_closed (Display *dpy, const char *error_message, bool ioerror) | |||
| 21459 | x_dnd_last_seen_window = None; | 21473 | x_dnd_last_seen_window = None; |
| 21460 | x_dnd_last_seen_toplevel = None; | 21474 | x_dnd_last_seen_toplevel = None; |
| 21461 | x_dnd_in_progress = false; | 21475 | x_dnd_in_progress = false; |
| 21462 | x_set_dnd_targets (NULL, 0); | ||
| 21463 | x_dnd_waiting_for_finish = false; | 21476 | x_dnd_waiting_for_finish = false; |
| 21464 | 21477 | ||
| 21465 | if (x_dnd_use_toplevels) | 21478 | if (x_dnd_use_toplevels) |
| @@ -25493,7 +25506,6 @@ x_delete_terminal (struct terminal *terminal) | |||
| 25493 | x_dnd_last_seen_window = None; | 25506 | x_dnd_last_seen_window = None; |
| 25494 | x_dnd_last_seen_toplevel = None; | 25507 | x_dnd_last_seen_toplevel = None; |
| 25495 | x_dnd_in_progress = false; | 25508 | x_dnd_in_progress = false; |
| 25496 | x_set_dnd_targets (NULL, 0); | ||
| 25497 | x_dnd_waiting_for_finish = false; | 25509 | x_dnd_waiting_for_finish = false; |
| 25498 | 25510 | ||
| 25499 | if (x_dnd_use_toplevels) | 25511 | if (x_dnd_use_toplevels) |