Subject: Re: bug#68914: Windows makes Emacs choke on and swallow the WIN keys

From: Raffael Stocker <[email-masked]>
Date: Sun, 04 Feb 2024 14:02:02 +0100

Eli Zaretskii <[email-masked]> writes:

> It would be better to have some independent verification that this is
> what happens.  Is there any way to find out whether the hook was
> removed, even from outside of Emacs?

MS say there is no direct way.  But for debugging it might be possible
to produce some output whenever the hook is called, if that is missing,
we would know.

> I find it hard to believe that
> we could miss the 200-ms deadline on modern systems.  Are your systems
> heavily loaded at times?  What kind of CPU do you have on those
> systems?  Emacs can hog CPU with only a single thread, so if your
> systems have a reasonably modern CPU, Windows should have plenty of
> execution units to spread any additional load without preempting
> Emacs.

It (also) happens when the systems are basically idle, with only some
keyboard input.  The systems are also relatively new (Intel i7 or i5
from a few years ago).

> Another idea is to add code to Emacs that measures the time it takes
> Emacs to produce the WM_KEYUP event, and log some message if that
> takes more than some threshold.

I have managed to set up a build environment on one of the machines and
I will try to experiment with this in the coming weeks. Perhaps I can
find out more.

>> - If Emacs being too slow somewhere is indeed the problem, can it be
>>   sped up, maybe by putting the slow stuff in a different thread than
>>   the low level keyboard handling?
>
> According to the MS documentation, the hook is called by sending a
> message to the thread that installed the hook, which in our case is
> already a separate thread, not the main Lisp thread (which is likely
> to be busy at times).  The thread which handles the hook callbacks is
> the input thread, which is relatively light-weight and shouldn't be
> too busy.

We saw the correlation with working on a network share and IIUC Windows
Defender blocks a process/thread while writing (or only closing?) a
file.  Therefore my suspicion.  But if saving files is not done in the
same thread as input, that can't be it...

>> - Can we put the workaround described above (with the LowLevelHooksTimeout
>>   value) into the Emacs documentation so it is findable?
>
> Please suggest the text to put in the manual to document this.

I attached a patch that adds a paragraph to the “Windows Keyboard” section.

>> This sets both ki.wVk and ki.wScan to the virtual-key code (0x5B for
>> VK_LWIN), but the ‘KEYEVENTF_EXTENDEDKEY’ flag is set, which IIUC would
>> require adding ‘0xE0’ to the virtual-key code to obtain the scan code,
>> e.g. 0xE05B for LWIN [1].  Can this cause any (additional) problems?
>
> I'm not an expert, but this code was working for years.  However, you
> could try making the change you propose and see if that solves the
> problem (or causes new ones).

I'll give it a try.

Regards,
Raffael

>From d227643ab02d8cf8b955df4034c6c00219a0cbc1 Mon Sep 17 00:00:00 2001
From: Raffael Stocker <[email-masked]>
Date: Sun, 4 Feb 2024 13:41:28 +0100
Subject: [PATCH] Document workaround for a stuck Windows key on MS-Windows
 (bug#68914)

* doc/emacs/msdos.texi (Windows Keyboard): describe workaround
---
 doc/emacs/msdos.texi | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/doc/emacs/msdos.texi b/doc/emacs/msdos.texi
index 861c0d90dc6..1c633adde65 100644
--- a/doc/emacs/msdos.texi
+++ b/doc/emacs/msdos.texi
@@ -697,6 +697,16 @@ Windows Keyboard
 its normal effect: for example, @kbd{@key{Lwindow}} opens the
 @code{Start} menu, etc.
 
+@cindex Windows key getting stuck (MS-Windows)
+  Some users experience the Windows key getting ``stuck'' while Emacs is
+running, that is, Windows behaves as if the key were permanently pressed
+down.  This may happen even when no Emacs frame is focussed.  If you see
+this behavior, you can try setting the variable
+@code{LowLevelHooksTimeout} in the registry key
+@samp{HKEY_CURRENT_USER\Control Panel\Desktop} to a higher value, adding
+it if it does not yet exist.  The default value is 200 ms, and it can be
+increased to up to 1000 ms.
+
 @vindex w32-recognize-altgr
 @kindex AltGr @r{(MS-Windows)}
 @cindex @key{AltGr} key (MS-Windows)
-- 
2.43.0