diff options
| author | Po Lu | 2022-03-16 12:33:15 +0800 |
|---|---|---|
| committer | Po Lu | 2022-03-16 12:33:15 +0800 |
| commit | f62a6acd00fa5045fbc537bcaa87756416e246a4 (patch) | |
| tree | ff29580e4f687a5d5ec7841486cd1d62f002f27f | |
| parent | 5ff13718a53c161c3a0d3e8795544a740c10064b (diff) | |
| download | emacs-f62a6acd00fa5045fbc537bcaa87756416e246a4.tar.gz emacs-f62a6acd00fa5045fbc537bcaa87756416e246a4.zip | |
Better handle drag-and-drop from one Emacs frame to another
* doc/lispref/frames.texi (Drag and Drop): Document new
parameter `return-frame' to `x-begin-drag'.
* lisp/mouse.el (mouse-drag-and-drop-region): Utilize new
feature.
* src/xfns.c (Fx_begin_drag): New parameter `return-frame'.
* src/xterm.c (x_dnd_begin_drag_and_drop): New parameter
return_frame_p.
(handle_one_xevent): Set new flags and return frame whenever
appropriate.
* src/xterm.h: Update prototypes.
| -rw-r--r-- | doc/lispref/frames.texi | 8 | ||||
| -rw-r--r-- | lisp/mouse.el | 235 | ||||
| -rw-r--r-- | src/xfns.c | 11 | ||||
| -rw-r--r-- | src/xterm.c | 50 | ||||
| -rw-r--r-- | src/xterm.h | 3 |
5 files changed, 185 insertions, 122 deletions
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 38897d6a0b3..ea5dd4c675b 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi | |||
| @@ -4042,7 +4042,7 @@ you want to alter Emacs behavior, you can customize these variables. | |||
| 4042 | On some window systems, Emacs also supports dragging contents from | 4042 | On some window systems, Emacs also supports dragging contents from |
| 4043 | itself to other frames. | 4043 | itself to other frames. |
| 4044 | 4044 | ||
| 4045 | @defun x-begin-drag targets action &optional frame | 4045 | @defun x-begin-drag targets action &optional frame return-frame |
| 4046 | This function begins a drag from @var{frame}, and returns when the | 4046 | This function begins a drag from @var{frame}, and returns when the |
| 4047 | session ends, either because the drop was successful, or because the | 4047 | session ends, either because the drop was successful, or because the |
| 4048 | drop was rejected. The drop occurs when all mouse buttons are | 4048 | drop was rejected. The drop occurs when all mouse buttons are |
| @@ -4061,6 +4061,12 @@ the drop target, or @code{XdndActionMove}, which means the same as | |||
| 4061 | @code{XdndActionCopy}, but also means the caller should delete | 4061 | @code{XdndActionCopy}, but also means the caller should delete |
| 4062 | whatever was saved into that selection afterwards. | 4062 | whatever was saved into that selection afterwards. |
| 4063 | 4063 | ||
| 4064 | If @var{return-frame} is non-nil and the mouse moves over an Emacs | ||
| 4065 | frame after first moving out of @var{frame}, then that frame will be | ||
| 4066 | returned immediately. This is useful when you want to treat dragging | ||
| 4067 | content from one frame to another specially, while also being able to | ||
| 4068 | drag content to other programs. | ||
| 4069 | |||
| 4064 | If the drop was rejected or no drop target was found, this function | 4070 | If the drop was rejected or no drop target was found, this function |
| 4065 | returns @code{nil}. Otherwise, it returns a symbol describing the | 4071 | returns @code{nil}. Otherwise, it returns a symbol describing the |
| 4066 | action the target chose to perform, which can differ from @var{action} | 4072 | action the target chose to perform, which can differ from @var{action} |
diff --git a/lisp/mouse.el b/lisp/mouse.el index 3e2097e761f..b650bea1bde 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el | |||
| @@ -3061,123 +3061,126 @@ is copied instead of being cut." | |||
| 3061 | (or (mouse-movement-p event) | 3061 | (or (mouse-movement-p event) |
| 3062 | ;; Handle `mouse-autoselect-window'. | 3062 | ;; Handle `mouse-autoselect-window'. |
| 3063 | (memq (car event) '(select-window switch-frame)))) | 3063 | (memq (car event) '(select-window switch-frame)))) |
| 3064 | ;; Obtain the dragged text in region. When the loop was | 3064 | (catch 'drag-again |
| 3065 | ;; skipped, value-selection remains nil. | 3065 | ;; Obtain the dragged text in region. When the loop was |
| 3066 | (unless value-selection | 3066 | ;; skipped, value-selection remains nil. |
| 3067 | (setq value-selection (funcall region-extract-function nil)) | 3067 | (unless value-selection |
| 3068 | (when mouse-drag-and-drop-region-show-tooltip | 3068 | (setq value-selection (funcall region-extract-function nil)) |
| 3069 | (let ((text-size mouse-drag-and-drop-region-show-tooltip)) | 3069 | (when mouse-drag-and-drop-region-show-tooltip |
| 3070 | (setq text-tooltip | 3070 | (let ((text-size mouse-drag-and-drop-region-show-tooltip)) |
| 3071 | (if (and (integerp text-size) | 3071 | (setq text-tooltip |
| 3072 | (> (length value-selection) text-size)) | 3072 | (if (and (integerp text-size) |
| 3073 | (concat | 3073 | (> (length value-selection) text-size)) |
| 3074 | (substring value-selection 0 (/ text-size 2)) | 3074 | (concat |
| 3075 | "\n...\n" | 3075 | (substring value-selection 0 (/ text-size 2)) |
| 3076 | (substring value-selection (- (/ text-size 2)) -1)) | 3076 | "\n...\n" |
| 3077 | value-selection)))) | 3077 | (substring value-selection (- (/ text-size 2)) -1)) |
| 3078 | 3078 | value-selection)))) | |
| 3079 | ;; Check if selected text is read-only. | 3079 | |
| 3080 | (setq text-from-read-only | 3080 | ;; Check if selected text is read-only. |
| 3081 | (or text-from-read-only | 3081 | (setq text-from-read-only |
| 3082 | (catch 'loop | 3082 | (or text-from-read-only |
| 3083 | (dolist (bound (region-bounds)) | 3083 | (catch 'loop |
| 3084 | (when (text-property-not-all | 3084 | (dolist (bound (region-bounds)) |
| 3085 | (car bound) (cdr bound) 'read-only nil) | 3085 | (when (text-property-not-all |
| 3086 | (throw 'loop t))))))) | 3086 | (car bound) (cdr bound) 'read-only nil) |
| 3087 | 3087 | (throw 'loop t))))))) | |
| 3088 | (when (and mouse-drag-and-drop-region-cross-program | 3088 | |
| 3089 | (fboundp 'x-begin-drag) | 3089 | (when (and mouse-drag-and-drop-region-cross-program |
| 3090 | (framep (posn-window (event-end event))) | 3090 | (fboundp 'x-begin-drag) |
| 3091 | (let ((location (posn-x-y (event-end event))) | 3091 | (framep (posn-window (event-end event))) |
| 3092 | (frame (posn-window (event-end event)))) | 3092 | (let ((location (posn-x-y (event-end event))) |
| 3093 | (or (< (car location) 0) | 3093 | (frame (posn-window (event-end event)))) |
| 3094 | (< (cdr location) 0) | 3094 | (or (< (car location) 0) |
| 3095 | (> (car location) | 3095 | (< (cdr location) 0) |
| 3096 | (frame-pixel-width frame)) | 3096 | (> (car location) |
| 3097 | (> (cdr location) | 3097 | (frame-pixel-width frame)) |
| 3098 | (frame-pixel-height frame))))) | 3098 | (> (cdr location) |
| 3099 | (tooltip-hide) | 3099 | (frame-pixel-height frame))))) |
| 3100 | (gui-set-selection 'XdndSelection value-selection) | 3100 | (tooltip-hide) |
| 3101 | (x-begin-drag '("UTF8_STRING" "STRING") | 3101 | (gui-set-selection 'XdndSelection value-selection) |
| 3102 | 'XdndActionMove (posn-window (event-end event))) | 3102 | (when (framep |
| 3103 | (throw 'cross-program-drag nil)) | 3103 | (x-begin-drag '("UTF8_STRING" "STRING") 'XdndActionCopy |
| 3104 | 3104 | (posn-window (event-end event)) t)) | |
| 3105 | (setq window-to-paste (posn-window (event-end event))) | 3105 | (throw 'drag-again nil)) |
| 3106 | (setq point-to-paste (posn-point (event-end event))) | 3106 | (throw 'cross-program-drag nil)) |
| 3107 | ;; Set nil when target buffer is minibuffer. | 3107 | |
| 3108 | (setq buffer-to-paste (let (buf) | 3108 | (setq window-to-paste (posn-window (event-end event))) |
| 3109 | (when (windowp window-to-paste) | 3109 | (setq point-to-paste (posn-point (event-end event))) |
| 3110 | (setq buf (window-buffer window-to-paste)) | 3110 | ;; Set nil when target buffer is minibuffer. |
| 3111 | (when (not (minibufferp buf)) | 3111 | (setq buffer-to-paste (let (buf) |
| 3112 | buf)))) | 3112 | (when (windowp window-to-paste) |
| 3113 | (setq cursor-in-text-area (and window-to-paste | 3113 | (setq buf (window-buffer window-to-paste)) |
| 3114 | point-to-paste | 3114 | (when (not (minibufferp buf)) |
| 3115 | buffer-to-paste)) | 3115 | buf)))) |
| 3116 | 3116 | (setq cursor-in-text-area (and window-to-paste | |
| 3117 | (when cursor-in-text-area | 3117 | point-to-paste |
| 3118 | ;; Check if point under mouse is read-only. | 3118 | buffer-to-paste)) |
| 3119 | (save-window-excursion | 3119 | |
| 3120 | (select-window window-to-paste) | ||
| 3121 | (setq point-to-paste-read-only | ||
| 3122 | (or buffer-read-only | ||
| 3123 | (get-text-property point-to-paste 'read-only)))) | ||
| 3124 | |||
| 3125 | ;; Check if "drag but negligible". Operation "drag but | ||
| 3126 | ;; negligible" is defined as drag-and-drop the text to | ||
| 3127 | ;; the original region. When modifier is pressed, the | ||
| 3128 | ;; text will be inserted to inside of the original | ||
| 3129 | ;; region. | ||
| 3130 | ;; | ||
| 3131 | ;; If the region is rectangular, check if the newly inserted | ||
| 3132 | ;; rectangular text would intersect the already selected | ||
| 3133 | ;; region. If it would, then set "drag-but-negligible" to t. | ||
| 3134 | ;; As a special case, allow dragging the region freely anywhere | ||
| 3135 | ;; to the left, as this will never trigger its contents to be | ||
| 3136 | ;; inserted into the overlays tracking it. | ||
| 3137 | (setq drag-but-negligible | ||
| 3138 | (and (eq (overlay-buffer (car mouse-drag-and-drop-overlays)) | ||
| 3139 | buffer-to-paste) | ||
| 3140 | (if region-noncontiguous | ||
| 3141 | (let ((dimensions (rectangle-dimensions start end)) | ||
| 3142 | (start-coordinates | ||
| 3143 | (rectangle-position-as-coordinates start)) | ||
| 3144 | (point-to-paste-coordinates | ||
| 3145 | (rectangle-position-as-coordinates | ||
| 3146 | point-to-paste))) | ||
| 3147 | (and (rectangle-intersect-p | ||
| 3148 | start-coordinates dimensions | ||
| 3149 | point-to-paste-coordinates dimensions) | ||
| 3150 | (not (< (car point-to-paste-coordinates) | ||
| 3151 | (car start-coordinates))))) | ||
| 3152 | (and (<= (overlay-start | ||
| 3153 | (car mouse-drag-and-drop-overlays)) | ||
| 3154 | point-to-paste) | ||
| 3155 | (<= point-to-paste | ||
| 3156 | (overlay-end | ||
| 3157 | (car mouse-drag-and-drop-overlays)))))))) | ||
| 3158 | |||
| 3159 | ;; Show a tooltip. | ||
| 3160 | (if mouse-drag-and-drop-region-show-tooltip | ||
| 3161 | (tooltip-show text-tooltip) | ||
| 3162 | (tooltip-hide)) | ||
| 3163 | |||
| 3164 | ;; Show cursor and highlight the original region. | ||
| 3165 | (when mouse-drag-and-drop-region-show-cursor | ||
| 3166 | ;; Modify cursor even when point is out of frame. | ||
| 3167 | (setq cursor-type (cond | ||
| 3168 | ((not cursor-in-text-area) | ||
| 3169 | nil) | ||
| 3170 | ((or point-to-paste-read-only | ||
| 3171 | drag-but-negligible) | ||
| 3172 | 'hollow) | ||
| 3173 | (t | ||
| 3174 | 'bar))) | ||
| 3175 | (when cursor-in-text-area | 3120 | (when cursor-in-text-area |
| 3176 | (dolist (overlay mouse-drag-and-drop-overlays) | 3121 | ;; Check if point under mouse is read-only. |
| 3177 | (overlay-put overlay | 3122 | (save-window-excursion |
| 3178 | 'face 'mouse-drag-and-drop-region)) | 3123 | (select-window window-to-paste) |
| 3179 | (deactivate-mark) ; Maintain region in other window. | 3124 | (setq point-to-paste-read-only |
| 3180 | (mouse-set-point event)))))) | 3125 | (or buffer-read-only |
| 3126 | (get-text-property point-to-paste 'read-only)))) | ||
| 3127 | |||
| 3128 | ;; Check if "drag but negligible". Operation "drag but | ||
| 3129 | ;; negligible" is defined as drag-and-drop the text to | ||
| 3130 | ;; the original region. When modifier is pressed, the | ||
| 3131 | ;; text will be inserted to inside of the original | ||
| 3132 | ;; region. | ||
| 3133 | ;; | ||
| 3134 | ;; If the region is rectangular, check if the newly inserted | ||
| 3135 | ;; rectangular text would intersect the already selected | ||
| 3136 | ;; region. If it would, then set "drag-but-negligible" to t. | ||
| 3137 | ;; As a special case, allow dragging the region freely anywhere | ||
| 3138 | ;; to the left, as this will never trigger its contents to be | ||
| 3139 | ;; inserted into the overlays tracking it. | ||
| 3140 | (setq drag-but-negligible | ||
| 3141 | (and (eq (overlay-buffer (car mouse-drag-and-drop-overlays)) | ||
| 3142 | buffer-to-paste) | ||
| 3143 | (if region-noncontiguous | ||
| 3144 | (let ((dimensions (rectangle-dimensions start end)) | ||
| 3145 | (start-coordinates | ||
| 3146 | (rectangle-position-as-coordinates start)) | ||
| 3147 | (point-to-paste-coordinates | ||
| 3148 | (rectangle-position-as-coordinates | ||
| 3149 | point-to-paste))) | ||
| 3150 | (and (rectangle-intersect-p | ||
| 3151 | start-coordinates dimensions | ||
| 3152 | point-to-paste-coordinates dimensions) | ||
| 3153 | (not (< (car point-to-paste-coordinates) | ||
| 3154 | (car start-coordinates))))) | ||
| 3155 | (and (<= (overlay-start | ||
| 3156 | (car mouse-drag-and-drop-overlays)) | ||
| 3157 | point-to-paste) | ||
| 3158 | (<= point-to-paste | ||
| 3159 | (overlay-end | ||
| 3160 | (car mouse-drag-and-drop-overlays)))))))) | ||
| 3161 | |||
| 3162 | ;; Show a tooltip. | ||
| 3163 | (if mouse-drag-and-drop-region-show-tooltip | ||
| 3164 | (tooltip-show text-tooltip) | ||
| 3165 | (tooltip-hide)) | ||
| 3166 | |||
| 3167 | ;; Show cursor and highlight the original region. | ||
| 3168 | (when mouse-drag-and-drop-region-show-cursor | ||
| 3169 | ;; Modify cursor even when point is out of frame. | ||
| 3170 | (setq cursor-type (cond | ||
| 3171 | ((not cursor-in-text-area) | ||
| 3172 | nil) | ||
| 3173 | ((or point-to-paste-read-only | ||
| 3174 | drag-but-negligible) | ||
| 3175 | 'hollow) | ||
| 3176 | (t | ||
| 3177 | 'bar))) | ||
| 3178 | (when cursor-in-text-area | ||
| 3179 | (dolist (overlay mouse-drag-and-drop-overlays) | ||
| 3180 | (overlay-put overlay | ||
| 3181 | 'face 'mouse-drag-and-drop-region)) | ||
| 3182 | (deactivate-mark) ; Maintain region in other window. | ||
| 3183 | (mouse-set-point event))))))) | ||
| 3181 | 3184 | ||
| 3182 | ;; Hide a tooltip. | 3185 | ;; Hide a tooltip. |
| 3183 | (when mouse-drag-and-drop-region-show-tooltip (tooltip-hide)) | 3186 | (when mouse-drag-and-drop-region-show-tooltip (tooltip-hide)) |
diff --git a/src/xfns.c b/src/xfns.c index 0d197c1dd7d..b5d0b2c54e8 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -6582,7 +6582,7 @@ The coordinates X and Y are interpreted in pixels relative to a position | |||
| 6582 | return Qnil; | 6582 | return Qnil; |
| 6583 | } | 6583 | } |
| 6584 | 6584 | ||
| 6585 | DEFUN ("x-begin-drag", Fx_begin_drag, Sx_begin_drag, 1, 3, 0, | 6585 | DEFUN ("x-begin-drag", Fx_begin_drag, Sx_begin_drag, 1, 4, 0, |
| 6586 | doc: /* Begin dragging contents on FRAME, with targets TARGETS. | 6586 | doc: /* Begin dragging contents on FRAME, with targets TARGETS. |
| 6587 | TARGETS is a list of strings, which defines the X selection targets | 6587 | TARGETS is a list of strings, which defines the X selection targets |
| 6588 | that will be available to the drop target. Block until the mouse | 6588 | that will be available to the drop target. Block until the mouse |
| @@ -6607,9 +6607,14 @@ Emacs. For that reason, they are not mentioned here. Consult | |||
| 6607 | "Drag-and-Drop Protocol for the X Window System" for more details: | 6607 | "Drag-and-Drop Protocol for the X Window System" for more details: |
| 6608 | https://freedesktop.org/wiki/Specifications/XDND/. | 6608 | https://freedesktop.org/wiki/Specifications/XDND/. |
| 6609 | 6609 | ||
| 6610 | If RETURN-FRAME is non-nil, this function will return the frame if the | ||
| 6611 | mouse pointer moves onto an Emacs frame, after first moving out of | ||
| 6612 | FRAME. | ||
| 6613 | |||
| 6610 | If ACTION is not specified or nil, `XdndActionCopy' is used | 6614 | If ACTION is not specified or nil, `XdndActionCopy' is used |
| 6611 | instead. */) | 6615 | instead. */) |
| 6612 | (Lisp_Object targets, Lisp_Object action, Lisp_Object frame) | 6616 | (Lisp_Object targets, Lisp_Object action, Lisp_Object frame, |
| 6617 | Lisp_Object return_frame) | ||
| 6613 | { | 6618 | { |
| 6614 | struct frame *f = decode_window_system_frame (frame); | 6619 | struct frame *f = decode_window_system_frame (frame); |
| 6615 | int ntargets = 0; | 6620 | int ntargets = 0; |
| @@ -6655,7 +6660,7 @@ instead. */) | |||
| 6655 | 6660 | ||
| 6656 | x_set_dnd_targets (target_atoms, ntargets); | 6661 | x_set_dnd_targets (target_atoms, ntargets); |
| 6657 | lval = x_dnd_begin_drag_and_drop (f, FRAME_DISPLAY_INFO (f)->last_user_time, | 6662 | lval = x_dnd_begin_drag_and_drop (f, FRAME_DISPLAY_INFO (f)->last_user_time, |
| 6658 | xaction); | 6663 | xaction, !NILP (return_frame)); |
| 6659 | 6664 | ||
| 6660 | return lval; | 6665 | return lval; |
| 6661 | } | 6666 | } |
diff --git a/src/xterm.c b/src/xterm.c index 8a4344f2a4f..a3d20a9d226 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -771,6 +771,15 @@ static void x_scroll_bar_end_update (struct x_display_info *, struct scroll_bar | |||
| 771 | #endif | 771 | #endif |
| 772 | 772 | ||
| 773 | static bool x_dnd_in_progress; | 773 | static bool x_dnd_in_progress; |
| 774 | |||
| 775 | /* Whether or not to return a frame from `x_dnd_begin_drag_and_drop'. | ||
| 776 | |||
| 777 | 0 means to do nothing. 1 means to wait for the mouse to first exit | ||
| 778 | `x_dnd_frame'. 2 means to wait for the mouse to move onto a frame, | ||
| 779 | and 3 means to `x_dnd_return_frame_object'. */ | ||
| 780 | static int x_dnd_return_frame; | ||
| 781 | static struct frame *x_dnd_return_frame_object; | ||
| 782 | |||
| 774 | static Window x_dnd_last_seen_window; | 783 | static Window x_dnd_last_seen_window; |
| 775 | static int x_dnd_last_protocol_version; | 784 | static int x_dnd_last_protocol_version; |
| 776 | static Time x_dnd_selection_timestamp; | 785 | static Time x_dnd_selection_timestamp; |
| @@ -1025,7 +1034,8 @@ x_set_dnd_targets (Atom *targets, int ntargets) | |||
| 1025 | } | 1034 | } |
| 1026 | 1035 | ||
| 1027 | Lisp_Object | 1036 | Lisp_Object |
| 1028 | x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction) | 1037 | x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, |
| 1038 | bool return_frame_p) | ||
| 1029 | { | 1039 | { |
| 1030 | XEvent next_event; | 1040 | XEvent next_event; |
| 1031 | struct input_event hold_quit; | 1041 | struct input_event hold_quit; |
| @@ -1054,6 +1064,10 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction) | |||
| 1054 | x_dnd_mouse_rect_target = None; | 1064 | x_dnd_mouse_rect_target = None; |
| 1055 | x_dnd_action = None; | 1065 | x_dnd_action = None; |
| 1056 | x_dnd_wanted_action = xaction; | 1066 | x_dnd_wanted_action = xaction; |
| 1067 | x_dnd_return_frame = 0; | ||
| 1068 | |||
| 1069 | if (return_frame_p) | ||
| 1070 | x_dnd_return_frame = 1; | ||
| 1057 | 1071 | ||
| 1058 | while (x_dnd_in_progress) | 1072 | while (x_dnd_in_progress) |
| 1059 | { | 1073 | { |
| @@ -1085,6 +1099,14 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction) | |||
| 1085 | } | 1099 | } |
| 1086 | } | 1100 | } |
| 1087 | 1101 | ||
| 1102 | if (x_dnd_return_frame == 3) | ||
| 1103 | { | ||
| 1104 | x_dnd_return_frame_object->mouse_moved = true; | ||
| 1105 | |||
| 1106 | XSETFRAME (action, x_dnd_return_frame_object); | ||
| 1107 | return action; | ||
| 1108 | } | ||
| 1109 | |||
| 1088 | FRAME_DISPLAY_INFO (f)->grabbed = 0; | 1110 | FRAME_DISPLAY_INFO (f)->grabbed = 0; |
| 1089 | 1111 | ||
| 1090 | if (x_dnd_wanted_action != None) | 1112 | if (x_dnd_wanted_action != None) |
| @@ -11606,6 +11628,19 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 11606 | && x_dnd_last_seen_window != FRAME_X_WINDOW (x_dnd_frame)) | 11628 | && x_dnd_last_seen_window != FRAME_X_WINDOW (x_dnd_frame)) |
| 11607 | x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window); | 11629 | x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window); |
| 11608 | 11630 | ||
| 11631 | if (x_dnd_last_seen_window == FRAME_X_WINDOW (x_dnd_frame) | ||
| 11632 | && x_dnd_return_frame == 1) | ||
| 11633 | x_dnd_return_frame = 2; | ||
| 11634 | |||
| 11635 | if (x_dnd_return_frame == 2 | ||
| 11636 | && x_window_to_frame (dpyinfo, target)) | ||
| 11637 | { | ||
| 11638 | x_dnd_in_progress = false; | ||
| 11639 | x_dnd_return_frame_object | ||
| 11640 | = x_window_to_frame (dpyinfo, target); | ||
| 11641 | x_dnd_return_frame = 3; | ||
| 11642 | } | ||
| 11643 | |||
| 11609 | x_dnd_wanted_action = None; | 11644 | x_dnd_wanted_action = None; |
| 11610 | x_dnd_last_seen_window = target; | 11645 | x_dnd_last_seen_window = target; |
| 11611 | x_dnd_last_protocol_version | 11646 | x_dnd_last_protocol_version |
| @@ -12825,6 +12860,19 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 12825 | && x_dnd_last_seen_window != FRAME_X_WINDOW (x_dnd_frame)) | 12860 | && x_dnd_last_seen_window != FRAME_X_WINDOW (x_dnd_frame)) |
| 12826 | x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window); | 12861 | x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window); |
| 12827 | 12862 | ||
| 12863 | if (x_dnd_last_seen_window == FRAME_X_WINDOW (x_dnd_frame) | ||
| 12864 | && x_dnd_return_frame == 1) | ||
| 12865 | x_dnd_return_frame = 2; | ||
| 12866 | |||
| 12867 | if (x_dnd_return_frame == 2 | ||
| 12868 | && x_window_to_frame (dpyinfo, target)) | ||
| 12869 | { | ||
| 12870 | x_dnd_in_progress = false; | ||
| 12871 | x_dnd_return_frame_object | ||
| 12872 | = x_window_to_frame (dpyinfo, target); | ||
| 12873 | x_dnd_return_frame = 3; | ||
| 12874 | } | ||
| 12875 | |||
| 12828 | x_dnd_last_seen_window = target; | 12876 | x_dnd_last_seen_window = target; |
| 12829 | x_dnd_last_protocol_version | 12877 | x_dnd_last_protocol_version |
| 12830 | = x_dnd_get_window_proto (dpyinfo, target); | 12878 | = x_dnd_get_window_proto (dpyinfo, target); |
diff --git a/src/xterm.h b/src/xterm.h index 225aaf4cad5..9665e92a9fb 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -1367,7 +1367,8 @@ extern void x_scroll_bar_configure (GdkEvent *); | |||
| 1367 | 1367 | ||
| 1368 | extern void x_display_set_last_user_time (struct x_display_info *, Time); | 1368 | extern void x_display_set_last_user_time (struct x_display_info *, Time); |
| 1369 | 1369 | ||
| 1370 | extern Lisp_Object x_dnd_begin_drag_and_drop (struct frame *, Time, Atom); | 1370 | extern Lisp_Object x_dnd_begin_drag_and_drop (struct frame *, Time, Atom, |
| 1371 | bool); | ||
| 1371 | extern void x_set_dnd_targets (Atom *, int); | 1372 | extern void x_set_dnd_targets (Atom *, int); |
| 1372 | 1373 | ||
| 1373 | INLINE int | 1374 | INLINE int |