Subject: 25.1; [PATCH] Caps-lock doesn't affect interpretation of key chords
From: Dima Kogan <[email-masked]>
To: [email-masked]
Date: Sun, 18 Sep 2016 00:01:23 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi.

I noticed that on some platforms the caps-lock state can affect how key
chords are interpreted. It is currently inconsistent across platforms.
The behavior that feels correct to me is that caps-lock should affect
the case of letters as they are typed, and NOTHING else.

On gtk, if caps-lock is ON then Control+s produces C-S-s and
Control+Shift+s produces C-s; this is backwards from what I think it
should do.

On OSX it looks like with caps-lock, both shifted and non-shifted
presses produce C-s, which is 50% wrong regardless of how one thinks
this SHOULD work.

On Windows it does the right thing.

In a console on Debian it looks like Control+Shift+s produces C-s
regardless of caps-lock, but I suspect this has a deeper cause than what
this patch touches.

I have tested this patch on gtk (fixes it) and the console (doesn't
change anything). Hopefully it makes osx work properly while letting
windows builds keep working.

From 7e34d122ff981c4a9eb671aa2400efbf65144506 Mon Sep 17 00:00:00 2001
From: Dima Kogan <[email-masked]>
Date: Sat, 17 Sep 2016 23:47:48 -0700
Subject: [PATCH] Caps-lock doesn't affect interpretation of key chords

* src/keyboard.c (make_lispy_event): when a user pressed key-chords the
caps-lock no longer affects the "shift" state of the generated chord.  For
instance Control+s produces C-s regardless of the caps-lock state.  And
Control+Shift+s produces C-S-s regardless of the caps-lock state.
---
 src/keyboard.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/src/keyboard.c b/src/keyboard.c
index b8bc361..a977de5 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5415,6 +5415,32 @@ make_lispy_event (struct input_event *event)
 	EMACS_INT c = event->code;
 	if (event->kind == ASCII_KEYSTROKE_EVENT)
 	  {
+            /* Caps-lock shouldn't affect interpretation of key chords:
+               Control+s should produce C-s whether caps-lock is on or
+               not.  And Control+Shift+s should produce C-S-s whether
+               caps-lock is on or not. */
+            if (event->modifiers & ~shift_modifier)
+              {
+                /* this is a key chord: some non-shift modifier is
+                   depressed */
+
+                if ('A' <= c && c <= 'Z' &&
+                    !(event->modifiers & shift_modifier) )
+                  {
+                    /* Got a capital letter without a shift.  The caps
+                       lock is on.   Un-capitalize the letter */
+                    c |= (unsigned)('a' - 'A');
+                  }
+                else if (('a' <= c && c <= 'z') &&
+                         (event->modifiers & shift_modifier) )
+                  {
+                    /* Got a lower-case letter even though shift is
+                       depressed.  The caps lock is on.  Capitalize the
+                       letter */
+                    c &= ~(unsigned)('a' - 'A');
+                  }
+              }
+
 	    c &= 0377;
 	    eassert (c == event->code);
 	    /* Turn ASCII characters into control characters
-- 
2.9.3