diff --git a/SOURCES/0001-events-Sync-pending-pointer-events-without-a-window.patch b/SOURCES/0001-events-Sync-pending-pointer-events-without-a-window.patch
new file mode 100644
index 0000000..14878a7
--- /dev/null
+++ b/SOURCES/0001-events-Sync-pending-pointer-events-without-a-window.patch
@@ -0,0 +1,122 @@
+From 3582d1780c9bf3fc93604963a11b9b60d9895178 Mon Sep 17 00:00:00 2001
+From: Olivier Fourdan <ofourdan@redhat.com>
+Date: Wed, 2 Oct 2019 16:49:28 +0200
+Subject: [PATCH] events: Sync pending pointer events without a window
+
+Mutter issues a synchronous grab on the pointer for unfocused client
+windows to be able to catch the button events first and raise/focus
+client windows accordingly.
+
+When there is a synchronous grab in effect, all events are queued until
+the grabbing client releases the event queue as it processes the events.
+
+Mutter does release the events in its event handler function but does so
+only if it is able to find the window matching the event. If the window
+is a shell widget, that matching may fail and therefore Mutter will not
+release the events, hence causing a freeze in pointer events delivery.
+
+To avoid the issue, make sure we sync the pointer events in case we
+can't find a matching window.
+
+https://gitlab.gnome.org/GNOME/mutter/merge_requests/821
+---
+ src/core/events.c | 62 ++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 51 insertions(+), 11 deletions(-)
+
+diff --git a/src/core/events.c b/src/core/events.c
+index 92503a168..9b19065fb 100644
+--- a/src/core/events.c
++++ b/src/core/events.c
+@@ -51,6 +51,12 @@
+ #define IS_KEY_EVENT(e) ((e)->type == CLUTTER_KEY_PRESS || \
+                          (e)->type == CLUTTER_KEY_RELEASE)
+ 
++typedef enum
++{
++  EVENTS_UNFREEZE_SYNC,
++  EVENTS_UNFREEZE_REPLAY,
++} EventsUnfreezeMethod;
++
+ static gboolean
+ stage_has_key_focus (void)
+ {
+@@ -167,6 +173,43 @@ sequence_is_pointer_emulated (MetaDisplay        *display,
+   return FALSE;
+ }
+ 
++static void
++maybe_unfreeze_pointer_events (MetaBackend          *backend,
++                               const ClutterEvent   *event,
++                               EventsUnfreezeMethod  unfreeze_method)
++{
++  Display *xdisplay;
++  int event_mode;
++  int device_id;
++
++  if (event->type != CLUTTER_BUTTON_PRESS)
++    return;
++
++  if (!META_IS_BACKEND_X11 (backend))
++    return;
++
++  device_id = clutter_event_get_device_id (event);
++  switch (unfreeze_method)
++    {
++    case EVENTS_UNFREEZE_SYNC:
++      event_mode = XISyncDevice;
++      meta_verbose ("Syncing events time %u device %i\n",
++                    (unsigned int) event->button.time, device_id);
++      break;
++    case EVENTS_UNFREEZE_REPLAY:
++      event_mode = XIReplayDevice;
++      meta_verbose ("Replaying events time %u device %i\n",
++                    (unsigned int) event->button.time, device_id);
++      break;
++    default:
++      g_assert_not_reached ();
++      return;
++    }
++
++  xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
++  XIAllowEvents (xdisplay, device_id, event_mode, event->button.time);
++}
++
+ static gboolean
+ meta_display_handle_event (MetaDisplay        *display,
+                            const ClutterEvent *event)
+@@ -366,17 +409,7 @@ meta_display_handle_event (MetaDisplay        *display,
+         {
+           /* Only replay button press events, since that's where we
+            * have the synchronous grab. */
+-          if (event->type == CLUTTER_BUTTON_PRESS)
+-            {
+-              if (META_IS_BACKEND_X11 (backend))
+-                {
+-                  Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend));
+-                  meta_verbose ("Allowing events time %u\n",
+-                                (unsigned int)event->button.time);
+-                  XIAllowEvents (xdisplay, clutter_event_get_device_id (event),
+-                                 XIReplayDevice, event->button.time);
+-                }
+-            }
++          maybe_unfreeze_pointer_events (backend, event, EVENTS_UNFREEZE_REPLAY);
+ 
+           /* If the focus window has an active close dialog let clutter
+            * events go through, so fancy clutter dialogs can get to handle
+@@ -392,6 +425,13 @@ meta_display_handle_event (MetaDisplay        *display,
+ 
+       goto out;
+     }
++  else
++    {
++      /* We could not match the event with a window, make sure we sync
++       * the pointer to discard the sequence and don't keep events frozen.
++       */
++       maybe_unfreeze_pointer_events (backend, event, EVENTS_UNFREEZE_SYNC);
++    }
+ 
+  out:
+   /* If the compositor has a grab, don't pass that through to Wayland */
+-- 
+2.23.0
+
diff --git a/SPECS/mutter.spec b/SPECS/mutter.spec
index ab0e8b9..7149b2e 100644
--- a/SPECS/mutter.spec
+++ b/SPECS/mutter.spec
@@ -10,7 +10,7 @@
 
 Name:          mutter
 Version:       3.28.3
-Release:       10%{?dist}
+Release:       11%{?dist}
 Summary:       Window and compositing manager based on Clutter
 
 License:       GPLv2+
@@ -78,6 +78,9 @@ Patch262: 0002-monitor-manager-xrandr-Create-dummy-screen-sized-mon.patch
 Patch270: 0001-idle-monitor-Use-G_SOURCE_CONTINUE-instead-of-TRUE.patch
 Patch271: 0002-idle-monitor-Postpone-dispatching-of-idle-timeout-if.patch
 
+# Don't loose pointer button grabs (#1756263)
+Patch272: 0001-events-Sync-pending-pointer-events-without-a-window.patch
+
 BuildRequires: chrpath
 BuildRequires: pango-devel
 BuildRequires: startup-notification-devel
@@ -233,6 +236,10 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
 %{_libdir}/pkgconfig/*
 
 %changelog
+* Wed Oct 02 2019 Jonas Ådahl <jadahl@redhat.com>) - 3.28.3-11
+- Don't loose pointer button grabs
+  Resolves: #1756263
+
 * Wed Apr 17 2019 Jonas Ådahl <jadahl@redhat.com> - 3.28.3-10
 - Fix idle monitor race condition
   Resolves: #1636460