unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#30929: 26.0.91; Text drag and drop does not work
@ 2018-03-24 12:28 Nick Helm
  2018-03-25 11:57 ` Alan Third
  0 siblings, 1 reply; 18+ messages in thread
From: Nick Helm @ 2018-03-24 12:28 UTC (permalink / raw)
  To: 30929


On MacOS text drag-n-drop does not work out of the box. Also a dnd 
event seems to be bound to different functions depending on modifier 
settings.

Emacs -Q

C-h v ns-command-modifier -> "It's value is super"

C-h k <drag and drop external text> 
  -> "<M-s-drag-n-drop> is undefined"

(setq ns-command-modifier 'none)
C-h k <drag and drop external text>
  -> "<M-drag-n-drop> at that spot runs the command
      ns-drag-n-drop-as-text"

(setq ns-command-modifier 'control)
C-h k <drag and drop external text>
  -> "<C-M-drag-n-drop> at that spot runs the command
      ns-drag-n-drop-as-text-other-frame"

etc


In GNU Emacs 26.0.91 (build 1, x86_64-apple-darwin17.4.0, NS appkit-1561.20 Version 10.13.3 (Build 17D102))
 of 2018-03-22 built on jupiter.local
Repository revision: f8cad16bb3272a8069b3008019f9d18516aef1a5
Windowing system distributor 'Apple', version 10.3.1561
Recent messages:
Opening nnimap server on Office365...
Opening connection to localhost via shell...
Opening connection to localhost...done
Opening nnimap server on Office365...done
Opening nntp server on Gmane...done
1 new newsgroup has arrived
Checking new news...
Reading active file via nnnil...done
Reading active file via nndraft...done
Checking new news...done

Configured using:
 'configure --with-gnutls=no'

Configured features:
JPEG NOTIFY ACL LIBXML2 ZLIB TOOLKIT_SCROLL_BARS NS THREADS LCMS2

Important settings:
  value of $LANG: en_NZ.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Text

Minor modes in effect:
  savehist-mode: t
  global-eldoc-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  visual-line-mode: t
  transient-mark-mode: t

Load-path shadows:
None found.

Features:
(shadow gnus-cite sort mail-extr nnir emacsbug sendmail gnus-demon
nndraft nnmh cl-extra help-mode utf-7 network-stream nsm auth-source
cl-seq eieio eieio-core cl-macs eieio-loaddefs starttls nnfolder nnnil
gnus-agent gnus-srvr gnus-score score-mode nnvirtual gnus-msg gnus-art
mm-uu mml2015 mm-view mml-smime smime dig mailcap nntp gnus-cache
gnus-sum gnus-group gnus-undo gnus-start gnus-cloud nnimap nnmail
mail-source tls gnutls utf7 netrc nnoo parse-time gnus-spec gnus-int
gnus-range message rmc puny seq byte-opt bytecomp byte-compile cconv
format-spec rfc822 mml mml-sec password-cache epa derived epg epg-config
mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils
mailheader gnus-win gnus nnheader gnus-util rmail rmail-loaddefs rfc2047
rfc2045 ietf-drums mail-utils mm-util mail-prsvr wid-edit time dired-x
easymenu dired dired-loaddefs pcase savehist easy-mmode iso-transl
edmacro kmacro cl-loaddefs cl-lib gv plain-theme time-date tooltip eldoc
electric uniquify ediff-hook vc-hooks lisp-float-type mwheel term/ns-win
ns-win ucs-normalize mule-util term/common-win tool-bar dnd fontset
image regexp-opt fringe tabulated-list replace newcomment text-mode
elisp-mode lisp-mode prog-mode register page menu-bar rfn-eshadow
isearch timer select scroll-bar mouse jit-lock font-lock syntax facemenu
font-core term/tty-colors frame cl-generic cham georgian utf-8-lang
misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms
cp51932 hebrew greek romanian slovak czech european ethiopic indian
cyrillic chinese composite charscript charprop case-table epa-hook
jka-cmpr-hook help simple abbrev obarray minibuffer cl-preloaded nadvice
loaddefs button faces cus-face macroexp files text-properties overlay
sha1 md5 base64 format env code-pages mule custom widget
hashtable-print-readable backquote kqueue cocoa ns lcms2 multi-tty
make-network-process emacs)

Memory information:
((conses 16 282192 18056)
 (symbols 48 28457 1)
 (miscs 40 54 283)
 (strings 32 54201 2932)
 (string-bytes 1 1603692)
 (vectors 16 43788)
 (vector-slots 8 823234 17468)
 (floats 8 217 385)
 (intervals 56 246 0)
 (buffers 992 16))





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2018-03-24 12:28 bug#30929: 26.0.91; Text drag and drop does not work Nick Helm
@ 2018-03-25 11:57 ` Alan Third
  2018-03-28  9:20   ` Nick Helm
  0 siblings, 1 reply; 18+ messages in thread
From: Alan Third @ 2018-03-25 11:57 UTC (permalink / raw)
  To: Nick Helm; +Cc: 30929

On Sun, Mar 25, 2018 at 01:28:11AM +1300, Nick Helm wrote:
> 
> On MacOS text drag-n-drop does not work out of the box. Also a dnd 
> event seems to be bound to different functions depending on modifier 
> settings.
> 
> Emacs -Q
> 
> C-h v ns-command-modifier -> "It's value is super"
> 
> C-h k <drag and drop external text> 
>   -> "<M-s-drag-n-drop> is undefined"
> 
> (setq ns-command-modifier 'none)
> C-h k <drag and drop external text>
>   -> "<M-drag-n-drop> at that spot runs the command
>       ns-drag-n-drop-as-text"
> 
> (setq ns-command-modifier 'control)
> C-h k <drag and drop external text>
>   -> "<C-M-drag-n-drop> at that spot runs the command
>       ns-drag-n-drop-as-text-other-frame"

Looks like this is how the modifiers are set in performDragOperation

  if (! (op & (NSDragOperationMove|NSDragOperationDelete)) &&
      // URL drags contain all operations (0xf), don't allow all to be set.
      (op & 0xf) != 0xf)
    {
      if (op & NSDragOperationLink)
        modifiers |= NSEventModifierFlagControl;
      if (op & NSDragOperationCopy)
        modifiers |= NSEventModifierFlagOption;
      if (op & NSDragOperationGeneric)
        modifiers |= NSEventModifierFlagCommand;
    }

  modifiers = EV_MODIFIERS2 (modifiers);

It’s setting the actual modifier keys, so when a user changes those
keys’ settings this breaks.

You can also set these flags by using the actual modifier keys.

This looks like it matches up with what Apple expect you to do, but it
doesn’t seem to match up with Emacs’s event handling very well. I’ll
have to read up on it and have a think to see if I can work out a
solution.
-- 
Alan Third





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2018-03-25 11:57 ` Alan Third
@ 2018-03-28  9:20   ` Nick Helm
  2018-04-07 15:01     ` Alan Third
  0 siblings, 1 reply; 18+ messages in thread
From: Nick Helm @ 2018-03-28  9:20 UTC (permalink / raw)
  To: Alan Third; +Cc: 30929

