diff --git a/.gitignore b/.gitignore
index efa9477..41861cf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/mutter-40.4.tar.xz
+SOURCES/mutter-40.6.tar.xz
diff --git a/.mutter.metadata b/.mutter.metadata
index 4344d2e..2712620 100644
--- a/.mutter.metadata
+++ b/.mutter.metadata
@@ -1 +1 @@
-e97fff99b075736fc6f0d5bd5713d89983fe99e1 SOURCES/mutter-40.4.tar.xz
+44d47eab96bad599ae003956904265e5bcd8ac17 SOURCES/mutter-40.6.tar.xz
diff --git a/SOURCES/0001-Test-deny-atomic-KMS-for-tegra-RHBZ-1936991.patch b/SOURCES/0001-Test-deny-atomic-KMS-for-tegra-RHBZ-1936991.patch
index 622ce5f..d847397 100644
--- a/SOURCES/0001-Test-deny-atomic-KMS-for-tegra-RHBZ-1936991.patch
+++ b/SOURCES/0001-Test-deny-atomic-KMS-for-tegra-RHBZ-1936991.patch
@@ -1,4 +1,4 @@
-From a8746403352be96bae7dfd73ac31fe0253f884b8 Mon Sep 17 00:00:00 2001
+From 9d0ded3178777cd6afcdd5fff7b6f0f39a0d5236 Mon Sep 17 00:00:00 2001
 From: Adam Williamson <awilliam@redhat.com>
 Date: Tue, 9 Mar 2021 17:21:59 -0800
 Subject: [PATCH] Test: deny atomic KMS for "tegra" (RHBZ #1936991)
@@ -19,17 +19,17 @@ index edc03e6c1..d8e3c5f00 100644
  ENV{ID_PATH}=="platform-vkms", TAG+="mutter-device-ignore"
 +DRIVER=="tegra", SUBSYSTEM=="platform", TAG+="mutter-device-disable-atomic-kms"
 diff --git a/src/backends/native/meta-kms-device.c b/src/backends/native/meta-kms-device.c
-index c388096d5..ef65cf82b 100644
+index 85aded9a6..e749ab6b9 100644
 --- a/src/backends/native/meta-kms-device.c
 +++ b/src/backends/native/meta-kms-device.c
-@@ -252,6 +252,7 @@ is_atomic_allowed (const char *driver_name)
-     "vmwgfx",
+@@ -253,6 +253,7 @@ is_atomic_allowed (const char *driver_name)
      "vboxvideo",
      "nvidia-drm",
+     "virtio_gpu",
 +    "tegra",
      NULL,
    };
  
 -- 
-2.28.0
+2.32.0
 
