unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Free modifier key assignment (OS X)
@ 2005-09-25 20:34 David Reitter
  2005-09-26 13:18 ` Stefan Monnier
  2005-09-27  3:45 ` YAMAMOTO Mitsuharu
  0 siblings, 2 replies; 10+ messages in thread
From: David Reitter @ 2005-09-25 20:34 UTC (permalink / raw)



[-- Attachment #1.1.1: Type: text/plain, Size: 895 bytes --]

Here is the latest version of mac-modifier-keys patch, which allows  
people to freely assign modifier keys on their keyboard to Emacs  
modifiers.

The current solution is overly complicated and doesn't allow certain  
combinations of settings such as Command->Hyper (while saying Option- 
 >Meta). The reasoning behind it is described here.

http://lists.gnu.org/archive/html/emacs-devel/2005-05/msg00661.html

Note that any xmodmap solution people may think of will not work on  
OS X when using Carbon - OS X doesn't normally use X11 for its  
graphics output.

I would like to recommend applying this now before the release is  
readied, because otherwise one will have to change customization  
options that get documented in the release. The present patch allows  
for longer-term stability. (It is backwards-compatible to cater for  
the many people who've been installing CVS Emacs.)



[-- Attachment #1.1.2: mac-modifier-keys.patch --]
[-- Type: application/octet-stream, Size: 16644 bytes --]

Index: src/macterm.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/macterm.c,v
retrieving revision 1.123
diff -c -r1.123 macterm.c
*** src/macterm.c	14 Jul 2005 09:23:24 -0000	1.123
--- src/macterm.c	15 Jul 2005 23:15:49 -0000
***************
*** 86,99 ****
  #include "atimer.h"
  #include "keymap.h"
  
! /* Set of macros that handle mapping of Mac modifier keys to emacs.  */
! #define macCtrlKey     (NILP (Vmac_reverse_ctrl_meta) ? controlKey :	\
! 			(NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey))
  #define macShiftKey    (shiftKey)
! #define macMetaKey     (NILP (Vmac_reverse_ctrl_meta) ?			\
! 			(NILP (Vmac_command_key_is_meta) ? optionKey : cmdKey) \
! 			: controlKey)
! #define macAltKey      (NILP (Vmac_command_key_is_meta) ? cmdKey : optionKey)
  \f
  
  /* Non-nil means Emacs uses toolkit scroll bars.  */
--- 86,118 ----
  #include "atimer.h"
  #include "keymap.h"
  
! /* Set of macros that handle mapping of Mac modifier keys to emacs.  
!     If any of the newer-style mac_*_modifier variables is set, these 
!     macros are basically out of function.
!  */
!  
! #define macOldModifierSetting   (  NILP(Vmac_control_modifier) && \
! 				   NILP(Vmac_option_modifier) && \
! 				   NILP(Vmac_command_modifier)   )
!  
! #define macCtrlKey     (macOldModifierSetting ? \
!  			(NILP(Vmac_reverse_ctrl_meta) ? controlKey :	\
!  			       (NILP(Vmac_command_key_is_meta) ? \
! 				optionKey : cmdKey)) :		 \
!  			controlKey)
  #define macShiftKey    (shiftKey)
!  
! #define macMetaKey     (macOldModifierSetting ? \
!  			(NILP(Vmac_reverse_ctrl_meta) ?		\
!  			 (NILP(Vmac_command_key_is_meta) ? optionKey : \
! 			  cmdKey) : controlKey) :		       \
!  			(cmdKey | controlKey | optionKey))
!  
! #define macAltKey     (macOldModifierSetting ?  \
! 			(NILP(Vmac_command_key_is_meta) ? \
! 			 cmdKey : optionKey) : optionKey)
!  
! #define macCmdKey (cmdKey)
  \f
  
  /* Non-nil means Emacs uses toolkit scroll bars.  */
***************
*** 205,211 ****
  
  /* The keysyms to use for the various modifiers.  */
  
! static Lisp_Object Qalt, Qhyper, Qsuper, Qmodifier_value;
  
  extern int inhibit_window_system;
  
--- 224,230 ----
  
  /* The keysyms to use for the various modifiers.  */
  
! static Lisp_Object Qalt, Qhyper, Qsuper, Qctrl, Qmeta, Qmodifier_value;
  
  extern int inhibit_window_system;
  
