Subject: Re: bug#6677: 24.0.50; NS variant cannot copy to pasteboard correctly

From: David De La Harpe Golden <[email-masked]>
Date: Tue, 20 Jul 2010 23:18:56 +0100

On 20/07/10 11:13, Peter Dyballa wrote:
> Hello!
>
> Although it obviously works to copy some text in an X client or in a Mac
> OS X application and paste it into the *scratch* buffer it does not work
> to mark some text in any buffer of the NS variant and either use the
> Copy entry from the Edit menu or just press ⌘-C (Cmd-C) and insert
> (paste) it into the X client or a Mac OS X application (the name of the
> application in the  bar only flashes, because some bad content, not
> fitting into the text pane, is held in pasteboard?).
>

My MacOSX/GNUStep/ObjC, while not quite non-existent, is not amazing.

But it looks to me like src/nsselect.m  needs some adjustment so it can 
handle recent changes to defaults (and N.B. in fact to handle settings 
that have been possible for a long time)

It looks like it has been mapping NSGeneralPBoard (the macosx "normal" 
cut/copy/paste clipboard) to an emulated X11 PRIMARY, when in fact 
NSGeneralPBoard is much more closely analagous to X11 CLIPBOARD.

*** Since x11 emacs is now actually using X11 CLIPBOARD, it is likely 
that the attached  _untested_ but minor patch or something very like it 
is correct on nextstep.

Can you try building an emacs with the patch on macosx?

Note that even with the patch applied, it may not act quite the same as 
before, but that is not necessarily a bug but rather a change.

(N.B. it should be possible to get historical behaviour back (even 
though looking at nsselect.m it was probably a bit odd) by twiddling 
customizations).

> Additionally double-click to mark a word is interpreted as
> <down-mouse-1> <mouse-1>, bound to mouse-drag-region. I don't think that
> this is desirable...

N.B. Mouse-drag-region calls mouse-drag-track which calls 
mouse-start-end to _implement_ double-click to mark a word, perhaps not 
intuitively given the name. So does double-clicking nonetheless actually 
mark the word on NS?

--- src/nsselect.m.orig	2010-07-20 22:44:08.000000000 +0100
+++ src/nsselect.m	2010-07-20 22:53:05.000000000 +0100
@@ -31,51 +31,56 @@
 #include <setjmp.h>
 
 #include "lisp.h"
 #include "nsterm.h"
 #include "termhooks.h"
 
 #define CUT_BUFFER_SUPPORT
 
-Lisp_Object QPRIMARY, QSECONDARY, QTEXT, QFILE_NAME;
+Lisp_Object QCLIPBOARD, QPRIMARY, QSECONDARY, QTEXT, QFILE_NAME;
 
 static Lisp_Object Vns_sent_selection_hooks;
 static Lisp_Object Vns_lost_selection_hooks;
 static Lisp_Object Vselection_alist;
 static Lisp_Object Vselection_converter_alist;
 
 static Lisp_Object Qforeign_selection;
 
+/* NSGeneralPboard is pretty much analogous to X11 CLIPBOARD */
+NSString *NXPrimaryPboard;
 NSString *NXSecondaryPboard;

 /* ==========================================================================
 
     Internal utility functions
 
    ========================================================================== */

 static NSString *
 symbol_to_nsstring (Lisp_Object sym)
 {
   CHECK_SYMBOL (sym);
-  if (EQ (sym, QPRIMARY))     return NSGeneralPboard;
+  if (EQ (sym, QCLIPBOARD))     return NSGeneralPboard;
+  if (EQ (sym, QPRIMARY))     return NXPrimaryPboard;
   if (EQ (sym, QSECONDARY))   return NXSecondaryPboard;
   if (EQ (sym, QTEXT))        return NSStringPboardType;
   return [NSString stringWithUTF8String: SDATA (XSYMBOL (sym)->xname)];
 }

 static Lisp_Object
 ns_string_to_symbol (NSString *t)
 {
   if ([t isEqualToString: NSGeneralPboard])
+    return QCLIPBOARD;
+  if ([t isEqualToString: NXPrimaryPboard])
     return QPRIMARY;
   if ([t isEqualToString: NXSecondaryPboard])
     return QSECONDARY;
   if ([t isEqualToString: NSStringPboardType])
     return QTEXT;
   if ([t isEqualToString: NSFilenamesPboardType])
     return QFILE_NAME;
   if ([t isEqualToString: NSTabularTextPboardType])
@@ -531,22 +536,24 @@
   return Qnil;
 }
 #endif

 void
 nxatoms_of_nsselect (void)
 {
-  NXSecondaryPboard = @"Selection";
+  NXPrimaryPboard = @"PrimarySelection";
+  NXSecondaryPboard = @"SecondarySelection";
 }
 
 void
 syms_of_nsselect (void)
 {
+  QCLIPBOARD = intern ("CLIPBOARD");	staticpro (&QCLIPBOARD);
   QPRIMARY   = intern ("PRIMARY");	staticpro (&QPRIMARY);
   QSECONDARY = intern ("SECONDARY");	staticpro (&QSECONDARY);
   QTEXT      = intern ("TEXT"); 	staticpro (&QTEXT);
   QFILE_NAME = intern ("FILE_NAME"); 	staticpro (&QFILE_NAME);
 
   defsubr (&Sx_disown_selection_internal);
   defsubr (&Sx_get_selection_internal);
   defsubr (&Sx_own_selection_internal);