[-- Attachment #1: Type: text/plain, Size: 1348 bytes --]

Hi Alan,

On Sun, 25 Mar 2018 at 12:57:32 +0100, Alan Third wrote:

> Looks like this is how the modifiers are set in performDragOperation
>
>   if (! (op & (NSDragOperationMove|NSDragOperationDelete)) &&
>       // URL drags contain all operations (0xf), don't allow all to be set.
>       (op & 0xf) != 0xf)
>     {
>       if (op & NSDragOperationLink)
>         modifiers |= NSEventModifierFlagControl;
>       if (op & NSDragOperationCopy)
>         modifiers |= NSEventModifierFlagOption;
>       if (op & NSDragOperationGeneric)
>         modifiers |= NSEventModifierFlagCommand;
>     }
>
>   modifiers = EV_MODIFIERS2 (modifiers);
>
> It’s setting the actual modifier keys, so when a user changes those
> keys’ settings this breaks.
>
> You can also set these flags by using the actual modifier keys.
>
> This looks like it matches up with what Apple expect you to do, but it
> doesn’t seem to match up with Emacs’s event handling very well. 

That looks about right to me too, it least it matches the general
approach in the docs.

I had a go at mapping the hardware modifiers to Emacs events (and
existing bindings) for each drag type and DragOperation mask. Patch
attached. This doesn't support the ns-right-*-modifiers yet, but they
should be pretty easy to add if you want to go this way.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Improve-handling-of-drag-and-drop-modifiers-on-NS.patch --]
[-- Type: text/x-patch, Size: 4273 bytes --]

From 9a177de5bacde98ef5c513c73f7aa48b58909af4 Mon Sep 17 00:00:00 2001
From: Nick Helm <nick@tenpoint.co.nz>
Date: Wed, 28 Mar 2018 21:06:59 +1300
Subject: [PATCH] Improve handling of drag-and-drop modifiers on NS.

---
 src/nsterm.m | 56 +++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 41 insertions(+), 15 deletions(-)

diff --git a/src/nsterm.m b/src/nsterm.m
index c8ae31abc0..4ad60d1b6a 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -8115,19 +8115,6 @@ -(BOOL)performDragOperation: (id <NSDraggingInfo>) sender
   pb = [sender draggingPasteboard];
   type = [pb availableTypeFromArray: ns_drag_types];
 
