all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Raffael Stocker <r.stocker@mnet-mail.de>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 68914@debbugs.gnu.org
Subject: bug#68914: Windows makes Emacs choke on and swallow the WIN keys
Date: Mon, 12 Feb 2024 21:13:27 +0100	[thread overview]
Message-ID: <yplma5o5pg9k.fsf@mnet-mail.de> (raw)
In-Reply-To: <865xz42u5a.fsf@gnu.org>

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


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


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: funhook debug output --]
[-- Type: text/x-patch, Size: 5214 bytes --]

diff --git a/src/w32fns.c b/src/w32fns.c
index 1d5a591466c..b2572463e04 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -20,6 +20,7 @@ Copyright (C) 1989, 1992-2024 Free Software Foundation, Inc.
 /* Added by Kevin Gallo */
 
 #include <config.h>
+#include <time.h>
 /* Override API version to get the latest functionality.  */
 #undef _WIN32_WINNT
 #define _WIN32_WINNT 0x0600
@@ -2556,6 +2557,8 @@ funhook (int code, WPARAM w, LPARAM l)
   int console = 0;
   KBDLLHOOKSTRUCT const *hs = (KBDLLHOOKSTRUCT*)l;
 
+  struct timespec begin;
+  clock_gettime (CLOCK_MONOTONIC, &begin);
   if (code < 0 || (hs->flags & LLKHF_INJECTED))
     return CallNextHookEx (0, code, w, l);
 
@@ -2595,6 +2598,11 @@ funhook (int code, WPARAM w, LPARAM l)
 	      kbdhook.winseen = 1;
 	      kbdhook.winsdown++;
 	    }
+	  struct timespec end;
+	  clock_gettime (CLOCK_MONOTONIC, &end);
+	  fprintf (stderr, "KEYDOWN 0x%lx, 0x%lx: %.3g ms\n\n", hs->vkCode, hs->scanCode,
+		   (double)(end.tv_nsec - begin.tv_nsec)/1000000);
+
 	  /* Returning 1 here drops the keypress without further processing.
 	     If the keypress was allowed to go through, the normal Windows
 	     hotkeys would take over.  */
@@ -2602,6 +2610,8 @@ funhook (int code, WPARAM w, LPARAM l)
 	}
       else if (kbdhook.winsdown > 0 && (w == WM_KEYUP || w == WM_SYSKEYUP))
 	{
+	  fprintf (stderr, "KEYUP received, winsdown: %d, w: 0x%llx\n", kbdhook.winsdown, w);
+
 	  /* A key that has been captured earlier is being released now.  */
 	  if (hs->vkCode == VK_LWIN && kbdhook.lwindown)
 	    {
@@ -2640,29 +2650,43 @@ funhook (int code, WPARAM w, LPARAM l)
 			= KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP;
 		      inputs[1].ki.time = 0;
 		      SendInput (2, inputs, sizeof (INPUT));
+		      fprintf (stderr, "Simulated KEYUP to system\n");
 		    }
 		  else if (focus != NULL)
 		    {
 		      /* When not passed to system, must simulate privately to Emacs.	 */
 		      PostMessage (focus, WM_SYSKEYDOWN, hs->vkCode, 0);
 		      PostMessage (focus, WM_SYSKEYUP, hs->vkCode, 0);
+		      fprintf (stderr, "passing to system, simulating privately\n");
 		    }
+		  else
+		    fprintf (stderr, "winsdown == 0, but nothing to do\n");
 		}
 	    }
 	  if (kbdhook.winsdown == 0)
 	    {
+	      fprintf (stderr, "no key pressed anymore, clear flags\n");
 	      /* No Windows keys pressed anymore - clear the state flags.  */
 	      kbdhook.suppress_lone = 0;
 	      kbdhook.winseen = 0;
 	    }
 	  if (!kbdhook.send_win_up)
 	    {
+	      struct timespec end;
+	      clock_gettime (CLOCK_MONOTONIC, &end);
+	      fprintf (stderr, "swallowing KEYUP: %.3g ms\n\n",
+		       (double)(end.tv_nsec - begin.tv_nsec)/1000000);
+
 	      /* Swallow this release message, as not to confuse
 		 applications who did not get to see the original
 		 WM_KEYDOWN message either.  */
 	      return 1;
 	    }
 	  kbdhook.send_win_up = 0;
