diff options
| author | Po Lu | 2022-06-09 13:11:08 +0800 |
|---|---|---|
| committer | Po Lu | 2022-06-09 13:11:08 +0800 |
| commit | 2f31dbeadff0abc38ded5dd072df1ec179c49945 (patch) | |
| tree | 5e3a0da965fa681348bb48d045d9d94f8edbaea0 | |
| parent | 7e41b4aa231ed094613fe0ea12e7ec37a396240f (diff) | |
| download | emacs-2f31dbeadff0abc38ded5dd072df1ec179c49945.tar.gz emacs-2f31dbeadff0abc38ded5dd072df1ec179c49945.zip | |
Also show mouse DND tooltip contents during interprogram drag-and-drop
* doc/lispref/frames.texi (Drag and Drop): Document new
parameter to `x-begin-drag'.
* lisp/mouse.el (mouse-drag-and-drop-region): Don't hide tooltip
when initiating interprogram drag-and-drop.
* lisp/term/haiku-win.el (x-begin-drag):
* lisp/term/ns-win.el (x-begin-drag): Add stubs for new
parameter.
* src/xfns.c (Fx_begin_drag): New parameter `follow-tooltip'.
(Fx_show_tip, syms_of_xfns): Add records of the last dx and dy
given to `x-show-tip'.
* src/xterm.c (x_clear_dnd_monitors): New function.
(x_dnd_begin_drag_and_drop): Save monitor attributes list if
appropriate.
(x_dnd_compute_tip_xy, x_dnd_update_tooltip_position): New
function.
(x_dnd_update_state, handle_one_xevent): Update tooltip position
during DND mouse movement.
(syms_of_xterm): Update staticpros.
* src/xterm.h: Update prototypes.
| -rw-r--r-- | doc/lispref/frames.texi | 8 | ||||
| -rw-r--r-- | lisp/mouse.el | 3 | ||||
| -rw-r--r-- | lisp/term/haiku-win.el | 3 | ||||
| -rw-r--r-- | lisp/term/ns-win.el | 3 | ||||
| -rw-r--r-- | src/xfns.c | 23 | ||||
| -rw-r--r-- | src/xterm.c | 153 | ||||
| -rw-r--r-- | src/xterm.h | 5 |
7 files changed, 187 insertions, 11 deletions
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 9f7666ac63c..16f7ad312a4 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi | |||
| @@ -4194,7 +4194,7 @@ instead. However, using it will require detailed knowledge of the | |||
| 4194 | data types and actions used by the programs to transfer content via | 4194 | data types and actions used by the programs to transfer content via |
| 4195 | drag-and-drop on each platform you want to support. | 4195 | drag-and-drop on each platform you want to support. |
| 4196 | 4196 | ||
| 4197 | @defun x-begin-drag targets &optional action frame return-frame allow-current-frame | 4197 | @defun x-begin-drag targets &optional action frame return-frame allow-current-frame follow-tooltip |
| 4198 | This function begins a drag from @var{frame}, and returns when the | 4198 | This function begins a drag from @var{frame}, and returns when the |
| 4199 | drag-and-drop operation ends, either because the drop was successful, | 4199 | drag-and-drop operation ends, either because the drop was successful, |
| 4200 | or because the drop was rejected. The drop occurs when all mouse | 4200 | or because the drop was rejected. The drop occurs when all mouse |
| @@ -4231,6 +4231,12 @@ want to treat dragging content from one frame to another specially, | |||
| 4231 | while also being able to drag content to other programs, but it is not | 4231 | while also being able to drag content to other programs, but it is not |
| 4232 | guaranteed to work on all systems and with all window managers. | 4232 | guaranteed to work on all systems and with all window managers. |
| 4233 | 4233 | ||
| 4234 | If @var{follow-tooltip} is non-@code{nil}, the position of any tooltip | ||
| 4235 | (such as one shown by @code{tooltip-show}) will follow the location of | ||
| 4236 | the mouse pointer whenever it moves during the drag-and-drop | ||
| 4237 | operation. The tooltip will be hidden once all mouse buttons are | ||
| 4238 | released. | ||
| 4239 | |||
| 4234 | If the drop was rejected or no drop target was found, this function | 4240 | If the drop was rejected or no drop target was found, this function |
| 4235 | returns @code{nil}. Otherwise, it returns a symbol describing the | 4241 | returns @code{nil}. Otherwise, it returns a symbol describing the |
| 4236 | action the target chose to perform, which can differ from @var{action} | 4242 | action the target chose to perform, which can differ from @var{action} |
diff --git a/lisp/mouse.el b/lisp/mouse.el index 024a018bb91..6a2b1738f71 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el | |||
| @@ -3244,7 +3244,6 @@ is copied instead of being cut." | |||
| 3244 | (cdr mouse-position))))))) | 3244 | (cdr mouse-position))))))) |
| 3245 | (not (posn-window (event-end event)))))) | 3245 | (not (posn-window (event-end event)))))) |
| 3246 | (setq drag-again-mouse-position nil) | 3246 | (setq drag-again-mouse-position nil) |
| 3247 | (mouse-drag-and-drop-region-hide-tooltip) | ||
| 3248 | (gui-set-selection 'XdndSelection value-selection) | 3247 | (gui-set-selection 'XdndSelection value-selection) |
| 3249 | (let ((drag-action-or-frame | 3248 | (let ((drag-action-or-frame |
| 3250 | (condition-case nil | 3249 | (condition-case nil |
| @@ -3259,7 +3258,7 @@ is copied instead of being cut." | |||
| 3259 | ;; `return-frame' doesn't | 3258 | ;; `return-frame' doesn't |
| 3260 | ;; work, allow dropping on | 3259 | ;; work, allow dropping on |
| 3261 | ;; the drop frame. | 3260 | ;; the drop frame. |
| 3262 | (eq window-system 'haiku)) | 3261 | (eq window-system 'haiku) t) |
| 3263 | (quit nil)))) | 3262 | (quit nil)))) |
| 3264 | (when (framep drag-action-or-frame) | 3263 | (when (framep drag-action-or-frame) |
| 3265 | ;; With some window managers `x-begin-drag' | 3264 | ;; With some window managers `x-begin-drag' |
diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el index 6ddf546ee57..58217513902 100644 --- a/lisp/term/haiku-win.el +++ b/lisp/term/haiku-win.el | |||
| @@ -366,7 +366,8 @@ take effect on menu items until the menu bar is updated again." | |||
| 366 | 366 | ||
| 367 | (setq haiku-drag-track-function #'haiku-dnd-drag-handler) | 367 | (setq haiku-drag-track-function #'haiku-dnd-drag-handler) |
| 368 | 368 | ||
| 369 | (defun x-begin-drag (targets &optional action frame _return-frame allow-current-frame) | 369 | (defun x-begin-drag (targets &optional action frame _return-frame |
| 370 | allow-current-frame _follow-tooltip) | ||
| 370 | "SKIP: real doc in xfns.c." | 371 | "SKIP: real doc in xfns.c." |
| 371 | (unless haiku-dnd-selection-value | 372 | (unless haiku-dnd-selection-value |
| 372 | (error "No local value for XdndSelection")) | 373 | (error "No local value for XdndSelection")) |
diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el index 2e021b9b29c..0d46a895ce8 100644 --- a/lisp/term/ns-win.el +++ b/lisp/term/ns-win.el | |||
| @@ -895,7 +895,8 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.") | |||
| 895 | &context (window-system ns)) | 895 | &context (window-system ns)) |
| 896 | (ns-get-selection selection-symbol target-type)) | 896 | (ns-get-selection selection-symbol target-type)) |
| 897 | 897 | ||
| 898 | (defun x-begin-drag (targets &optional action frame return-frame allow-current-frame) | 898 | (defun x-begin-drag (targets &optional action frame return-frame |
| 899 | allow-current-frame _follow-tooltip) | ||
| 899 | "SKIP: real doc in xfns.c." | 900 | "SKIP: real doc in xfns.c." |
| 900 | (unless ns-dnd-selection-value | 901 | (unless ns-dnd-selection-value |
| 901 | (error "No local value for XdndSelection")) | 902 | (error "No local value for XdndSelection")) |
diff --git a/src/xfns.c b/src/xfns.c index f0a2ec666c9..15e96183e3b 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -6831,7 +6831,7 @@ The coordinates X and Y are interpreted in pixels relative to a position | |||
| 6831 | return Qnil; | 6831 | return Qnil; |
| 6832 | } | 6832 | } |
| 6833 | 6833 | ||
| 6834 | DEFUN ("x-begin-drag", Fx_begin_drag, Sx_begin_drag, 1, 5, 0, | 6834 | DEFUN ("x-begin-drag", Fx_begin_drag, Sx_begin_drag, 1, 6, 0, |
| 6835 | doc: /* Begin dragging contents on FRAME, with targets TARGETS. | 6835 | doc: /* Begin dragging contents on FRAME, with targets TARGETS. |
| 6836 | TARGETS is a list of strings, which defines the X selection targets | 6836 | TARGETS is a list of strings, which defines the X selection targets |
| 6837 | that will be available to the drop target. Block until the mouse | 6837 | that will be available to the drop target. Block until the mouse |
| @@ -6882,12 +6882,17 @@ If ALLOW-CURRENT-FRAME is not specified or nil, then the drop target | |||
| 6882 | is allowed to be FRAME. Otherwise, no action will be taken if the | 6882 | is allowed to be FRAME. Otherwise, no action will be taken if the |
| 6883 | mouse buttons are released on top of FRAME. | 6883 | mouse buttons are released on top of FRAME. |
| 6884 | 6884 | ||
| 6885 | If FOLLOW-TOOLTIP is non-nil, any tooltip currently being displayed | ||
| 6886 | will be moved to follow the mouse pointer while the drag is in | ||
| 6887 | progress. | ||
| 6888 | |||
| 6885 | This function will sometimes return immediately if no mouse buttons | 6889 | This function will sometimes return immediately if no mouse buttons |
| 6886 | are currently held down. It should only be called when it is known | 6890 | are currently held down. It should only be called when it is known |
| 6887 | that mouse buttons are being held down, such as immediately after a | 6891 | that mouse buttons are being held down, such as immediately after a |
| 6888 | `down-mouse-1' (or similar) event. */) | 6892 | `down-mouse-1' (or similar) event. */) |
| 6889 | (Lisp_Object targets, Lisp_Object action, Lisp_Object frame, | 6893 | (Lisp_Object targets, Lisp_Object action, Lisp_Object frame, |
| 6890 | Lisp_Object return_frame, Lisp_Object allow_current_frame) | 6894 | Lisp_Object return_frame, Lisp_Object allow_current_frame, |
| 6895 | Lisp_Object follow_tooltip) | ||
| 6891 | { | 6896 | { |
| 6892 | struct frame *f = decode_window_system_frame (frame); | 6897 | struct frame *f = decode_window_system_frame (frame); |
| 6893 | int ntargets = 0, nnames = 0; | 6898 | int ntargets = 0, nnames = 0; |
| @@ -6985,7 +6990,7 @@ that mouse buttons are being held down, such as immediately after a | |||
| 6985 | xaction, return_frame, action_list, | 6990 | xaction, return_frame, action_list, |
| 6986 | (const char **) &name_list, nnames, | 6991 | (const char **) &name_list, nnames, |
| 6987 | !NILP (allow_current_frame), target_atoms, | 6992 | !NILP (allow_current_frame), target_atoms, |
| 6988 | ntargets, original); | 6993 | ntargets, original, !NILP (follow_tooltip)); |
| 6989 | 6994 | ||
| 6990 | SAFE_FREE (); | 6995 | SAFE_FREE (); |
| 6991 | return lval; | 6996 | return lval; |
| @@ -7787,12 +7792,15 @@ static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object, | |||
| 7787 | Lisp_Object, int, int, int *, int *); | 7792 | Lisp_Object, int, int, int *, int *); |
| 7788 | 7793 | ||
| 7789 | /* The frame of the currently visible tooltip, or nil if none. */ | 7794 | /* The frame of the currently visible tooltip, or nil if none. */ |
| 7790 | static Lisp_Object tip_frame; | 7795 | Lisp_Object tip_frame; |
| 7791 | 7796 | ||
| 7792 | /* The window-system window corresponding to the frame of the | 7797 | /* The window-system window corresponding to the frame of the |
| 7793 | currently visible tooltip. */ | 7798 | currently visible tooltip. */ |
| 7794 | Window tip_window; | 7799 | Window tip_window; |
| 7795 | 7800 | ||
| 7801 | /* The X and Y deltas of the last call to `x-show-tip'. */ | ||
| 7802 | Lisp_Object tip_dx, tip_dy; | ||
| 7803 | |||
| 7796 | /* A timer that hides or deletes the currently visible tooltip when it | 7804 | /* A timer that hides or deletes the currently visible tooltip when it |
| 7797 | fires. */ | 7805 | fires. */ |
| 7798 | static Lisp_Object tip_timer; | 7806 | static Lisp_Object tip_timer; |
| @@ -8506,6 +8514,9 @@ Text larger than the specified size is clipped. */) | |||
| 8506 | else | 8514 | else |
| 8507 | CHECK_FIXNUM (dy); | 8515 | CHECK_FIXNUM (dy); |
| 8508 | 8516 | ||
| 8517 | tip_dx = dx; | ||
| 8518 | tip_dy = dy; | ||
| 8519 | |||
| 8509 | #ifdef USE_GTK | 8520 | #ifdef USE_GTK |
| 8510 | if (use_system_tooltips) | 8521 | if (use_system_tooltips) |
| 8511 | { | 8522 | { |
| @@ -9931,6 +9942,10 @@ eliminated in future versions of Emacs. */); | |||
| 9931 | staticpro (&tip_last_string); | 9942 | staticpro (&tip_last_string); |
| 9932 | tip_last_parms = Qnil; | 9943 | tip_last_parms = Qnil; |
| 9933 | staticpro (&tip_last_parms); | 9944 | staticpro (&tip_last_parms); |
| 9945 | tip_dx = Qnil; | ||
| 9946 | staticpro (&tip_dx); | ||
| 9947 | tip_dy = Qnil; | ||
| 9948 | staticpro (&tip_dy); | ||
| 9934 | 9949 | ||
| 9935 | defsubr (&Sx_uses_old_gtk_dialog); | 9950 | defsubr (&Sx_uses_old_gtk_dialog); |
| 9936 | #if defined (USE_MOTIF) || defined (USE_GTK) | 9951 | #if defined (USE_MOTIF) || defined (USE_GTK) |
diff --git a/src/xterm.c b/src/xterm.c index 3cc730c4eeb..557555e7a4d 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -1104,6 +1104,13 @@ struct frame *x_dnd_finish_frame; | |||
| 1104 | important information. */ | 1104 | important information. */ |
| 1105 | bool x_dnd_waiting_for_finish; | 1105 | bool x_dnd_waiting_for_finish; |
| 1106 | 1106 | ||
| 1107 | /* Whether or not to move the tooltip along with the mouse pointer | ||
| 1108 | during drag-and-drop. */ | ||
| 1109 | static bool x_dnd_update_tooltip; | ||
| 1110 | |||
| 1111 | /* Monitor attribute list used for updating the tooltip position. */ | ||
| 1112 | static Lisp_Object x_dnd_monitors; | ||
| 1113 | |||
| 1107 | /* The display the drop target that is supposed to send information is | 1114 | /* The display the drop target that is supposed to send information is |
| 1108 | on. */ | 1115 | on. */ |
| 1109 | static Display *x_dnd_finish_display; | 1116 | static Display *x_dnd_finish_display; |
| @@ -4190,6 +4197,12 @@ x_free_dnd_targets (void) | |||
| 4190 | } | 4197 | } |
| 4191 | 4198 | ||
| 4192 | static void | 4199 | static void |
| 4200 | x_clear_dnd_monitors (void) | ||
| 4201 | { | ||
| 4202 | x_dnd_monitors = Qnil; | ||
| 4203 | } | ||
| 4204 | |||
| 4205 | static void | ||
| 4193 | x_free_dnd_toplevels (void) | 4206 | x_free_dnd_toplevels (void) |
| 4194 | { | 4207 | { |
| 4195 | if (!x_dnd_use_toplevels || !x_dnd_toplevels) | 4208 | if (!x_dnd_use_toplevels || !x_dnd_toplevels) |
| @@ -10738,7 +10751,8 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 10738 | Lisp_Object return_frame, Atom *ask_action_list, | 10751 | Lisp_Object return_frame, Atom *ask_action_list, |
| 10739 | const char **ask_action_names, size_t n_ask_actions, | 10752 | const char **ask_action_names, size_t n_ask_actions, |
| 10740 | bool allow_current_frame, Atom *target_atoms, | 10753 | bool allow_current_frame, Atom *target_atoms, |
| 10741 | int ntargets, Lisp_Object selection_target_list) | 10754 | int ntargets, Lisp_Object selection_target_list, |
| 10755 | bool follow_tooltip) | ||
| 10742 | { | 10756 | { |
| 10743 | #ifndef USE_GTK | 10757 | #ifndef USE_GTK |
| 10744 | XEvent next_event; | 10758 | XEvent next_event; |
| @@ -10941,6 +10955,15 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction, | |||
| 10941 | unblock_input (); | 10955 | unblock_input (); |
| 10942 | } | 10956 | } |
| 10943 | 10957 | ||
| 10958 | if (follow_tooltip) | ||
| 10959 | { | ||
| 10960 | x_dnd_monitors | ||
| 10961 | = Fx_display_monitor_attributes_list (frame); | ||
| 10962 | record_unwind_protect_void (x_clear_dnd_monitors); | ||
| 10963 | } | ||
| 10964 | |||
| 10965 | x_dnd_update_tooltip = follow_tooltip; | ||
| 10966 | |||
| 10944 | /* This shouldn't happen. */ | 10967 | /* This shouldn't happen. */ |
| 10945 | if (x_dnd_toplevels) | 10968 | if (x_dnd_toplevels) |
| 10946 | x_dnd_free_toplevels (true); | 10969 | x_dnd_free_toplevels (true); |
| @@ -15131,6 +15154,106 @@ mouse_or_wdesc_frame (struct x_display_info *dpyinfo, int wdesc) | |||
| 15131 | } | 15154 | } |
| 15132 | } | 15155 | } |
| 15133 | 15156 | ||
| 15157 | static void | ||
| 15158 | x_dnd_compute_tip_xy (int *root_x, int *root_y, Lisp_Object attributes) | ||
| 15159 | { | ||
| 15160 | Lisp_Object monitor, geometry; | ||
| 15161 | int min_x, min_y, max_x, max_y; | ||
| 15162 | int width, height; | ||
| 15163 | |||
| 15164 | width = FRAME_PIXEL_WIDTH (XFRAME (tip_frame)); | ||
| 15165 | height = FRAME_PIXEL_HEIGHT (XFRAME (tip_frame)); | ||
| 15166 | |||
| 15167 | max_y = -1; | ||
| 15168 | |||
| 15169 | /* Try to determine the monitor where the mouse pointer is and | ||
| 15170 | its geometry. See bug#22549. */ | ||
| 15171 | while (CONSP (attributes)) | ||
| 15172 | { | ||
| 15173 | monitor = XCAR (attributes); | ||
| 15174 | geometry = assq_no_quit (Qgeometry, monitor); | ||
| 15175 | |||
| 15176 | if (CONSP (geometry)) | ||
| 15177 | { | ||
| 15178 | min_x = XFIXNUM (Fnth (make_fixnum (1), geometry)); | ||
| 15179 | min_y = XFIXNUM (Fnth (make_fixnum (2), geometry)); | ||
| 15180 | max_x = min_x + XFIXNUM (Fnth (make_fixnum (3), geometry)); | ||
| 15181 | max_y = min_y + XFIXNUM (Fnth (make_fixnum (4), geometry)); | ||
| 15182 | |||
| 15183 | if (min_x <= *root_x && *root_x < max_x | ||
| 15184 | && min_y <= *root_y && *root_y < max_y) | ||
| 15185 | break; | ||
| 15186 | |||
| 15187 | max_y = -1; | ||
| 15188 | } | ||
| 15189 | |||
| 15190 | attributes = XCDR (attributes); | ||
| 15191 | } | ||
| 15192 | |||
| 15193 | /* It was not possible to determine the monitor's geometry, so we | ||
| 15194 | assign some sane defaults here: */ | ||
| 15195 | if (max_y < 0) | ||
| 15196 | { | ||
| 15197 | min_x = 0; | ||
| 15198 | min_y = 0; | ||
| 15199 | max_x = x_display_pixel_width (FRAME_DISPLAY_INFO (x_dnd_frame)); | ||
| 15200 | max_y = x_display_pixel_height (FRAME_DISPLAY_INFO (x_dnd_frame)); | ||
| 15201 | } | ||
| 15202 | |||
| 15203 | if (*root_y + XFIXNUM (tip_dy) <= min_y) | ||
| 15204 | *root_y = min_y; /* Can happen for negative dy */ | ||
| 15205 | else if (*root_y + XFIXNUM (tip_dy) + height <= max_y) | ||
| 15206 | /* It fits below the pointer */ | ||
| 15207 | *root_y += XFIXNUM (tip_dy); | ||
| 15208 | else if (height + XFIXNUM (tip_dy) + min_y <= *root_y) | ||
| 15209 | /* It fits above the pointer. */ | ||
| 15210 | *root_y -= height + XFIXNUM (tip_dy); | ||
| 15211 | else | ||
| 15212 | /* Put it on the top. */ | ||
| 15213 | *root_y = min_y; | ||
| 15214 | |||
| 15215 | if (*root_x + XFIXNUM (tip_dx) <= min_x) | ||
| 15216 | *root_x = 0; /* Can happen for negative dx */ | ||
| 15217 | else if (*root_x + XFIXNUM (tip_dx) + width <= max_x) | ||
| 15218 | /* It fits to the right of the pointer. */ | ||
| 15219 | *root_x += XFIXNUM (tip_dx); | ||
| 15220 | else if (width + XFIXNUM (tip_dx) + min_x <= *root_x) | ||
| 15221 | /* It fits to the left of the pointer. */ | ||
| 15222 | *root_x -= width + XFIXNUM (tip_dx); | ||
| 15223 | else | ||
| 15224 | /* Put it left justified on the screen -- it ought to fit that way. */ | ||
| 15225 | *root_x = min_x; | ||
| 15226 | } | ||
| 15227 | |||
| 15228 | static void | ||
| 15229 | x_dnd_update_tooltip_position (int root_x, int root_y) | ||
| 15230 | { | ||
| 15231 | struct frame *tip_f; | ||
| 15232 | |||
| 15233 | if (!x_dnd_in_progress || !x_dnd_update_tooltip) | ||
| 15234 | return; | ||
| 15235 | |||
| 15236 | if (!FRAMEP (tip_frame)) | ||
| 15237 | return; | ||
| 15238 | |||
| 15239 | tip_f = XFRAME (tip_frame); | ||
| 15240 | |||
| 15241 | if (!FRAME_LIVE_P (tip_f) | ||
| 15242 | || (FRAME_X_DISPLAY (tip_f) | ||
| 15243 | != FRAME_X_DISPLAY (x_dnd_frame))) | ||
| 15244 | return; | ||
| 15245 | |||
| 15246 | if (tip_window != None | ||
| 15247 | && FIXNUMP (tip_dx) && FIXNUMP (tip_dy)) | ||
| 15248 | { | ||
| 15249 | x_dnd_compute_tip_xy (&root_x, &root_y, | ||
| 15250 | x_dnd_monitors); | ||
| 15251 | |||
| 15252 | XMoveWindow (FRAME_X_DISPLAY (x_dnd_frame), | ||
| 15253 | tip_window, root_x, root_y); | ||
| 15254 | } | ||
| 15255 | } | ||
| 15256 | |||
| 15134 | /* Get the window underneath the pointer, see if it moved, and update | 15257 | /* Get the window underneath the pointer, see if it moved, and update |
| 15135 | the DND state accordingly. */ | 15258 | the DND state accordingly. */ |
| 15136 | static void | 15259 | static void |
| @@ -15292,6 +15415,8 @@ x_dnd_update_state (struct x_display_info *dpyinfo, Time timestamp) | |||
| 15292 | xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame), | 15415 | xm_send_drag_motion_message (dpyinfo, FRAME_X_WINDOW (x_dnd_frame), |
| 15293 | target, &dmsg); | 15416 | target, &dmsg); |
| 15294 | } | 15417 | } |
| 15418 | |||
| 15419 | x_dnd_update_tooltip_position (root_x, root_y); | ||
| 15295 | } | 15420 | } |
| 15296 | /* The pointer moved out of the screen. */ | 15421 | /* The pointer moved out of the screen. */ |
| 15297 | else if (x_dnd_last_protocol_version != -1) | 15422 | else if (x_dnd_last_protocol_version != -1) |
| @@ -17462,6 +17587,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17462 | target, &dmsg); | 17587 | target, &dmsg); |
| 17463 | } | 17588 | } |
| 17464 | 17589 | ||
| 17590 | x_dnd_update_tooltip_position (event->xmotion.x_root, | ||
| 17591 | event->xmotion.y_root); | ||
| 17592 | |||
| 17465 | goto OTHER; | 17593 | goto OTHER; |
| 17466 | } | 17594 | } |
| 17467 | 17595 | ||
| @@ -17966,6 +18094,14 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 17966 | { | 18094 | { |
| 17967 | x_dnd_end_window = x_dnd_last_seen_window; | 18095 | x_dnd_end_window = x_dnd_last_seen_window; |
| 17968 | x_dnd_in_progress = false; | 18096 | x_dnd_in_progress = false; |
| 18097 | |||
| 18098 | if (x_dnd_update_tooltip | ||
| 18099 | && FRAMEP (tip_frame) | ||
| 18100 | && FRAME_LIVE_P (XFRAME (tip_frame)) | ||
| 18101 | && (FRAME_X_DISPLAY (XFRAME (tip_frame)) | ||
| 18102 | == FRAME_X_DISPLAY (x_dnd_frame))) | ||
| 18103 | Fx_hide_tip (); | ||
| 18104 | |||
| 17969 | x_dnd_finish_frame = x_dnd_frame; | 18105 | x_dnd_finish_frame = x_dnd_frame; |
| 17970 | 18106 | ||
| 17971 | if (x_dnd_last_seen_window != None | 18107 | if (x_dnd_last_seen_window != None |
| @@ -19172,6 +19308,8 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 19172 | target, &dmsg); | 19308 | target, &dmsg); |
| 19173 | } | 19309 | } |
| 19174 | 19310 | ||
| 19311 | x_dnd_update_tooltip_position (xev->root_x, xev->root_y); | ||
| 19312 | |||
| 19175 | goto XI_OTHER; | 19313 | goto XI_OTHER; |
| 19176 | } | 19314 | } |
| 19177 | 19315 | ||
| @@ -19332,6 +19470,16 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 19332 | x_dnd_end_window = x_dnd_last_seen_window; | 19470 | x_dnd_end_window = x_dnd_last_seen_window; |
| 19333 | x_dnd_in_progress = false; | 19471 | x_dnd_in_progress = false; |
| 19334 | 19472 | ||
| 19473 | /* If a tooltip that we're following is | ||
| 19474 | displayed, hide it now. */ | ||
| 19475 | |||
| 19476 | if (x_dnd_update_tooltip | ||
| 19477 | && FRAMEP (tip_frame) | ||
| 19478 | && FRAME_LIVE_P (XFRAME (tip_frame)) | ||
| 19479 | && (FRAME_X_DISPLAY (XFRAME (tip_frame)) | ||
| 19480 | == FRAME_X_DISPLAY (x_dnd_frame))) | ||
| 19481 | Fx_hide_tip (); | ||
| 19482 | |||
| 19335 | /* This doesn't have to be marked since it | 19483 | /* This doesn't have to be marked since it |
| 19336 | is only accessed if | 19484 | is only accessed if |
| 19337 | x_dnd_waiting_for_finish is true, which | 19485 | x_dnd_waiting_for_finish is true, which |
| @@ -26645,6 +26793,9 @@ syms_of_xterm (void) | |||
| 26645 | x_error_message = NULL; | 26793 | x_error_message = NULL; |
| 26646 | PDUMPER_IGNORE (x_error_message); | 26794 | PDUMPER_IGNORE (x_error_message); |
| 26647 | 26795 | ||
| 26796 | x_dnd_monitors = Qnil; | ||
| 26797 | staticpro (&x_dnd_monitors); | ||
| 26798 | |||
| 26648 | DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms"); | 26799 | DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms"); |
| 26649 | DEFSYM (Qlatin_1, "latin-1"); | 26800 | DEFSYM (Qlatin_1, "latin-1"); |
| 26650 | DEFSYM (Qnow, "now"); | 26801 | DEFSYM (Qnow, "now"); |
diff --git a/src/xterm.h b/src/xterm.h index 7e91e28ed13..25d145c6c0a 100644 --- a/src/xterm.h +++ b/src/xterm.h | |||
| @@ -736,6 +736,9 @@ extern bool x_display_ok (const char *); | |||
| 736 | extern void select_visual (struct x_display_info *); | 736 | extern void select_visual (struct x_display_info *); |
| 737 | 737 | ||
| 738 | extern Window tip_window; | 738 | extern Window tip_window; |
| 739 | extern Lisp_Object tip_dx; | ||
| 740 | extern Lisp_Object tip_dy; | ||
| 741 | extern Lisp_Object tip_frame; | ||
| 739 | 742 | ||
| 740 | /* Each X frame object points to its own struct x_output object | 743 | /* Each X frame object points to its own struct x_output object |
| 741 | in the output_data.x field. The x_output structure contains | 744 | in the output_data.x field. The x_output structure contains |
| @@ -1467,7 +1470,7 @@ extern bool x_detect_pending_selection_requests (void); | |||
| 1467 | extern Lisp_Object x_dnd_begin_drag_and_drop (struct frame *, Time, Atom, | 1470 | extern Lisp_Object x_dnd_begin_drag_and_drop (struct frame *, Time, Atom, |
| 1468 | Lisp_Object, Atom *, const char **, | 1471 | Lisp_Object, Atom *, const char **, |
| 1469 | size_t, bool, Atom *, int, | 1472 | size_t, bool, Atom *, int, |
| 1470 | Lisp_Object); | 1473 | Lisp_Object, bool); |
| 1471 | extern void x_dnd_do_unsupported_drop (struct x_display_info *, Lisp_Object, | 1474 | extern void x_dnd_do_unsupported_drop (struct x_display_info *, Lisp_Object, |
| 1472 | Lisp_Object, Lisp_Object, Window, int, | 1475 | Lisp_Object, Lisp_Object, Window, int, |
| 1473 | int, Time); | 1476 | int, Time); |