***************
*** 7321,7333 ****
  /* Contains the string "reverse", which is a constant for mouse button emu.*/
  Lisp_Object Qreverse;
  
! /* True if using command key as meta key.  */
  Lisp_Object Vmac_command_key_is_meta;
  
  /* Modifier associated with the option key, or nil for normal behavior. */
  Lisp_Object Vmac_option_modifier;
  
! /* True if the ctrl and meta keys should be reversed.  */
  Lisp_Object Vmac_reverse_ctrl_meta;
  
  /* True if the option and command modifiers should be used to emulate
--- 7340,7360 ----
  /* Contains the string "reverse", which is a constant for mouse button emu.*/
  Lisp_Object Qreverse;
  
! /* True if using command key as meta key.  
!    Deprecated; only use if macOldModifierSetting evaluates to true. */
  Lisp_Object Vmac_command_key_is_meta;
  
+ /* Modifier associated with the control key, or nil for normal behavior. */
+ Lisp_Object Vmac_control_modifier;
+ 
  /* Modifier associated with the option key, or nil for normal behavior. */
  Lisp_Object Vmac_option_modifier;
  
! /* Modifier associated with the command key, or nil for normal behavior. */
! Lisp_Object Vmac_command_modifier;
! 
! /* True if the ctrl and meta keys should be reversed. 
! 	Deprecated; only use if macOldModifierSetting evaluates to true. */
  Lisp_Object Vmac_reverse_ctrl_meta;
  
  /* True if the option and command modifiers should be used to emulate
***************
*** 7347,7352 ****
--- 7374,7386 ----
     for processing before Emacs sees it.  */
  Lisp_Object Vmac_pass_control_to_system;
  
+ /* If  non-nil, the Mac \"Option\" key can be used to compose
+        characters as handled by the system and depending on the
+        keyboard layout chosen. Only if the Mac \"Command\" or \"Ctrl\" key
+        is depressed at the same time, Emacs evaluates the combination using
+        whatever modifier is set in mac-option-modifier.  */
+ Lisp_Object Vmac_pass_option_to_system;
+ 
  /* Points to the variable `inev' in the function XTread_socket.  It is
     used for passing an input event to the function back from
     Carbon/Apple event handlers.  */
***************
*** 7404,7420 ****
    unsigned int result = 0;
    if (mods & macShiftKey)
      result |= shift_modifier;
!   if (mods & macCtrlKey)
!     result |= ctrl_modifier;
!   if (mods & macMetaKey)
!     result |= meta_modifier;
!   if (NILP (Vmac_command_key_is_meta) && (mods & macAltKey))
!     result |= alt_modifier;
!   if (!NILP (Vmac_option_modifier) && (mods & optionKey)) {
!       Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value);
!       if (!NILP(val))
            result |= XUINT(val);
!   }
  
    return result;
  }
--- 7438,7512 ----
    unsigned int result = 0;
    if (mods & macShiftKey)
      result |= shift_modifier;
! 
!   if (macOldModifierSetting)   /* compatibility with old-style modifier keys */
!     {
!       if (mods & macCtrlKey)
! 	result |= ctrl_modifier;
!       if (mods & macMetaKey)
! 	result |= meta_modifier;
! 
!       if ( ( NILP(Vmac_pass_option_to_system) || 
! 	     ( /* only for ctrl/cmd combos if option is handled by system */
! 	      (mods & cmdKey) || (mods & controlKey) 
! 	       )
! 	     ) &&
! 	   !NILP (Vmac_command_key_is_meta) &&
! 	   (mods & macAltKey) 
! 	)
! 	result |= alt_modifier;
!     } else
!     {
!       /* new-style modifier keys */ 
! 
!       /* if Vmac_pass_option_to_system is NIL, we fully process the Option
! 	 key. Otherwise, we only process it if an additional Ctrl or Command
! 	 is pressed. That way the system may convert the character to a 
! 	 composed one.
!       */
! 
!       if (
! 	  (mods & optionKey) &&
! 	  (
! 	   ( NILP(Vmac_pass_option_to_system) || 
! 	     ( 
! 	      (mods & cmdKey) || (mods & controlKey) 
! 	       )
! 	     )
! 	   )
! 	  )
! 	{
! 	  if (!NILP (Vmac_option_modifier)) {
! 	    Lisp_Object val = Fget(Vmac_option_modifier, Qmodifier_value);
! 	    if (!NILP(val))
! 	      result |= XUINT(val);
! 	  } else { /* default behavior if modifier variable is set to nil: 
! 		      do NOT assume alt modifier, because the OS already 
! 		      sends a modified key (e.g. option-l -> @ 
! 		      on German keyboard) */
! 	      
! 	      result |= alt_modifier;  
! 	  }
! 
! 	}
!       if (!NILP (Vmac_command_modifier) && (mods & cmdKey)) {
! 	Lisp_Object val = Fget(Vmac_command_modifier, Qmodifier_value);
! 	if (!NILP(val))
            result |= XUINT(val);
!       } else { /* default behavior if modifier variable is not set: 
! 		  assign hyper*/
! 	if (mods & macCmdKey)
! 	  result |= hyper_modifier;
!       }
!       if (!NILP (Vmac_control_modifier) && (mods & controlKey)) {
! 	Lisp_Object val = Fget(Vmac_control_modifier, Qmodifier_value);
! 	if (!NILP(val))
!           result |= XUINT(val);
!       } else { /* default behavior if modifier variable is not set */
! 	if (mods & macCtrlKey)
! 	  result |= ctrl_modifier;
!       }
!     }
  
    return result;
  }