-  if (! (op & (NSDragOperationMove|NSDragOperationDelete)) &&
-      // URL drags contain all operations (0xf), don't allow all to be set.
-      (op & 0xf) != 0xf)
-    {
-      if (op & NSDragOperationLink)
-        modifiers |= NSEventModifierFlagControl;
-      if (op & NSDragOperationCopy)
-        modifiers |= NSEventModifierFlagOption;
-      if (op & NSDragOperationGeneric)
-        modifiers |= NSEventModifierFlagCommand;
-    }
-
-  modifiers = EV_MODIFIERS2 (modifiers);
   if (type == 0)
     {
       return NO;
@@ -8141,13 +8128,24 @@ -(BOOL)performDragOperation: (id <NSDraggingInfo>) sender
       if (!(files = [pb propertyListForType: type]))
         return NO;
 
+      if (! (op & (NSDragOperationMove | NSDragOperationDelete)) &&
+          (op & 0xf) != 0xf)
+        {
+          if (op & NSDragOperationGeneric)
+            modifiers |= NSEventModifierFlagCommand;
+          else if (op & NSDragOperationLink)
+            modifiers |= NSEventModifierFlagControl;
+          else if (op & NSDragOperationCopy)
+            modifiers |= NSEventModifierFlagOption;
+        }
+
       fenum = [files objectEnumerator];
       while ( (file = [fenum nextObject]) )
         {
           emacs_event->kind = DRAG_N_DROP_EVENT;
           XSETINT (emacs_event->x, x);
           XSETINT (emacs_event->y, y);
-          emacs_event->modifiers = modifiers;
+          emacs_event->modifiers = EV_MODIFIERS2 (modifiers);
           emacs_event->arg =  list2 (Qfile, build_string ([file UTF8String]));
           EV_TRAILER (theEvent);
         }
@@ -8158,10 +8156,22 @@ -(BOOL)performDragOperation: (id <NSDraggingInfo>) sender
       NSURL *url = [NSURL URLFromPasteboard: pb];
       if (url == nil) return NO;
 
+      if (! (op & (NSDragOperationMove|NSDragOperationDelete)) &&
+          // URL drags contain all operations (0xf), don't allow all to be set.
+          (op & 0xf) != 0xf)
+        {
+          if (op & NSDragOperationGeneric)
+            modifiers |= NSEventModifierFlagCommand;
+          else if (op & NSDragOperationLink)
+            modifiers |= NSEventModifierFlagControl;
+          else if (op & NSDragOperationCopy)
+            modifiers |= NSEventModifierFlagOption;
+        }
+
       emacs_event->kind = DRAG_N_DROP_EVENT;
       XSETINT (emacs_event->x, x);
       XSETINT (emacs_event->y, y);
-      emacs_event->modifiers = modifiers;
+      emacs_event->modifiers = EV_MODIFIERS2 (modifiers);
       emacs_event->arg =  list2 (Qurl,
                                  build_string ([[url absoluteString]
                                                  UTF8String]));
@@ -8183,6 +8193,22 @@ -(BOOL)performDragOperation: (id <NSDraggingInfo>) sender
       if (! (data = [pb stringForType: type]))
         return NO;
 
+      if (! (op & (NSDragOperationMove | NSDragOperationDelete)) &&
+          (op & 0xf) != 0xf)
+        {
+          if ((op & NSDragOperationCopy) && (op & NSDragOperationGeneric))
+            modifiers |= meta_modifier;
+          else if (op & NSDragOperationGeneric)
+            modifiers |= (parse_solitary_modifier (ns_command_modifier)
+                          | meta_modifier);
+          else if (op & NSDragOperationCopy)
+            modifiers |= (parse_solitary_modifier (ns_alternate_modifier)
+                          | meta_modifier);
+          else
+            modifiers |= (parse_solitary_modifier (ns_control_modifier)
+                          | meta_modifier);
+        }
+
       emacs_event->kind = DRAG_N_DROP_EVENT;
       XSETINT (emacs_event->x, x);
       XSETINT (emacs_event->y, y);
-- 
2.14.3 (Apple Git-98)


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2018-03-28  9:20   ` Nick Helm
@ 2018-04-07 15:01     ` Alan Third
  2018-04-09  1:51       ` Nick Helm
  0 siblings, 1 reply; 18+ messages in thread
From: Alan Third @ 2018-04-07 15:01 UTC (permalink / raw)
  To: Nick Helm; +Cc: 30929

On Wed, Mar 28, 2018 at 10:20:13PM +1300, Nick Helm wrote:
> > It’s setting the actual modifier keys, so when a user changes those
> > keys’ settings this breaks.
> >
> > You can also set these flags by using the actual modifier keys.
> >
> > This looks like it matches up with what Apple expect you to do, but it
> > doesn’t seem to match up with Emacs’s event handling very well. 
> 
> That looks about right to me too, it least it matches the general
> approach in the docs.
> 
> I had a go at mapping the hardware modifiers to Emacs events (and
> existing bindings) for each drag type and DragOperation mask. Patch
> attached. This doesn't support the ns-right-*-modifiers yet, but they
> should be pretty easy to add if you want to go this way.

Except we have no way of identifying whether the left or right
modifier has been pressed.

I’ve been thinking about this and I’m not entirely sure it’s a good
idea to expose these modifier presses to Emacs. At least not by
default.

I have two reasons for avoiding this:

  1. They’re not always modifier presses. Applications set these flags
     themselves and it seems strange to me that it can look like a modifier
     has been pressed when the user has done no such thing.

  2. It’s so very easy to break the bindings by rebinding the
     modifiers, which is often recommended for people using non‐US
     keyboards.

ns-drag-n-drop is perfectly capable of determining what action to take
by examining what it’s been passed in the event. So I think that if we
receive, for example, a filename and only NSDragOperationLink is set
then we should mark the filename as a string and then send the event
to lisp where it is inserted as plain text. But if NSDragOperationCopy
or NSDragOperationGeneric is set we mark it as a file and lisp will
open the file.

This does mean that the modifier presses aren’t customisable, but they
will always match the OS default at least.

If there’s a good use case for allowing these modifiers to leak
through then I suggest we make it customisable. That way new users
aren’t going to completely break drag‐n‐drop accidentally, and people
who know what they’re doing can break it as much as they want and live
with the consequences.

-- 
Alan Third





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2018-04-07 15:01     ` Alan Third
@ 2018-04-09  1:51       ` Nick Helm
  2018-04-10 19:38         ` Alan Third
  0 siblings, 1 reply; 18+ messages in thread
From: Nick Helm @ 2018-04-09  1:51 UTC (permalink / raw)
  To: Alan Third; +Cc: 30929

On Sun, 08 Apr 2018 at 03:01:19 +1200, Alan Third wrote:

> On Wed, Mar 28, 2018 at 10:20:13PM +1300, Nick Helm wrote:
>> > It’s setting the actual modifier keys, so when a user changes those
>> > keys’ settings this breaks.
>> >
>> > You can also set these flags by using the actual modifier keys.
>> >
>> > This looks like it matches up with what Apple expect you to do, but it
>> > doesn’t seem to match up with Emacs’s event handling very well. 
>> 
>> That looks about right to me too, it least it matches the general
>> approach in the docs.
>> 
>> I had a go at mapping the hardware modifiers to Emacs events (and
>> existing bindings) for each drag type and DragOperation mask. Patch
>> attached. This doesn't support the ns-right-*-modifiers yet, but they
>> should be pretty easy to add if you want to go this way.

> I’ve been thinking about this and I’m not entirely sure it’s a good
> idea to expose these modifier presses to Emacs. At least not by
> default.

For what it's worth, I think this is a much better idea. It's a
significant change from what we have now though.

> ns-drag-n-drop is perfectly capable of determining what action to take
> by examining what it’s been passed in the event. 

Based solely on the received operation mask (which may include the
user's OS-level modifers) and the data type sitting on the pb, right?

> This does mean that the modifier presses aren’t customisable, but they
> will always match the OS default at least.

Isn't that a good thing in this case? If dnd is considered an OS-level
event, then adding customisable modifier bindings was actually the wrong
thing to do.

> If there’s a good use case for allowing these modifiers to leak
> through then I suggest we make it customisable. 

Personally, I don't see a need. I think it's better to just do what the
user expects, which is what I think you're proposing. Experts can still
intercept the event in Lisp (BTW, it's interesting to note that the
mac-port doesn't expose incoming dnd events to Lisp at all and silently
ignores all the modifiers).


If the dnd code gets a rewrite, it would be nice to add support for
Emacs as the dragging source as well as a few nicities like mouse
pointer overlays on copy operations etc.

I'm guessing the boat has well and truly sailed for such major tweaks in
Emacs 26 though. Instead, would it make sense to change the default
binding on macOS so at least basic (unmodified) text dnd works out of
the box for the upcoming release?





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2018-04-09  1:51       ` Nick Helm
@ 2018-04-10 19:38         ` Alan Third
  2018-04-12  5:34           ` Nick Helm
  0 siblings, 1 reply; 18+ messages in thread
From: Alan Third @ 2018-04-10 19:38 UTC (permalink / raw)
  To: Nick Helm; +Cc: 30929

On Mon, Apr 09, 2018 at 01:51:58PM +1200, Nick Helm wrote:
> On Sun, 08 Apr 2018 at 03:01:19 +1200, Alan Third wrote:
> 
> > I’ve been thinking about this and I’m not entirely sure it’s a good
> > idea to expose these modifier presses to Emacs. At least not by
> > default.
> 
> For what it's worth, I think this is a much better idea. It's a
> significant change from what we have now though.

Indeed. But given it doesn’t work without a reasonable amount of work
just now, I suspect it’s not going to affect too many people.

> > ns-drag-n-drop is perfectly capable of determining what action to take
> > by examining what it’s been passed in the event. 
> 
> Based solely on the received operation mask (which may include the
> user's OS-level modifers) and the data type sitting on the pb, right?

Well, that’s not quite what I was thinking of. At the moment, in C, we
build a list like:

    '(file "filename")
    '(url "http://url")
    '(nil "plain text")

So I was thinking that using the operation mask and PB type we can
choose the correct type of list (like, it’s a file, but we only have
the link mask, so use the nil list). Then ns-drag-n-drop just looks at
that list and handles it.

But...

> > If there’s a good use case for allowing these modifiers to leak
> > through then I suggest we make it customisable. 
> 
> Personally, I don't see a need. I think it's better to just do what the
> user expects, which is what I think you're proposing. Experts can still
> intercept the event in Lisp (BTW, it's interesting to note that the
> mac-port doesn't expose incoming dnd events to Lisp at all and silently
> ignores all the modifiers).

This is probably a better idea, we pass the string, the type (from the
PB) and the mask to lisp, and then let ns-drag-n-drop sort it out.
Like you say, if an expert wants to do something different they can
then write their own function.

So in C we just construct something like:

    '(file
      (ns-drag-operation-copy
       ns-drag-operation-link)
      "filename")

Are you wanting to give this a go? I’m happy to work on it if not.

> If the dnd code gets a rewrite, it would be nice to add support for
> Emacs as the dragging source as well as a few nicities like mouse
> pointer overlays on copy operations etc.

I’m not sure what the deal is with drag‐n‐drop from Emacs on
GNU/Linux, but assuming it works under GNUstep as well as Cocoa we
could add Emacs as a drag source.

> I'm guessing the boat has well and truly sailed for such major tweaks in
> Emacs 26 though. Instead, would it make sense to change the default
> binding on macOS so at least basic (unmodified) text dnd works out of
> the box for the upcoming release?

That’s up to Eli. What would we have to do, just change the default
bindings in ns-win.el?

(global-set-key [drag-n-drop] 'ns-drag-n-drop)
(global-set-key [C-drag-n-drop] 'ns-drag-n-drop-other-frame)
(global-set-key [M-s-drag-n-drop] 'ns-drag-n-drop-as-text)
(global-set-key [C-M-s-drag-n-drop] 'ns-drag-n-drop-as-text-other-frame)

BTW, is it just me or does ‘ns-drag-n-drop-as-text-other-frame’ not
actually do anything different from ‘ns-drag-n-drop-as-text’?

...

OK. This is a disaster area. The current binding works if I drag and
drop text from iterm2, but fails if I drag from textedit. So I think
we need to bind every combination that includes meta to text dragging:

(global-set-key [M-drag-n-drop] 'ns-drag-n-drop-as-text)
(global-set-key [M-s-drag-n-drop] 'ns-drag-n-drop-as-text)
(global-set-key [C-M-s-drag-n-drop] 'ns-drag-n-drop-as-text)

And probably drop ns-drag-n-drop-as-text-other-frame, unless someone
can show that it does actually do what it’s supposed to.
-- 
Alan Third





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2018-04-10 19:38         ` Alan Third
@ 2018-04-12  5:34           ` Nick Helm
  2018-04-13 18:33             ` Alan Third
  0 siblings, 1 reply; 18+ messages in thread
From: Nick Helm @ 2018-04-12  5:34 UTC (permalink / raw)
  To: Alan Third; +Cc: 30929

On Wed, 11 Apr 2018 at 07:38:24 +1200, Alan Third wrote:

> On Mon, Apr 09, 2018 at 01:51:58PM +1200, Nick Helm wrote:

> This is probably a better idea, we pass the string, the type (from the
> PB) and the mask to lisp, and then let ns-drag-n-drop sort it out.
> Like you say, if an expert wants to do something different they can
> then write their own function.
>
> So in C we just construct something like:
>
>     '(file
>       (ns-drag-operation-copy
>        ns-drag-operation-link)
>       "filename")
>
> Are you wanting to give this a go? I’m happy to work on it if not.

Ok, I see what you mean. Yep, I can have a go at it.

> I’m not sure what the deal is with drag‐n‐drop from Emacs on
> GNU/Linux, but assuming it works under GNUstep as well as Cocoa we
> could add Emacs as a drag source.

I'll check. There may also be some technical hurdle, but I'd like to
have a go at this too. The docs for NSDraggingSource make it sound so
easy...

>> I'm guessing the boat has well and truly sailed for such major tweaks
>> in Emacs 26 though. Instead, would it make sense to change the
>> default binding on macOS so at least basic (unmodified) text dnd
>> works out of the box for the upcoming release?

> What would we have to do, just change the default bindings in
> ns-win.el?
>
> (global-set-key [drag-n-drop] 'ns-drag-n-drop)
> (global-set-key [C-drag-n-drop] 'ns-drag-n-drop-other-frame)
> (global-set-key [M-s-drag-n-drop] 'ns-drag-n-drop-as-text)
> (global-set-key [C-M-s-drag-n-drop] 'ns-drag-n-drop-as-text-other-frame)

Yes, but I was thinking of only changing this one

- (global-set-key [M-drag-n-drop] 'ns-drag-n-drop-as-text)
+ (global-set-key [M-s-drag-n-drop] 'ns-drag-n-drop-as-text)

as it's the only one unbound by default. This would be the bare minimum
change to make sure all unmodified dnd operations work by default. 

> BTW, is it just me or does ‘ns-drag-n-drop-as-text-other-frame’ not
> actually do anything different from ‘ns-drag-n-drop-as-text’?

The former pops up a new frame for me, but I have to bind it to an event
first. I don't think there's an easy way to generate the default
[C-M-drag-n-drop] event because of the way the modifiers are
interpreted, so `ns-drag-n-drop-as-text-other-frame' is never called.

> The current binding works if I drag and drop text from iterm2, but
> fails if I drag from textedit.

I'm guessing, but this might be expected. The sender sets the initial
operation mask based on its capabilities. I don't know iTerm2 very well,
but it probably doesn't support move operations (as its text is read
only) so it masks out the move to force a copy. Emacs receives
[drag-n-drop] and the op works because `ns-drag-n-drop' is smart enough
to know what to do with text on the pb. TextEdit supports both move and
copy, so it doesn't mask out the move, and Emacs receives
[M-s-drag-n-drop] which is currently unbound.





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2018-04-12  5:34           ` Nick Helm
@ 2018-04-13 18:33             ` Alan Third
  2018-04-24 12:42               ` Nick Helm
  0 siblings, 1 reply; 18+ messages in thread
From: Alan Third @ 2018-04-13 18:33 UTC (permalink / raw)
  To: Nick Helm; +Cc: 30929

On Thu, Apr 12, 2018 at 05:34:17PM +1200, Nick Helm wrote:
> On Wed, 11 Apr 2018 at 07:38:24 +1200, Alan Third wrote:
> 
> > On Mon, Apr 09, 2018 at 01:51:58PM +1200, Nick Helm wrote:
> 
> > This is probably a better idea, we pass the string, the type (from the
> > PB) and the mask to lisp, and then let ns-drag-n-drop sort it out.
> > Like you say, if an expert wants to do something different they can
> > then write their own function.
> >
> > So in C we just construct something like:
> >
> >     '(file
> >       (ns-drag-operation-copy
> >        ns-drag-operation-link)
> >       "filename")
> >
> > Are you wanting to give this a go? I’m happy to work on it if not.
> 
> Ok, I see what you mean. Yep, I can have a go at it.

I look forward to it.

BTW, there’s some code in the drag and drop stuff that sets
ns_input_file. You don’t need that, it’s not used for DnD and, in
fact, causes problems with other ways of opening files.

(More info in commit 292c09ff6db4bba1655bbb3160e859fef59ab34b and
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=29121, which I now see
was raised by you. :) )
-- 
Alan Third





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2018-04-13 18:33             ` Alan Third
@ 2018-04-24 12:42               ` Nick Helm
  2018-04-24 18:19                 ` Alan Third
  0 siblings, 1 reply; 18+ messages in thread
From: Nick Helm @ 2018-04-24 12:42 UTC (permalink / raw)
  To: Alan Third; +Cc: 30929

On Sat, 14 Apr 2018 at 06:33:34 +1200, Alan Third wrote:

> On Thu, Apr 12, 2018 at 05:34:17PM +1200, Nick Helm wrote:
>> On Wed, 11 Apr 2018 at 07:38:24 +1200, Alan Third wrote:
>> 
>> > On Mon, Apr 09, 2018 at 01:51:58PM +1200, Nick Helm wrote:
>> 
>> > This is probably a better idea, we pass the string, the type (from the
>> > PB) and the mask to lisp, and then let ns-drag-n-drop sort it out.
>> > Like you say, if an expert wants to do something different they can
>> > then write their own function.
>> >
>> > So in C we just construct something like:
>> >
>> >     '(file
>> >       (ns-drag-operation-copy
>> >        ns-drag-operation-link)
>> >       "filename")
>> >
>> > Are you wanting to give this a go? I’m happy to work on it if not.
>> 
>> Ok, I see what you mean. Yep, I can have a go at it.
>
> I look forward to it.

I've spent many many hours on this but I'm afraid I can't get it to
work. There are just too many permutations.

I give up, sorry.





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2018-04-24 12:42               ` Nick Helm
@ 2018-04-24 18:19                 ` Alan Third
  2018-04-25 23:16                   ` Nick Helm
  0 siblings, 1 reply; 18+ messages in thread
From: Alan Third @ 2018-04-24 18:19 UTC (permalink / raw)
  To: Nick Helm; +Cc: 30929

On Wed, Apr 25, 2018 at 12:42:19AM +1200, Nick Helm wrote:
> 
> I've spent many many hours on this but I'm afraid I can't get it to
> work. There are just too many permutations.

What do you mean by too many permutations? Is it because of the number
of NSDragOperation options?
-- 
Alan Third





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2018-04-24 18:19                 ` Alan Third
@ 2018-04-25 23:16                   ` Nick Helm
  2018-04-26 20:44                     ` Alan Third
  0 siblings, 1 reply; 18+ messages in thread
From: Nick Helm @ 2018-04-25 23:16 UTC (permalink / raw)
  To: Alan Third; +Cc: 30929

On Wed, 25 Apr 2018 at 06:19:33 +1200, Alan Third wrote:

> What do you mean by too many permutations? Is it because of the number
> of NSDragOperation options?

No, the NSDragOperation and mask stuff is relatively straightforward,
although we have to work out which one to apply and a lot of that
depends on the context in Lisp.

My main problem is the bewildering number of different data types that
have be to handled, in particular casting every possibility from 
ObjC -> C -> Lisp and interpreting them at the end.

But there are other complications. When the source adds a dragging image
to the pasteboard, I thought it was a single type. It's not, each one
(NSStringPboardType, NSFilenamesPboardType, etc) is an array of
conforming types, and different sources can use different conforming
types to represent the same image. We have to work out which one to use.
This gets harder when we're dealing with more than one image on the
pasteboard, each with it's own types. Some sources also place the same
image on the pasteboard twice (or more) to represent it using different
types, so we need to know about those too.

Then there's backwards compatibility, as not all these things work the
same way on older versions of macOS. It all gets pretty convoluted. 

Other related stuff doesn't work the way I expect either. I'd planned to
highlight the target Emacs window with a border to give the user better
feedback about the drop location. That's a pretty basic thing to do. But
there's something odd about Emacs's NSView implementation, which means
any code using drawRect is either ignored or affects all the objects in
the view at once, as if everything is drawn onto one flat canvas.

I also wanted to use draggingUpdate to update point during the dragging
session, in order to give the user better control over the insertion
point. Again, pretty rudimentary stuff. But I'm embarrassed to admit, I
can't even work out how to move point from C, much less from ObjC, and
much much less make it follow the mouse mid-dragging session.

As far as I can tell, Emacs on free platforms doesn't support being the
dragging source (either to other apps or within Emacs itself), so
I didn't look at that option at all.










^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2018-04-25 23:16                   ` Nick Helm
@ 2018-04-26 20:44                     ` Alan Third
  2018-04-28  9:57                       ` Nick Helm
  0 siblings, 1 reply; 18+ messages in thread
From: Alan Third @ 2018-04-26 20:44 UTC (permalink / raw)
  To: Nick Helm; +Cc: 30929

On Thu, Apr 26, 2018 at 11:16:32AM +1200, Nick Helm wrote:
> 
> My main problem is the bewildering number of different data types that
> have be to handled, in particular casting every possibility from 
> ObjC -> C -> Lisp and interpreting them at the end.

Can we simplify this? For example, the current code only supports
‘file’, ‘URL’ and ‘text’. I don’t think we need to worry about more
than that. At least for now.

I also don’t think you need to worry about converting many different
types. When we pass the data to lisp we *always* want it in plain
text, so if it’s a file then the filepath, a URL is plaintext anyway,
as is text.

Anything else we can ignore or reject.

If we did want to add other types, like say images, then we would
still want to accept only a plaintext description, like a filepath or
URL.

FWIW, the current code appears to handle this. But I may be completely
misunderstanding what you’re telling me.

> Then there's backwards compatibility, as not all these things work the
> same way on older versions of macOS. It all gets pretty convoluted. 

Remember we only support back to 10.6, so it may not be too bad.
Either way, we can deal with it as we go. Just make sure to mark where
you think there may be issues in the code. In the worst case we can
continue to use the current code, modified somewhat, in older versions
of macOS.

> Other related stuff doesn't work the way I expect either. I'd planned to
> highlight the target Emacs window with a border to give the user better
> feedback about the drop location. That's a pretty basic thing to do. But
> there's something odd about Emacs's NSView implementation, which means
> any code using drawRect is either ignored or affects all the objects in
> the view at once, as if everything is drawn onto one flat canvas.

It is pretty much drawn onto a single flat canvas. I think this
because of the way Emacs draws. It is annoying.

Do you need to use ns_focus and ns_unfocus? These select and unselect
an NSRect you want to update. If you search through nsterm.m for
ns_focus you’ll be able to find other places where we draw to the
frame.

> I also wanted to use draggingUpdate to update point during the dragging
> session, in order to give the user better control over the insertion
> point. Again, pretty rudimentary stuff. But I'm embarrassed to admit, I
> can't even work out how to move point from C, much less from ObjC, and
> much much less make it follow the mouse mid-dragging session.

I’m not sure how you’d implement that, nor whether it’s actually a
good idea: you could accidentally move point by dragging over the
wrong window. But you should be able to use lisp functions from C, for
example goto-char is Fgoto_char, but you need to remember to convert
the C int type to a lisp number type before passing it in. (see
make_number)

I don’t think this stuff is terribly easy, mostly I’ve got to know it
through modifying existing code (and messing it up).

> As far as I can tell, Emacs on free platforms doesn't support being the
> dragging source (either to other apps or within Emacs itself), so
> I didn't look at that option at all.

If it works in GNUstep, and I think this must, then we’re home free as
it counts as a Free platform.

    http://wiki.gnustep.org/index.php/Drag_and_drop

I’ve got a GNUstep build virtual machine, so I can make sure it all
works OK.

If you need any help, or don’t understand something, please feel free
to ask.
-- 
Alan Third





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2018-04-26 20:44                     ` Alan Third
@ 2018-04-28  9:57                       ` Nick Helm
  2019-01-05 10:27                         ` Alan Third
  0 siblings, 1 reply; 18+ messages in thread
From: Nick Helm @ 2018-04-28  9:57 UTC (permalink / raw)
  To: Alan Third; +Cc: 30929

On Fri, 27 Apr 2018 at 08:44:42 +1200, Alan Third wrote:

> On Thu, Apr 26, 2018 at 11:16:32AM +1200, Nick Helm wrote:
>> 
>> My main problem is the bewildering number of different data types that
>> have be to handled, in particular casting every possibility from 
>> ObjC -> C -> Lisp and interpreting them at the end.
>
> When we pass the data to lisp we *always* want it in plain
> text, so if it’s a file then the filepath, a URL is plaintext anyway,
> as is text.
>
> Anything else we can ignore or reject.

OK, this is helpful. I was thinking we'd need to handle all the uniform
type identifiers. For example, yes a NSURLPboardType is always text but
it might conform to public.text, public.plain-text,
public.utf8-plain-text, public.url, public.file-url, etc. But I guess
Emacs couldn't care less about all that. The current code simply
converts to a UTF8 string and sends it on, so I'll do that too.

>> I'd planned to highlight the target Emacs window with a border to
>> give the user better feedback about the drop location
>
> Do you need to use ns_focus and ns_unfocus? These select and unselect
> an NSRect you want to update. If you search through nsterm.m for
> ns_focus you’ll be able to find other places where we draw to the
> frame.

Thanks, I'll give that a try.

>> As far as I can tell, Emacs on free platforms doesn't support being the
>> dragging source (either to other apps or within Emacs itself), so
>> I didn't look at that option at all.
>
> If it works in GNUstep, and I think this must, then we’re home free as
> it counts as a Free platform.
>
>     http://wiki.gnustep.org/index.php/Drag_and_drop
>
> I’ve got a GNUstep build virtual machine, so I can make sure it all
> works OK.

If you could check and let me know, that would be great. I'll get the
destination stuff working properly first though.

> If you need any help, or don’t understand something, please feel free
> to ask.

Thanks, I really appreciate it.









^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2018-04-28  9:57                       ` Nick Helm
@ 2019-01-05 10:27                         ` Alan Third
  2019-01-05 13:05                           ` Nick Helm
  0 siblings, 1 reply; 18+ messages in thread
From: Alan Third @ 2019-01-05 10:27 UTC (permalink / raw)
  To: Nick Helm; +Cc: 30929

Nick Helm <nick@tenpoint.co.nz> writes:

> On Fri, 27 Apr 2018 at 08:44:42 +1200, Alan Third wrote:
>
>> On Thu, Apr 26, 2018 at 11:16:32AM +1200, Nick Helm wrote:
>>> 
>>> My main problem is the bewildering number of different data types that
>>> have be to handled, in particular casting every possibility from 
>>> ObjC -> C -> Lisp and interpreting them at the end.
>>
>> When we pass the data to lisp we *always* want it in plain
>> text, so if it’s a file then the filepath, a URL is plaintext anyway,
>> as is text.
>>
>> Anything else we can ignore or reject.
>
> OK, this is helpful. I was thinking we'd need to handle all the uniform
> type identifiers. For example, yes a NSURLPboardType is always text but
> it might conform to public.text, public.plain-text,
> public.utf8-plain-text, public.url, public.file-url, etc. But I guess
> Emacs couldn't care less about all that. The current code simply
> converts to a UTF8 string and sends it on, so I'll do that too.

Hi Nick, did you make any progress on the drag and drop stuff?
-- 
Alan Third





^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2019-01-05 10:27                         ` Alan Third
@ 2019-01-05 13:05                           ` Nick Helm
  2019-01-05 16:20                             ` Alan Third
  0 siblings, 1 reply; 18+ messages in thread
From: Nick Helm @ 2019-01-05 13:05 UTC (permalink / raw)
  To: Alan Third; +Cc: 30929

On Sat, 2019-01-05 at 10:27 +0000, Alan Third wrote:
> Nick Helm <nick@tenpoint.co.nz> writes:
> 
> > On Fri, 27 Apr 2018 at 08:44:42 +1200, Alan Third wrote:
> > 
> > > On Thu, Apr 26, 2018 at 11:16:32AM +1200, Nick Helm wrote:
> > > > My main problem is the bewildering number of different data
> > > > types that
> > > > have be to handled, in particular casting every possibility
> > > > from 
> > > > ObjC -> C -> Lisp and interpreting them at the end.
> > > 
> > > When we pass the data to lisp we *always* want it in plain
> > > text, so if it’s a file then the filepath, a URL is plaintext
> > > anyway,
> > > as is text.
> > > 
> > > Anything else we can ignore or reject.
> > 
> > OK, this is helpful. I was thinking we'd need to handle all the
> > uniform
> > type identifiers. For example, yes a NSURLPboardType is always text
> > but
> > it might conform to public.text, public.plain-text,
> > public.utf8-plain-text, public.url, public.file-url, etc. But I
> > guess
> > Emacs couldn't care less about all that. The current code simply
> > converts to a UTF8 string and sends it on, so I'll do that too.
> 
> Hi Nick, did you make any progress on the drag and drop stuff?

Hi Alan. Sorry, no I never managed to get it working they way I wanted.







^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2019-01-05 13:05                           ` Nick Helm
@ 2019-01-05 16:20                             ` Alan Third
  2019-01-07 10:38                               ` Nick Helm
  0 siblings, 1 reply; 18+ messages in thread
From: Alan Third @ 2019-01-05 16:20 UTC (permalink / raw)
  To: Nick Helm; +Cc: 30929

[-- Attachment #1: Type: text/plain, Size: 615 bytes --]

On Sun, Jan 06, 2019 at 02:05:57AM +1300, Nick Helm wrote:
> On Sat, 2019-01-05 at 10:27 +0000, Alan Third wrote:
> > Hi Nick, did you make any progress on the drag and drop stuff?
> 
> Hi Alan. Sorry, no I never managed to get it working they way I wanted.

No problem. Can you have a look at the attached. It’s not as ambitious
as we discussed, but it does pretty much the minimum required to make
drag and drop usable.

If you think the defaults I’ve chosen don’t make sense, I’m happy to
change them. I don’t ever use drag and drop, so I don’t know what’s
really useful for people.
-- 
Alan Third

[-- Attachment #2: 0001-Fix-drag-and-drop-behaviour-on-NS.patch --]
[-- Type: text/plain, Size: 10646 bytes --]

From 1d4cbb250bb0f8fd75a3c749b454c9b177c4dae7 Mon Sep 17 00:00:00 2001
From: Alan Third <alan@idiocy.org>
Date: Sat, 5 Jan 2019 16:11:37 +0000
Subject: [PATCH] Fix drag and drop behaviour on NS

* doc/emacs/macos.texi (Mac / GNUstep Events): Describe the new drag
and drop behaviour.
* lisp/term/ns-win.el (ns-drag-n-drop): Handle the new event format.
(ns-drag-n-drop-other-frame):
(ns-drag-n-drop-as-text):
(ns-drag-n-drop-as-text-other-frame): Remove functions and key
bindings.
* src/nsterm.m ([EmacsView performDragOperation:]): Send Emacs event
in new format without setting any modifiers.
---
 doc/emacs/macos.texi | 21 ++++++++++--
 etc/NEWS             |  6 ++++
 lisp/term/ns-win.el  | 54 ++++++++++++-----------------
 src/nsterm.m         | 81 ++++++++++++++++++++------------------------
 4 files changed, 84 insertions(+), 78 deletions(-)

diff --git a/doc/emacs/macos.texi b/doc/emacs/macos.texi
index 6d27e97821..d9920957ad 100644
--- a/doc/emacs/macos.texi
+++ b/doc/emacs/macos.texi
@@ -170,8 +170,25 @@ Mac / GNUstep Events
 This event occurs when a user drags an object from another application
 into an Emacs frame.  The default behavior is to open a file in the
 window under the mouse, or to insert text at point of the window under
-the mouse.  It may sometimes be necessary to use the @key{Meta} key in
-conjunction with dragging to force text insertion.
+the mouse.
+
+The sending application has some limited ability to decide how Emacs
+handles the sent object, but the user may override the default
+behaviour by holding one or more modifier key.
+
+@table @kbd
+@item control
+Insert as text in the current buffer.  If the object is a file, this
+will insert the filename.
+@item alt/option
+Attempt to open the object as though it is a file or URL.
+@item super/command
+Perform the default action for the type.  This can be useful when an
+application is overriding the default behaviour.
+@end table
+
+The modifier keys listed above are defined by macOS and are unaffected
+by user changes to the modifiers in Emacs.
 
 @item ns-change-font
 This event occurs when the user selects a font in a Nextstep font
diff --git a/etc/NEWS b/etc/NEWS
index b316aecbfa..3b3c4483e9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1480,6 +1480,12 @@ versions of MS-Windows.  Set this variable to 50 if for some reason
 you need the old behavior (and please report such situations to Emacs
 developers).
 
++++
+** On NS the behaviour of drag and drop can now be modified by use of
+modifier keys in line with Apples guidelines.  This makes the drag and
+drop behaviour more consistent, as previously the sending application
+was able to 'set' modifiers without the knowledge of the user.
+
 \f
 ----------------------------------------------------------------------
 This file is part of GNU Emacs.
diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el
index c9f5bfef52..6a668b213d 100644
--- a/lisp/term/ns-win.el
+++ b/lisp/term/ns-win.el
@@ -501,48 +501,38 @@ ns-find-file
       (find-file f)))))
 
 
-(defun ns-drag-n-drop (event &optional new-frame force-text)
+(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."
+Switch to a buffer editing the last file dropped, or insert the
+string dropped into the current buffer."
   (interactive "e")
   (let* ((window (posn-window (event-start event)))
          (arg (car (cdr (cdr event))))
          (type (car arg))
-         (data (car (cdr arg)))
-         (url-or-string (cond ((eq type 'file)
-                               (concat "file:" data))
-                              (t data))))
+         (operations (car (cdr arg)))
+         (objects (cdr (cdr arg)))
+         (string (mapconcat 'identity objects "\n")))
     (set-frame-selected-window nil window)
-    (when new-frame
-      (select-frame (make-frame)))
     (raise-frame)
     (setq window (selected-window))
-    (if force-text
-        (dnd-insert-text window 'private data)
-      (dnd-handle-one-url window 'private url-or-string))))
-
-
-(defun ns-drag-n-drop-other-frame (event)
-  "Edit the files listed in the drag-n-drop EVENT, in other frames.
-May create new frames, or reuse existing ones.  The frame editing
-the last file dropped is selected."
-  (interactive "e")
-  (ns-drag-n-drop event t))
-
-(defun ns-drag-n-drop-as-text (event)
-  "Drop the data in EVENT as text."
-  (interactive "e")
-  (ns-drag-n-drop event nil t))
-
-(defun ns-drag-n-drop-as-text-other-frame (event)
-  "Drop the data in EVENT as text in a new frame."
-  (interactive "e")
-  (ns-drag-n-drop event t t))
+    (cond ((memq 'ns-drag-operation-generic operations)
+           ;; Perform the default action for the type.
+           (if (eq type 'file)
+               (dolist (data objects)
+                 (dnd-handle-one-url window 'private (concat "file:" data)))
+             (dnd-insert-text window 'private string)))
+          ((memq 'ns-drag-operation-copy operations)
+           ;; Try to open the file/URL.  If type is nil, try to open
+           ;; it as a URL anyway.
+           (dolist (data objects)
+             (dnd-handle-one-url window 'private (if (eq type 'file)
+                                                     (concat "file:" data)
+                                                   data))))
+          (t
+           ;; Insert the text as is.
+           (dnd-insert-text window 'private string)))))
 
 (global-set-key [drag-n-drop] 'ns-drag-n-drop)
-(global-set-key [C-drag-n-drop] 'ns-drag-n-drop-other-frame)
-(global-set-key [M-drag-n-drop] 'ns-drag-n-drop-as-text)
-(global-set-key [C-M-drag-n-drop] 'ns-drag-n-drop-as-text-other-frame)
 
 ;;;; Frame-related functions.
 
diff --git a/src/nsterm.m b/src/nsterm.m
index 016c044760..2bce4a89ae 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -8230,7 +8230,9 @@ -(BOOL)performDragOperation: (id <NSDraggingInfo>) sender
   NSEvent *theEvent = [[self window] currentEvent];
   NSPoint position;
   NSDragOperation op = [sender draggingSourceOperationMask];
-  int modifiers = 0;
+  Lisp_Object operations = Qnil;
+  Lisp_Object strings = Qnil;
+  Lisp_Object type_sym;
 
   NSTRACE ("[EmacsView performDragOperation:]");
 
@@ -8243,19 +8245,17 @@ -(BOOL)performDragOperation: (id <NSDraggingInfo>) sender
   pb = [sender draggingPasteboard];
   type = [pb availableTypeFromArray: ns_drag_types];
 
-  if (! (op & (NSDragOperationMove|NSDragOperationDelete)) &&
-      // URL drags contain all operations (0xf), don't allow all to be set.
-      (op & 0xf) != 0xf)
-    {
-      if (op & NSDragOperationLink)
-        modifiers |= NSEventModifierFlagControl;
-      if (op & NSDragOperationCopy)
-        modifiers |= NSEventModifierFlagOption;
-      if (op & NSDragOperationGeneric)
-        modifiers |= NSEventModifierFlagCommand;
-    }
+  /* We used to convert these drag operations to keyboard modifiers,
+     but because they can be set by the sending program as well as the
+     keyboard modifiers it was difficult to work out a sensible key
+     mapping for drag and drop.  */
+  if (op & NSDragOperationLink)
+    operations = Fcons (Qns_drag_operation_link, operations);
+  if (op & NSDragOperationCopy)
+    operations = Fcons (Qns_drag_operation_copy, operations);
+  if (op & NSDragOperationGeneric || NILP (operations))
+    operations = Fcons (Qns_drag_operation_generic, operations);
 
-  modifiers = EV_MODIFIERS2 (modifiers);
   if (type == 0)
     {
       return NO;
@@ -8269,39 +8269,20 @@ -(BOOL)performDragOperation: (id <NSDraggingInfo>) sender
       if (!(files = [pb propertyListForType: type]))
         return NO;
 
+      type_sym = Qfile;
+
       fenum = [files objectEnumerator];
       while ( (file = [fenum nextObject]) )
-        {
-          emacs_event->kind = DRAG_N_DROP_EVENT;
-          XSETINT (emacs_event->x, x);
-          XSETINT (emacs_event->y, y);
-          emacs_event->modifiers = modifiers;
-          emacs_event->arg =  list2 (Qfile, build_string ([file UTF8String]));
-          EV_TRAILER (theEvent);
-        }
-      return YES;
+        strings = Fcons (build_string ([file UTF8String]), strings);
     }
   else if ([type isEqualToString: NSURLPboardType])
     {
       NSURL *url = [NSURL URLFromPasteboard: pb];
       if (url == nil) return NO;
 
-      emacs_event->kind = DRAG_N_DROP_EVENT;
-      XSETINT (emacs_event->x, x);
-      XSETINT (emacs_event->y, y);
-      emacs_event->modifiers = modifiers;
-      emacs_event->arg =  list2 (Qurl,
-                                 build_string ([[url absoluteString]
-                                                 UTF8String]));
-      EV_TRAILER (theEvent);
+      type_sym = Qurl;
 
-      if ([url isFileURL] != NO)
-        {
-          NSString *file = [url path];
-          ns_input_file = append2 (ns_input_file,
-                                   build_string ([file UTF8String]));
-        }
-      return YES;
+      strings = Fcons (build_string ([[url absoluteString] UTF8String]), Qnil);
     }
   else if ([type isEqualToString: NSStringPboardType]
            || [type isEqualToString: NSTabularTextPboardType])
@@ -8311,19 +8292,27 @@ -(BOOL)performDragOperation: (id <NSDraggingInfo>) sender
       if (! (data = [pb stringForType: type]))
         return NO;
 
-      emacs_event->kind = DRAG_N_DROP_EVENT;
-      XSETINT (emacs_event->x, x);
-      XSETINT (emacs_event->y, y);
-      emacs_event->modifiers = modifiers;
-      emacs_event->arg =  list2 (Qnil, build_string ([data UTF8String]));
-      EV_TRAILER (theEvent);
-      return YES;
+      type_sym = Qnil;
+
+      strings = Fcons (build_string ([data UTF8String]), Qnil);
     }
   else
     {
       fprintf (stderr, "Invalid data type in dragging pasteboard");
       return NO;
     }
+
+  emacs_event->kind = DRAG_N_DROP_EVENT;
+  XSETINT (emacs_event->x, x);
+  XSETINT (emacs_event->y, y);
+  emacs_event->modifiers = 0;
+
+  emacs_event->arg = Fcons (type_sym,
+                            Fcons (operations,
+                                   strings));
+  EV_TRAILER (theEvent);
+
+  return YES;
 }
 
 
@@ -9358,6 +9347,10 @@ Convert an X font name (XLFD) to an NS font name.
   DEFSYM (Qfile, "file");
   DEFSYM (Qurl, "url");
 
+  DEFSYM (Qns_drag_operation_copy, "ns-drag-operation-copy");
+  DEFSYM (Qns_drag_operation_link, "ns-drag-operation-link");
+  DEFSYM (Qns_drag_operation_generic, "ns-drag-operation-generic");
+
   Fput (Qalt, Qmodifier_value, make_fixnum (alt_modifier));
   Fput (Qhyper, Qmodifier_value, make_fixnum (hyper_modifier));
   Fput (Qmeta, Qmodifier_value, make_fixnum (meta_modifier));
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2019-01-05 16:20                             ` Alan Third
@ 2019-01-07 10:38                               ` Nick Helm
  2019-01-10 19:23                                 ` Alan Third
  0 siblings, 1 reply; 18+ messages in thread
From: Nick Helm @ 2019-01-07 10:38 UTC (permalink / raw)
  To: Alan Third; +Cc: 30929


On Sun, Jan 6, 2019 at 5:20 AM, Alan Third <alan@idiocy.org> wrote:
> No problem. Can you have a look at the attached. It’s not as 
> ambitious
> as we discussed, but it does pretty much the minimum required to make
> drag and drop usable.
> 
> If you think the defaults I’ve chosen don’t make sense, I’m 
> happy to
> change them. I don’t ever use drag and drop, so I don’t know 
> what’s
> really useful for people.

Thanks, this is a big improvement.

I like the default modifier actions - they match how drag and drop works
on my other apps. I was worried having the modifiers independent of the
Emacs modifiers might be a bit confusing with non-default bindings, but
in practice it doesn't cause me any trouble.

I also tried as many different dnd operations as I could think of. They
all worked as expected except one - when I try to open a malformed URL
Emacs creates a spurious buffer and freezes momentarily (C-g to clear).
Specifically, I selected the text "file://~/test.txt" in TextEdit.app
and dropped it into Emacs with Alt/Opt held down. Properly formed URLs
work as expected and open the file.

Thanks again for working on this.

Nick








^ permalink raw reply	[flat|nested] 18+ messages in thread

* bug#30929: 26.0.91; Text drag and drop does not work
  2019-01-07 10:38                               ` Nick Helm
@ 2019-01-10 19:23                                 ` Alan Third
  0 siblings, 0 replies; 18+ messages in thread
From: Alan Third @ 2019-01-10 19:23 UTC (permalink / raw)
  To: Nick Helm; +Cc: 30929-done

On Mon, Jan 07, 2019 at 11:38:33PM +1300, Nick Helm wrote:
> 
> I like the default modifier actions - they match how drag and drop works
> on my other apps. I was worried having the modifiers independent of the
> Emacs modifiers might be a bit confusing with non-default bindings, but
> in practice it doesn't cause me any trouble.

Excellent.

> I also tried as many different dnd operations as I could think of. They
> all worked as expected except one - when I try to open a malformed URL
> Emacs creates a spurious buffer and freezes momentarily (C-g to clear).
> Specifically, I selected the text "file://~/test.txt" in TextEdit.app
> and dropped it into Emacs with Alt/Opt held down. Properly formed URLs
> work as expected and open the file.

I’ve dug into this a bit and I think that’s actually a valid URL as
far as Emacs is concerned. I’m not sure what protocol it’s trying to
use, but it matches the form file://hostname/filename. I assume the
freeze you see is it doing a lookup and if left long enough it will
time out (although it’s an extraordinarily long timeout if true).

I’ll push this to master now.
-- 
Alan Third





^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2019-01-10 19:23 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-24 12:28 bug#30929: 26.0.91; Text drag and drop does not work Nick Helm
2018-03-25 11:57 ` Alan Third
2018-03-28  9:20   ` Nick Helm
2018-04-07 15:01     ` Alan Third
2018-04-09  1:51       ` Nick Helm
2018-04-10 19:38         ` Alan Third
2018-04-12  5:34           ` Nick Helm
2018-04-13 18:33             ` Alan Third
2018-04-24 12:42               ` Nick Helm
2018-04-24 18:19                 ` Alan Third
2018-04-25 23:16                   ` Nick Helm
2018-04-26 20:44                     ` Alan Third
2018-04-28  9:57                       ` Nick Helm
2019-01-05 10:27                         ` Alan Third
2019-01-05 13:05                           ` Nick Helm
2019-01-05 16:20                             ` Alan Third
2019-01-07 10:38                               ` Nick Helm
2019-01-10 19:23                                 ` Alan Third

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).