From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Alan Third Newsgroups: gmane.emacs.bugs Subject: bug#30929: 26.0.91; Text drag and drop does not work Date: Sat, 5 Jan 2019 16:20:20 +0000 Message-ID: <20190105162020.GA52639@breton.holly.idiocy.org> References: <20180410193824.GA15361@breton.holly.idiocy.org> <20180413183334.GA39515@breton.holly.idiocy.org> <20180424181933.GA48133@breton.holly.idiocy.org> <20180426204442.GB48707@breton.holly.idiocy.org> <17f6792bc79ba45c3c3be0bc00288ebb452275ec.camel@tenpoint.co.nz> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="+QahgC5+KEYLbs62" Content-Transfer-Encoding: 8bit X-Trace: blaine.gmane.org 1546705167 12135 195.159.176.226 (5 Jan 2019 16:19:27 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sat, 5 Jan 2019 16:19:27 +0000 (UTC) User-Agent: Mutt/1.10.1 (2018-07-13) Cc: 30929@debbugs.gnu.org To: Nick Helm Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Jan 05 17:19:23 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gfofQ-00031v-M8 for geb-bug-gnu-emacs@m.gmane.org; Sat, 05 Jan 2019 17:19:21 +0100 Original-Received: from localhost ([127.0.0.1]:59672 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gfohX-0005f6-F3 for geb-bug-gnu-emacs@m.gmane.org; Sat, 05 Jan 2019 11:21:31 -0500 Original-Received: from eggsout.gnu.org ([209.51.188.92]:34084 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gfoh7-0005R1-P1 for bug-gnu-emacs@gnu.org; Sat, 05 Jan 2019 11:21:07 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gfoh4-00013A-Gq for bug-gnu-emacs@gnu.org; Sat, 05 Jan 2019 11:21:05 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:52519) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gfoh4-00012y-AG for bug-gnu-emacs@gnu.org; Sat, 05 Jan 2019 11:21:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1gfoh4-0001ga-1Y for bug-gnu-emacs@gnu.org; Sat, 05 Jan 2019 11:21:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Alan Third Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 05 Jan 2019 16:21:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30929 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 30929-submit@debbugs.gnu.org id=B30929.15467052326420 (code B ref 30929); Sat, 05 Jan 2019 16:21:01 +0000 Original-Received: (at 30929) by debbugs.gnu.org; 5 Jan 2019 16:20:32 +0000 Original-Received: from localhost ([127.0.0.1]:48012 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gfogZ-0001fT-GD for submit@debbugs.gnu.org; Sat, 05 Jan 2019 11:20:32 -0500 Original-Received: from mail-wr1-f51.google.com ([209.85.221.51]:34174) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1gfogX-0001fG-68 for 30929@debbugs.gnu.org; Sat, 05 Jan 2019 11:20:30 -0500 Original-Received: by mail-wr1-f51.google.com with SMTP id j2so39259825wrw.1 for <30929@debbugs.gnu.org>; Sat, 05 Jan 2019 08:20:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=qI/dbhitA28jdUHOw9pzqta3d3q/o6NRLm6i0y8upaI=; b=ENt/RO6BrjXuaGWInETA7/KcDpdVTFQ0v43vClx/JdVGfdGmQl0LjYIz4WxWbMNMGX +xBjJejs2jEzd5OgUUmME1Ut23uxxi36pfyl0ydd1WBfH1iTHApsgS0auwIbn3eeZ6uJ K/hWzFxalT2YvLpO5vLKzXijhtOjMCGcPMu01++ksMNTV6r2aFO/ZL+37/IMCa0NPWMK HveQmdFoPlOBwtOW3coPNqqIfxDAbr9CsCNA7n4zhhgfiJjGeh9X5LCHhUPxfRTSimbb yJE/VelrRCBoGjnGcDr81+Bbb3v0XDZydcca6e+ISYn88liNrYIGATa9qTdB+F04iLM9 9J+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:from:to:cc:subject:message-id :references:mime-version:content-disposition :content-transfer-encoding:in-reply-to:user-agent; bh=qI/dbhitA28jdUHOw9pzqta3d3q/o6NRLm6i0y8upaI=; b=SEpazYRQGsN+6N4TE+ut9FLpKH+0XgZi51SEwbo+/FWVTVZ09N+8oODbfkAPmRiD1f L3fyU/oY70YDWyVERZqQbULgjUNII+YlTiAEWIh9LSZlBMDj4xqXaOuUf2d91hmDtsDz iSdJ1XMMoj/XyxHvkHvl1b9YlwF8S3hDAloQhZdLElpJ0recyq7rBlTjwQZNfofy/cyE R+c0RsTWOP3+SmhDsh9ql+p9kqyZXVUu7iT5Y+gXa/ZpZT+lTu5bStaD8vlf4JyvaIi2 lIAm6YeaWshTtrhZfOASQs9G6WBD2trOx4A35gUj3i/ig15wYfmdJRHk3+TAH1ctXUOF NoUg== X-Gm-Message-State: AJcUukfb8GoXfYvTIbpaJd2Q+nVSX8Bylh/EHutz0XEWr99JbRhwEIKj YSzRcZKp8tYSEMJT6U9CDlpjZ7oBefE= X-Google-Smtp-Source: ALg8bN71VqOuesWF3wSCUwWR4GeOtHFZM9VCtA6ixLcsbEYKe4SfhZDDiFNBWGXKxd55symMCoZVMQ== X-Received: by 2002:adf:e3d0:: with SMTP id k16mr49474959wrm.223.1546705223408; Sat, 05 Jan 2019 08:20:23 -0800 (PST) Original-Received: from breton.holly.idiocy.org (ip6-2001-08b0-03f8-8129-952c-07b1-cb8c-2eaf.holly.idiocy.org. [2001:8b0:3f8:8129:952c:7b1:cb8c:2eaf]) by smtp.gmail.com with ESMTPSA id q12sm3344138wmf.2.2019.01.05.08.20.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 05 Jan 2019 08:20:22 -0800 (PST) Content-Disposition: inline In-Reply-To: <17f6792bc79ba45c3c3be0bc00288ebb452275ec.camel@tenpoint.co.nz> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:154165 Archived-At: --+QahgC5+KEYLbs62 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit 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 --+QahgC5+KEYLbs62 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="0001-Fix-drag-and-drop-behaviour-on-NS.patch" >From 1d4cbb250bb0f8fd75a3c749b454c9b177c4dae7 Mon Sep 17 00:00:00 2001 From: Alan Third 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. + ---------------------------------------------------------------------- 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 ) 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 ) 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 ) 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 ) 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 --+QahgC5+KEYLbs62--