Commit 76850b26 authored by Po Lu's avatar Po Lu
Browse files

Implement `allow-same-frame' for NS drag-and-drop

* lisp/term/ns-win.el (x-begin-drag): Implement
`allow-same-frame'.
* src/nsselect.m (Fns_begin_drag): New parameter
`allow-same-frame'.
* src/nsterm.h (@interface EmacsWindow): Update prototypes.
* src/nsterm.m ([EmacsView draggingEntered:]):
([EmacsView prepareForDragOperation:]):
([EmacsView performDragOperation:]): Respect new parameter.
([EmacsWindow beginDrag:forPasteboard:withMode:returnFrameTo:]):
Likewise.
parent f610b4b5
Pipeline #18213 failed with stages
in 37 minutes and 24 seconds
......@@ -895,7 +895,7 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.")
&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"))
......@@ -910,7 +910,7 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.")
(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.
......
......@@ -662,7 +662,7 @@ Updated by Christian Limpach (chris@nice.ch)
}
}
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
......@@ -680,13 +680,16 @@ Updated by Christian Limpach (chris@nice.ch)
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;
......@@ -715,7 +718,8 @@ nil if no action was performed (either because there was no drop
operation = [window beginDrag: operation
forPasteboard: pasteboard
withMode: mode
returnFrameTo: &return_to];
returnFrameTo: &return_to
prohibitSame: (BOOL) NILP (allow_same_frame)];
if (return_to)
{
......
......@@ -425,6 +425,7 @@ enum ns_return_frame_mode
struct frame *dnd_return_frame;
enum ns_return_frame_mode dnd_mode;
BOOL dnd_allow_same_frame;
}
#ifdef NS_IMPL_GNUSTEP
......@@ -444,7 +445,9 @@ enum ns_return_frame_mode
- (NSDragOperation) beginDrag: (NSDragOperation) op
forPasteboard: (NSPasteboard *) pasteboard
withMode: (enum ns_return_frame_mode) mode
returnFrameTo: (struct frame **) frame_return;
returnFrameTo: (struct frame **) frame_return
prohibitSame: (BOOL) prohibit_same_frame;
- (BOOL) mustNotDropOn: (NSView *) receiver;
@end
......
......@@ -8608,13 +8608,30 @@ - (void)drawRect: (NSRect)rect
-(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;
}
......@@ -8675,25 +8692,29 @@ - (NSDragOperation) draggingUpdated: (id <NSDraggingInfo>) sender
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];
......@@ -8709,10 +8730,8 @@ -(BOOL)performDragOperation: (id <NSDraggingInfo>) sender
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])
{
......@@ -8764,21 +8783,16 @@ -(BOOL)performDragOperation: (id <NSDraggingInfo>) sender
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;
}
......@@ -9611,10 +9625,17 @@ - (void) draggedImage: (NSImage *) dragged_image
}
#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
......@@ -9627,6 +9648,7 @@ - (NSDragOperation) beginDrag: (NSDragOperation) op
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];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment