&context (window-system ns))
(ns-get-selection selection-symbol target-type))
-(defun x-begin-drag (targets &optional action frame return-frame _allow-current-frame)
+(defun x-begin-drag (targets &optional action frame return-frame allow-current-frame)
"SKIP: real doc in xfns.c."
(unless ns-dnd-selection-value
(error "No local value for XdndSelection"))
(expand-file-name
ns-dnd-selection-value))))
pasteboard))
- (ns-begin-drag frame pasteboard action return-frame)))
+ (ns-begin-drag frame pasteboard action return-frame allow-current-frame)))
(defun ns-handle-drag-motion (frame x y)
"Handle mouse movement on FRAME at X and Y during drag-and-drop.
}
}
-DEFUN ("ns-begin-drag", Fns_begin_drag, Sns_begin_drag, 3, 4, 0,
+DEFUN ("ns-begin-drag", Fns_begin_drag, Sns_begin_drag, 3, 5, 0,
doc: /* Begin a drag-and-drop operation on FRAME.
FRAME must be a window system frame. PBOARD is an alist of (TYPE
Return the action that the drop target actually chose to perform, or
nil if no action was performed (either because there was no drop
-target, or the drop was rejected). If RETURN_FRAME is the symbol
+target, or the drop was rejected). If RETURN-FRAME is the symbol
`now', also return any frame that mouse moves into during the
drag-and-drop operation, whilst simultaneously cancelling it. Any
other non-nil value means to do the same, but to wait for the mouse to
-leave FRAME first. */)
+leave FRAME first.
+
+If ALLOW-SAME-FRAME is nil, dropping on FRAME will result in the drop
+being ignored. */)
(Lisp_Object frame, Lisp_Object pboard, Lisp_Object action,
- Lisp_Object return_frame)
+ Lisp_Object return_frame, Lisp_Object allow_same_frame)
{
struct frame *f, *return_to;
NSPasteboard *pasteboard;
operation = [window beginDrag: operation
forPasteboard: pasteboard
withMode: mode
- returnFrameTo: &return_to];
+ returnFrameTo: &return_to
+ prohibitSame: (BOOL) NILP (allow_same_frame)];
if (return_to)
{
-(NSDragOperation) draggingEntered: (id <NSDraggingInfo>) sender
{
+ id source;
+
NSTRACE ("[EmacsView draggingEntered:]");
+
+ source = [sender draggingSource];
+
+ if (source && [source respondsToSelector: @selector(mustNotDropOn:)]
+ && [source mustNotDropOn: self])
+ return NSDragOperationNone;
+
return NSDragOperationGeneric;
}
--(BOOL)prepareForDragOperation: (id <NSDraggingInfo>) sender
+-(BOOL) prepareForDragOperation: (id <NSDraggingInfo>) sender
{
+ id source;
+
+ source = [sender draggingSource];
+
+ if (source && [source respondsToSelector: @selector(mustNotDropOn:)]
+ && [source mustNotDropOn: self])
+ return NO;
+
return YES;
}
return NSDragOperationGeneric;
}
--(BOOL)performDragOperation: (id <NSDraggingInfo>) sender
+- (BOOL) performDragOperation: (id <NSDraggingInfo>) sender
{
- id pb;
+ id pb, source;
int x, y;
NSString *type;
- NSEvent *theEvent = [[self window] currentEvent];
NSPoint position;
NSDragOperation op = [sender draggingSourceOperationMask];
Lisp_Object operations = Qnil;
Lisp_Object strings = Qnil;
Lisp_Object type_sym;
+ struct input_event ie;
NSTRACE ("[EmacsView performDragOperation:]");
- if (!emacs_event)
+ source = [sender draggingSource];
+
+ if (source && [source respondsToSelector: @selector(mustNotDropOn:)]
+ && [source mustNotDropOn: self])
return NO;
position = [self convertPoint: [sender draggingLocation] fromView: nil];
- x = lrint (position.x); y = lrint (position.y);
+ x = lrint (position.x);
+ y = lrint (position.y);
pb = [sender draggingPasteboard];
type = [pb availableTypeFromArray: ns_drag_types];
if (op & NSDragOperationGeneric || NILP (operations))
operations = Fcons (Qns_drag_operation_generic, operations);
- if (type == 0)
- {
- return NO;
- }
+ if (!type)
+ return NO;
#if NS_USE_NSPasteboardTypeFileURL != 0
else if ([type isEqualToString: NSPasteboardTypeFileURL])
{
strings = list1 ([data lispString]);
}
else
- {
- fputs ("Invalid data type in dragging pasteboard\n", stderr);
- return NO;
- }
-
- emacs_event->kind = DRAG_N_DROP_EVENT;
- XSETINT (emacs_event->x, x);
- XSETINT (emacs_event->y, y);
- emacs_event->modifiers = 0;
+ return NO;
- emacs_event->arg = Fcons (type_sym,
- Fcons (operations,
- strings));
- EV_TRAILER (theEvent);
+ EVENT_INIT (ie);
+ ie.kind = DRAG_N_DROP_EVENT;
+ ie.arg = Fcons (type_sym, Fcons (operations, strings));
+ XSETINT (ie.x, x);
+ XSETINT (ie.y, y);
+ XSETFRAME (ie.frame_or_window, emacsframe);
+ kbd_buffer_store_event (&ie);
return YES;
}
}
#endif
+- (BOOL) mustNotDropOn: (NSView *) receiver
+{
+ return ([receiver window] == self
+ ? !dnd_allow_same_frame : NO);
+}
+
- (NSDragOperation) beginDrag: (NSDragOperation) op
forPasteboard: (NSPasteboard *) pasteboard
withMode: (enum ns_return_frame_mode) mode
returnFrameTo: (struct frame **) frame_return
+ prohibitSame: (BOOL) prohibit_same_frame
{
NSImage *image;
#ifdef NS_IMPL_COCOA
image = [[NSImage alloc] initWithSize: NSMakeSize (1.0, 1.0)];
dnd_mode = mode;
dnd_return_frame = NULL;
+ dnd_allow_same_frame = !prohibit_same_frame;
/* Now draw transparency onto the image. */
[image lockFocus];