(when mark-active
(deactivate-mark))
(save-excursion
- (goto-char (posn-point (event-end event)))
+ (with-selected-window (posn-window (event-end event))
+ (goto-char (posn-point (event-end event))))
(track-mouse
(let ((new-event (read-event)))
(if (not (eq (event-basic-type new-event) 'mouse-movement))
(condition-case nil
(progn
(gui-backend-set-selection 'XdndSelection
- (dired-file-name-at-point))
+ (with-selected-window (posn-window
+ (event-end event))
+ (dired-file-name-at-point)))
(x-begin-drag '("text/uri-list"
"text/x-dnd-username")
(if (eq 'dired-mouse-drag-files 'link)
the action we want for the drop,
any protocol specific data.")
+(declare-function x-get-selection-internal "xselect.c"
+ (selection-symbol target-type &optional time-stamp terminal))
+
(defvar x-dnd-empty-state [nil nil nil nil nil nil nil])
(declare-function x-register-dnd-atom "xselect.c")
Currently XDND, Motif and old KDE 1.x protocols are recognized."
(interactive "e")
(let* ((client-message (car (cdr (cdr event))))
- (window (posn-window (event-start event)))
- (message-atom (aref client-message 0))
- (frame (aref client-message 1))
- (format (aref client-message 2))
- (data (aref client-message 3)))
-
- (cond ((equal "DndProtocol" message-atom) ; Old KDE 1.x.
- (x-dnd-handle-old-kde event frame window message-atom format data))
-
- ((equal "_MOTIF_DRAG_AND_DROP_MESSAGE" message-atom) ; Motif
- (x-dnd-handle-motif event frame window message-atom format data))
-
- ((and (> (length message-atom) 4) ; XDND protocol.
- (equal "Xdnd" (substring message-atom 0 4)))
- (x-dnd-handle-xdnd event frame window message-atom format data)))))
+ (window (posn-window (event-start event))))
+ (if (eq (and (consp client-message)
+ (car client-message))
+ 'XdndSelection)
+ ;; This is an internal Emacs message caused by something being
+ ;; dropped on top of a frame.
+ (progn
+ (let ((action (cdr (assoc (symbol-name (cadr client-message))
+ x-dnd-xdnd-to-action)))
+ (targets (cddr client-message)))
+ (x-dnd-save-state window nil nil
+ (apply #'vector targets))
+ (x-dnd-maybe-call-test-function window action)
+ (unwind-protect
+ (x-dnd-drop-data event (if (framep window) window
+ (window-frame window))
+ window
+ (x-get-selection-internal
+ 'XdndSelection
+ (intern (x-dnd-current-type window)))
+ (x-dnd-current-type window))
+ (x-dnd-forget-drop window))))
+ (let ((message-atom (aref client-message 0))
+ (frame (aref client-message 1))
+ (format (aref client-message 2))
+ (data (aref client-message 3)))
+ (cond ((equal "DndProtocol" message-atom) ; Old KDE 1.x.
+ (x-dnd-handle-old-kde event frame window message-atom format data))
+
+ ((equal "_MOTIF_DRAG_AND_DROP_MESSAGE" message-atom) ; Motif
+ (x-dnd-handle-motif event frame window message-atom format data))
+
+ ((and (> (length message-atom) 4) ; XDND protocol.
+ (equal "Xdnd" (substring message-atom 0 4)))
+ (x-dnd-handle-xdnd event frame window message-atom format data)))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(declare-function x-get-atom-name "xselect.c" (value &optional frame))
(declare-function x-send-client-message "xselect.c"
(display dest from message-type format values))
-(declare-function x-get-selection-internal "xselect.c"
- (selection-symbol target-type &optional time-stamp terminal))
(defun x-dnd-version-from-flags (flags)
"Return the version byte from the 32 bit FLAGS in an XDndEnter message."
int i;
XEvent msg;
+ if (x_top_window_to_frame (dpyinfo, target))
+ return;
+
msg.xclient.type = ClientMessage;
msg.xclient.message_type = dpyinfo->Xatom_XdndEnter;
msg.xclient.format = 32;
return;
}
+ if (x_top_window_to_frame (dpyinfo, target))
+ return;
+
msg.xclient.type = ClientMessage;
msg.xclient.message_type = dpyinfo->Xatom_XdndPosition;
msg.xclient.format = 32;
struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
XEvent msg;
+ if (x_top_window_to_frame (dpyinfo, target))
+ return;
+
msg.xclient.type = ClientMessage;
msg.xclient.message_type = dpyinfo->Xatom_XdndLeave;
msg.xclient.format = 32;
{
struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
XEvent msg;
+ struct input_event ie;
+ struct frame *self_frame;
+ int root_x, root_y, win_x, win_y, i;
+ unsigned int mask;
+ Window root, child;
+ Lisp_Object lval;
+ char **atom_names;
+ char *name;
+
+ self_frame = x_top_window_to_frame (dpyinfo, target);
+
+ if (self_frame)
+ {
+ /* Send a special drag-and-drop event when dropping on top of an
+ Emacs frame to avoid all the overhead involved with sending
+ client events. */
+ EVENT_INIT (ie);
+
+ if (XQueryPointer (dpyinfo->display, FRAME_X_WINDOW (self_frame),
+ &root, &child, &root_x, &root_y, &win_x, &win_y,
+ &mask))
+ {
+ ie.kind = DRAG_N_DROP_EVENT;
+ XSETFRAME (ie.frame_or_window, self_frame);
+
+ lval = Qnil;
+ atom_names = alloca (x_dnd_n_targets * sizeof *atom_names);
+ name = XGetAtomName (dpyinfo->display, x_dnd_wanted_action);
+
+ if (!XGetAtomNames (dpyinfo->display, x_dnd_targets,
+ x_dnd_n_targets, atom_names))
+ {
+ XFree (name);
+ return;
+ }
+
+ for (i = x_dnd_n_targets; i != 0; --i)
+ {
+ lval = Fcons (intern (atom_names[i - 1]), lval);
+ XFree (atom_names[i - 1]);
+ }
+
+ lval = Fcons (intern (name), lval);
+ lval = Fcons (QXdndSelection, lval);
+ ie.arg = lval;
+ ie.timestamp = CurrentTime;
+
+ XSETINT (ie.x, win_x);
+ XSETINT (ie.y, win_y);
+
+ XFree (name);
+ kbd_buffer_store_event (&ie);
+
+ return;
+ }
+ }
msg.xclient.type = ClientMessage;
msg.xclient.message_type = dpyinfo->Xatom_XdndDrop;