***************
*** 9326,9334 ****
  		 || !(er.modifiers & cmdKey))
  		&& (!NILP (Vmac_pass_control_to_system)
  		    || !(er.modifiers & controlKey))
! 		&& (!NILP (Vmac_command_key_is_meta)
! 		    && NILP (Vmac_option_modifier)
! 		    || !(er.modifiers & optionKey)))
  	      if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
  		  != eventNotHandledErr)
  		break;
--- 9418,9431 ----
  		 || !(er.modifiers & cmdKey))
  		&& (!NILP (Vmac_pass_control_to_system)
  		    || !(er.modifiers & controlKey))
! 		&& (!NILP (Vmac_pass_option_to_system)
! 		    || (macOldModifierSetting ?
! 		    ((!NILP (Vmac_command_key_is_meta)
! 		      && NILP (Vmac_option_modifier)
! 		      || !(er.modifiers & optionKey)))
! 			:  !(er.modifiers & optionKey))
! 		    )
! 		)
  	      if (SendEventToEventTarget (eventRef, toolbox_dispatcher)
  		  != eventNotHandledErr)
  		break;
***************
*** 9377,9386 ****
  		inev.kind = NON_ASCII_KEYSTROKE_EVENT;
  	      }
  	    else
! 	      {
! 		if (er.modifiers & (controlKey |
! 				    (NILP (Vmac_command_key_is_meta) ? optionKey
! 				     : cmdKey)))
  		  {
  		    /* This code comes from Keyboard Resource,
  		       Appendix C of IM - Text.  This is necessary
--- 9474,9492 ----
  		inev.kind = NON_ASCII_KEYSTROKE_EVENT;
  	      }
  	    else
! 	      { 
! 		if  (er.modifiers & (controlKey | 
! 				     (NILP (Vmac_pass_option_to_system) ? optionKey : 0) | 
!  				     (
!  				      (macOldModifierSetting ?  
!  				       (NILP (Vmac_command_key_is_meta) ? 
!  					optionKey : cmdKey
!  					) 
!  				       : cmdKey
!  				       )
!  				      )  
!  				     )
!  		     )
  		  {
  		    /* This code comes from Keyboard Resource,
  		       Appendix C of IM - Text.  This is necessary
***************
*** 9388,9394 ****
  		       translation when option or command is pressed.
  		       It also does not translate correctly
  		       control-shift chars like C-% so mask off shift
! 		       here also */
  		    int new_modifiers = er.modifiers & 0xe600;
  		    /* mask off option and command */
  		    int new_keycode = keycode | new_modifiers;
--- 9494,9507 ----
  		       translation when option or command is pressed.
  		       It also does not translate correctly
  		       control-shift chars like C-% so mask off shift
! 		       here also.
! 
! 		       For combinations with the option key (alt), this is only
! 		       done if either command or control are used additionally,
! 		       in which case this isn't handled 
! 		       or if mac-pass-option-to-system is nil  -- in order
! 		       to preserve key combinations translated by the OS, such as Alt-3.
! 		    */
  		    int new_modifiers = er.modifiers & 0xe600;
  		    /* mask off option and command */
  		    int new_keycode = keycode | new_modifiers;
***************
*** 9397,9415 ****
  		    inev.code = KeyTranslate (kchr_ptr, new_keycode,
  					      &some_state) & 0xff;
  		  }
- 		else if (!NILP (Vmac_option_modifier)
- 			 && (er.modifiers & optionKey))
- 		  {
- 		    /* When using the option key as an emacs modifier,
- 		       convert the pressed key code back to one
- 		       without the Mac option modifier applied. */
- 		    int new_modifiers = er.modifiers & ~optionKey;
- 		    int new_keycode = keycode | new_modifiers;
- 		    Ptr kchr_ptr = (Ptr) GetScriptManagerVariable (smKCHRCache);
- 		    unsigned long some_state = 0;
- 		    inev.code = KeyTranslate (kchr_ptr, new_keycode,
- 					      &some_state) & 0xff;
- 		  }
  		else
  		  inev.code = er.message & charCodeMask;
  		inev.kind = ASCII_KEYSTROKE_EVENT;
--- 9510,9515 ----
***************
*** 10029,10034 ****
--- 10129,10138 ----
  #if TARGET_API_MAC_CARBON
    init_required_apple_events ();
  
+   Qctrl = intern ("ctrl");
+   Fput (Qctrl, Qmodifier_value, make_number (ctrl_modifier));
+   Qmeta = intern ("meta");
+   Fput (Qmeta, Qmodifier_value, make_number (meta_modifier)); 
  #if USE_CARBON_EVENTS
  #ifdef MAC_OSX
    init_service_handler ();
***************
*** 10079,10084 ****
--- 10183,10191 ----
  #ifdef MAC_OSX
    Fprovide (intern ("mac-carbon"), Qnil);
  #endif
+ /* Deprecated variables to configure modifier key assignment.
+ 	Retained for backward-compatibility. */
+ 	
  
    staticpro (&Qreverse);
    Qreverse = intern ("reverse");
***************
*** 10105,10123 ****
  
    DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta,
      doc: /* Non-nil means that the command key is used as the Emacs meta key.
! Otherwise the option key is used.  */);
    Vmac_command_key_is_meta = Qt;
  
    DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier,
      doc: /* Modifier to use for the Mac alt/option key.  The value can
  be alt, hyper, or super for the respective modifier.  If the value is
! nil then the key will act as the normal Mac option modifier.  */);
    Vmac_option_modifier = Qnil;
  
