Subject: Re: bug#23251: 25.0.92; M-< and M-> don't work with Croatian keyboard

From: Ilya Zakharevich <[email-masked]>
Date: Sat, 16 Apr 2016 20:47:05 -0700

On Thu, Apr 14, 2016 at 06:21:28PM +0300, Eli Zaretskii wrote:
> Is it possible to devise a simple work-around that would depend on
> some optional variable?  The work-around doesn't need to handle all
> usage scenarios, just allow using a particular keyboard layout with
> reasonable results (e.g., it could break usage of some other layouts).
> 
> If such  work-around is possible, I think we should consider it for
> the upcoming Emacs 25.1 as a temporary stopgap.

I much prefer a simple heuristic which (hopefully) breaks orders of
magnitude less things than what it fixes.  Hopefully, this 2-LOC edit
must be such!

It affects ONLY the discussed case (“secondary” keys), and (if the
heuristic triggers) changes it by ONLY falling back to pre-my-patch
behaviour.  I put a lot of comments explaining what happens, and
REALLY hope that the cases where this patch HURTS would NEVER arise…

Hope this helps,
Ilya

--- w32fns.c-pre-secondary	2015-08-16 18:53:58.569735600 -0700
+++ w32fns.c	2016-04-16 19:30:38.026157600 -0700
@@ -3149,6 +3149,42 @@ deliver_wm_chars (int do_translate, HWND
                                wParam));
               if ((r & 0xFF) == wParam)
                 bitmap = r>>8; /* *b is reachable via simple interface */
+              else
+                {
+                  /* VkKeyScanW() (essentially) returns the FIRST key with
+                     the specified character; so here the pressed key is the
+                     SECONDARY key producing the character.
+
+                     Essentially, we have no information about the "role" of
+                     modifiers on this key: which contribute into the
+                     produced character (so "are consumed"), and which are
+                     "extra" (must attache to bindable events).
+
+                     The default above would consume ALL modifiers, so the
+                     character is reported "as is".  However, on many layouts
+                     the ordering of the keys (in the layout table) is not
+                     thought out well, so the "secondary" keys are often those
+                     which the users would prefer to use with Alt-CHAR.
+                     (Moreover - with e.g. Czech-QWERTY - the ASCII
+                     punctuation is accessible from two equally [nu]preferable
+                     AltGr-keys.)
+
+                     SO:   Heuristic: if the reported char is ASCII, AND Meta
+                     modifier is a candidate, behave as if Meta is present
+                     (fallback to the legacy branch; bug#23251).
+
+                     (This would break layouts
+                       - delivering ASCII characters
+                       - on SECONDARY keys
+                       - with not Shift/AltGr-like modifier combinations.
+                      All 3 conditions together must be pretty exotic
+                      cases - and a workaround exists: use "primary" keys!) */
+                   if (*b < 0x80
+                       && (wmsg.dwModifiers
+                           & (alt_modifier | meta_modifier
+                              | super_modifier | hyper_modifier)))
+                     return 0;
+                }
               if (*type_CtrlAlt == 'a') /* Simple Alt seen */
                 {
                   if ((bitmap & ~1) == 0) /* 1: KBDSHIFT */