Subject: Re: bug#43470: 27.1; Drag and Drop not working properly in 27.1 on OSX

From: Alan Third <[email-masked]>
Date: Sat, 19 Sep 2020 15:08:17 +0100

On Fri, Sep 18, 2020 at 11:22:46PM +0000, Paul Magwene, Ph.D. wrote:
> 
> My testing suggests that there's still source application specific behavior.
> 
> * Simple drag of images works when Safari or Chrome is the web browser.
> 
> * No combination of Option, Command, or Control seems to work in Firefox; the drag behavior always produces a URL.

That's how Apple designed it, what we wanted to avoid was where the
source application defined which modifiers Emacs saw in use as that
just turned into a nightmare of random behaviour.

Probably what's happening is that Firefox is setting some drag
operations that don't include NSDragOperationCopy, which is the one we
chose to always try opening the text as a URL.

It would be interesting to know what it's setting. You could try
adding something like

    NSLog ("%lx", op);

into performDragOperation in nsterm.m and then we can compare it to
the constants listed here:

    https://developer.apple.com/documentation/appkit/nsdragoperation?language=objc

> So I guess the patch partially fixes the regression. Given the state
> of the OS X api I'm not sure what the best way forward is. I'd try
> and jump in to contribute but I unfortunately have zero experience
> working with Objective C or programming against Apple's APIs

The ns-drag-n-drop function is customisable, so if you wanted to
ALWAYS force it to try and open ANY text as a URL you could do
something like

(defun ns-drag-n-drop (event)
  "Edit the files listed in the drag-n-drop EVENT.
Switch to a buffer editing the last file dropped."
  (interactive "e")
  (let* ((window (posn-window (event-start event)))
         (arg (car (cdr (cdr event))))
         (type (car arg))
         (objects (cdr (cdr arg))))
    (set-frame-selected-window nil window)
    (raise-frame)
    (setq window (selected-window))
    (princ operations)
    (dolist (data objects)
      (dnd-handle-one-url window 'private (if (eq type 'file)
                                              (concat "file:" data)
                                            data)))))

It's quite possible we should have more logic in ns-drag-n-drop to
work out what to do given the data type and available dragging
options.

BTW, Apple's documentation seems to be inconsistent. One page[1] has
this table:

    | Modifier Key       | Dragging Operation  |
    |--------------------+---------------------|
    | Option             | NSDragOperationCopy | 
    | Command            | NSDragOperationMove | 
    | Option and Command | NSDragOperationLink | 

and another[2] has this:

    | Modifier Key | Dragging Operation     |
    |--------------+------------------------|
    | Control      | NSDragOperationLink    |
    | Option       | NSDragOperationCopy    |
    | Command      | NSDragOperationGeneric |

The latter seems to be the correct one.

[1] https://developer.apple.com/documentation/appkit/nsdragginginfo/1415966-draggingsourceoperationmask?language=objc
[2] https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/DragandDrop/Concepts/dragsource.html#//apple_ref/doc/uid/20000976-104936
-- 
Alan Third