diff --git a/SOURCES/0001-backends-x11-Fix-key-repeat-of-on-screen-keyboard-fo.patch b/SOURCES/0001-backends-x11-Fix-key-repeat-of-on-screen-keyboard-fo.patch
new file mode 100644
index 0000000..1099461
--- /dev/null
+++ b/SOURCES/0001-backends-x11-Fix-key-repeat-of-on-screen-keyboard-fo.patch
@@ -0,0 +1,260 @@
+From a1f33bdac95ba4fd0599f164ef893c05d8be123b Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode@redhat.com>
+Date: Wed, 6 Oct 2021 15:31:30 -0400
+Subject: [PATCH] backends/x11: Fix key repeat of on-screen keyboard for second
+ level keysyms
+
+Certains keys (such as ~ and |) are in the keyboard map behind the
+second shift level. This means in order for them to be input, the
+shift key needs to be held down by the user.
+
+The GNOME Shell on-screen keyboard presents these keys separately on
+a page of keys that has no shift key. Instead, it relies on mutter
+to set a shift latch before the key event is emitted. A shift latch
+is a virtual press of the shift key that automatically gets released
+after the next key press (in our case the ~ or | key).
+
+The problem is using a shift latch doesn't work very well in the face
+of key repeat. The latch is automatically released after the first
+press, and subsequent repeats of that press no longer have shift
+latched to them.
+
+This commit fixes the problem by using a shift lock instead of a shift
+latch. A shift lock is never implicitly released, so it remains
+in place for the duration of key repeat.
+---
+ src/backends/x11/meta-keymap-x11.c               | 12 ++++++------
+ src/backends/x11/meta-keymap-x11.h               |  6 +++---
+ src/backends/x11/meta-virtual-input-device-x11.c |  4 ++--
+ 3 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/src/backends/x11/meta-keymap-x11.c b/src/backends/x11/meta-keymap-x11.c
+index da5d064e7..1192cc387 100644
+--- a/src/backends/x11/meta-keymap-x11.c
++++ b/src/backends/x11/meta-keymap-x11.c
+@@ -829,85 +829,85 @@ meta_keymap_x11_reserve_keycode (MetaKeymapX11 *keymap_x11,
+       g_warning ("Cannot reserve a keycode for keyval %d: no available keycode", keyval);
+       return FALSE;
+     }
+ 
+   if (!meta_keymap_x11_replace_keycode (keymap_x11, *keycode_out, keyval))
+     {
+       g_warning ("Failed to remap keycode %d to keyval %d", *keycode_out, keyval);
+       return FALSE;
+     }
+ 
+   g_hash_table_insert (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (*keycode_out), GUINT_TO_POINTER (keyval));
+   g_queue_remove (keymap_x11->available_keycodes, GUINT_TO_POINTER (*keycode_out));
+ 
+   return TRUE;
+ }
+ 
+ void
+ meta_keymap_x11_release_keycode_if_needed (MetaKeymapX11 *keymap_x11,
+                                            uint32_t       keycode)
+ {
+   g_return_if_fail (META_IS_KEYMAP_X11 (keymap_x11));
+ 
+   if (!g_hash_table_contains (keymap_x11->reserved_keycodes, GUINT_TO_POINTER (keycode)) ||
+       g_queue_index (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode)) != -1)
+     return;
+ 
+   g_queue_push_tail (keymap_x11->available_keycodes, GUINT_TO_POINTER (keycode));
+ }
+ 
+ void
+-meta_keymap_x11_latch_modifiers (MetaKeymapX11 *keymap_x11,
+-                                 uint32_t       level,
+-                                 gboolean       enable)
++meta_keymap_x11_lock_modifiers (MetaKeymapX11 *keymap_x11,
++                                uint32_t       level,
++                                gboolean       enable)
+ {
+   uint32_t modifiers[] = {
+     0,
+     ShiftMask,
+     keymap_x11->level3_shift_mask,
+     keymap_x11->level3_shift_mask | ShiftMask,
+   };
+   uint32_t value = 0;
+ 
+   if (!keymap_x11->use_xkb)
+     return;
+ 
+   level = CLAMP (level, 0, G_N_ELEMENTS (modifiers) - 1);
+ 
+   if (enable)
+     value = modifiers[level];
+   else
+     value = 0;
+ 
+-  XkbLatchModifiers (clutter_x11_get_default_display (),
+-                     XkbUseCoreKbd, modifiers[level],
+-                     value);
++  XkbLockModifiers (clutter_x11_get_default_display (),
++                    XkbUseCoreKbd, modifiers[level],
++                    value);
+ }
+ 
+ static uint32_t
+ meta_keymap_x11_get_current_group (MetaKeymapX11 *keymap_x11)
+ {
+   XkbStateRec state_rec;
+ 
+   if (keymap_x11->current_group >= 0)
+     return keymap_x11->current_group;
+ 
+   XkbGetState (clutter_x11_get_default_display (),
+                XkbUseCoreKbd, &state_rec);
+   return XkbStateGroup (&state_rec);
+ }
+ 
+ gboolean
+ meta_keymap_x11_keycode_for_keyval (MetaKeymapX11 *keymap_x11,
+                                     uint32_t       keyval,
+                                     uint32_t      *keycode_out,
+                                     uint32_t      *level_out)
+ {
+   ClutterKeymapKey *keys;
+   int i, n_keys, group;
+   gboolean found = FALSE;
+ 
+   g_return_val_if_fail (keycode_out != NULL, FALSE);
+   g_return_val_if_fail (level_out != NULL, FALSE);
+ 
+   group = meta_keymap_x11_get_current_group (keymap_x11);
+ 
+diff --git a/src/backends/x11/meta-keymap-x11.h b/src/backends/x11/meta-keymap-x11.h
+index 67a5f8eb9..2f93acdbc 100644
+--- a/src/backends/x11/meta-keymap-x11.h
++++ b/src/backends/x11/meta-keymap-x11.h
+@@ -17,45 +17,45 @@
+  * Author: Emmanuele Bassi <ebassi@linux.intel.com>
+  */
+ 
+ #ifndef META_KEYMAP_X11_H
+ #define META_KEYMAP_X11_H
+ 
+ #include <glib-object.h>
+ #include <pango/pango.h>
+ 
+ #include "clutter/clutter.h"
+ 
+ G_BEGIN_DECLS
+ 
+ #define META_TYPE_KEYMAP_X11 (meta_keymap_x11_get_type ())
+ G_DECLARE_FINAL_TYPE (MetaKeymapX11, meta_keymap_x11,
+                       META, KEYMAP_X11, ClutterKeymap)
+ 
+ int      meta_keymap_x11_get_key_group       (MetaKeymapX11       *keymap,
+                                               ClutterModifierType  state);
+ int      meta_keymap_x11_translate_key_state (MetaKeymapX11       *keymap,
+                                               guint                hardware_keycode,
+                                               ClutterModifierType *modifier_state_p,
+                                               ClutterModifierType *mods_p);
+ gboolean meta_keymap_x11_get_is_modifier     (MetaKeymapX11       *keymap,
+                                               int                  keycode);
+ 
+ gboolean meta_keymap_x11_keycode_for_keyval       (MetaKeymapX11    *keymap_x11,
+                                                    guint             keyval,
+                                                    guint            *keycode_out,
+                                                    guint            *level_out);
+-void     meta_keymap_x11_latch_modifiers          (MetaKeymapX11 *keymap_x11,
+-                                                   uint32_t          level,
+-                                                   gboolean          enable);
++void     meta_keymap_x11_lock_modifiers           (MetaKeymapX11 *keymap_x11,
++                                                   uint32_t       level,
++                                                   gboolean       enable);
+ gboolean meta_keymap_x11_reserve_keycode           (MetaKeymapX11 *keymap_x11,
+                                                     guint             keyval,
+                                                     guint            *keycode_out);
+ void     meta_keymap_x11_release_keycode_if_needed (MetaKeymapX11 *keymap_x11,
+                                                     guint             keycode);
+ 
+ gboolean meta_keymap_x11_handle_event        (MetaKeymapX11 *keymap_x11,
+                                               XEvent        *xevent);
+ 
+ G_END_DECLS
+ 
+ #endif /* META_KEYMAP_X11_H */
+diff --git a/src/backends/x11/meta-virtual-input-device-x11.c b/src/backends/x11/meta-virtual-input-device-x11.c
+index fe6040859..1a5cdfc2e 100644
+--- a/src/backends/x11/meta-virtual-input-device-x11.c
++++ b/src/backends/x11/meta-virtual-input-device-x11.c
+@@ -159,71 +159,71 @@ meta_virtual_input_device_x11_notify_key (ClutterVirtualInputDevice *virtual_dev
+                                           ClutterKeyState            key_state)
+ {
+   XTestFakeKeyEvent (clutter_x11_get_default_display (),
+                      key + 8, key_state == CLUTTER_KEY_STATE_PRESSED, 0);
+ }
+ 
+ static void
+ meta_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtual_device,
+                                              uint64_t                   time_us,
+                                              uint32_t                   keyval,
+                                              ClutterKeyState            key_state)
+ {
+   ClutterBackend *backend = clutter_get_default_backend ();
+   ClutterSeat *seat = clutter_backend_get_default_seat (backend);
+   MetaKeymapX11 *keymap = META_KEYMAP_X11 (clutter_seat_get_keymap (seat));
+   uint32_t keycode, level;
+ 
+   if (!meta_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level))
+     {
+       level = 0;
+ 
+       if (!meta_keymap_x11_reserve_keycode (keymap, keyval, &keycode))
+         {
+           g_warning ("No keycode found for keyval %x in current group", keyval);
+           return;
+         }
+     }
+ 
+   if (!meta_keymap_x11_get_is_modifier (keymap, keycode) &&
+       key_state == CLUTTER_KEY_STATE_PRESSED)
+-    meta_keymap_x11_latch_modifiers (keymap, level, TRUE);
++    meta_keymap_x11_lock_modifiers (keymap, level, TRUE);
+ 
+   XTestFakeKeyEvent (clutter_x11_get_default_display (),
+                      (KeyCode) keycode,
+                      key_state == CLUTTER_KEY_STATE_PRESSED, 0);
+ 
+ 
+   if (key_state == CLUTTER_KEY_STATE_RELEASED)
+     {
+       if (!meta_keymap_x11_get_is_modifier (keymap, keycode))
+-        meta_keymap_x11_latch_modifiers (keymap, level, FALSE);
++        meta_keymap_x11_lock_modifiers (keymap, level, FALSE);
+       meta_keymap_x11_release_keycode_if_needed (keymap, keycode);
+     }
+ }
+ 
+ static void
+ meta_virtual_input_device_x11_notify_touch_down (ClutterVirtualInputDevice *virtual_device,
+                                                  uint64_t                   time_us,
+                                                  int                        device_slot,
+                                                  double                     x,
+                                                  double                     y)
+ {
+   g_warning ("Virtual touch motion not implemented under X11");
+ }
+ 
+ static void
+ meta_virtual_input_device_x11_notify_touch_motion (ClutterVirtualInputDevice *virtual_device,
+                                                    uint64_t                   time_us,
+                                                    int                        device_slot,
+                                                    double                     x,
+                                                    double                     y)
+ {
+   g_warning ("Virtual touch motion not implemented under X11");
+ }
+ 
+ static void
+ meta_virtual_input_device_x11_notify_touch_up (ClutterVirtualInputDevice *virtual_device,
+                                                uint64_t                   time_us,
+                                                int                        device_slot)
+ {
+   g_warning ("Virtual touch motion not implemented under X11");
+-- 
+2.33.1
+
diff --git a/SPECS/mutter.spec b/SPECS/mutter.spec
index 7b45a0e..41510a3 100644
--- a/SPECS/mutter.spec
+++ b/SPECS/mutter.spec
@@ -9,8 +9,8 @@
 %global tarball_version %%(echo %{version} | tr '~' '.')
 
 Name:          mutter
-Version:       40.4
-Release:       3%{?dist}
+Version:       40.6
+Release:       1%{?dist}
 Summary:       Window and compositing manager based on Clutter
 
 License:       GPLv2+
@@ -51,10 +51,14 @@ Patch9:       0001-main-be-more-aggressive-in-assuming-X11-backend.patch
 # Fixes --replace
 Patch10:      0001-backend-Clean-up-renderer-after-clutter-backendm.patch
 
-# Fixes a race in wl_seat capabilities (rhbz#1957807)
+# Fixes a race in wl_seat capabilities (rhbz#2003032)
 # https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/77
 Patch11: 0001-wayland-Avoid-a-race-in-wl_seat-capabilities.patch
 
+# OSK keyboard repeat fix
+# https://bugzilla.redhat.com/show_bug.cgi?id=2010705
+Patch12: 0001-backends-x11-Fix-key-repeat-of-on-screen-keyboard-fo.patch
+
 BuildRequires: chrpath
 BuildRequires: pango-devel
 BuildRequires: startup-notification-devel
@@ -200,9 +204,17 @@ desktop-file-validate %{buildroot}/%{_datadir}/applications/%{name}.desktop
 %{_datadir}/mutter-%{mutter_api_version}/tests
 
 %changelog
+* Mon Nov 08 2021 Florian Müllner <fmuellner@redhat.com> - 40.6-1
+- Update to 40.6
+  Resolves: #2021064
+
+* Tue Nov  2 2021 Ray Strode <rstrode@redhat.com> - 40.4-4
+- Maintain shift state when doing key repeat in on screen keyboard
+  Related: #2010705
+
 * Fri Sep 10 2021 Olivier Fourdan <ofourdan@redhat.com> - 40.4-3
 - Fixes a race in wl_seat capabilities
-  Resolves: #1957807
+  Resolves: #2003032
 
 * Wed Aug 27 2021 Florian Müllner <fmuellner@redhat.com> - 40.4-2
 - Remove firstboot(windowmanager) provide