!   DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta,
!     doc: /* Non-nil means that the control and meta keys are reversed.  This is
! useful for non-standard keyboard layouts.  */);
!   Vmac_reverse_ctrl_meta = Qnil;
  
    DEFVAR_LISP ("mac-emulate-three-button-mouse",
  	       &Vmac_emulate_three_button_mouse,
--- 10212,10267 ----
  
    DEFVAR_LISP ("mac-command-key-is-meta", &Vmac_command_key_is_meta,
      doc: /* Non-nil means that the command key is used as the Emacs meta key.
! Otherwise the option key is used. This variable is DEPRECATED. 
! It is only in effect if all of the variables mac-*-modifier are nil. */);
    Vmac_command_key_is_meta = Qt;
+   
+   DEFVAR_LISP ("mac-reverse-ctrl-meta", &Vmac_reverse_ctrl_meta,
+     doc: /* Non-nil means that the control and meta keys are reversed.  This is
+ useful for non-standard keyboard layouts. This variable is DEPRECATED. 
+ Backwards-compatibility: It is only in effect if none of the variables 
+ mac-{command|control|option}-modifier is non-nil. */);
+   Vmac_reverse_ctrl_meta = Qnil;
+ 
+ 
+ /* Variables to configure modifier key assignment.  */
+ 	
+   DEFVAR_LISP ("mac-control-modifier", &Vmac_control_modifier,
+     doc: /* Modifier to use for the Mac control key.  The value can
+ be alt, hyper, or super for the respective modifier.  If the value is
+ nil then the key will act as the normal Mac control modifier.  
+ Backwards-compatibility: If all values of 
+ mac-{command|control|option}-modifier are nil, the deprecated
+ default assignment determined by mac-command-key-is-meta and
+ mac-reverse-ctrl-meta is used. */);
+   Vmac_control_modifier = Qnil;
  
    DEFVAR_LISP ("mac-option-modifier", &Vmac_option_modifier,
      doc: /* Modifier to use for the Mac alt/option key.  The value can
  be alt, hyper, or super for the respective modifier.  If the value is
! nil then the key will act as the normal Mac option modifier, and the option
! key can be used to compose characters depending on the chosen Mac keyboard
! setting. 
! Note that mac-pass-option-to-system takes precedence over this setting. If 
! mac-pass-option-to-system is non-nil, simple key combinations with Option
! will be handled by the system in order to produce characters, and only
! combinations in conjunction with Command or Control will let Emacs see
! the modifier that is assigned to the Option key. 
! Backwards-compatibility: If all values of 
! mac-{command|control|option}-modifier are nil, the deprecated default 
! assignment determined by mac-command-key-is-meta and
! mac-reverse-ctrl-meta is used.  */);
    Vmac_option_modifier = Qnil;
  
!   DEFVAR_LISP ("mac-command-modifier", &Vmac_command_modifier,
!     doc: /* Modifier to use for the Mac command key.  The value can
! be alt, hyper, or super for the respective modifier. If the value is
! nil then the key will act as the Emacs 'hyper' modifier. 
! Backwards-compatibility: If all values of 
! mac-{command|control|option}-modifier are nil, the deprecated
! default assignment determined by mac-command-key-is-meta and
! mac-reverse-ctrl-meta is used.  */);
!   Vmac_command_modifier = Qnil;
  
    DEFVAR_LISP ("mac-emulate-three-button-mouse",
  	       &Vmac_emulate_three_button_mouse,
***************
*** 10146,10151 ****
--- 10290,10303 ----
     doc: /* If non-nil, the Mac \"Control\" key is passed on to the Mac
  Toolbox for processing before Emacs sees it.  */);
    Vmac_pass_control_to_system = Qt;
+ 
+   DEFVAR_LISP ("mac-pass-option-to-system", &Vmac_pass_option_to_system,
+    doc: /* If  non-nil, the Mac \"Option\" key can be used to compose
+       characters as handled by the system and depending on the
+       keyboard layout chosen. Only if the Mac \"Command\" or \"Ctrl\" key
+       is depressed at the same time, Emacs evaluates the combination using
+       whatever modifier is set in mac-option-modifier.  */);
+   Vmac_pass_option_to_system = Qt;
  
  #endif
  

[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2400 bytes --]

[-- Attachment #2: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel

^ permalink raw reply	[flat|nested] 10+ messages in thread
* Carbon port: M-§ not recognized (Italian keyboards)
@ 2005-12-11 17:33 David Reitter
  2005-12-12  2:41 ` YAMAMOTO Mitsuharu
  0 siblings, 1 reply; 10+ messages in thread
From: David Reitter @ 2005-12-11 17:33 UTC (permalink / raw)


It seems like M-§ isn't recognized as such on Italian keyboards in  
the Mac (Carbon) port.
define-key for this sequence doesn't show an effect, and the error  
message is
	
	M-¤ is undefined

suggesting that something goes wrong with back-translating the  
keycode in macterm.c.
Does anyone have a good suggestion about the underlying cause of this?

Note that this is with (setq mac-option-modifier 'meta).

Option-§ is - by default - bound to @ under OS X, so getting that key  
to work properly would bear some significance, because people might  
want to manually bind this key to something like (insert "@").]

(Apart from that, "\M-(" gives me a nice "\250", while "\M-§" gives  
me just "§". I assume this has traditional reasons.)

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

end of thread, other threads:[~2006-05-20  8:26 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-09-25 20:34 Free modifier key assignment (OS X) David Reitter
2005-09-26 13:18 ` Stefan Monnier
2005-09-27  3:45 ` YAMAMOTO Mitsuharu
2005-09-27 10:01   ` David Reitter
2005-09-28  8:28     ` YAMAMOTO Mitsuharu
2006-05-20  8:26       ` YAMAMOTO Mitsuharu
2005-12-13  3:26   ` Carbon port: M-§ not recognized (Italian keyboards) YAMAMOTO Mitsuharu
  -- strict thread matches above, loose matches on Subject: below --
2005-12-11 17:33 David Reitter
2005-12-12  2:41 ` YAMAMOTO Mitsuharu
2006-01-17  0:26   ` David Reitter

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).