+	  struct timespec end;
+	  clock_gettime (CLOCK_MONOTONIC, &end);
+	  fprintf (stderr, "KEYUP processed normally: %.3g ms\n\n",
+		   (double)(end.tv_nsec - begin.tv_nsec)/1000000);
 	}
     }
   else if (kbdhook.winsdown > 0)
@@ -2698,10 +2722,19 @@ funhook (int code, WPARAM w, LPARAM l)
 	     channel when the keys are released.  */
 	  kbdhook.suppress_lone = 1;
 	  kbdhook.send_win_up = 1;
+	  struct timespec end;
+	  clock_gettime (CLOCK_MONOTONIC, &end);
+	  fprintf (stderr, "Simulated S-x combination: %.3g ms\n\n",
+		   (double)(end.tv_nsec - begin.tv_nsec)/1000000);
 	  /* Swallow the original keypress (as we want the Win key
 	     down message simulated above to precede this real message).  */
 	  return 1;
 	}
+      struct timespec end;
+      clock_gettime (CLOCK_MONOTONIC, &end);
+      fprintf (stderr, "0 < winsdown = %d: %.3g ms\n\n",
+	       kbdhook.winsdown,
+	       (double)(end.tv_nsec - begin.tv_nsec)/1000000);
     }
 
   /* Next, handle the registered Alt-* combinations.  */
@@ -2905,6 +2938,7 @@ reset_w32_kbdhook_state (void)
   kbdhook.send_win_up = 0;
   kbdhook.suppress_lone = 0;
   kbdhook.winseen = 0;
+  fprintf (stderr, "Resetting state\n");
 }
 
 /* GetKeyState and MapVirtualKey on Windows 95 do not actually distinguish
@@ -3526,6 +3560,7 @@ send_deferred_msg (deferred_msg * msg_buf,
 		   WPARAM wParam,
 		   LPARAM lParam)
 {
+  fprintf(stderr, "Sending deferred message\n");
   /* Only input thread can send deferred messages.  */
   if (GetCurrentThreadId () != dwWindowsThreadId)
     emacs_abort ();
@@ -4343,6 +4378,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 	case VK_LWIN:
 	  if (!w32_kbdhook_active && NILP (Vw32_pass_lwindow_to_system))
 	    {
+	      fprintf (stderr, "kbdhook not active, processing VK_LWIN\n");
 	      /* Prevent system from acting on keyup (which opens the
 		 Start menu if no other key was pressed) by simulating a
 		 press of Space which we will ignore.  */
@@ -4362,6 +4398,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 	case VK_RWIN:
 	  if (!w32_kbdhook_active && NILP (Vw32_pass_rwindow_to_system))
 	    {
+	      fprintf (stderr, "kbdhook not active, processing VK_RWIN\n");
 	      if (GetAsyncKeyState (wParam) & 1)
 		{
 		  if (FIXNUMP (Vw32_phantom_key_code))

  reply	other threads:[~2024-02-12 20:13 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-03 20:45 bug#68914: Windows makes Emacs choke on and swallow the WIN keys Raffael Stocker
2024-02-04  6:31 ` Eli Zaretskii
2024-02-04 13:02   ` Raffael Stocker
2024-02-04 14:14     ` Eli Zaretskii
2024-02-12 20:13       ` Raffael Stocker [this message]
2024-02-04 13:32 ` Nikolay Kudryavtsev
2024-02-04 13:56   ` Eli Zaretskii

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

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

  git send-email \
    --in-reply-to=yplma5o5pg9k.fsf@mnet-mail.de \
    --to=r.stocker@mnet-mail.de \
    --cc=68914@debbugs.gnu.org \
    --cc=eliz@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 external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.