unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: "Mattias Engdegård" <mattiase@acm.org>
To: 38296@debbugs.gnu.org
Subject: bug#38296: Allow Option key to be modifier for non-char key and mouse events
Date: Wed, 20 Nov 2019 11:55:04 +0100	[thread overview]
Message-ID: <278BB45E-2B2A-4B98-A658-324F1E6F60D2@acm.org> (raw)

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

Mac users, especially those of us with a non-US keyboard, need the Option keys for entering various characters, and thus set 'ns-alternate-modifier' to nil, or use 'ns-right-alternate-modifier' to employ only one of them for this purpose. However, this prevents use of that key as modifier for function keys (arrows, backspace etc) or mouse actions.

This patch adds the variable 'ns-alternate-modifier-char-entry' which, when non-nil, inhibits the Option key translation to Emacs modifiers for character keys but allows it for any other event. For example, setting

(setq ns-alternate-modifier 'super)
(setq ns-alternate-modifier-char-entry t)

makes Option act as Super with function keys and mouse clicks, but retains the standard macOS semantics for character entry (for example, Option + p = π).


[-- Attachment #2: 0001-Add-ns-alternate-modifier-char-entry.patch --]
[-- Type: application/octet-stream, Size: 7468 bytes --]

From 57e5811920211a41cfd97db9da30acebc32024e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= <mattiase@acm.org>
Date: Tue, 19 Nov 2019 20:54:49 +0100
Subject: [PATCH] Add ns-alternate-modifier-char-entry

Allow the Option keys to be used for normal character entry while
having them generate Emacs modifiers for other events
by setting 'ns-alternate-modifier-char-entry' to non-nil.

* doc/emacs/macos.texi (Mac / GNUstep Basics): Document the variable.
* lisp/cus-start.el (standard): Allow customisation.
* src/nsterm.m (EV_MODIFIERS2): Add argument.
(EV_MODIFIERS): Adapt EV_MODIFIERS2 invocation.
(ns_get_shifted_character, [EmacsView keyDown:]): Use the new variable.
(syms_of_nsterm): Define the new variable.
* etc/NEWS: Mention the new variable.
---
 doc/emacs/macos.texi |  6 ++++++
 etc/NEWS             |  6 ++++++
 lisp/cus-start.el    |  1 +
 src/nsterm.m         | 35 +++++++++++++++++++++++++----------
 4 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/doc/emacs/macos.texi b/doc/emacs/macos.texi
index d9920957ad..85ede7bd68 100644
--- a/doc/emacs/macos.texi
+++ b/doc/emacs/macos.texi
@@ -61,6 +61,12 @@ Mac / GNUstep Basics
 ignore them, in which case you get the default behavior of macOS
 accentuation system from the right @key{Option} key.
 
+@vindex ns-alternate-modifier-char-entry
+  To make the @key{Option} keys retain their macOS behaviour for
+entering characters but work as Emacs modifiers with function keys and
+mouse actions, set the @code{ns-alternate-modifier-char-entry}
+variable to a non-nil value.
+
   @kbd{S-mouse-1} adjusts the region to the click position,
 just like @kbd{mouse-3} (@code{mouse-save-then-kill}); it does not pop
 up a menu for changing the default face, as @kbd{S-mouse-1} normally
diff --git a/etc/NEWS b/etc/NEWS
index db00d40bb6..75f54304fe 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -3218,6 +3218,12 @@ Previously it was supported only in the Cygwin-w32 build.
 ** Emacs now handles key combinations involving the macOS "command"
 and "option" modifier keys more correctly.
 
++++
+** New user option 'ns-alternate-modifier-char-entry'.
+Set to non-nil to allow the macOS "option" keys to be used for normal
+character entry while treating them as Emacs modifiers for function keys
+and mouse events.
+
 ** The special handling of 'frame-title-format' on NS where setting it
 to 't' would enable the macOS proxy icon has been replaced with a
 separate variable, 'ns-use-proxy-icon'.  'frame-title-format' will now
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index e4b6d8f2d6..9d50108204 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -470,6 +470,7 @@ minibuffer-prompt-properties--setter
 		      (const control) (const meta)
 		      (const alt) (const hyper)
 		      (const super)) "23.3")
