diff -urN gtk-3.24.52-orig/gdk/x11/gdkdevicemanager-core-x11.c gtk-3.24.52/gdk/x11/gdkdevicemanager-core-x11.c
--- gtk-3.24.52-orig/gdk/x11/gdkdevicemanager-core-x11.c	2026-03-23 11:24:49 +0900
+++ gtk-3.24.52/gdk/x11/gdkdevicemanager-core-x11.c	2026-07-03 08:39:57 +0900
@@ -347,6 +347,7 @@
                                              XEvent             *xevent)
 {
   GdkWindowImplX11 *impl;
+  GdkToplevelX11 *toplevel;
   GdkX11DeviceManagerCore *device_manager;
   GdkWindow *window;
   gboolean return_val;
@@ -391,6 +392,8 @@
         }
     }
 
+  toplevel = window ? _gdk_x11_window_get_toplevel (window) : NULL;
+
   /* We do a "manual" conversion of the XEvent to a
    *  GdkEvent. The structures are mostly the same so
    *  the conversion is fairly straightforward. We also
@@ -408,6 +411,15 @@
           return_val = FALSE;
           break;
         }
+
+      /* See notes on repeat handling in KeyRelease. */
+      if (toplevel && xevent->xkey.keycode < 256)
+        {
+          int byte = xevent->xkey.keycode >> 3;
+          unsigned int mask = 1 << (xevent->xkey.keycode & 7);
+          toplevel->valid_repeat_keys[byte] |= mask;
+        }
+
       translate_key_event (display, device_manager, event, xevent);
       set_user_time (window, event);
       break;
@@ -422,6 +434,12 @@
       /* Emulate detectable auto-repeat by checking to see
        * if the next event is a key press with the same
        * keycode and timestamp, and if so, ignoring the event.
+       *
+       * Also detect repeating keys which have not been pressed since we
+       * last gained focus and suppress repeat presses of those keys.
+       * Among other benefits, this prevents misdirected input attacks
+       * where an attacker causes a window (such as a file chooser dialog)
+       * to open while the user has a relevant key (such as Enter) pressed.
        */
 
       if (!display_x11->have_xkb_autorepeat && XPending (xevent->xkey.display))
@@ -434,6 +452,20 @@
               next_event.xkey.keycode == xevent->xkey.keycode &&
               next_event.xkey.time == xevent->xkey.time)
             {
+              /* Note that the keycode is an 8-bit value in the
+               * X11 protocol, so this range test should always pass,
+               * but we play it safe when indexing memory.
+               */
+              if (toplevel && xevent->xkey.keycode < 256)
+                {
+                  int byte = xevent->xkey.keycode >> 3;
+                  unsigned int mask = 1 << (xevent->xkey.keycode & 7);
+                  if (!(toplevel->valid_repeat_keys[byte] & mask))
+                    {
+                      /* This is guaranteed to return the same event. */
+                      XNextEvent (xevent->xkey.display, &next_event);
+                    }
+                }
               return_val = FALSE;
               break;
             }
@@ -918,6 +950,9 @@
 
       gdk_event_put (event);
       gdk_event_free (event);
+
+      memset (toplevel->valid_repeat_keys, 0,
+              sizeof(toplevel->valid_repeat_keys));
     }
 }
 
diff -urN gtk-3.24.52-orig/gdk/x11/gdkdevicemanager-xi2.c gtk-3.24.52/gdk/x11/gdkdevicemanager-xi2.c
--- gtk-3.24.52-orig/gdk/x11/gdkdevicemanager-xi2.c	2026-03-23 11:24:49 +0900
+++ gtk-3.24.52/gdk/x11/gdkdevicemanager-xi2.c	2026-07-03 08:43:03 +0900
@@ -1507,6 +1507,7 @@
   gboolean return_val = TRUE;
   GdkWindow *window;
   GdkWindowImplX11 *impl;
+  GdkToplevelX11 *toplevel;
   int scale;
   XIEvent *ev;
 
@@ -1536,6 +1537,8 @@
       scale = impl->window_scale;
     }
 
+  toplevel = window ? _gdk_x11_window_get_toplevel (window) : NULL;
+
   if (ev->evtype == XI_Motion ||
       ev->evtype == XI_ButtonRelease)
     {
@@ -1578,6 +1581,24 @@
                              xev->sourceid,
                              xev->detail));
 
+        /* Suppress repeat of keys held across a focus change.
+         * See notes in gdkdevicemanager-core-x11.c for details.
+         */
+        if (toplevel && ev->evtype == XI_KeyPress && xev->detail < 256)
+          {
+            int byte = xev->detail >> 3;
+            unsigned int mask = 1 << (xev->detail & 7);
+            if (xev->flags & XIKeyRepeat)
+              {
+                if (!(toplevel->valid_repeat_keys[byte] & mask))
+                  return FALSE;
+              }
+            else
+              {
+                toplevel->valid_repeat_keys[byte] |= mask;
+              }
+          }
+
         event->key.type = xev->evtype == XI_KeyPress ? GDK_KEY_PRESS : GDK_KEY_RELEASE;
 
         event->key.window = window;
diff -urN gtk-3.24.52-orig/gdk/x11/gdkdisplay-x11.c gtk-3.24.52/gdk/x11/gdkdisplay-x11.c
--- gtk-3.24.52-orig/gdk/x11/gdkdisplay-x11.c	2026-03-23 11:24:49 +0900
+++ gtk-3.24.52/gdk/x11/gdkdisplay-x11.c	2026-07-03 06:58:44 +0900
@@ -1770,15 +1770,21 @@
 				   XkbAllStateComponentsMask,
                                    XkbModifierStateMask|XkbGroupStateMask);
 
+            /* Disable XKB detectable autorepeat so we can suppress repeating
+             * keys on focus change.  (Ironically, the XKB implementation of
+             * "detectable" autorepeat makes repeat presses _un_detectable
+             * across an input focus change.)  See notes at KeyRelease
+             * handling in gdk_x11_device_manager_core_translate_event().
+             */
 	    XkbSetDetectableAutoRepeat (display_x11->xdisplay,
-					True,
+					False,
 					&detectable_autorepeat_supported);
 
 	    GDK_NOTE (MISC, g_message ("Detectable autorepeat %s.",
 				       detectable_autorepeat_supported ?
-				       "supported" : "not supported"));
+				       "supported (not used)" : "not supported"));
 	    
-	    display_x11->have_xkb_autorepeat = detectable_autorepeat_supported;
+	    display_x11->have_xkb_autorepeat = FALSE;
           }
       }
   }
diff -urN gtk-3.24.52-orig/gdk/x11/gdkwindow-x11.h gtk-3.24.52/gdk/x11/gdkwindow-x11.h
--- gtk-3.24.52-orig/gdk/x11/gdkwindow-x11.h	2026-03-23 11:24:49 +0900
+++ gtk-3.24.52/gdk/x11/gdkwindow-x11.h	2026-07-03 06:46:18 +0900
@@ -169,6 +169,9 @@
   /* Constrained edge information */
   guint edge_constraints;
 
+  /* Bitmap of keys which have been pressed since the last FocusIn event */
+  guint8 valid_repeat_keys[256/8];
+
 #ifdef HAVE_XSYNC
   XID update_counter;
   XID extended_update_counter;
