Package: emacs;
Reported by: Raffael Stocker <r.stocker <at> mnet-mail.de>
Date: Sat, 3 Feb 2024 22:23:02 UTC
Severity: normal
To reply to this bug, email your comments to 68914 AT debbugs.gnu.org.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
bug-gnu-emacs <at> gnu.org
:bug#68914
; Package emacs
.
(Sat, 03 Feb 2024 22:23:02 GMT) Full text and rfc822 format available.Raffael Stocker <r.stocker <at> mnet-mail.de>
:bug-gnu-emacs <at> gnu.org
.
(Sat, 03 Feb 2024 22:23:02 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Raffael Stocker <r.stocker <at> mnet-mail.de> To: bug-gnu-emacs <at> gnu.org Subject: Windows makes Emacs choke on and swallow the WIN keys Date: Sat, 03 Feb 2024 21:45:46 +0100
Hi, this is a weird one (and long, apologies). On MS Windows, it sometimes happens that a windows key gets stuck, that is, it remains (logically) pressed down, and this behaviour is correlated with Emacs use. A colleague and I are seeing this on two installations with Emacs 28.2 and 29.2 on Windows 10 and 11. Unfortunately, this is somewhat random and we have not found a way to trigger it directly. Emacs implements WIN key handling using the low level keyboard API in the ‘funhook’ callback function in ‘src/w32fnc.c’. Microsoft write about this hook that the application must handle the hook within some timeout. If it doesn't, the hook is silently removed [0]: MS> The hook procedure should process a message in less time than the data MS> entry specified in the LowLevelHooksTimeout value in the following MS> registry key: MS> MS> HKEY_CURRENT_USER**\**Control Panel**\**Desktop MS> MS> The value is in milliseconds. If the hook procedure times out, the MS> system passes the message to the next hook. However, on Windows 7 MS> and later, the hook is silently removed without being called. There MS> is no way for the application to know whether the hook is removed. MS> MS> Windows 10 version 1709 and later The maximum timeout value the MS> system allows is 1000 milliseconds (1 second). The system will MS> default to using a 1000 millisecond timeout if the MS> LowLevelHooksTimeout value is set to a value larger than 1000. It seems that this might be what happens to Emacs. Possibly Windows removes the keyboard hook due to a timeout, not giving Emacs a chance to produce a ‘WM_KEYUP’ event. And it seems to be correlated with working on Windows network shares; we also have Windows Defender active, which might make matters worse by slowing Emacs down while it is writing to a file. We have had good results with increasing the ‘LowLevelHooksTimeout’, but we had to set it to the maximum value of 1000 ms. I am not sure about the default value; the internet claims it to be 200 ms. A mid-range value (500 ms) alleviated the problem somewhat, but it seems to require the maximum to vanish, at least judging by a limited experience of a few days of observation. I am not sure there is an Emacs bug at all here, but I think it warrants some investigation: - Might it be possible to find a way to trigger this behaviour using a debugger? Unfortunately, I can neither compile nor debug on the Windows machines (company computers with limited usefulness...). - 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? - Can we put the workaround described above (with the LowLevelHooksTimeout value) into the Emacs documentation so it is findable? In related news, I noticed that the input events constructed in ‘funhook’ seem to use incorrect scan codes, for example starting at line 2630 in w32fns.c: --8<---------------cut here---------------start------------->8--- inputs[0].type = INPUT_KEYBOARD; inputs[0].ki.wVk = hs->vkCode; inputs[0].ki.wScan = hs->vkCode; inputs[0].ki.dwFlags = KEYEVENTF_EXTENDEDKEY; inputs[0].ki.time = 0; inputs[1].type = INPUT_KEYBOARD; inputs[1].ki.wVk = hs->vkCode; inputs[1].ki.wScan = hs->vkCode; inputs[1].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP; inputs[1].ki.time = 0; --8<---------------cut here---------------end--------------->8--- 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? And, BTW, why is the callback called ‘funhook’? Using the Windows low level keyboard API doesn't seem to be much fun and I can't see anyone get hooked on this either. Regards, Raffael [0] https://learn.microsoft.com/en-us/windows/win32/winmsg/lowlevelkeyboardproc [1] https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-keybdinput
bug-gnu-emacs <at> gnu.org
:bug#68914
; Package emacs
.
(Sun, 04 Feb 2024 06:32:02 GMT) Full text and rfc822 format available.Message #8 received at 68914 <at> debbugs.gnu.org (full text, mbox):
From: Eli Zaretskii <eliz <at> gnu.org> To: Raffael Stocker <r.stocker <at> mnet-mail.de> Cc: 68914 <at> debbugs.gnu.org Subject: Re: bug#68914: Windows makes Emacs choke on and swallow the WIN keys Date: Sun, 04 Feb 2024 08:31:15 +0200
> From: Raffael Stocker <r.stocker <at> mnet-mail.de> > Date: Sat, 03 Feb 2024 21:45:46 +0100 > > It seems that this might be what happens to Emacs. Possibly Windows > removes the keyboard hook due to a timeout, not giving Emacs a chance to > produce a ‘WM_KEYUP’ event. And it seems to be correlated with working > on Windows network shares; we also have Windows Defender active, which > might make matters worse by slowing Emacs down while it is writing to a > file. > > We have had good results with increasing the ‘LowLevelHooksTimeout’, but > we had to set it to the maximum value of 1000 ms. I am not sure about > the default value; the internet claims it to be 200 ms. A mid-range > value (500 ms) alleviated the problem somewhat, but it seems to require > the maximum to vanish, at least judging by a limited experience of a few > days of observation. 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? 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. 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. > - Might it be possible to find a way to trigger this behaviour using a > debugger? Unfortunately, I can neither compile nor debug on the > Windows machines (company computers with limited usefulness...). That's probably tricky, given the time constraints. > - 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. > - 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. > In related news, I noticed that the input events constructed in > ‘funhook’ seem to use incorrect scan codes, for example starting at line > 2630 in w32fns.c: > > --8<---------------cut here---------------start------------->8--- > inputs[0].type = INPUT_KEYBOARD; > inputs[0].ki.wVk = hs->vkCode; > inputs[0].ki.wScan = hs->vkCode; > inputs[0].ki.dwFlags = KEYEVENTF_EXTENDEDKEY; > inputs[0].ki.time = 0; > inputs[1].type = INPUT_KEYBOARD; > inputs[1].ki.wVk = hs->vkCode; > inputs[1].ki.wScan = hs->vkCode; > inputs[1].ki.dwFlags > = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP; > inputs[1].ki.time = 0; > --8<---------------cut here---------------end--------------->8--- > > 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). > And, BTW, why is the callback called ‘funhook’? Using the Windows low > level keyboard API doesn't seem to be much fun and I can't see anyone > get hooked on this either. I think this question is for the author of the code. I'm not sure he is reading this. There's nothing wrong with the name from my POV. Thanks.
bug-gnu-emacs <at> gnu.org
:bug#68914
; Package emacs
.
(Sun, 04 Feb 2024 13:16:01 GMT) Full text and rfc822 format available.Message #11 received at 68914 <at> debbugs.gnu.org (full text, mbox):
From: Raffael Stocker <r.stocker <at> mnet-mail.de> To: Eli Zaretskii <eliz <at> gnu.org> Cc: 68914 <at> debbugs.gnu.org Subject: Re: bug#68914: Windows makes Emacs choke on and swallow the WIN keys Date: Sun, 04 Feb 2024 14:02:02 +0100
[Message part 1 (text/plain, inline)]
Eli Zaretskii <eliz <at> gnu.org> 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
[0001-Document-workaround-for-a-stuck-Windows-key-on-MS-Wi.patch (text/x-patch, attachment)]
bug-gnu-emacs <at> gnu.org
:bug#68914
; Package emacs
.
(Sun, 04 Feb 2024 13:34:02 GMT) Full text and rfc822 format available.Message #14 received at 68914 <at> debbugs.gnu.org (full text, mbox):
From: Nikolay Kudryavtsev <nikolay.kudryavtsev <at> gmail.com> To: Raffael Stocker <r.stocker <at> mnet-mail.de>, 68914 <at> debbugs.gnu.org Subject: Re: bug#68914: Windows makes Emacs choke on and swallow the WIN keys Date: Sun, 4 Feb 2024 16:32:48 +0300
Hello. I think I've seen this bug in the wild a couple of times too. But there's something else. I'm not sure if it's the same bug, but something's been iffy about Emacs keyboard input handling on Windows for the last few major versions. Unfortunately I've yet to find a simple reproduction recipe and hence why I haven't filled that one the tracker. The problem is as follows. I use a certain piece of software that switches between keyboard layouts by CAPS LOCK. So CAPS LOCK, the feature, is normally mostly inactive on my machine and requires a certain other combination to activate. Emacs normally respects that. Except when it's under a load running lisp code. During that time there are time intervals during which pressing CAPS LOCK would incorrectly set it on for me. One way I can reliably reproduce this is by doing M-x list-packages and then tapping CAPS LOCK. At some point it would light up. Thus I believe that the input handling intermittently breaks during the high load(lisp evaluation). My testing had shown that the last version that does not suffer from this is Emacs 25. Just posting this in case it's the same problem and this information is of any use in debugging.
bug-gnu-emacs <at> gnu.org
:bug#68914
; Package emacs
.
(Sun, 04 Feb 2024 13:57:03 GMT) Full text and rfc822 format available.Message #17 received at 68914 <at> debbugs.gnu.org (full text, mbox):
From: Eli Zaretskii <eliz <at> gnu.org> To: Nikolay Kudryavtsev <nikolay.kudryavtsev <at> gmail.com> Cc: r.stocker <at> mnet-mail.de, 68914 <at> debbugs.gnu.org Subject: Re: bug#68914: Windows makes Emacs choke on and swallow the WIN keys Date: Sun, 04 Feb 2024 15:56:31 +0200
> From: Nikolay Kudryavtsev <nikolay.kudryavtsev <at> gmail.com> > Date: Sun, 4 Feb 2024 16:32:48 +0300 > > But there's something else. I'm not sure if it's the same bug, but > something's been iffy about Emacs keyboard input handling on Windows for > the last few major versions. I don't think it's the same issue. I suggest submitting a separate bug report with the details. > Unfortunately I've yet to find a simple reproduction recipe and hence > why I haven't filled that one the tracker. The problem is as follows. > > I use a certain piece of software that switches between keyboard layouts > by CAPS LOCK. So CAPS LOCK, the feature, is normally mostly inactive on > my machine and requires a certain other combination to activate. Emacs > normally respects that. Except when it's under a load running lisp code. > During that time there are time intervals during which pressing CAPS > LOCK would incorrectly set it on for me. > > One way I can reliably reproduce this is by doing M-x list-packages and > then tapping CAPS LOCK. At some point it would light up. In the bug report I suggest to submit, please describe in more detail how to reproduce this using list-packages. How to "tap CAPS LOCK" and what to look for while doing that. I just tried naïvely to reproduce that and didn't see any problems, probably because I didn't know where to look. > Thus I believe that the input handling intermittently breaks during the > high load(lisp evaluation). > > My testing had shown that the last version that does not suffer from > this is Emacs 25. Emacs 26 introduced the low-level keyboard hook.
bug-gnu-emacs <at> gnu.org
:bug#68914
; Package emacs
.
(Sun, 04 Feb 2024 14:16:01 GMT) Full text and rfc822 format available.Message #20 received at 68914 <at> debbugs.gnu.org (full text, mbox):
From: Eli Zaretskii <eliz <at> gnu.org> To: Raffael Stocker <r.stocker <at> mnet-mail.de> Cc: 68914 <at> debbugs.gnu.org Subject: Re: bug#68914: Windows makes Emacs choke on and swallow the WIN keys Date: Sun, 04 Feb 2024 16:14:57 +0200
> From: Raffael Stocker <r.stocker <at> mnet-mail.de> > Cc: 68914 <at> debbugs.gnu.org > Date: Sun, 04 Feb 2024 14:02:02 +0100 > > > 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. That could be a good solution, yes. > > 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). That's even weirder. > > 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. Thanks. > >> - 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... Our input thread doesn't write to any files, not in our code anyway. It just runs the message pump and little else. > >> - 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. On second thought, I think this kind of problems are better described in etc/PROBLEMS, so I have now added something there with the description of the problem and the workaround/
bug-gnu-emacs <at> gnu.org
:bug#68914
; Package emacs
.
(Mon, 12 Feb 2024 20:56:01 GMT) Full text and rfc822 format available.Message #23 received at 68914 <at> debbugs.gnu.org (full text, mbox):
From: Raffael Stocker <r.stocker <at> mnet-mail.de> To: Eli Zaretskii <eliz <at> gnu.org> Cc: 68914 <at> debbugs.gnu.org Subject: Re: bug#68914: Windows makes Emacs choke on and swallow the WIN keys Date: Mon, 12 Feb 2024 21:13:27 +0100
[Message part 1 (text/plain, inline)]
I have added debug output to the keyboard hook (see the attached patch) and was able to observe the bug while Emacs was unresponsive (either because the current master is iffy on Windows or because of my output...). The locked windows key problem seems to appear when an s-<something> combination is pressed. Normal debug output looks like this: --8<---------------cut here---------------start------------->8--- KEYDOWN 0x5b, 0x5b: 0.0018 ms Simulated S-x combination: 0.647 ms KEYUP received, winsdown: 1, w: 0x101 no key pressed anymore, clear flags KEYUP processed normally: 4.57 ms --8<---------------cut here---------------end--------------->8--- Emacs first registers the windows key to be pressed in a WM_KEYDOWN event, then upon the second call of ‘funhook’ sees the other key in the combination and sends a WIN+<x> input to the system and then in the third call receives the WM_KEYUP event, cleans up its state and calls ‘CallNextHookEx’ to let other applications in the hook chain process the combination normally. The times are the execution times of the hook. With the bug present, I get the following output: --8<---------------cut here---------------start------------->8--- KEYDOWN 0x5b, 0x5b: 0.0005 ms Simulated S-x combination: 1.08 ms 0 < winsdown = 1: 0.0015 ms 0 < winsdown = 1: 0.0015 ms 0 < winsdown = 1: 0.0016 ms --8<---------------cut here---------------end--------------->8--- The WM_KEYUP event is missing here; instead, if I press any key, Emacs ignores it and calls ‘CallNextHookEx’ normally; the above output shows three such key presses. If I press ‘e’ now, Windows Explorer will open. That is, Emacs doesn't seem to receive the WM_KEYUP event, but the system doesn't seem to see it either (unless my understanding of the situation is completely wrong). Note that the times shown above are very short; I have seen up to 15 ms, but nothing longer. Emacs was unresponsive for a few seconds while the behaviour occurred; but if the hook was removed by Windows, this was not permanent, as the remaining output shows. Also, pressing a windows key seems to cure the problem in this case. I will continue to observe this and try to find out more, but any insights are welcome. Regards, Raffael
[funhook-debug-prints.patch (text/x-patch, attachment)]
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.