+	     (ns-alternate-modifier-char-entry ns boolean "27.1")
 	     (ns-function-modifier
 	      ns
 	      (choice (const :tag "No modifier (work as function)" none)
diff --git a/src/nsterm.m b/src/nsterm.m
index e1d745e332..38a404620d 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -380,7 +380,7 @@ - (NSColor *)colorUsingDefaultColorSpace
   return modifiers;
 }
 
-#define EV_MODIFIERS2(flags)                                            \
+#define EV_MODIFIERS2(flags, enable_alternate_mod)                      \
   (((flags & NSEventModifierFlagHelp) ?                                 \
     hyper_modifier : 0)                                                 \
    | ((flags & NSEventModifierFlagShift) ?                              \
@@ -397,13 +397,15 @@ - (NSColor *)colorUsingDefaultColorSpace
                           NSEventModifierFlagCommand,                   \
                           ns_command_modifier,                          \
                           ns_right_command_modifier)                    \
-   | ev_modifiers_helper (flags, NSLeftAlternateKeyMask,                \
-                          NSRightAlternateKeyMask,                      \
-                          NSEventModifierFlagOption,                    \
-                          ns_alternate_modifier,                        \
-                          ns_right_alternate_modifier))
+   | (enable_alternate_mod                                              \
+      ? ev_modifiers_helper (flags, NSLeftAlternateKeyMask,             \
+                             NSRightAlternateKeyMask,                   \
+                             NSEventModifierFlagOption,                 \
+                             ns_alternate_modifier,                     \
+                             ns_right_alternate_modifier)               \
+      : 0))
 
-#define EV_MODIFIERS(e) EV_MODIFIERS2 ([e modifierFlags])
+#define EV_MODIFIERS(e) EV_MODIFIERS2 ([e modifierFlags], true)
 
 #define EV_UDMODIFIERS(e)                                      \
     ((([e type] == NSEventTypeLeftMouseDown) ? down_modifier : 0)       \
@@ -2630,13 +2632,15 @@ so some key presses (TAB) are swallowed by the system.  */
   NSTRACE ("ns_get_shifted_character");
 
   if ((flags & NSRightAlternateKeyMask) == NSRightAlternateKeyMask
-      && (EQ (ns_right_alternate_modifier, Qnone)
+      && (ns_alternate_modifier_char_entry
+          || EQ (ns_right_alternate_modifier, Qnone)
           || (EQ (ns_right_alternate_modifier, Qleft)
               && EQ (ns_alternate_modifier, Qnone))))
     modifiers |= rightOptionKey;
 
   if ((flags & NSLeftAlternateKeyMask) == NSLeftAlternateKeyMask
-      && EQ (ns_alternate_modifier, Qnone))
+      && (ns_alternate_modifier_char_entry
+          || EQ (ns_alternate_modifier, Qnone)))
     modifiers |= optionKey;
 
   if ((flags & NSRightCommandKeyMask) == NSRightCommandKeyMask
@@ -6287,7 +6291,8 @@ In that case we use UCKeyTranslate (ns_get_shifted_character)
          modifier keys, which returns 0 for shift-like modifiers.
          Therefore its return value is the set of control-like
          modifiers.  */
-      emacs_event->modifiers = EV_MODIFIERS2 (flags);
+      bool enable_alt = fnKeysym || !ns_alternate_modifier_char_entry;
+      emacs_event->modifiers = EV_MODIFIERS2 (flags, enable_alt);
 
       /* Function keys (such as the F-keys, arrow keys, etc.) set
          modifiers as though the fn key has been pressed when it
@@ -9414,6 +9419,16 @@ Convert an X font name (XLFD) to an NS font name.
 at all, allowing it to be used at a lower level for accented character entry.");
   ns_right_alternate_modifier = Qleft;
 
+  DEFVAR_BOOL ("ns-alternate-modifier-char-entry",
+               ns_alternate_modifier_char_entry,
+               "Whether the option or alternate keys are used for character entry.\n\
+When non-nil, the alternate / option keys work as Emacs modifiers for\n\
+function keys and mouse actions but not with character-generating keys.\n\
+When nil, the keys are interpreted by Emacs for all events.\n\
+In either case, `ns-alternate-modifier' and `ns-right-alternate-modifier'\n\
+describe what Emacs modifiers are being generated.");
+  ns_alternate_modifier_char_entry = false;
+
   DEFVAR_LISP ("ns-command-modifier", ns_command_modifier,
                "This variable describes the behavior of the command key.\n\
 Set to the symbol control, meta, alt, super, or hyper means it is taken to be\n\
-- 
2.21.0 (Apple Git-122)


             reply	other threads:[~2019-11-20 10:55 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-20 10:55 Mattias Engdegård [this message]
2019-11-21 18:39 ` bug#38296: Allow Option key to be modifier for non-char key and mouse events Mattias Engdegård
2019-11-21 21:12   ` Alan Third
2019-11-22 20:01     ` Mattias Engdegård
2019-11-25 19:15     ` Mattias Engdegård
2019-11-26 20:33       ` Alan Third
2019-11-26 21:36         ` Mattias Engdegård
2019-11-26 22:03           ` Alan Third
2019-11-27 10:50             ` Mattias Engdegård
2019-11-27  4:51           ` Eli Zaretskii
2019-11-27  6:40       ` Richard Stallman
2019-11-27 10:45         ` Mattias Engdegård
2019-11-28  4:17           ` Richard Stallman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=278BB45E-2B2A-4B98-A658-324F1E6F60D2@acm.org \
    --to=mattiase@acm.org \
    --cc=38296@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).