[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#935250: buster-pu: package mutter 3.30.2-9~deb10u1



Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu
X-Debbugs-Cc: debian-gtk-gnome@lists.debian.org, debian-desktop@lists.debian.org, budgie-core@packages.debian.org

I uploaded some mutter fixes to unstable after the buster release which
I think would be worth considering for a buster update - perhaps for
10.2 rather than 10.1 at this point. The diffstat is larger than I'd like,
so it will need a good amount of testing, but it's all targeted fixes.

There are only trivial changes since 3.30.2-8, which I uploaded to
unstable at the beginning of August with no regression reports since then.

I would appreciate further testing from people who use buster on their
desktop/laptop systems. Equivalent signed source and amd64 binaries for
testing are available here: https://people.debian.org/~smcv/201908/mutter/

>   * Update to upstream gnome-3-30 branch at 3.30.2-42-g2a81dc45e

Since upstream have a branch for the benefit of distributors like us,
we should probably at least consider it. Unfortunately there was never
a 3.30.3 release.

Some of the changes fix crash bugs. GNOME Shell crashes are quite
disruptive now that we default to Wayland mode (in which they end the
session), and could be considered to be a security issue in X11 mode
(in which windows become visible while the Shell restarts even if the
session was locked), so it seems important to fix known crashes.

>   * d/p/wayland-output-Set-user-data-of-xdg_output-resource.patch:
>     Backport patch from 3.32.1 to fix use-after-free in Wayland monitor
>     management (Closes: #932428, #932767, #932781)

This was always theoretically a bug, but it became a practical problem
when we moved to Mesa 19.x, which does more multi-threading than older
versions - so it's probably important to get this into buster if the Xorg
team is going to backport Mesa for hardware-enablement, like they did for
stretch.

>   * d/libmutter-3-0.symbols:
>     Add meta_stack_get_default_focus_candidates(), which is added by a
>     patch

This is technically new public ABI on the gnome-3-30 branch, but it's only
used within mutter.

>   * d/p/renderer-native-Use-g_set_error-instead-of-_cogl_set_erro.patch,
>     d/p/renderer-native-Make-sure-we-re-not-destroying-an-active-.patch,
>     d/p/renderer-native-Fix-EGLSurface-destruction-order.patch:
>     Backport patches from upstream gnome-3-32 branch to fix another
>     use-after-free crash that can be triggered by suspend/resume

More crash fixes.

Thanks,
    smcv
diffstat for mutter-3.30.2 mutter-3.30.2

 changelog                                                               |   90 ++
 libmutter-3-0.bug-control                                               |    1 
 libmutter-3-0.symbols                                                   |    1 
 patches/Makefile-tests-Fix-paths-for-stacking-metatests.patch           |   35 
 patches/Sync-to-the-hardware-refresh-rate-not-just-60.00Hz.patch        |    8 
 patches/Updated-Spanish-translation.patch                               |  176 ++++
 patches/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch |   51 +
 patches/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch |  292 +++++++
 patches/cogl-pipeline-Don-t-try-to-access-to-free-d-pointer-data.patch  |   43 +
 patches/compositor-Destroy-window-actors-list-on-destruction.patch      |   62 +
 patches/compositor-Disconnect-from-stage-signals-on-destruction.patch   |   76 ++
 patches/cursor-renderer-native-Free-MetaCursorNativePrivate-struc.patch |   26 
 patches/renderer-native-Fix-EGLSurface-destruction-order.patch          |  123 +++
 patches/renderer-native-Make-sure-we-re-not-destroying-an-active-.patch |   89 ++
 patches/renderer-native-Use-g_set_error-instead-of-_cogl_set_erro.patch |   27 
 patches/renderer-native-add-missing-eglTerminate-in-EGLDevice-err.patch |   46 +
 patches/series                                                          |   36 
 patches/stack-Add-a-function-to-get-a-sorted-list-of-focus-candid.patch |  127 +++
 patches/surface-actor-x11-Assign-X11-Display-only-if-we-have-reso.patch |   55 +
 patches/surface-actor-x11-Bind-the-surface-actor-resources-to-win.patch |   86 ++
 patches/test-client-Add-x11-events-GSource-handler.patch                |  184 ++++
 patches/test-runner-Add-assert_focused-command.patch                    |   72 +
 patches/test-runner-Add-dispatch-command.patch                          |   80 ++
 patches/test-runner-Add-sleep-command.patch                             |   78 ++
 patches/tests-Add-accept_focus-command-to-runner-and-client.patch       |   73 +
 patches/tests-Add-accept_take_focus-command.patch                       |  253 ++++++
 patches/tests-Add-can_take_focus-command-to-runner-and-client.patch     |  111 ++
 patches/tests-Verify-focused-window-in-closed-transient-tests.patch     |   60 +
 patches/tests-stacking-Add-tests-with-no-input-and-no-take-focus-.patch |  121 +++
 patches/wayland-output-Set-user-data-of-xdg_output-resource.patch       |   59 +
 patches/wayland-seat-Use-g_free-to-cleanup-MetaWaylandSeat.patch        |   28 
 patches/window-Emit-an-error-and-return-when-trying-to-activate-a.patch |   37 
 patches/window-actor-Set-actor-as-compositor-private-in-window-be.patch |   44 +
 patches/window-x11-Accept-any-focusable-window-as-fallback-focus.patch  |  102 ++
 patches/window-x11-Add-lost-definition-for-TAKE_FOCUS_FALLBACK_DE.patch |   28 
 patches/window-x11-Don-t-double-check-for-unmanaging-windows.patch      |   32 
 patches/window-x11-Focus-a-window-in-the-active-workspace-as-take.patch |   63 +
 patches/window-x11-Focus-the-default-window-with-delay-while-wait.patch |  233 ++++++
 patches/window-x11-Remove-double-definition-of-MetaStack.patch          |   28 
 patches/window-x11-Use-any-focusable-window-as-fallback-delayed-f.patch |  374 ++++++++++
 patches/workspace-Focus-only-ancestors-that-are-focusable.patch         |   80 ++
 41 files changed, 3586 insertions(+), 4 deletions(-)

diff -Nru mutter-3.30.2/debian/changelog mutter-3.30.2/debian/changelog
--- mutter-3.30.2/debian/changelog	2019-04-28 00:13:35.000000000 +0100
+++ mutter-3.30.2/debian/changelog	2019-08-18 19:51:33.000000000 +0100
@@ -1,3 +1,93 @@
+mutter (3.30.2-9~deb10u1) buster; urgency=medium
+
+  * Team upload
+  * Rebuild for Debian 10
+  * d/gbp.conf: Set packaging branch to debian/buster
+
+ -- Simon McVittie <smcv@debian.org>  Sun, 18 Aug 2019 19:51:33 +0100
+
+mutter (3.30.2-9) unstable; urgency=medium
+
+  * Team upload
+  * d/libmutter-3-0.bug-control: Include GL drivers in bug reports
+  * d/p/renderer-native-Fix-EGLSurface-destruction-order.patch:
+    Fix attribution
+  * d/p/wayland-output-Set-user-data-of-xdg_output-resource.patch:
+    Add bug references for #932428, #932767 and #932781, and retroactively
+    mark them as closed by this patch in the previous changelog entry,
+    based on feedback from bug reporters
+
+ -- Simon McVittie <smcv@debian.org>  Sun, 18 Aug 2019 17:23:17 +0100
+
+mutter (3.30.2-8) unstable; urgency=medium
+
+  * Team upload
+  * Update to upstream gnome-3-30 branch at 3.30.2-42-g2a81dc45e
+    - d/p/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch:
+      Fix repeated inputs from extended characters (long-press) in
+      on-screen keyboard
+    - d/p/compositor-Destroy-window-actors-list-on-destruction.patch,
+      d/p/window-actor-Set-actor-as-compositor-private-in-window-be.patch,
+      d/p/surface-actor-x11-Assign-X11-Display-only-if-we-have-reso.patch,
+      d/p/surface-actor-x11-Bind-the-surface-actor-resources-to-win.patch,
+      Fix intermittent crashes on exit/reload
+    - d/p/compositor-Disconnect-from-stage-signals-on-destruction.patch:
+      Fix stuck windows if an application stops responding and one of its
+      windows gets unmanaged
+    - d/p/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch:
+      Fix missing inputs from extended characters (long-press) in
+      on-screen keyboard
+    - d/p/cursor-renderer-native-Free-MetaCursorNativePrivate-struc.patch:
+      Fix a small memory leak
+    - d/p/wayland-seat-Use-g_free-to-cleanup-MetaWaylandSeat.patch:
+      Fix an incorrect free-function that could lead to memory corruption
+    - d/p/cogl-pipeline-Don-t-try-to-access-to-free-d-pointer-data.patch:
+      Fix use-after-free
+    - d/p/renderer-native-add-missing-eglTerminate-in-EGLDevice-err.patch:
+      Avoid reusing an amdgpu display connection if EGL is missing the
+      desired extensions
+    - d/p/workspace-Focus-only-ancestors-that-are-focusable.patch,
+      d/p/window-x11-Focus-the-default-window-with-delay-while-wait.patch,
+      d/p/window-x11-Add-lost-definition-for-TAKE_FOCUS_FALLBACK_DE.patch,
+      d/p/window-x11-Focus-a-window-in-the-active-workspace-as-take.patch,
+      d/p/window-x11-Remove-double-definition-of-MetaStack.patch:
+      Fix crashes involving window focus with some applications, notably
+      JetBrains IDE
+    - d/p/window-Emit-an-error-and-return-when-trying-to-activate-a.patch:
+      Fix crashes when an unmanaged window is activated
+    - d/p/window-x11-Don-t-double-check-for-unmanaging-windows.patch,
+      d/p/window-x11-Accept-any-focusable-window-as-fallback-focus.patch,
+      d/p/stack-Add-a-function-to-get-a-sorted-list-of-focus-candid.patch,
+      d/p/window-x11-Use-any-focusable-window-as-fallback-delayed-f.patch:
+      Fix hang when windows take focus but do not accept input
+    - d/p/Updated-Spanish-translation.patch:
+      Update translations
+    - d/p/tests-Add-accept_focus-command-to-runner-and-client.patch,
+      d/p/tests-Add-can_take_focus-command-to-runner-and-client.patch,
+      d/p/tests-stacking-Add-tests-with-no-input-and-no-take-focus-.patch,
+      d/p/test-runner-Add-assert_focused-command.patch,
+      d/p/tests-Verify-focused-window-in-closed-transient-tests.patch,
+      d/p/test-runner-Add-sleep-command.patch,
+      d/p/test-runner-Add-dispatch-command.patch,
+      d/p/Makefile-tests-Fix-paths-for-stacking-metatests.patch,
+      d/p/test-client-Add-x11-events-GSource-handler.patch,
+      d/p/tests-Add-accept_take_focus-command.patch:
+      Improve test coverage related to the above bug fixes
+  * d/p/wayland-output-Set-user-data-of-xdg_output-resource.patch:
+    Backport patch from 3.32.1 to fix use-after-free in Wayland monitor
+    management (Closes: #932428, #932767, #932781)
+  * d/libmutter-3-0.symbols:
+    Add meta_stack_get_default_focus_candidates(), which is added by a
+    patch
+  * d/gbp.conf: Set branch to debian/unstable
+  * d/p/renderer-native-Use-g_set_error-instead-of-_cogl_set_erro.patch,
+    d/p/renderer-native-Make-sure-we-re-not-destroying-an-active-.patch,
+    d/p/renderer-native-Fix-EGLSurface-destruction-order.patch:
+    Backport patches from upstream gnome-3-32 branch to fix another
+    use-after-free crash that can be triggered by suspend/resume
+
+ -- Simon McVittie <smcv@debian.org>  Tue, 30 Jul 2019 10:40:38 +0100
+
 mutter (3.30.2-7) unstable; urgency=medium
 
   * Team upload
diff -Nru mutter-3.30.2/debian/libmutter-3-0.bug-control mutter-3.30.2/debian/libmutter-3-0.bug-control
--- mutter-3.30.2/debian/libmutter-3-0.bug-control	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/libmutter-3-0.bug-control	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1 @@
+package-status: libegl-vendor libglx-vendor libgl1-mesa-dri
diff -Nru mutter-3.30.2/debian/libmutter-3-0.symbols mutter-3.30.2/debian/libmutter-3-0.symbols
--- mutter-3.30.2/debian/libmutter-3-0.symbols	2019-04-28 00:13:35.000000000 +0100
+++ mutter-3.30.2/debian/libmutter-3-0.symbols	2019-08-18 19:51:33.000000000 +0100
@@ -1247,6 +1247,7 @@
  meta_stack_get_above@Base 3.28.2
  meta_stack_get_below@Base 3.28.2
  meta_stack_get_bottom@Base 3.28.2
+ meta_stack_get_default_focus_candidates@Base 3.30.2-8~
  meta_stack_get_default_focus_window@Base 3.28.2
  meta_stack_get_default_focus_window_at_point@Base 3.28.2
  meta_stack_get_positions@Base 3.28.2
diff -Nru mutter-3.30.2/debian/patches/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch mutter-3.30.2/debian/patches/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch
--- mutter-3.30.2/debian/patches/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,51 @@
+From: Andrea Azzarone <andrea.azzarone@canonical.com>
+Date: Tue, 22 Jan 2019 17:20:37 +0000
+Subject: clutter/x11: Consider remapped keys when guessing the keycode from
+ the keysym
+
+Since e3e933c4 a keyval can be temporarily remapped to an unused keycode. Due to
+some limitations in XTestFakeKeyEvent, the remapping has to be done in the first
+xkb group/layout. In case there are two or more keyboard layouts enabled and the
+selected keyboard layout is not the first, clutter_keymap_x11_keycode_for_keyval
+will fail to retrieve the correct keycode for a remapped keyval. Let's use the
+reserved_keycodes map in order to retrieve the correct keycode if needed.
+
+(cherry picked from commit e0811ce1416f93906026a18fda4cd6811594cfb2)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/issues/443
+Origin: upstream, 3.30.3, commit:0f7c35b94a14b06d2d606f4cf13800b6557cbb86
+---
+ clutter/clutter/x11/clutter-keymap-x11.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+diff --git a/clutter/clutter/x11/clutter-keymap-x11.c b/clutter/clutter/x11/clutter-keymap-x11.c
+index c34e676..32cb5a2 100644
+--- a/clutter/clutter/x11/clutter-keymap-x11.c
++++ b/clutter/clutter/x11/clutter-keymap-x11.c
+@@ -838,6 +838,26 @@ clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11,
+         }
+     }
+ 
++  if (!found)
++    {
++      GHashTableIter iter;
++      gpointer key, value;
++
++      g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes);
++      while (!found && g_hash_table_iter_next (&iter, &key, &value))
++        {
++          guint reserved_keycode = GPOINTER_TO_UINT (key);
++          guint reserved_keysym = GPOINTER_TO_UINT (value);
++
++          if (keyval == reserved_keysym)
++            {
++              *keycode_out = reserved_keycode;
++              *level_out = 0;
++              found = TRUE;
++            }
++        }
++    }
++
+   g_free (keys);
+   return found;
+ }
diff -Nru mutter-3.30.2/debian/patches/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch mutter-3.30.2/debian/patches/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch
--- mutter-3.30.2/debian/patches/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,292 @@
+From: Andrea Azzarone <azzaronea@gmail.com>
+Date: Fri, 13 Jul 2018 14:49:38 +0200
+Subject: clutter/x11: Implement keycode remap to keysyms on virtual key
+ devices
+
+Keycode lookup can fail for serveral reasons, e.g. if there is no combination of
+modifiers and keycodes that can produce the target keysym with the current
+keyboard layout.
+
+In case the keycode lookup fails, remap temporarily the keysym to an unused
+keycodes.
+
+(cherry-picked from commit e3e933c47a69bd137bb83b3692d105d1261d16ff)
+
+Bug: https://gitlab.gnome.org/GNOME/gnome-shell/issues/109
+Origin: upstream, 3.30.3, commit:956bb8066758fcd27b0bc593227d40551ed85275
+---
+ clutter/clutter/x11/clutter-keymap-x11.c           | 167 +++++++++++++++++++++
+ clutter/clutter/x11/clutter-keymap-x11.h           |   6 +-
+ .../clutter/x11/clutter-virtual-input-device-x11.c |  19 ++-
+ 3 files changed, 186 insertions(+), 6 deletions(-)
+
+diff --git a/clutter/clutter/x11/clutter-keymap-x11.c b/clutter/clutter/x11/clutter-keymap-x11.c
+index 32cb5a2..f1bdf16 100644
+--- a/clutter/clutter/x11/clutter-keymap-x11.c
++++ b/clutter/clutter/x11/clutter-keymap-x11.c
+@@ -79,6 +79,9 @@ struct _ClutterKeymapX11
+   guint current_cache_serial;
+   DirectionCacheEntry group_direction_cache[4];
+   int current_group;
++
++  GHashTable *reserved_keycodes;
++  GQueue *available_keycodes;
+ #endif
+ 
+   guint caps_lock_state : 1;
+@@ -441,16 +444,100 @@ clutter_keymap_x11_set_property (GObject      *gobject,
+     }
+ }
+ 
++#ifdef HAVE_XKB
++static void
++clutter_keymap_x11_refresh_reserved_keycodes (ClutterKeymapX11 *keymap_x11)
++{
++  Display *dpy = clutter_x11_get_default_display ();
++  GHashTableIter iter;
++  gpointer key, value;
++
++  g_hash_table_iter_init (&iter, keymap_x11->reserved_keycodes);
++  while (g_hash_table_iter_next (&iter, &key, &value))
++    {
++      guint reserved_keycode = GPOINTER_TO_UINT (key);
++      guint reserved_keysym = GPOINTER_TO_UINT (value);
++      guint actual_keysym = XkbKeycodeToKeysym (dpy, reserved_keycode, 0, 0);
++
++      /* If an available keycode is no longer mapped to the stored keysym, then
++       * the keycode should not be considered available anymore and should be
++       * removed both from the list of available and reserved keycodes.
++       */
++      if (reserved_keysym != actual_keysym)
++        {
++          g_hash_table_iter_remove (&iter);
++          g_queue_remove (keymap_x11->available_keycodes, key);
++        }
++    }
++}
++
++static gboolean
++clutter_keymap_x11_replace_keycode (ClutterKeymapX11 *keymap_x11,
++                                    KeyCode           keycode,
++                                    KeySym            keysym)
++{
++  if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb)
++    {
++      Display *dpy = clutter_x11_get_default_display ();
++      XkbDescPtr xkb = get_xkb (keymap_x11);
++      XkbMapChangesRec changes;
++
++      XFlush (dpy);
++
++      xkb->device_spec = XkbUseCoreKbd;
++      memset (&changes, 0, sizeof(changes));
++
++      if (keysym != NoSymbol)
++        {
++          int types[XkbNumKbdGroups] = { XkbOneLevelIndex };
++          XkbChangeTypesOfKey (xkb, keycode, 1, XkbGroup1Mask, types, &changes);
++          XkbKeySymEntry (xkb, keycode, 0, 0) = keysym;
++        }
++      else
++        {
++          /* Reset to NoSymbol */
++          XkbChangeTypesOfKey (xkb, keycode, 0, XkbGroup1Mask, NULL, &changes);
++        }
++
++      changes.changed = XkbKeySymsMask | XkbKeyTypesMask;
++      changes.first_key_sym = keycode;
++      changes.num_key_syms = 1;
++      changes.first_type = 0;
++      changes.num_types = xkb->map->num_types;
++      XkbChangeMap (dpy, xkb, &changes);
++
++      XFlush (dpy);
++
++      return TRUE;
++    }
++
++  return FALSE;
++}
++#endif
++
+ static void
+ clutter_keymap_x11_finalize (GObject *gobject)
+ {
+   ClutterKeymapX11 *keymap;
+   ClutterEventTranslator *translator;
++  GHashTableIter iter;
++  gpointer key, value;
+ 
+   keymap = CLUTTER_KEYMAP_X11 (gobject);
+   translator = CLUTTER_EVENT_TRANSLATOR (keymap);
+ 
+ #ifdef HAVE_XKB
++  clutter_keymap_x11_refresh_reserved_keycodes (keymap);
++  g_hash_table_iter_init (&iter, keymap->reserved_keycodes);
++  while (g_hash_table_iter_next (&iter, &key, &value))
++    {
++      guint keycode = GPOINTER_TO_UINT (key);
++      clutter_keymap_x11_replace_keycode (keymap, keycode, NoSymbol);
++    }
++
++  g_hash_table_destroy (keymap->reserved_keycodes);
++  g_queue_free (keymap->available_keycodes);
++
+   _clutter_backend_remove_event_translator (keymap->backend, translator);
+ 
+   if (keymap->xkb_desc != NULL)
+@@ -460,6 +547,7 @@ clutter_keymap_x11_finalize (GObject *gobject)
+   G_OBJECT_CLASS (clutter_keymap_x11_parent_class)->finalize (gobject);
+ }
+ 
++
+ static void
+ clutter_keymap_x11_class_init (ClutterKeymapX11Class *klass)
+ {
+@@ -483,6 +571,11 @@ clutter_keymap_x11_init (ClutterKeymapX11 *keymap)
+ {
+   keymap->current_direction = PANGO_DIRECTION_NEUTRAL;
+   keymap->current_group = -1;
++
++#ifdef HAVE_XKB
++  keymap->reserved_keycodes = g_hash_table_new (NULL, NULL);
++  keymap->available_keycodes = g_queue_new ();
++#endif
+ }
+ 
+ static ClutterTranslateReturn
+@@ -766,6 +859,80 @@ clutter_keymap_x11_get_entries_for_keyval (ClutterKeymapX11  *keymap_x11,
+     }
+ }
+ 
++#ifdef HAVE_XKB
++static guint
++clutter_keymap_x11_get_available_keycode (ClutterKeymapX11 *keymap_x11)
++{
++  if (CLUTTER_BACKEND_X11 (keymap_x11->backend)->use_xkb)
++    {
++      clutter_keymap_x11_refresh_reserved_keycodes (keymap_x11);
++
++      if (g_hash_table_size (keymap_x11->reserved_keycodes) < 5)
++        {
++          Display *dpy = clutter_x11_get_default_display ();
++          XkbDescPtr xkb = get_xkb (keymap_x11);
++          guint i;
++
++          for (i = xkb->max_key_code; i >= xkb->min_key_code; --i)
++            {
++              if (XkbKeycodeToKeysym (dpy, i, 0, 0) == NoSymbol)
++                return i;
++            }
++        }
++
++      return GPOINTER_TO_UINT (g_queue_pop_head (keymap_x11->available_keycodes));
++    }
++
++  return 0;
++}
++#endif
++
++gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11,
++                                             guint             keyval,
++                                             guint            *keycode_out)
++{
++  g_return_val_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11), FALSE);
++  g_return_val_if_fail (keyval != 0, FALSE);
++  g_return_val_if_fail (keycode_out != NULL, FALSE);
++
++#ifdef HAVE_XKB
++  *keycode_out = clutter_keymap_x11_get_available_keycode (keymap_x11);
++
++  if (*keycode_out == NoSymbol)
++    {
++      g_warning ("Cannot reserve a keycode for keyval %d: no available keycode", keyval);
++      return FALSE;
++    }
++
++  if (!clutter_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;
++#else
++  return FALSE;
++#endif
++}
++
++void clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11,
++                                                   guint             keycode)
++{
++  g_return_if_fail (CLUTTER_IS_KEYMAP_X11 (keymap_x11));
++
++#ifdef HAVE_XKB
++  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));
++#endif
++}
++
+ void
+ clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11,
+                                     uint32_t          level,
+diff --git a/clutter/clutter/x11/clutter-keymap-x11.h b/clutter/clutter/x11/clutter-keymap-x11.h
+index 4b5b403..4decb44 100644
+--- a/clutter/clutter/x11/clutter-keymap-x11.h
++++ b/clutter/clutter/x11/clutter-keymap-x11.h
+@@ -58,7 +58,11 @@ gboolean clutter_keymap_x11_keycode_for_keyval (ClutterKeymapX11 *keymap_x11,
+ void     clutter_keymap_x11_latch_modifiers (ClutterKeymapX11 *keymap_x11,
+                                              uint32_t          level,
+                                              gboolean          enable);
+-
++gboolean clutter_keymap_x11_reserve_keycode (ClutterKeymapX11 *keymap_x11,
++                                             guint             keyval,
++                                             guint            *keycode_out);
++void     clutter_keymap_x11_release_keycode_if_needed (ClutterKeymapX11 *keymap_x11,
++                                                       guint             keycode);
+ G_END_DECLS
+ 
+ #endif /* __CLUTTER_KEYMAP_X11_H__ */
+diff --git a/clutter/clutter/x11/clutter-virtual-input-device-x11.c b/clutter/clutter/x11/clutter-virtual-input-device-x11.c
+index e16ba3f..cab26c3 100644
+--- a/clutter/clutter/x11/clutter-virtual-input-device-x11.c
++++ b/clutter/clutter/x11/clutter-virtual-input-device-x11.c
+@@ -143,8 +143,13 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu
+ 
+   if (!clutter_keymap_x11_keycode_for_keyval (keymap, keyval, &keycode, &level))
+     {
+-      g_warning ("No keycode found for keyval %x in current group", keyval);
+-      return;
++      level = 0;
++
++      if (!clutter_keymap_x11_reserve_keycode (keymap, keyval, &keycode))
++        {
++          g_warning ("No keycode found for keyval %x in current group", keyval);
++          return;
++        }
+     }
+ 
+   if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode) &&
+@@ -155,9 +160,13 @@ clutter_virtual_input_device_x11_notify_keyval (ClutterVirtualInputDevice *virtu
+                      (KeyCode) keycode,
+                      key_state == CLUTTER_KEY_STATE_PRESSED, 0);
+ 
+-  if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode) &&
+-      key_state == CLUTTER_KEY_STATE_RELEASED)
+-    clutter_keymap_x11_latch_modifiers (keymap, level, FALSE);
++
++  if (key_state == CLUTTER_KEY_STATE_RELEASED)
++    {
++      if (!_clutter_keymap_x11_get_is_modifier (keymap, keycode))
++        clutter_keymap_x11_latch_modifiers (keymap, level, FALSE);
++      clutter_keymap_x11_release_keycode_if_needed (keymap, keycode);
++    }
+ }
+ 
+ static void
diff -Nru mutter-3.30.2/debian/patches/cogl-pipeline-Don-t-try-to-access-to-free-d-pointer-data.patch mutter-3.30.2/debian/patches/cogl-pipeline-Don-t-try-to-access-to-free-d-pointer-data.patch
--- mutter-3.30.2/debian/patches/cogl-pipeline-Don-t-try-to-access-to-free-d-pointer-data.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/cogl-pipeline-Don-t-try-to-access-to-free-d-pointer-data.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,43 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Fri, 17 May 2019 19:35:46 +0000
+Subject: cogl/pipeline: Don't try to access to free'd pointer data
+
+When free'ing a pipeline we destroy the BigState first and then the fragment and
+vertex snippets lists using the big state pointer which is now invalid.
+This causes a crash  when G_SLICE=always-malloc is set and using MALLOC_CHECK_.
+
+So, invert the operations by free'ing the snippet lists first, and the big state
+afterwards.
+
+(cherry picked from commit 7e0d185120ea116c91a8db60276971d3fecece80)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/581
+Origin: upstream, 3.30.3, commit:49dcf50727d7e998cb5641baeaded4889a4d0a9f
+---
+ cogl/cogl/cogl-pipeline.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/cogl/cogl/cogl-pipeline.c b/cogl/cogl/cogl-pipeline.c
+index da2d2ce..6a77cda 100644
+--- a/cogl/cogl/cogl-pipeline.c
++++ b/cogl/cogl/cogl-pipeline.c
+@@ -492,9 +492,6 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
+       _cogl_bitmask_destroy (&uniforms_state->changed_mask);
+     }
+ 
+-  if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
+-    g_slice_free (CoglPipelineBigState, pipeline->big_state);
+-
+   if (pipeline->differences & COGL_PIPELINE_STATE_LAYERS)
+     {
+       g_list_foreach (pipeline->layer_differences,
+@@ -508,6 +505,9 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
+   if (pipeline->differences & COGL_PIPELINE_STATE_FRAGMENT_SNIPPETS)
+     _cogl_pipeline_snippet_list_free (&pipeline->big_state->fragment_snippets);
+ 
++  if (pipeline->differences & COGL_PIPELINE_STATE_NEEDS_BIG_STATE)
++    g_slice_free (CoglPipelineBigState, pipeline->big_state);
++
+   g_list_free (pipeline->deprecated_get_layers_list);
+ 
+   recursively_free_layer_caches (pipeline);
diff -Nru mutter-3.30.2/debian/patches/compositor-Destroy-window-actors-list-on-destruction.patch mutter-3.30.2/debian/patches/compositor-Destroy-window-actors-list-on-destruction.patch
--- mutter-3.30.2/debian/patches/compositor-Destroy-window-actors-list-on-destruction.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/compositor-Destroy-window-actors-list-on-destruction.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,62 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Mon, 29 Apr 2019 19:57:03 +0000
+Subject: compositor: Destroy window actors list on destruction
+
+When the compositor is destroyed we should cleanup the list of window actors we
+created and destroy them.
+Since all the actors are added to the window_group or top_window_group we can
+just destroy these containers (together with the feedback_group), and simply
+free the windows list.
+
+This is particularly needed under X11 because before we destroy the display, we
+might do some cleanups as detaching the surface pixmaps and freeing the damages
+and if this happens at later point (for example when triggered by garbage
+collector in gnome-shell), we might crash because the x11 dpy reference is
+already gone.
+
+Destroying the window actors instead, ensures we avoid any further call to X11
+related functions and that we release the actors XServer resources.
+
+(cherry picked from commit 7718e67f5c0c78ed93e9ad04e7254b6db70a0337)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/issues/576
+Origin: upstream, 3.30.3, commit:ffe94b0d73237e637c5198a7018e96f2f867f700
+---
+ src/compositor/compositor.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
+index e1f5973..cc1455a 100644
+--- a/src/compositor/compositor.c
++++ b/src/compositor/compositor.c
+@@ -91,6 +91,10 @@ on_presented (ClutterStage     *stage,
+               ClutterFrameInfo *frame_info,
+               MetaCompositor   *compositor);
+ 
++static void
++on_top_window_actor_destroyed (MetaWindowActor *window_actor,
++                               MetaCompositor  *compositor);
++
+ static gboolean
+ is_modal (MetaDisplay *display)
+ {
+@@ -133,6 +137,19 @@ meta_compositor_destroy (MetaCompositor *compositor)
+   clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
+   clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
+ 
++  if (compositor->top_window_actor)
++    {
++      g_signal_handlers_disconnect_by_func (compositor->top_window_actor,
++                                            on_top_window_actor_destroyed,
++                                            compositor);
++      compositor->top_window_actor = NULL;
++    }
++
++  g_clear_pointer (&compositor->window_group, clutter_actor_destroy);
++  g_clear_pointer (&compositor->top_window_group, clutter_actor_destroy);
++  g_clear_pointer (&compositor->feedback_group, clutter_actor_destroy);
++  g_clear_pointer (&compositor->windows, g_list_free);
++
+   if (compositor->have_x11_sync_object)
+     meta_sync_ring_destroy ();
+ }
diff -Nru mutter-3.30.2/debian/patches/compositor-Disconnect-from-stage-signals-on-destruction.patch mutter-3.30.2/debian/patches/compositor-Disconnect-from-stage-signals-on-destruction.patch
--- mutter-3.30.2/debian/patches/compositor-Disconnect-from-stage-signals-on-destruction.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/compositor-Disconnect-from-stage-signals-on-destruction.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,76 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Mon, 29 Apr 2019 20:02:18 +0000
+Subject: compositor: Disconnect from stage signals on destruction
+
+From this point there's not any need for the compositor to listen to signals
+so we can disconnect from the stage ones we are connected to.
+
+(cherry picked from commit 3ba79961fed2c70df3201b3e588990c92aadcd7f)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/556
+Origin: upstream, 3.30.3, commit:1d8c4285b9b521985c611fd77b59049b197c67f5
+---
+ src/compositor/compositor-private.h |  3 +++
+ src/compositor/compositor.c         | 21 ++++++++++++++++-----
+ 2 files changed, 19 insertions(+), 5 deletions(-)
+
+diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h
+index 125a0af..5d9e830 100644
+--- a/src/compositor/compositor-private.h
++++ b/src/compositor/compositor-private.h
+@@ -18,6 +18,9 @@ struct _MetaCompositor
+   guint           pre_paint_func_id;
+   guint           post_paint_func_id;
+ 
++  guint           stage_presented_id;
++  guint           stage_after_paint_id;
++
+   gint64          server_time_query_time;
+   gint64          server_time_offset;
+ 
+diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
+index cc1455a..24ff72f 100644
+--- a/src/compositor/compositor.c
++++ b/src/compositor/compositor.c
+@@ -134,6 +134,15 @@ meta_switch_workspace_completed (MetaCompositor *compositor)
+ void
+ meta_compositor_destroy (MetaCompositor *compositor)
+ {
++  g_signal_handler_disconnect (compositor->stage,
++                               compositor->stage_after_paint_id);
++  g_signal_handler_disconnect (compositor->stage,
++                               compositor->stage_presented_id);
++
++  compositor->stage_after_paint_id = 0;
++  compositor->stage_presented_id = 0;
++  compositor->stage = NULL;
++
+   clutter_threads_remove_repaint_func (compositor->pre_paint_func_id);
+   clutter_threads_remove_repaint_func (compositor->post_paint_func_id);
+ 
+@@ -519,9 +528,10 @@ meta_compositor_manage (MetaCompositor *compositor)
+ 
+   compositor->stage = meta_backend_get_stage (backend);
+ 
+-  g_signal_connect (compositor->stage, "presented",
+-                    G_CALLBACK (on_presented),
+-                    compositor);
++  compositor->stage_presented_id =
++    g_signal_connect (compositor->stage, "presented",
++                      G_CALLBACK (on_presented),
++                                                     compositor);
+ 
+   /* We use connect_after() here to accomodate code in GNOME Shell that,
+    * when benchmarking drawing performance, connects to ::after-paint
+@@ -531,8 +541,9 @@ meta_compositor_manage (MetaCompositor *compositor)
+    * connections to ::after-paint, connect() vs. connect_after() doesn't
+    * matter.
+    */
+-  g_signal_connect_after (CLUTTER_STAGE (compositor->stage), "after-paint",
+-                          G_CALLBACK (after_stage_paint), compositor);
++  compositor->stage_after_paint_id =
++    g_signal_connect_after (compositor->stage, "after-paint",
++                            G_CALLBACK (after_stage_paint), compositor);
+ 
+   clutter_stage_set_sync_delay (CLUTTER_STAGE (compositor->stage), META_SYNC_DELAY);
+ 
diff -Nru mutter-3.30.2/debian/patches/cursor-renderer-native-Free-MetaCursorNativePrivate-struc.patch mutter-3.30.2/debian/patches/cursor-renderer-native-Free-MetaCursorNativePrivate-struc.patch
--- mutter-3.30.2/debian/patches/cursor-renderer-native-Free-MetaCursorNativePrivate-struc.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/cursor-renderer-native-Free-MetaCursorNativePrivate-struc.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,26 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Fri, 17 May 2019 19:46:33 +0000
+Subject: cursor-renderer-native: Free MetaCursorNativePrivate struct
+
+Fix a small leak in native renderer.
+
+(cherry picked from commit b016ff29f638b04d1a756b82c461563207083391)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/581
+Origin: upstream, 3.30.3, commit:41d28e254a7f4824f6378bfdd9b218d98a5569d2
+---
+ src/backends/native/meta-cursor-renderer-native.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c
+index 890a0d4..e5f868b 100644
+--- a/src/backends/native/meta-cursor-renderer-native.c
++++ b/src/backends/native/meta-cursor-renderer-native.c
+@@ -798,6 +798,7 @@ static void
+ cursor_priv_free (MetaCursorNativePrivate *cursor_priv)
+ {
+   g_hash_table_destroy (cursor_priv->gpu_states);
++  g_free (cursor_priv);
+ }
+ 
+ static MetaCursorNativePrivate *
diff -Nru mutter-3.30.2/debian/patches/Makefile-tests-Fix-paths-for-stacking-metatests.patch mutter-3.30.2/debian/patches/Makefile-tests-Fix-paths-for-stacking-metatests.patch
--- mutter-3.30.2/debian/patches/Makefile-tests-Fix-paths-for-stacking-metatests.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/Makefile-tests-Fix-paths-for-stacking-metatests.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,35 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Mon, 8 Jul 2019 17:12:25 +0200
+Subject: Makefile-tests: Fix paths for stacking metatests
+
+In commit 29ffaa6f8 and commit 8abd1b009 were added stacking tests with wrong
+paths.
+
+Fix them.
+
+Realated to: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
+
+Origin: upstream, 3.30.3, commit:4349e682f8d2c37a27c1dab5f636f8bcbbae0a23
+---
+ src/Makefile-tests.am | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/Makefile-tests.am b/src/Makefile-tests.am
+index 7cfae23..7c1dd60 100644
+--- a/src/Makefile-tests.am
++++ b/src/Makefile-tests.am
+@@ -15,10 +15,10 @@ dist_stacking_DATA =						\
+ 	$(srcdir)/tests/stacking/basic-x11.metatest 	\
+ 	$(srcdir)/tests/stacking/basic-wayland.metatest	\
+ 	$(srcdir)/tests/stacking/closed-transient.metatest	\
+-	$(srcdir)/closed-transient-no-input-no-take-focus-parent.metatest	\
+-	$(srcdir)/closed-transient-no-input-no-take-focus-parents.metatest	\
+-	$(srcdir)/closed-transient-no-input-parent.metatest	\
+-	$(srcdir)/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest	\
++	$(srcdir)/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest	\
++	$(srcdir)/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest	\
++	$(srcdir)/tests/stacking/closed-transient-no-input-parent.metatest	\
++	$(srcdir)/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest	\
+ 	$(srcdir)/tests/stacking/minimized.metatest 	\
+ 	$(srcdir)/tests/stacking/mixed-windows.metatest     \
+ 	$(srcdir)/tests/stacking/set-parent.metatest	\
diff -Nru mutter-3.30.2/debian/patches/renderer-native-add-missing-eglTerminate-in-EGLDevice-err.patch mutter-3.30.2/debian/patches/renderer-native-add-missing-eglTerminate-in-EGLDevice-err.patch
--- mutter-3.30.2/debian/patches/renderer-native-add-missing-eglTerminate-in-EGLDevice-err.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/renderer-native-add-missing-eglTerminate-in-EGLDevice-err.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,46 @@
+From: Emil Velikov <emil.velikov@collabora.com>
+Date: Wed, 12 Jun 2019 16:58:54 +0000
+Subject: renderer/native: add missing eglTerminate in EGLDevice error path
+MIME-Version: 1.0
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+Currently the EGLDevice code gets the display and calls eglInitialize.
+As a follow-up it checks the required EGL extensions - technically it
+could check the EGL device extensions earlier.
+
+In either case, eglTerminate is missing. Thus the connection to the
+display was still bound.
+
+This was highlighted with Mesa commit d6edccee8da ("egl: add
+EGL_platform_device support") + amdgpu.
+
+In that case, since the eglTerminate is missing, we end up reusing the
+underlying amdgpu_device due to some caching in libdrm_amdgpu. The
+latter in itself being a good solution since it allows buffer sharing
+across primary and render node of the same device.
+
+Note: we should really get this in branches all the way back to 3.30.
+
+(cherry picked from commit 9213574870faee7fe40609791fc48f4b44f861c0)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/619
+Fixes: 934184e23 ("MetaRendererNative: Add EGLDevice based rendering support")
+Cc: Jonas Ådahl <jadahl@gmail.com>
+Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
+---
+ src/backends/native/meta-renderer-native.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
+index f58e6b3..b3976d4 100644
+--- a/src/backends/native/meta-renderer-native.c
++++ b/src/backends/native/meta-renderer-native.c
+@@ -3342,6 +3342,7 @@ create_renderer_gpu_data_egl_device (MetaRendererNative  *renderer_native,
+                    G_IO_ERROR_FAILED,
+                    "Missing EGL extensions required for EGLDevice renderer: %s",
+                    missing_extensions_str);
++      meta_egl_terminate (egl, egl_display, NULL);
+       g_free (missing_extensions_str);
+       g_free (missing_extensions);
+       return NULL;
diff -Nru mutter-3.30.2/debian/patches/renderer-native-Fix-EGLSurface-destruction-order.patch mutter-3.30.2/debian/patches/renderer-native-Fix-EGLSurface-destruction-order.patch
--- mutter-3.30.2/debian/patches/renderer-native-Fix-EGLSurface-destruction-order.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/renderer-native-Fix-EGLSurface-destruction-order.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,123 @@
+From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com>
+Date: Mon, 17 Jun 2019 18:16:12 +0100
+Subject: renderer/native: Fix EGLSurface destruction order
+
+Make sure to destroy the EGL surface after releasing held buffers,
+otherwise we'll get the following valgrind warnings:
+
+==24016== Invalid read of size 8
+==24016==    at 0x1739943F: release_buffer (platform_drm.c:73)
+==24016==    by 0x49AC355: meta_drm_buffer_gbm_finalize (meta-drm-buffer-gbm.c:213)
+==24016==    by 0x4B75B61: g_object_unref (gobject.c:3346)
+==24016==    by 0x49B4B41: free_current_bo (meta-renderer-native.c:991)
+==24016==    by 0x49B816F: meta_renderer_native_release_onscreen (meta-renderer-native.c:2971)
+==24016==    by 0x5209441: _cogl_onscreen_free (cogl-onscreen.c:167)
+==24016==    by 0x5208D81: _cogl_object_onscreen_indirect_free (cogl-onscreen.c:51)
+==24016==    by 0x51C8066: _cogl_object_default_unref (cogl-object.c:103)
+==24016==    by 0x5207989: _cogl_framebuffer_unref (cogl-framebuffer.c:1814)
+==24016==    by 0x51C80B1: cogl_object_unref (cogl-object.c:115)
+==24016==    by 0x53673C7: clutter_stage_view_dispose (clutter-stage-view.c:304)
+==24016==    by 0x4B75AF2: g_object_unref (gobject.c:3309)
+==24016==  Address 0x18e742a8 is 536 bytes inside a block of size 784 free'd
+==24016==    at 0x4839A0C: free (vg_replace_malloc.c:540)
+==24016==    by 0x17399764: dri2_drm_destroy_surface (platform_drm.c:231)
+==24016==    by 0x1738550A: eglDestroySurface (eglapi.c:1145)
+==24016==    by 0x5440286: eglDestroySurface (in /home/jonas/Dev/gnome/install/lib/libEGL.so.1.1.0)
+==24016==    by 0x49613A5: meta_egl_destroy_surface (meta-egl.c:432)
+==24016==    by 0x49B80F9: meta_renderer_native_release_onscreen (meta-renderer-native.c:2954)
+==24016==    by 0x5209441: _cogl_onscreen_free (cogl-onscreen.c:167)
+==24016==    by 0x5208D81: _cogl_object_onscreen_indirect_free (cogl-onscreen.c:51)
+==24016==    by 0x51C8066: _cogl_object_default_unref (cogl-object.c:103)
+==24016==    by 0x5207989: _cogl_framebuffer_unref (cogl-framebuffer.c:1814)
+==24016==    by 0x51C80B1: cogl_object_unref (cogl-object.c:115)
+==24016==    by 0x53673C7: clutter_stage_view_dispose (clutter-stage-view.c:304)
+==24016==  Block was alloc'd at
+==24016==    at 0x483AB1A: calloc (vg_replace_malloc.c:762)
+==24016==    by 0x173997AE: dri2_drm_create_window_surface (platform_drm.c:145)
+==24016==    by 0x17388906: _eglCreateWindowSurfaceCommon (eglapi.c:929)
+==24016==    by 0x5440197: eglCreateWindowSurface (in /home/jonas/Dev/gnome/install/lib/libEGL.so.1.1.0)
+==24016==    by 0x49612FF: meta_egl_create_window_surface (meta-egl.c:396)
+==24016==    by 0x49B752E: meta_renderer_native_create_surface_gbm (meta-renderer-native.c:2538)
+==24016==    by 0x49B7E6C: meta_onscreen_native_allocate (meta-renderer-native.c:2870)
+==24016==    by 0x49B8BCF: meta_renderer_native_create_view (meta-renderer-native.c:3387)
+==24016==    by 0x48D274B: meta_renderer_create_view (meta-renderer.c:78)
+==24016==    by 0x48D27DE: meta_renderer_rebuild_views (meta-renderer.c:111)
+==24016==    by 0x49BB4FB: meta_stage_native_rebuild_views (meta-stage-native.c:142)
+==24016==    by 0x49A733C: meta_backend_native_update_screen_size (meta-backend-native.c:517)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/622
+Origin: backport, 3.32.3, commit:e0922bffea44ed201dd0adf38bf3180b4a574fe2
+---
+ src/backends/native/meta-renderer-native.c | 38 +++++++++++++++++++++---------
+ 1 file changed, 27 insertions(+), 11 deletions(-)
+
+diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
+index c6e56e5..b5c5e42 100644
+--- a/src/backends/native/meta-renderer-native.c
++++ b/src/backends/native/meta-renderer-native.c
+@@ -2457,6 +2457,28 @@ meta_onscreen_native_allocate (CoglOnscreen *onscreen,
+   return TRUE;
+ }
+ 
++static void
++destroy_egl_surface (CoglOnscreen *onscreen)
++{
++  CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
++
++  if (onscreen_egl->egl_surface != EGL_NO_SURFACE)
++    {
++      MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
++      MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native);
++      CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
++      CoglContext *cogl_context = framebuffer->context;
++      CoglRenderer *cogl_renderer = cogl_context->display->renderer;
++      CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
++
++      meta_egl_destroy_surface (egl,
++                                cogl_renderer_egl->edpy,
++                                onscreen_egl->egl_surface,
++                                NULL);
++      onscreen_egl->egl_surface = EGL_NO_SURFACE;
++    }
++}
++
+ static void
+ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
+ {
+@@ -2487,17 +2509,6 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
+         g_warning ("Failed to clear current context");
+     }
+ 
+-  if (onscreen_egl->egl_surface != EGL_NO_SURFACE)
+-    {
+-      MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native);
+-
+-      meta_egl_destroy_surface (egl,
+-                                cogl_renderer_egl->edpy,
+-                                onscreen_egl->egl_surface,
+-                                NULL);
+-      onscreen_egl->egl_surface = EGL_NO_SURFACE;
+-    }
+-
+   renderer_gpu_data =
+     meta_renderer_native_get_gpu_data (onscreen_native->renderer_native,
+                                        onscreen_native->render_gpu);
+@@ -2510,6 +2521,8 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
+ 
+       free_current_bo (onscreen);
+ 
++      destroy_egl_surface (onscreen);
++
+       if (onscreen_native->gbm.surface)
+         {
+           gbm_surface_destroy (onscreen_native->gbm.surface);
+@@ -2520,6 +2533,9 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
+     case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
+       release_dumb_fb (&onscreen_native->egl.dumb_fb,
+                        onscreen_native->render_gpu);
++
++      destroy_egl_surface (onscreen);
++
+       if (onscreen_native->egl.stream != EGL_NO_STREAM_KHR)
+         {
+           MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native);
diff -Nru mutter-3.30.2/debian/patches/renderer-native-Make-sure-we-re-not-destroying-an-active-.patch mutter-3.30.2/debian/patches/renderer-native-Make-sure-we-re-not-destroying-an-active-.patch
--- mutter-3.30.2/debian/patches/renderer-native-Make-sure-we-re-not-destroying-an-active-.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/renderer-native-Make-sure-we-re-not-destroying-an-active-.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,89 @@
+From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com>
+Date: Mon, 17 Jun 2019 18:18:42 +0200
+Subject: renderer/native: Make sure we're not destroying an active EGLSurface
+
+When making a new surface/context pair current, mesa may want to flush
+the old context. Make sure we don't try to flush any freed memory by
+unmaking a surface/context pair current before freeing it.
+
+Not doing this results in the following valgrind warnings:
+
+==15986== Invalid read of size 8
+==15986==    at 0x69A6D80: dri_flush_front_buffer (gbm_dri.c:92)
+==15986==    by 0x1750D458: intel_flush_front (brw_context.c:251)
+==15986==    by 0x1750D4BB: intel_glFlush (brw_context.c:296)
+==15986==    by 0x1739D8DD: dri2_make_current (egl_dri2.c:1461)
+==15986==    by 0x17393A3A: eglMakeCurrent (eglapi.c:869)
+==15986==    by 0x54381FB: InternalMakeCurrentVendor (in /home/jonas/Dev/gnome/install/lib/libEGL.so.1.1.0)
+==15986==    by 0x5438515: eglMakeCurrent (in /home/jonas/Dev/gnome/install/lib/libEGL.so.1.1.0)
+==15986==    by 0x522A782: _cogl_winsys_egl_make_current (cogl-winsys-egl.c:303)
+==15986==    by 0x49B64C8: meta_renderer_native_create_view (meta-renderer-native.c:3076)
+==15986==    by 0x48D26E7: meta_renderer_create_view (meta-renderer.c:78)
+==15986==    by 0x48D277A: meta_renderer_rebuild_views (meta-renderer.c:111)
+==15986==    by 0x49BF46E: meta_stage_native_rebuild_views (meta-stage-native.c:142)
+==15986==  Address 0x1b076600 is 0 bytes inside a block of size 48 free'd
+==15986==    at 0x4839A0C: free (vg_replace_malloc.c:540)
+==15986==    by 0x49B59F3: meta_renderer_native_release_onscreen (meta-renderer-native.c:2651)
+==15986==    by 0x5211441: _cogl_onscreen_free (cogl-onscreen.c:167)
+==15986==    by 0x5210D81: _cogl_object_onscreen_indirect_free (cogl-onscreen.c:51)
+==15986==    by 0x51D0066: _cogl_object_default_unref (cogl-object.c:103)
+==15986==    by 0x520F989: _cogl_framebuffer_unref (cogl-framebuffer.c:1814)
+==15986==    by 0x51D00B1: cogl_object_unref (cogl-object.c:115)
+==15986==    by 0x536F3C7: clutter_stage_view_dispose (clutter-stage-view.c:304)
+==15986==    by 0x4B7DAF2: g_object_unref (gobject.c:3309)
+==15986==    by 0x4A9596C: g_list_foreach (glist.c:1013)
+==15986==    by 0x4A9599A: g_list_free_full (glist.c:223)
+==15986==    by 0x48D2737: meta_renderer_rebuild_views (meta-renderer.c:100)
+==15986==  Block was alloc'd at
+==15986==    at 0x483AB1A: calloc (vg_replace_malloc.c:762)
+==15986==    by 0x69A76B2: gbm_dri_surface_create (gbm_dri.c:1252)
+==15986==    by 0x69A6BFE: gbm_surface_create (gbm.c:600)
+==15986==    by 0x49B4E29: meta_renderer_native_create_surface_gbm (meta-renderer-native.c:2221)
+==15986==    by 0x49B57DB: meta_onscreen_native_allocate (meta-renderer-native.c:2569)
+==15986==    by 0x49B6423: meta_renderer_native_create_view (meta-renderer-native.c:3062)
+==15986==    by 0x48D26E7: meta_renderer_create_view (meta-renderer.c:78)
+==15986==    by 0x48D277A: meta_renderer_rebuild_views (meta-renderer.c:111)
+==15986==    by 0x49BF46E: meta_stage_native_rebuild_views (meta-stage-native.c:142)
+==15986==    by 0x49A75B5: meta_backend_native_update_screen_size (meta-backend-native.c:520)
+==15986==    by 0x48B01BB: meta_backend_sync_screen_size (meta-backend.c:224)
+==15986==    by 0x48B09B7: meta_backend_real_post_init (meta-backend.c:501)
+
+(cherry picked from commit 56ddaaa3809240a357b5e19b5789d1aa49aaecc3)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/622
+Origin: backport, 3.32.3, commit:8307c0f7ab60760de53f764e6636893733543be8
+---
+ src/backends/native/meta-renderer-native.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
+index b8e0f0c..c6e56e5 100644
+--- a/src/backends/native/meta-renderer-native.c
++++ b/src/backends/native/meta-renderer-native.c
+@@ -2462,6 +2462,8 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
+ {
+   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+   CoglContext *cogl_context = framebuffer->context;
++  CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
++  CoglDisplayEGL *cogl_display_egl = cogl_display->winsys;
+   CoglRenderer *cogl_renderer = cogl_context->display->renderer;
+   CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
+   CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
+@@ -2474,6 +2476,17 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
+ 
+   onscreen_native = onscreen_egl->platform;
+ 
++  if (onscreen_egl->egl_surface != EGL_NO_SURFACE &&
++      (cogl_display_egl->current_draw_surface == onscreen_egl->egl_surface ||
++       cogl_display_egl->current_read_surface == onscreen_egl->egl_surface))
++    {
++      if (!_cogl_winsys_egl_make_current (cogl_display,
++                                          cogl_display_egl->dummy_surface,
++                                          cogl_display_egl->dummy_surface,
++                                          cogl_display_egl->egl_context))
++        g_warning ("Failed to clear current context");
++    }
++
+   if (onscreen_egl->egl_surface != EGL_NO_SURFACE)
+     {
+       MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native);
diff -Nru mutter-3.30.2/debian/patches/renderer-native-Use-g_set_error-instead-of-_cogl_set_erro.patch mutter-3.30.2/debian/patches/renderer-native-Use-g_set_error-instead-of-_cogl_set_erro.patch
--- mutter-3.30.2/debian/patches/renderer-native-Use-g_set_error-instead-of-_cogl_set_erro.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/renderer-native-Use-g_set_error-instead-of-_cogl_set_erro.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,27 @@
+From: =?utf-8?q?Jonas_=C3=85dahl?= <jadahl@gmail.com>
+Date: Mon, 17 Jun 2019 18:18:12 +0200
+Subject: renderer/native: Use g_set_error() instead of _cogl_set_error()
+
+It's even a GError, so lets use the proper API.
+
+(cherry picked from commit 1efb32d3000ca06ee3cfcc146dc812866d243619)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/622
+Applied-upstream: 3.32.3, commit:cded69da6137bd1fbf03cb907078ef7959290845
+---
+ src/backends/native/meta-renderer-native.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
+index b3976d4..b8e0f0c 100644
+--- a/src/backends/native/meta-renderer-native.c
++++ b/src/backends/native/meta-renderer-native.c
+@@ -1097,7 +1097,7 @@ meta_renderer_native_egl_context_created (CoglDisplay *cogl_display,
+                                       cogl_display_egl->dummy_surface,
+                                       cogl_display_egl->egl_context))
+     {
+-      _cogl_set_error (error, COGL_WINSYS_ERROR,
++      g_set_error (error, COGL_WINSYS_ERROR,
+                    COGL_WINSYS_ERROR_CREATE_CONTEXT,
+                    "Failed to make context current");
+       return FALSE;
diff -Nru mutter-3.30.2/debian/patches/series mutter-3.30.2/debian/patches/series
--- mutter-3.30.2/debian/patches/series	2019-04-28 00:13:35.000000000 +0100
+++ mutter-3.30.2/debian/patches/series	2019-08-18 19:51:33.000000000 +0100
@@ -8,6 +8,42 @@
 monitor-manager-Don-t-use-switch-config-when-ensuring-con.patch
 clutter-evdev-Fix-toggling-accessibility-features-from-ke.patch
 clutter-Fix-check-for-keyboard-a11y-features.patch
+clutter-x11-Consider-remapped-keys-when-guessing-the-keyc.patch
+compositor-Destroy-window-actors-list-on-destruction.patch
+compositor-Disconnect-from-stage-signals-on-destruction.patch
+clutter-x11-Implement-keycode-remap-to-keysyms-on-virtual.patch
+cursor-renderer-native-Free-MetaCursorNativePrivate-struc.patch
+wayland-seat-Use-g_free-to-cleanup-MetaWaylandSeat.patch
+cogl-pipeline-Don-t-try-to-access-to-free-d-pointer-data.patch
+renderer-native-add-missing-eglTerminate-in-EGLDevice-err.patch
+Updated-Spanish-translation.patch
+workspace-Focus-only-ancestors-that-are-focusable.patch
+tests-Add-accept_focus-command-to-runner-and-client.patch
+tests-Add-can_take_focus-command-to-runner-and-client.patch
+tests-stacking-Add-tests-with-no-input-and-no-take-focus-.patch
+test-runner-Add-assert_focused-command.patch
+tests-Verify-focused-window-in-closed-transient-tests.patch
+test-runner-Add-sleep-command.patch
+test-runner-Add-dispatch-command.patch
+window-x11-Focus-the-default-window-with-delay-while-wait.patch
+window-Emit-an-error-and-return-when-trying-to-activate-a.patch
+window-x11-Add-lost-definition-for-TAKE_FOCUS_FALLBACK_DE.patch
+window-actor-Set-actor-as-compositor-private-in-window-be.patch
+surface-actor-x11-Assign-X11-Display-only-if-we-have-reso.patch
+surface-actor-x11-Bind-the-surface-actor-resources-to-win.patch
+Makefile-tests-Fix-paths-for-stacking-metatests.patch
+window-x11-Don-t-double-check-for-unmanaging-windows.patch
+window-x11-Accept-any-focusable-window-as-fallback-focus.patch
+stack-Add-a-function-to-get-a-sorted-list-of-focus-candid.patch
+test-client-Add-x11-events-GSource-handler.patch
+tests-Add-accept_take_focus-command.patch
+window-x11-Use-any-focusable-window-as-fallback-delayed-f.patch
+window-x11-Focus-a-window-in-the-active-workspace-as-take.patch
+window-x11-Remove-double-definition-of-MetaStack.patch
+wayland-output-Set-user-data-of-xdg_output-resource.patch
+renderer-native-Use-g_set_error-instead-of-_cogl_set_erro.patch
+renderer-native-Make-sure-we-re-not-destroying-an-active-.patch
+renderer-native-Fix-EGLSurface-destruction-order.patch
 theme-use-gtk_render_icon_suface-to-paint-button-icon.patch
 theme-load-icons-as-Gtk-does-with-fallback-and-RTL-suppor.patch
 bgo768531_workaround-startup-notifications.patch
diff -Nru mutter-3.30.2/debian/patches/stack-Add-a-function-to-get-a-sorted-list-of-focus-candid.patch mutter-3.30.2/debian/patches/stack-Add-a-function-to-get-a-sorted-list-of-focus-candid.patch
--- mutter-3.30.2/debian/patches/stack-Add-a-function-to-get-a-sorted-list-of-focus-candid.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/stack-Add-a-function-to-get-a-sorted-list-of-focus-candid.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,127 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Wed, 3 Jul 2019 16:48:07 +0000
+Subject: stack: Add a function to get a sorted list of focus candidates
+
+Use a static function if a window can be the default focus window, and use such
+function to return a filtered list of the stack.
+
+(cherry picked from commit 2439255f32b4e775d4427c92a6797b8bd33e7d5a)
+
+Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/669
+Origin: upstream, 3.30.3, commit:60ea32330a6c92760f79dba9c86bcc385ca0d348
+---
+ src/core/stack.c | 55 ++++++++++++++++++++++++++++++++++++++++++-------------
+ src/core/stack.h | 15 +++++++++++++++
+ 2 files changed, 57 insertions(+), 13 deletions(-)
+
+diff --git a/src/core/stack.c b/src/core/stack.c
+index c00e86c..78bfc4b 100644
+--- a/src/core/stack.c
++++ b/src/core/stack.c
+@@ -1183,6 +1183,27 @@ window_contains_point (MetaWindow *window,
+   return POINT_IN_RECT (root_x, root_y, rect);
+ }
+ 
++static gboolean
++window_can_get_default_focus (MetaWindow *window)
++{
++  if (window->unmaps_pending > 0)
++    return FALSE;
++
++  if (window->unmanaging)
++    return FALSE;
++
++  if (!(window->input || window->take_focus))
++    return FALSE;
++
++  if (!meta_window_should_be_showing (window))
++    return FALSE;
++
++  if (window->type == META_WINDOW_DOCK)
++    return FALSE;
++
++  return TRUE;
++}
++
+ static MetaWindow*
+ get_default_focus_window (MetaStack     *stack,
+                           MetaWorkspace *workspace,
+@@ -1210,24 +1231,12 @@ get_default_focus_window (MetaStack     *stack,
+       if (window == not_this_one)
+         continue;
+ 
+-      if (window->unmaps_pending > 0)
+-        continue;
+-
+-      if (window->unmanaging)
+-        continue;
+-
+-      if (!(window->input || window->take_focus))
+-        continue;
+-
+-      if (!meta_window_should_be_showing (window))
++      if (!window_can_get_default_focus (window))
+         continue;
+ 
+       if (must_be_at_point && !window_contains_point (window, root_x, root_y))
+         continue;
+ 
+-      if (window->type == META_WINDOW_DOCK)
+-        continue;
+-
+       return window;
+     }
+ 
+@@ -1282,6 +1291,26 @@ meta_stack_list_windows (MetaStack     *stack,
+   return workspace_windows;
+ }
+ 
++GList *
++meta_stack_get_default_focus_candidates (MetaStack     *stack,
++                                         MetaWorkspace *workspace)
++{
++  GList *windows = meta_stack_list_windows (stack, workspace);
++  GList *l;
++
++  for (l = windows; l;)
++    {
++      GList *next = l->next;
++
++      if (!window_can_get_default_focus (l->data))
++        windows = g_list_delete_link (windows, l);
++
++      l = next;
++    }
++
++  return windows;
++}
++
+ int
+ meta_stack_windows_cmp  (MetaStack  *stack,
+                          MetaWindow *window_a,
+diff --git a/src/core/stack.h b/src/core/stack.h
+index d976067..b8dc782 100644
+--- a/src/core/stack.h
++++ b/src/core/stack.h
+@@ -337,6 +337,21 @@ MetaWindow* meta_stack_get_default_focus_window_at_point (MetaStack     *stack,
+                                                           int            root_x,
+                                                           int            root_y);
+ 
++/**
++ * meta_stack_get_default_focus_candidates:
++ * @stack: The stack to examine.
++ * @workspace: If not %NULL, only windows on this workspace will be
++ *             returned; otherwise all windows in the stack will be
++ *             returned.
++ *
++ * Returns all the focus candidate windows in the stack, in order.
++ *
++ * Returns: (transfer container) (element-type Meta.Window):
++ *     A #GList of #MetaWindow, in stacking order, honouring layers.
++ */
++GList *     meta_stack_get_default_focus_candidates (MetaStack     *stack,
++                                                     MetaWorkspace *workspace);
++
+ /**
+  * meta_stack_list_windows:
+  * @stack: The stack to examine.
diff -Nru mutter-3.30.2/debian/patches/surface-actor-x11-Assign-X11-Display-only-if-we-have-reso.patch mutter-3.30.2/debian/patches/surface-actor-x11-Assign-X11-Display-only-if-we-have-reso.patch
--- mutter-3.30.2/debian/patches/surface-actor-x11-Assign-X11-Display-only-if-we-have-reso.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/surface-actor-x11-Assign-X11-Display-only-if-we-have-reso.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,55 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Fri, 28 Jun 2019 11:36:08 +0200
+Subject: surface-actor-x11: Assign X11 Display only if we have resources
+
+free_damage and detach_pixmap functions are called inside dispose and an object
+can be disposed multiple times, even when the display is already closed.
+
+So, don't try to deference a possibly null-pointer, assigning the xdisplay too
+early, as if the X11 related resources have been unset, the server might not be
+open anymore. In fact, we assume that if we have a damage or a pixmap set,
+the display is still open.
+
+(cherry picked from commit d7d97f247767ace2655f1fd2a7bbee0c0c8cfb50)
+
+Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/660
+Origin: upstream, 3.30.3, commit:d4759df5bbe1a7e6e49ba72bf0a9e267c0d1e1d0
+---
+ src/compositor/meta-surface-actor-x11.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c
+index 3b66ed5..fd00721 100644
+--- a/src/compositor/meta-surface-actor-x11.c
++++ b/src/compositor/meta-surface-actor-x11.c
+@@ -69,11 +69,13 @@ free_damage (MetaSurfaceActorX11 *self)
+ {
+   MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+   MetaDisplay *display = priv->display;
+-  Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
++  Display *xdisplay;
+ 
+   if (priv->damage == None)
+     return;
+ 
++  xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
++
+   meta_x11_error_trap_push (display->x11_display);
+   XDamageDestroy (xdisplay, priv->damage);
+   priv->damage = None;
+@@ -85,12 +87,14 @@ detach_pixmap (MetaSurfaceActorX11 *self)
+ {
+   MetaSurfaceActorX11Private *priv = meta_surface_actor_x11_get_instance_private (self);
+   MetaDisplay *display = priv->display;
+-  Display *xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
+   MetaShapedTexture *stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
++  Display *xdisplay;
+ 
+   if (priv->pixmap == None)
+     return;
+ 
++  xdisplay = meta_x11_display_get_xdisplay (display->x11_display);
++
+   /* Get rid of all references to the pixmap before freeing it; it's unclear whether
+    * you are supposed to be able to free a GLXPixmap after freeing the underlying
+    * pixmap, but it certainly doesn't work with current DRI/Mesa
diff -Nru mutter-3.30.2/debian/patches/surface-actor-x11-Bind-the-surface-actor-resources-to-win.patch mutter-3.30.2/debian/patches/surface-actor-x11-Bind-the-surface-actor-resources-to-win.patch
--- mutter-3.30.2/debian/patches/surface-actor-x11-Bind-the-surface-actor-resources-to-win.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/surface-actor-x11-Bind-the-surface-actor-resources-to-win.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,86 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Fri, 28 Jun 2019 11:45:22 +0200
+Subject: surface-actor-x11: Bind the surface actor resources to window actor
+ life
+
+X11 actors need to release the server data (pixmap and damage) before the
+display is closed.
+During the close phase all the windows are unmanaged and this causes the window
+actors to be removed from the compositor, unsetting their actor surface.
+
+However, in case a window is animating the surface might not be destroyed until
+the animation is completed and a reference to it kept around by gjs in the shell
+case. By the way, per commit 7718e67f all window actors (even the animating
+ones) are destroyed before the display is closed, but this is not true for the
+child surface, because the parent window will just unref it, leaving it around
+if reffed somewhere else. This is fine for wayland surfaces, but not for X11
+ones which are bound to server-side pixmaps.
+
+So, connect to the parent MetaWindowActor "destroy" signal, releasing the x11
+resources that implies detaching the pixmap (unsetting the texture) and removing
+the damages.
+
+(cherry picked from commit de97b54595cf4662c437fecf26ca2e08339a13a3)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/issues/629
+Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/660
+Origin: upstream, 3.30.3, commit:9f98743cfccaec396c835094d43f392f5ccb5390
+---
+ src/compositor/meta-surface-actor-x11.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/src/compositor/meta-surface-actor-x11.c b/src/compositor/meta-surface-actor-x11.c
+index fd00721..1f63e18 100644
+--- a/src/compositor/meta-surface-actor-x11.c
++++ b/src/compositor/meta-surface-actor-x11.c
+@@ -33,6 +33,7 @@
+ #include <meta/meta-x11-errors.h>
+ #include "window-private.h"
+ #include "meta-shaped-texture-private.h"
++#include "meta-window-actor-private.h"
+ #include "meta-cullable.h"
+ #include "x11/window-x11.h"
+ #include "x11/meta-x11-display-private.h"
+@@ -357,13 +358,19 @@ meta_surface_actor_x11_is_unredirected (MetaSurfaceActor *actor)
+   return priv->unredirected;
+ }
+ 
++static void
++release_x11_resources (MetaSurfaceActorX11 *self)
++{
++  detach_pixmap (self);
++  free_damage (self);
++}
++
+ static void
+ meta_surface_actor_x11_dispose (GObject *object)
+ {
+   MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (object);
+ 
+-  detach_pixmap (self);
+-  free_damage (self);
++  release_x11_resources (self);
+ 
+   G_OBJECT_CLASS (meta_surface_actor_x11_parent_class)->dispose (object);
+ }
+@@ -421,8 +428,7 @@ window_decorated_notify (MetaWindow *window,
+ {
+   MetaSurfaceActorX11 *self = META_SURFACE_ACTOR_X11 (user_data);
+ 
+-  detach_pixmap (self);
+-  free_damage (self);
++  release_x11_resources (self);
+   create_damage (self);
+ }
+ 
+@@ -461,6 +467,10 @@ meta_surface_actor_x11_new (MetaWindow *window)
+   g_signal_connect_object (priv->window, "notify::decorated",
+                            G_CALLBACK (window_decorated_notify), self, 0);
+ 
++  g_signal_connect_object (meta_window_actor_from_window (window), "destroy",
++                           G_CALLBACK (release_x11_resources), self,
++                           G_CONNECT_SWAPPED);
++
+   priv->unredirected = FALSE;
+   sync_unredirected (self);
+ 
diff -Nru mutter-3.30.2/debian/patches/Sync-to-the-hardware-refresh-rate-not-just-60.00Hz.patch mutter-3.30.2/debian/patches/Sync-to-the-hardware-refresh-rate-not-just-60.00Hz.patch
--- mutter-3.30.2/debian/patches/Sync-to-the-hardware-refresh-rate-not-just-60.00Hz.patch	2019-04-28 00:13:35.000000000 +0100
+++ mutter-3.30.2/debian/patches/Sync-to-the-hardware-refresh-rate-not-just-60.00Hz.patch	2019-08-18 19:51:33.000000000 +0100
@@ -267,7 +267,7 @@
  
  void meta_gpu_kms_flip_closure_container_free (MetaGpuKmsFlipClosureContainer *closure_container);
 diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
-index f58e6b3..24d6b8b 100644
+index b5c5e42..30bce3f 100644
 --- a/src/backends/native/meta-renderer-native.c
 +++ b/src/backends/native/meta-renderer-native.c
 @@ -60,8 +60,9 @@
@@ -349,7 +349,7 @@
  #ifdef HAVE_EGL_DEVICE
    if (renderer_gpu_data->mode == META_RENDERER_NATIVE_MODE_EGL_DEVICE)
      COGL_FLAGS_SET (cogl_context->features,
-@@ -2616,8 +2646,12 @@ meta_renderer_native_create_onscreen (MetaRendererNative   *renderer_native,
+@@ -2645,8 +2675,12 @@ meta_renderer_native_create_onscreen (MetaRendererNative   *renderer_native,
      }
  
    onscreen = cogl_onscreen_new (context, width, height);
@@ -364,7 +364,7 @@
  
    if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (onscreen), error))
      {
-@@ -2687,6 +2721,15 @@ meta_renderer_native_create_offscreen (MetaRendererNative    *renderer,
+@@ -2716,6 +2750,15 @@ meta_renderer_native_create_offscreen (MetaRendererNative    *renderer,
    return fb;
  }
  
@@ -380,7 +380,7 @@
  static const CoglWinsysVtable *
  get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer)
  {
-@@ -2715,6 +2758,8 @@ get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer)
+@@ -2744,6 +2787,8 @@ get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer)
        vtable.onscreen_swap_buffers_with_damage =
          meta_onscreen_native_swap_buffers_with_damage;
  
diff -Nru mutter-3.30.2/debian/patches/test-client-Add-x11-events-GSource-handler.patch mutter-3.30.2/debian/patches/test-client-Add-x11-events-GSource-handler.patch
--- mutter-3.30.2/debian/patches/test-client-Add-x11-events-GSource-handler.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/test-client-Add-x11-events-GSource-handler.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,184 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Wed, 3 Jul 2019 14:43:49 +0000
+Subject: test-client: Add x11 events GSource handler
+
+When using gtk under X11 some WM related events are always filtered and not
+delivered when using the gdk Window filters.
+
+So, add a new one with higher priority than the GTK events one so that we can
+pick those events before than Gtk itself.
+
+(cherry picked from commit bd0f1bd338d86b382ca34e659b6651e288eba2fd)
+
+Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/669
+Origin: upstream, 3.30.3, commit:0733f22b817fa0d12a28ff4654215d21089794a4
+---
+ src/tests/test-client.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 141 insertions(+)
+
+diff --git a/src/tests/test-client.c b/src/tests/test-client.c
+index 650f818..61fc341 100644
+--- a/src/tests/test-client.c
++++ b/src/tests/test-client.c
+@@ -29,6 +29,10 @@
+ const char *client_id = "0";
+ static gboolean wayland;
+ GHashTable *windows;
++GQuark event_source_quark;
++GQuark event_handlers_quark;
++
++typedef void (*XEventHandler) (GtkWidget *window, XEvent *event);
+ 
+ static void read_next_line (GDataInputStream *in);
+ 
+@@ -55,6 +59,141 @@ lookup_window (const char *window_id)
+   return window;
+ }
+ 
++typedef struct {
++  GSource base;
++  GPollFD event_poll_fd;
++  Display *xdisplay;
++} XClientEventSource;
++
++static gboolean
++x_event_source_prepare (GSource *source,
++                        int     *timeout)
++{
++  XClientEventSource *x_source = (XClientEventSource *) source;
++
++  *timeout = -1;
++
++  return XPending (x_source->xdisplay);
++}
++
++static gboolean
++x_event_source_check (GSource *source)
++{
++  XClientEventSource *x_source = (XClientEventSource *) source;
++
++  return XPending (x_source->xdisplay);
++}
++
++static gboolean
++x_event_source_dispatch (GSource     *source,
++                         GSourceFunc  callback,
++                         gpointer     user_data)
++{
++  XClientEventSource *x_source = (XClientEventSource *) source;
++
++  while (XPending (x_source->xdisplay))
++    {
++      GHashTableIter iter;
++      XEvent event;
++      gpointer value;
++
++      XNextEvent (x_source->xdisplay, &event);
++
++      g_hash_table_iter_init (&iter, windows);
++      while (g_hash_table_iter_next (&iter, NULL, &value))
++        {
++          GList *l;
++          GtkWidget *window = value;
++          GList *handlers =
++            g_object_get_qdata (G_OBJECT (window), event_handlers_quark);
++
++          for (l = handlers; l; l = l->next)
++            {
++              XEventHandler handler = l->data;
++              handler (window, &event);
++            }
++        }
++    }
++
++  return TRUE;
++}
++
++static GSourceFuncs x_event_funcs = {
++  x_event_source_prepare,
++  x_event_source_check,
++  x_event_source_dispatch,
++};
++
++static GSource*
++ensure_xsource_handler (GdkDisplay *gdkdisplay)
++{
++  static GSource *source = NULL;
++  Display *xdisplay = GDK_DISPLAY_XDISPLAY (gdkdisplay);
++  XClientEventSource *x_source;
++
++  if (source)
++    return g_source_ref (source);
++
++  source = g_source_new (&x_event_funcs, sizeof (XClientEventSource));
++  x_source = (XClientEventSource *) source;
++  x_source->xdisplay = xdisplay;
++  x_source->event_poll_fd.fd = ConnectionNumber (xdisplay);
++  x_source->event_poll_fd.events = G_IO_IN;
++  g_source_add_poll (source, &x_source->event_poll_fd);
++
++  g_source_set_priority (source, GDK_PRIORITY_EVENTS - 1);
++  g_source_set_can_recurse (source, TRUE);
++  g_source_attach (source, NULL);
++
++  return source;
++}
++
++static gboolean
++window_has_x11_event_handler (GtkWidget     *window,
++                              XEventHandler  handler)
++{
++  GList *handlers =
++    g_object_get_qdata (G_OBJECT (window), event_handlers_quark);
++
++  g_return_val_if_fail (handler, FALSE);
++  g_return_val_if_fail (!wayland, FALSE);
++
++  return g_list_find (handlers, handler) != NULL;
++}
++
++static void
++window_add_x11_event_handler (GtkWidget     *window,
++                              XEventHandler  handler)
++{
++  GSource *source;
++  GList *handlers =
++    g_object_get_qdata (G_OBJECT (window), event_handlers_quark);
++
++  g_return_if_fail (!window_has_x11_event_handler (window, handler));
++
++  source = ensure_xsource_handler (gtk_widget_get_display (window));
++  g_object_set_qdata_full (G_OBJECT (window), event_source_quark, source,
++                           (GDestroyNotify) g_source_unref);
++
++  handlers = g_list_append (handlers, handler);
++  g_object_set_qdata (G_OBJECT (window), event_handlers_quark, handlers);
++}
++
++static void
++window_remove_x11_event_handler (GtkWidget     *window,
++                                 XEventHandler  handler)
++{
++  GList *handlers =
++    g_object_get_qdata (G_OBJECT (window), event_handlers_quark);
++
++  g_return_if_fail (window_has_x11_event_handler (window, handler));
++
++  g_object_set_qdata (G_OBJECT (window), event_source_quark, NULL);
++
++  handlers = g_list_remove (handlers, handler);
++  g_object_set_qdata (G_OBJECT (window), event_handlers_quark, handlers);
++}
++
+ static void
+ process_line (const char *line)
+ {
+@@ -510,6 +649,8 @@ main(int argc, char **argv)
+ 
+   windows = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                    g_free, NULL);
++  event_source_quark = g_quark_from_static_string ("event-source");
++  event_handlers_quark = g_quark_from_static_string ("event-handlers");
+ 
+   GInputStream *raw_in = g_unix_input_stream_new (0, FALSE);
+   GDataInputStream *in = g_data_input_stream_new (raw_in);
diff -Nru mutter-3.30.2/debian/patches/test-runner-Add-assert_focused-command.patch mutter-3.30.2/debian/patches/test-runner-Add-assert_focused-command.patch
--- mutter-3.30.2/debian/patches/test-runner-Add-assert_focused-command.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/test-runner-Add-assert_focused-command.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,72 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Tue, 13 Nov 2018 08:37:14 +0100
+Subject: test-runner: Add 'assert_focused' command
+
+This allows to verify which window should have the focus, which might not
+be the same as the top of the stack.
+
+It's possible to assert the case where there's no focused window using
+"NONE" as parameter.
+
+(cherry picked from commit 51f9e04ef1fa8cd7298044ac8c82e83bea425770)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
+Origin: upstream, 3.30.3, commit:2021a7206cf5f710a010efc01d99686297babd44
+---
+ src/tests/test-runner.c | 36 ++++++++++++++++++++++++++++++++++++
+ 1 file changed, 36 insertions(+)
+
+diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c
+index b24ddcb..6497096 100644
+--- a/src/tests/test-runner.c
++++ b/src/tests/test-runner.c
+@@ -274,6 +274,37 @@ test_case_assert_stacking (TestCase *test,
+   return *error == NULL;
+ }
+ 
++static gboolean
++test_case_assert_focused (TestCase    *test,
++                          const char  *expected_window,
++                          GError     **error)
++{
++  MetaDisplay *display = meta_get_display ();
++
++  if (!display->focus_window)
++    {
++      if (g_strcmp0 (expected_window, "none") != 0)
++        {
++          g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED,
++                       "focus: expected='%s', actual='none'", expected_window);
++        }
++    }
++  else
++    {
++      const char *focused = display->focus_window->title;
++
++      if (g_str_has_prefix (focused, "test/"))
++        focused += 5;
++
++      if (g_strcmp0 (focused, expected_window) != 0)
++        g_set_error (error, TEST_RUNNER_ERROR, TEST_RUNNER_ERROR_ASSERTION_FAILED,
++                     "focus: expected='%s', actual='%s'",
++                     expected_window, focused);
++    }
++
++  return *error == NULL;
++}
++
+ static gboolean
+ test_case_check_xserver_stacking (TestCase *test,
+                                   GError  **error)
+@@ -560,6 +591,11 @@ test_case_do (TestCase *test,
+       if (!test_case_check_xserver_stacking (test, error))
+         return FALSE;
+     }
++  else if (strcmp (argv[0], "assert_focused") == 0)
++    {
++      if (!test_case_assert_focused (test, argv[1], error))
++        return FALSE;
++    }
+   else
+     {
+       BAD_COMMAND("Unknown command %s", argv[0]);
diff -Nru mutter-3.30.2/debian/patches/test-runner-Add-dispatch-command.patch mutter-3.30.2/debian/patches/test-runner-Add-dispatch-command.patch
--- mutter-3.30.2/debian/patches/test-runner-Add-dispatch-command.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/test-runner-Add-dispatch-command.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,80 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Fri, 21 Jun 2019 13:15:48 +0200
+Subject: test-runner: Add 'dispatch' command
+
+This will only wait for events to be dispatched and processed by the server
+without waiting for client processing.
+
+Reuse the code for the wait command too.
+
+(cherry picked from commit 6022b23923fa6192c630920e9f895f185977beee)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
+Origin: upstream, 3.30.3, commit:7d936018d216ae1ddf82b2fe655739f791000944
+---
+ src/tests/test-runner.c | 38 ++++++++++++++++++++++++++++----------
+ 1 file changed, 28 insertions(+), 10 deletions(-)
+
+diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c
+index 970fc24..5ec1c64 100644
+--- a/src/tests/test-runner.c
++++ b/src/tests/test-runner.c
+@@ -123,6 +123,24 @@ test_case_loop_quit (gpointer data)
+   return FALSE;
+ }
+ 
++static gboolean
++test_case_dispatch (TestCase *test,
++                    GError  **error)
++{
++  /* Wait until we've done any outstanding queued up work.
++   * Though we add this as BEFORE_REDRAW, the iteration that runs the
++   * BEFORE_REDRAW idles will proceed on and do the redraw, so we're
++   * waiting until after *all* frame processing.
++   */
++  meta_later_add (META_LATER_BEFORE_REDRAW,
++                  test_case_loop_quit,
++                  test,
++                  NULL);
++  g_main_loop_run (test->loop);
++
++  return TRUE;
++}
++
+ static gboolean
+ test_case_wait (TestCase *test,
+                 GError  **error)
+@@ -139,16 +157,8 @@ test_case_wait (TestCase *test,
+     if (!test_client_wait (value, error))
+       return FALSE;
+ 
+-  /* Then wait until we've done any outstanding queued up work.
+-   * Though we add this as BEFORE_REDRAW, the iteration that runs the
+-   * BEFORE_REDRAW idles will proceed on and do the redraw, so we're
+-   * waiting until after *all* frame processing.
+-   */
+-  meta_later_add (META_LATER_BEFORE_REDRAW,
+-                  test_case_loop_quit,
+-                  test,
+-                  NULL);
+-  g_main_loop_run (test->loop);
++  /* Then wait until we've done any outstanding queued up work. */
++  test_case_dispatch (test, error);
+ 
+   /* Then set an XSync counter ourselves and and wait until
+    * we receive the resulting event - this makes sure that we've
+@@ -594,6 +604,14 @@ test_case_do (TestCase *test,
+       if (!test_case_wait (test, error))
+         return FALSE;
+     }
++  else if (strcmp (argv[0], "dispatch") == 0)
++    {
++      if (argc != 1)
++        BAD_COMMAND("usage: %s", argv[0]);
++
++      if (!test_case_dispatch (test, error))
++        return FALSE;
++    }
+   else if (strcmp (argv[0], "sleep") == 0)
+     {
+       guint64 interval;
diff -Nru mutter-3.30.2/debian/patches/test-runner-Add-sleep-command.patch mutter-3.30.2/debian/patches/test-runner-Add-sleep-command.patch
--- mutter-3.30.2/debian/patches/test-runner-Add-sleep-command.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/test-runner-Add-sleep-command.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,78 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Tue, 18 Jun 2019 19:33:10 +0200
+Subject: test-runner: Add 'sleep' command
+
+This allows to sleep for a given timeout in milliseconds.
+
+Rename test_case_before_redraw to test_case_loop_quit since it's a generic
+function and use it for the timeout too.
+
+(cherry picked from commit d08763c18cb25fe250b27bf296e1607e63e86400)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
+Origin: upstream, 3.30.3, commit:b1dbdd41ab578ba1db51ce29ba921646b570b420
+---
+ src/tests/test-runner.c | 29 +++++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c
+index 6497096..970fc24 100644
+--- a/src/tests/test-runner.c
++++ b/src/tests/test-runner.c
+@@ -114,7 +114,7 @@ test_case_new (void)
+ }
+ 
+ static gboolean
+-test_case_before_redraw (gpointer data)
++test_case_loop_quit (gpointer data)
+ {
+   TestCase *test = data;
+ 
+@@ -145,7 +145,7 @@ test_case_wait (TestCase *test,
+    * waiting until after *all* frame processing.
+    */
+   meta_later_add (META_LATER_BEFORE_REDRAW,
+-                  test_case_before_redraw,
++                  test_case_loop_quit,
+                   test,
+                   NULL);
+   g_main_loop_run (test->loop);
+@@ -158,6 +158,17 @@ test_case_wait (TestCase *test,
+   return TRUE;
+ }
+ 
++static gboolean
++test_case_sleep (TestCase  *test,
++                 guint32    interval,
++                 GError   **error)
++{
++  g_timeout_add_full (G_PRIORITY_LOW, interval, test_case_loop_quit, test, NULL);
++  g_main_loop_run (test->loop);
++
++  return TRUE;
++}
++
+ #define BAD_COMMAND(...)                                                \
+   G_STMT_START {                                                        \
+       g_set_error (error,                                               \
+@@ -583,6 +594,20 @@ test_case_do (TestCase *test,
+       if (!test_case_wait (test, error))
+         return FALSE;
+     }
++  else if (strcmp (argv[0], "sleep") == 0)
++    {
++      guint64 interval;
++
++      if (argc != 2)
++        BAD_COMMAND("usage: %s <milliseconds>", argv[0]);
++
++      if (!g_ascii_string_to_unsigned (argv[1], 10, 0, G_MAXUINT32,
++                                       &interval, error))
++        return FALSE;
++
++      if (!test_case_sleep (test, (guint32) interval, error))
++        return FALSE;
++    }
+   else if (strcmp (argv[0], "assert_stacking") == 0)
+     {
+       if (!test_case_assert_stacking (test, argv + 1, argc - 1, error))
diff -Nru mutter-3.30.2/debian/patches/tests-Add-accept_focus-command-to-runner-and-client.patch mutter-3.30.2/debian/patches/tests-Add-accept_focus-command-to-runner-and-client.patch
--- mutter-3.30.2/debian/patches/tests-Add-accept_focus-command-to-runner-and-client.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/tests-Add-accept_focus-command-to-runner-and-client.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,73 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Tue, 13 Nov 2018 03:43:57 +0100
+Subject: tests: Add 'accept_focus' command to runner and client
+
+Under the hood, calls gtk_window_set_accept_focus in the client
+
+(cherry picked from commit e1f839f48f8e49c826ba558fbc9d6842a156b28b)
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
+Origin: upstream, 3.30.3, commit:81807fc3105aac8e469309cae87ee6f8ce5e0377
+---
+ src/tests/test-client.c | 18 ++++++++++++++++++
+ src/tests/test-runner.c | 19 +++++++++++++++++++
+ 2 files changed, 37 insertions(+)
+
+diff --git a/src/tests/test-client.c b/src/tests/test-client.c
+index 214f781..657ecc2 100644
+--- a/src/tests/test-client.c
++++ b/src/tests/test-client.c
+@@ -194,6 +194,24 @@ process_line (const char *line)
+                                              NULL))
+         g_print ("Fail to export handle for window id %s", argv[2]);
+     }
++  else if (strcmp (argv[0], "accept_focus") == 0)
++    {
++      if (argc != 3)
++        {
++          g_print ("usage: %s <window-id> [true|false]", argv[0]);
++          goto out;
++        }
++
++      GtkWidget *window = lookup_window (argv[1]);
++      if (!window)
++        {
++          g_print ("unknown window %s", argv[1]);
++          goto out;
++        }
++
++      gboolean enabled = g_ascii_strcasecmp (argv[2], "true") == 0;
++      gtk_window_set_accept_focus (GTK_WINDOW (window), enabled);
++    }
+   else if (strcmp (argv[0], "show") == 0)
+     {
+       if (argc != 2)
+diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c
+index ecd9fa7..cd3a858 100644
+--- a/src/tests/test-runner.c
++++ b/src/tests/test-runner.c
+@@ -435,6 +435,25 @@ test_case_do (TestCase *test,
+       if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
+         return FALSE;
+ 
++      if (!test_client_do (client, error,
++                           argv[0], window_id,
++                           argv[2],
++                           NULL))
++        return FALSE;
++    }
++  else if (strcmp (argv[0], "accept_focus") == 0)
++    {
++      if (argc != 3 ||
++          (g_ascii_strcasecmp (argv[2], "true") != 0 &&
++           g_ascii_strcasecmp (argv[2], "false") != 0))
++        BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]",
++                    argv[0]);
++
++      TestClient *client;
++      const char *window_id;
++      if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
++        return FALSE;
++
+       if (!test_client_do (client, error,
+                            argv[0], window_id,
+                            argv[2],
diff -Nru mutter-3.30.2/debian/patches/tests-Add-accept_take_focus-command.patch mutter-3.30.2/debian/patches/tests-Add-accept_take_focus-command.patch
--- mutter-3.30.2/debian/patches/tests-Add-accept_take_focus-command.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/tests-Add-accept_take_focus-command.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,253 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Wed, 3 Jul 2019 16:47:54 +0200
+Subject: tests: Add "accept_take_focus" command
+
+When used it setups an X11 event monitor that replies to WM_TAKE_FOCUS
+ClientMessage's with a XSetInputFocus request.
+
+It can only be used by x11 clients on windows that have WM_TAKE_FOCUS atom set
+and that does not accept input.
+
+(cherry picked from commit b80250e483e20bc2b66aa0117af0c442875c1b74)
+
+Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/669
+Origin: upstream, 3.30.3, commit:288ab54ccf4c6f7fcd5bd826aecb00094e2acdd6
+---
+ src/tests/test-client.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++-
+ src/tests/test-runner.c |  19 +++++++++
+ 2 files changed, 126 insertions(+), 1 deletion(-)
+
+diff --git a/src/tests/test-client.c b/src/tests/test-client.c
+index 61fc341..e5a211c 100644
+--- a/src/tests/test-client.c
++++ b/src/tests/test-client.c
+@@ -31,6 +31,7 @@ static gboolean wayland;
+ GHashTable *windows;
+ GQuark event_source_quark;
+ GQuark event_handlers_quark;
++GQuark can_take_focus_quark;
+ 
+ typedef void (*XEventHandler) (GtkWidget *window, XEvent *event);
+ 
+@@ -61,6 +62,7 @@ lookup_window (const char *window_id)
+ 
+ typedef struct {
+   GSource base;
++  GSource **self_ref;
+   GPollFD event_poll_fd;
+   Display *xdisplay;
+ } XClientEventSource;
+@@ -118,10 +120,19 @@ x_event_source_dispatch (GSource     *source,
+   return TRUE;
+ }
+ 
++static void
++x_event_source_finalize (GSource *source)
++{
++  XClientEventSource *x_source = (XClientEventSource *) source;
++
++  *x_source->self_ref = NULL;
++}
++
+ static GSourceFuncs x_event_funcs = {
+   x_event_source_prepare,
+   x_event_source_check,
+   x_event_source_dispatch,
++  x_event_source_finalize,
+ };
+ 
+ static GSource*
+@@ -136,6 +147,7 @@ ensure_xsource_handler (GdkDisplay *gdkdisplay)
+ 
+   source = g_source_new (&x_event_funcs, sizeof (XClientEventSource));
+   x_source = (XClientEventSource *) source;
++  x_source->self_ref = &source;
+   x_source->xdisplay = xdisplay;
+   x_source->event_poll_fd.fd = ConnectionNumber (xdisplay);
+   x_source->event_poll_fd.events = G_IO_IN;
+@@ -161,6 +173,15 @@ window_has_x11_event_handler (GtkWidget     *window,
+   return g_list_find (handlers, handler) != NULL;
+ }
+ 
++static void
++unref_and_maybe_destroy_gsource (GSource *source)
++{
++  g_source_unref (source);
++
++  if (source->ref_count == 1)
++    g_source_destroy (source);
++}
++
+ static void
+ window_add_x11_event_handler (GtkWidget     *window,
+                               XEventHandler  handler)
+@@ -173,7 +194,7 @@ window_add_x11_event_handler (GtkWidget     *window,
+ 
+   source = ensure_xsource_handler (gtk_widget_get_display (window));
+   g_object_set_qdata_full (G_OBJECT (window), event_source_quark, source,
+-                           (GDestroyNotify) g_source_unref);
++                           (GDestroyNotify) unref_and_maybe_destroy_gsource);
+ 
+   handlers = g_list_append (handlers, handler);
+   g_object_set_qdata (G_OBJECT (window), event_handlers_quark, handlers);
+@@ -194,6 +215,31 @@ window_remove_x11_event_handler (GtkWidget     *window,
+   g_object_set_qdata (G_OBJECT (window), event_handlers_quark, handlers);
+ }
+ 
++static void
++handle_take_focus (GtkWidget *window,
++                   XEvent    *xevent)
++{
++  GdkWindow *gdkwindow = gtk_widget_get_window (window);
++  GdkDisplay *display = gtk_widget_get_display (window);
++  Atom wm_protocols =
++    gdk_x11_get_xatom_by_name_for_display (display, "WM_PROTOCOLS");
++  Atom wm_take_focus =
++    gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
++
++  if (xevent->xany.type != ClientMessage ||
++      xevent->xany.window != GDK_WINDOW_XID (gdkwindow))
++    return;
++
++  if (xevent->xclient.message_type == wm_protocols &&
++      (Atom) xevent->xclient.data.l[0] == wm_take_focus)
++    {
++      XSetInputFocus (xevent->xany.display,
++                      GDK_WINDOW_XID (gdkwindow),
++                      RevertToParent,
++                      xevent->xclient.data.l[1]);
++    }
++}
++
+ static void
+ process_line (const char *line)
+ {
+@@ -262,6 +308,9 @@ process_line (const char *line)
+       gtk_window_set_title (GTK_WINDOW (window), title);
+       g_free (title);
+ 
++      g_object_set_qdata (G_OBJECT (window), can_take_focus_quark,
++                          GUINT_TO_POINTER (TRUE));
++
+       gtk_widget_realize (window);
+ 
+       if (!wayland)
+@@ -348,6 +397,14 @@ process_line (const char *line)
+           goto out;
+         }
+ 
++      if (!wayland &&
++          window_has_x11_event_handler (window, handle_take_focus))
++        {
++          g_print ("Impossible to use %s for windows accepting take focus",
++                   argv[1]);
++          goto out;
++        }
++
+       gboolean enabled = g_ascii_strcasecmp (argv[2], "true") == 0;
+       gtk_window_set_accept_focus (GTK_WINDOW (window), enabled);
+     }
+@@ -372,6 +429,13 @@ process_line (const char *line)
+           goto out;
+         }
+ 
++      if (window_has_x11_event_handler (window, handle_take_focus))
++        {
++          g_print ("Impossible to change %s for windows accepting take focus",
++                   argv[1]);
++          goto out;
++        }
++
+       GdkDisplay *display = gdk_display_get_default ();
+       GdkWindow *gdkwindow = gtk_widget_get_window (window);
+       Display *xdisplay = gdk_x11_display_get_xdisplay (display);
+@@ -397,10 +461,51 @@ process_line (const char *line)
+         new_protocols[n++] = wm_take_focus;
+ 
+       XSetWMProtocols (xdisplay, xwindow, new_protocols, n);
++      g_object_set_qdata (G_OBJECT (window), can_take_focus_quark,
++                          GUINT_TO_POINTER (add));
+ 
+       XFree (new_protocols);
+       XFree (protocols);
+     }
++  else if (strcmp (argv[0], "accept_take_focus") == 0)
++    {
++      if (argc != 3)
++        {
++          g_print ("usage: %s <window-id> [true|false]", argv[0]);
++          goto out;
++        }
++
++      GtkWidget *window = lookup_window (argv[1]);
++      if (!window)
++        {
++          g_print ("unknown window %s", argv[1]);
++          goto out;
++        }
++
++      if (wayland)
++        {
++          g_print ("%s not supported under wayland", argv[0]);
++          goto out;
++        }
++
++      if (gtk_window_get_accept_focus (GTK_WINDOW (window)))
++        {
++          g_print ("%s not supported for input windows", argv[0]);
++          goto out;
++        }
++
++      if (!g_object_get_qdata (G_OBJECT (window), can_take_focus_quark))
++        {
++          g_print ("%s not supported for windows with no WM_TAKE_FOCUS set",
++                   argv[0]);
++          goto out;
++        }
++
++      if (g_ascii_strcasecmp (argv[2], "true") == 0)
++        window_add_x11_event_handler (window, handle_take_focus);
++      else
++        window_remove_x11_event_handler (window, handle_take_focus);
++    }
+   else if (strcmp (argv[0], "show") == 0)
+     {
+       if (argc != 2)
+@@ -651,6 +756,7 @@ main(int argc, char **argv)
+                                    g_free, NULL);
+   event_source_quark = g_quark_from_static_string ("event-source");
+   event_handlers_quark = g_quark_from_static_string ("event-handlers");
++  can_take_focus_quark = g_quark_from_static_string ("can-take-focus");
+ 
+   GInputStream *raw_in = g_unix_input_stream_new (0, FALSE);
+   GDataInputStream *in = g_data_input_stream_new (raw_in);
+diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c
+index 5ec1c64..4998d1d 100644
+--- a/src/tests/test-runner.c
++++ b/src/tests/test-runner.c
+@@ -531,6 +531,25 @@ test_case_do (TestCase *test,
+                            NULL))
+         return FALSE;
+     }
++  else if (strcmp (argv[0], "accept_take_focus") == 0)
++    {
++      if (argc != 3 ||
++          (g_ascii_strcasecmp (argv[2], "true") != 0 &&
++           g_ascii_strcasecmp (argv[2], "false") != 0))
++        BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]",
++                    argv[0]);
++
++      TestClient *client;
++      const char *window_id;
++      if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
++        return FALSE;
++
++      if (!test_client_do (client, error,
++                           argv[0], window_id,
++                           argv[2],
++                           NULL))
++        return FALSE;
++    }
+   else if (strcmp (argv[0], "show") == 0)
+     {
+       if (argc != 2)
diff -Nru mutter-3.30.2/debian/patches/tests-Add-can_take_focus-command-to-runner-and-client.patch mutter-3.30.2/debian/patches/tests-Add-can_take_focus-command-to-runner-and-client.patch
--- mutter-3.30.2/debian/patches/tests-Add-can_take_focus-command-to-runner-and-client.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/tests-Add-can_take_focus-command-to-runner-and-client.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,111 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Tue, 13 Nov 2018 04:04:22 +0100
+Subject: tests: Add 'can_take_focus' command to runner and client
+
+Allow to set/unset WM_TAKE_FOCUS from client window.
+This is added by default by gtk, but this might not happen in other toolkits,
+so add an ability to (un)set this.
+
+So fetch the protocols with XGetWMProtocols and unset the atom.
+
+test-client now needs to depend on Xlib directly in meson build.
+
+(cherry picked from commit f2d2d473b71dbdb339c80f068c5cb3e529af2478)
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
+Origin: upstream, 3.30.3, commit:689bff0ac2f78402044ed62e62d7af08229c44b2
+---
+ src/tests/test-client.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++
+ src/tests/test-runner.c | 19 +++++++++++++++++++
+ 2 files changed, 69 insertions(+)
+
+diff --git a/src/tests/test-client.c b/src/tests/test-client.c
+index 657ecc2..650f818 100644
+--- a/src/tests/test-client.c
++++ b/src/tests/test-client.c
+@@ -212,6 +212,56 @@ process_line (const char *line)
+       gboolean enabled = g_ascii_strcasecmp (argv[2], "true") == 0;
+       gtk_window_set_accept_focus (GTK_WINDOW (window), enabled);
+     }
++  else if (strcmp (argv[0], "can_take_focus") == 0)
++    {
++      if (argc != 3)
++        {
++          g_print ("usage: %s <window-id> [true|false]", argv[0]);
++          goto out;
++        }
++
++      GtkWidget *window = lookup_window (argv[1]);
++      if (!window)
++        {
++          g_print ("unknown window %s", argv[1]);
++          goto out;
++        }
++
++      if (wayland)
++        {
++          g_print ("%s not supported under wayland", argv[0]);
++          goto out;
++        }
++
++      GdkDisplay *display = gdk_display_get_default ();
++      GdkWindow *gdkwindow = gtk_widget_get_window (window);
++      Display *xdisplay = gdk_x11_display_get_xdisplay (display);
++      Window xwindow = GDK_WINDOW_XID (gdkwindow);
++      Atom wm_take_focus = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
++      gboolean add = g_ascii_strcasecmp(argv[2], "true") == 0;
++      Atom *protocols = NULL;
++      Atom *new_protocols;
++      int n_protocols = 0;
++      int i, n = 0;
++
++      gdk_display_sync (display);
++      XGetWMProtocols (xdisplay, xwindow, &protocols, &n_protocols);
++      new_protocols = g_new0 (Atom, n_protocols + (add ? 1 : 0));
++
++      for (i = 0; i < n_protocols; ++i)
++        {
++          if (protocols[i] != wm_take_focus)
++            new_protocols[n++] = protocols[i];
++        }
++
++      if (add)
++        new_protocols[n++] = wm_take_focus;
++
++      XSetWMProtocols (xdisplay, xwindow, new_protocols, n);
++
++      XFree (new_protocols);
++      XFree (protocols);
++    }
+   else if (strcmp (argv[0], "show") == 0)
+     {
+       if (argc != 2)
+diff --git a/src/tests/test-runner.c b/src/tests/test-runner.c
+index cd3a858..b24ddcb 100644
+--- a/src/tests/test-runner.c
++++ b/src/tests/test-runner.c
+@@ -460,6 +460,25 @@ test_case_do (TestCase *test,
+                            NULL))
+         return FALSE;
+     }
++  else if (strcmp (argv[0], "can_take_focus") == 0)
++    {
++      if (argc != 3 ||
++          (g_ascii_strcasecmp (argv[2], "true") != 0 &&
++           g_ascii_strcasecmp (argv[2], "false") != 0))
++        BAD_COMMAND("usage: %s <client-id>/<window-id> [true|false]",
++                    argv[0]);
++
++      TestClient *client;
++      const char *window_id;
++      if (!test_case_parse_window_id (test, argv[1], &client, &window_id, error))
++        return FALSE;
++
++      if (!test_client_do (client, error,
++                           argv[0], window_id,
++                           argv[2],
++                           NULL))
++        return FALSE;
++    }
+   else if (strcmp (argv[0], "show") == 0)
+     {
+       if (argc != 2)
diff -Nru mutter-3.30.2/debian/patches/tests-stacking-Add-tests-with-no-input-and-no-take-focus-.patch mutter-3.30.2/debian/patches/tests-stacking-Add-tests-with-no-input-and-no-take-focus-.patch
--- mutter-3.30.2/debian/patches/tests-stacking-Add-tests-with-no-input-and-no-take-focus-.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/tests-stacking-Add-tests-with-no-input-and-no-take-focus-.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,121 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Tue, 13 Nov 2018 07:48:53 +0100
+Subject: tests, stacking: Add tests with no-input and no-take-focus windows
+
+When a window with no frame, that doesn't accept focus and that has no
+take-focus atom set is destroyed, we ended up in not changing the current_focus
+window, causing a crash.
+
+Added test cases that verify this situation.
+
+Related to https://gitlab.gnome.org/GNOME/mutter/issues/308
+(cherry picked from commit 2fc7760ceed6f948d4f3c1dd74d4e57c7df05eea)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
+Origin: upstream, 3.30.3, commit:29ffaa6f891253b10ec11b1b81c3bf1ac8b62f81
+---
+ src/Makefile-tests.am                              |  3 +++
+ ...ransient-no-input-no-take-focus-parent.metatest | 21 ++++++++++++++++++++
+ ...ansient-no-input-no-take-focus-parents.metatest | 23 ++++++++++++++++++++++
+ .../closed-transient-no-input-parent.metatest      | 20 +++++++++++++++++++
+ 4 files changed, 67 insertions(+)
+ create mode 100644 src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest
+ create mode 100644 src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest
+ create mode 100644 src/tests/stacking/closed-transient-no-input-parent.metatest
+
+diff --git a/src/Makefile-tests.am b/src/Makefile-tests.am
+index 278d3b0..e35ad91 100644
+--- a/src/Makefile-tests.am
++++ b/src/Makefile-tests.am
+@@ -15,6 +15,9 @@ dist_stacking_DATA =						\
+ 	$(srcdir)/tests/stacking/basic-x11.metatest 	\
+ 	$(srcdir)/tests/stacking/basic-wayland.metatest	\
+ 	$(srcdir)/tests/stacking/closed-transient.metatest	\
++	$(srcdir)/closed-transient-no-input-no-take-focus-parent.metatest	\
++	$(srcdir)/closed-transient-no-input-no-take-focus-parents.metatest	\
++	$(srcdir)/closed-transient-no-input-parent.metatest	\
+ 	$(srcdir)/tests/stacking/minimized.metatest 	\
+ 	$(srcdir)/tests/stacking/mixed-windows.metatest     \
+ 	$(srcdir)/tests/stacking/set-parent.metatest	\
+diff --git a/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest b/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest
+new file mode 100644
+index 0000000..4249c32
+--- /dev/null
++++ b/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest
+@@ -0,0 +1,21 @@
++new_client 1 x11
++create 1/1
++show 1/1
++
++create 1/2 csd
++set_parent 1/2 1
++can_take_focus 1/2 false
++accept_focus 1/2 false
++show 1/2
++
++create 1/3 csd
++set_parent 1/3 2
++show 1/3
++
++wait
++assert_stacking 1/1 1/2 1/3
++
++destroy 1/3
++
++wait
++assert_stacking 1/1 1/2
+diff --git a/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest b/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest
+new file mode 100644
+index 0000000..a61c640
+--- /dev/null
++++ b/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest
+@@ -0,0 +1,23 @@
++new_client 1 x11
++create 1/1
++accept_focus 1/1 false
++can_take_focus 1/1 false
++show 1/1
++
++create 1/2 csd
++set_parent 1/2 1
++can_take_focus 1/2 false
++accept_focus 1/2 false
++show 1/2
++
++create 1/3 csd
++set_parent 1/3 2
++show 1/3
++
++wait
++assert_stacking 1/1 1/2 1/3
++
++destroy 1/3
++wait
++
++assert_stacking 1/1 1/2
+diff --git a/src/tests/stacking/closed-transient-no-input-parent.metatest b/src/tests/stacking/closed-transient-no-input-parent.metatest
+new file mode 100644
+index 0000000..4cadb23
+--- /dev/null
++++ b/src/tests/stacking/closed-transient-no-input-parent.metatest
+@@ -0,0 +1,20 @@
++new_client 1 x11
++create 1/1
++show 1/1
++
++create 1/2 csd
++set_parent 1/2 1
++accept_focus 1/2 false
++show 1/2
++
++create 1/3 csd
++set_parent 1/3 2
++show 1/3
++
++wait
++assert_stacking 1/1 1/2 1/3
++
++destroy 1/3
++
++wait
++assert_stacking 1/1 1/2
diff -Nru mutter-3.30.2/debian/patches/tests-Verify-focused-window-in-closed-transient-tests.patch mutter-3.30.2/debian/patches/tests-Verify-focused-window-in-closed-transient-tests.patch
--- mutter-3.30.2/debian/patches/tests-Verify-focused-window-in-closed-transient-tests.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/tests-Verify-focused-window-in-closed-transient-tests.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,60 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Tue, 13 Nov 2018 08:45:56 +0100
+Subject: tests: Verify focused window in closed-transient tests
+
+Ensure that we have a focused window when closing transient windows with
+no-focus or no-take-focus atoms
+
+(cherry picked from commit fcb408ad5d8d7fec3e6a7bdaa92e5ef06b55c2c6)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
+Origin: upstream, 3.30.3, commit:7927415e5b1f3cb2d9206e112d2dfdf7c31df79f
+---
+ .../closed-transient-no-input-no-take-focus-parent.metatest |  2 ++
+ ...closed-transient-no-input-no-take-focus-parents.metatest | 13 ++++++++++---
+ 2 files changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest b/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest
+index 4249c32..0c0649c 100644
+--- a/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest
++++ b/src/tests/stacking/closed-transient-no-input-no-take-focus-parent.metatest
+@@ -13,9 +13,11 @@ set_parent 1/3 2
+ show 1/3
+ 
+ wait
++assert_focused 1/3
+ assert_stacking 1/1 1/2 1/3
+ 
+ destroy 1/3
+ 
+ wait
++assert_focused 1/1
+ assert_stacking 1/1 1/2
+diff --git a/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest b/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest
+index a61c640..6556803 100644
+--- a/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest
++++ b/src/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest
+@@ -1,3 +1,8 @@
++new_client 2 x11
++create 2/1
++show 2/1
++wait
++
+ new_client 1 x11
+ create 1/1
+ accept_focus 1/1 false
+@@ -15,9 +20,11 @@ set_parent 1/3 2
+ show 1/3
+ 
+ wait
+-assert_stacking 1/1 1/2 1/3
++assert_focused 1/3
++assert_stacking 2/1 1/1 1/2 1/3
+ 
+ destroy 1/3
+-wait
+ 
+-assert_stacking 1/1 1/2
++wait
++assert_stacking 1/1 1/2 2/1
++assert_focused 2/1
diff -Nru mutter-3.30.2/debian/patches/Updated-Spanish-translation.patch mutter-3.30.2/debian/patches/Updated-Spanish-translation.patch
--- mutter-3.30.2/debian/patches/Updated-Spanish-translation.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/Updated-Spanish-translation.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,176 @@
+From: Daniel Mustieles <daniel.mustieles@gmail.com>
+Date: Thu, 20 Jun 2019 10:03:36 +0200
+Subject: Updated Spanish translation
+
+Origin: upstream, 3.30.3, commit:6dbd057ef4cf8e4aa07790770e28f2762856016d
+---
+ po/es.po | 53 ++++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 32 insertions(+), 21 deletions(-)
+
+diff --git a/po/es.po b/po/es.po
+index 89b3a0c..b78782d 100644
+--- a/po/es.po
++++ b/po/es.po
+@@ -7,14 +7,14 @@
+ # Pablo Gonzalo del Campo <pablodc@bigfoot.com>,2002,2003.
+ # Francisco Javier F. Serrador <serrador@cvs.gnome.org>, 2004, 2005, 2006.
+ # Jorge González <jorgegonz@svn.gnome.org>, 2007, 2008, 2009, 2010, 2011.
+-# Daniel Mustieles <daniel.mustieles@gmail.com>, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018.
++# Daniel Mustieles <daniel.mustieles@gmail.com>, 2011-2019.
+ #
+ msgid ""
+ msgstr ""
+ "Project-Id-Version: mutter.master\n"
+ "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/mutter/issues\n";
+-"POT-Creation-Date: 2018-07-07 09:58+0000\n"
+-"PO-Revision-Date: 2018-07-23 12:31+0200\n"
++"POT-Creation-Date: 2019-06-13 16:46+0000\n"
++"PO-Revision-Date: 2019-06-20 09:25+0200\n"
+ "Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
+ "Language-Team: es <gnome-es-list@gnome.org>\n"
+ "Language: es\n"
+@@ -22,7 +22,7 @@ msgstr ""
+ "Content-Type: text/plain; charset=UTF-8\n"
+ "Content-Transfer-Encoding: 8bit\n"
+ "Plural-Forms: nplurals=2; plural=(n != 1);\n"
+-"X-Generator: Gtranslator 2.91.6\n"
++"X-Generator: Gtranslator 3.32.0\n"
+ 
+ #: data/50-mutter-navigation.xml:6
+ msgid "Navigation"
+@@ -397,7 +397,6 @@ msgid "Enable experimental features"
+ msgstr "Activar las características experimentales"
+ 
+ #: data/org.gnome.mutter.gschema.xml.in:108
+-#, fuzzy
+ #| msgid ""
+ #| "To enable experimental features, add the feature keyword to the list. "
+ #| "Whether the feature requires restarting the compositor depends on the "
+@@ -429,9 +428,7 @@ msgstr ""
+ "manera predeterminada de disponer monitores lógicos en un espacio lógico de "
+ "coordenadas de píxeles, al escalar framebuffers de monitores framebuffers en "
+ "lugar del contenido de ventana, para administrar monitores HiDPI. No "
+-"requiere un reinicio. • \"remote-desktop\" — activa el escritorio remoto. "
+-"Para soportarlo con compartición de pantalla es necesario activar \"screen-"
+-"cast\" • \"screen-cast\" — activa el soporte de compartición de pantalla."
++"requiere un reinicio."
+ 
+ #: data/org.gnome.mutter.gschema.xml.in:141
+ msgid "Select window from tab popup"
+@@ -513,6 +510,11 @@ msgid ""
+ "window or be among the applications white-listed in key “xwayland-grab-"
+ "access-rules”."
+ msgstr ""
++"Permitir que las pulsaciones del teclado emitidas por aplicaciones X11 "
++"ejecutándose en XWayland se tengan en cuenta. Para que una pulsación X11 se "
++"tenga en cuenta en Wayland el cliente debe o bien enviar un ClientMessage "
++"específico de X11 a la ventana raíz o estar en la lista blanca de "
++"aplicaciones en la clave “xwayland-grab-access-rules”."
+ 
+ #: data/org.gnome.mutter.wayland.gschema.xml.in:77
+ msgid "Xwayland applications allowed to issue keyboard grabs"
+@@ -531,11 +533,20 @@ msgid ""
+ "using the specific keyboard shortcut defined by the keybinding key “restore-"
+ "shortcuts”."
+ msgstr ""
++"Lista los nombres o las clases de recursos de ventanas X11 permitidas o no "
++"para emitir pulsaciones de teclado X11 en XWayland. El nombre o la clase del "
++"recurso de una ventana X11 dada se puede obtener usando el comando “xprop "
++"WM_CLASS”. Se soportan los comodines «*» y «?». Los valores que empiecen por "
++"«!» están en lista negra, que tiene prioridad sobre la lista blanca, para "
++"revocar aplicaciones de la lista predeterminada del sistema. Esta lista "
++"incluye las siguientes aplicaciones: “@XWAYLAND_GRAB_DEFAULT_ACCESS_RULES@”. "
++"Los usuarios pueden romper una pulsación existente usando el atajo "
++"específico del teclado definido por la clave “restore-shortcuts”."
+ 
+ #. TRANSLATORS: This string refers to a button that switches between
+ #. * different modes.
+ #.
+-#: src/backends/meta-input-settings.c:2325
++#: src/backends/meta-input-settings.c:2310
+ #, c-format
+ msgid "Mode Switch (Group %d)"
+ msgstr "Cambiar modo (grupo %d)"
+@@ -543,37 +554,37 @@ msgstr "Cambiar modo (grupo %d)"
+ #. TRANSLATORS: This string refers to an action, cycles drawing tablets'
+ #. * mapping through the available outputs.
+ #.
+-#: src/backends/meta-input-settings.c:2348
++#: src/backends/meta-input-settings.c:2333
+ msgid "Switch monitor"
+ msgstr "Cambiar monitor"
+ 
+-#: src/backends/meta-input-settings.c:2350
++#: src/backends/meta-input-settings.c:2335
+ msgid "Show on-screen help"
+ msgstr "Mostrar la ayuda en pantalla"
+ 
+-#: src/backends/meta-monitor-manager.c:907
++#: src/backends/meta-monitor-manager.c:886
+ msgid "Built-in display"
+ msgstr "Pantalla integrada"
+ 
+-#: src/backends/meta-monitor-manager.c:930
++#: src/backends/meta-monitor-manager.c:909
+ msgid "Unknown"
+ msgstr "Desconocida"
+ 
+-#: src/backends/meta-monitor-manager.c:932
++#: src/backends/meta-monitor-manager.c:911
+ msgid "Unknown Display"
+ msgstr "Pantalla desconocida"
+ 
+ #. TRANSLATORS: this is a monitor vendor name, followed by a
+ #. * size in inches, like 'Dell 15"'
+ #.
+-#: src/backends/meta-monitor-manager.c:940
++#: src/backends/meta-monitor-manager.c:919
+ #, c-format
+ msgid "%s %s"
+ msgstr "%s %s"
+ 
+ #. This probably means that a non-WM compositor like xcompmgr is running;
+ #. * we have no way to get it to exit
+-#: src/compositor/compositor.c:481
++#: src/compositor/compositor.c:507
+ #, c-format
+ msgid ""
+ "Another compositing manager is already running on screen %i on display “%s”."
+@@ -679,7 +690,7 @@ msgstr "Imprimir versión"
+ msgid "Mutter plugin to use"
+ msgstr "Complemento de mutter que usar"
+ 
+-#: src/core/prefs.c:1915
++#: src/core/prefs.c:1787
+ #, c-format
+ msgid "Workspace %d"
+ msgstr "Área de trabajo %d"
+@@ -693,7 +704,7 @@ msgstr "Mutter fue compilado sin soporte para modo prolijo\n"
+ msgid "Mode Switch: Mode %d"
+ msgstr "Cambiar modo: modo %d"
+ 
+-#: src/x11/meta-x11-display.c:666
++#: src/x11/meta-x11-display.c:672
+ #, c-format
+ msgid ""
+ "Display “%s” already has a window manager; try using the --replace option to "
+@@ -702,16 +713,16 @@ msgstr ""
+ "La pantalla «%s» ya tiene un gestor de ventanas; pruebe a usar la opción «--"
+ "replace» para reemplazar el gestor de ventanas activo."
+ 
+-#: src/x11/meta-x11-display.c:1010
++#: src/x11/meta-x11-display.c:1016
+ msgid "Failed to initialize GDK\n"
+ msgstr "Falló al inicializar GDK\n"
+ 
+-#: src/x11/meta-x11-display.c:1034
++#: src/x11/meta-x11-display.c:1040
+ #, c-format
+ msgid "Failed to open X Window System display “%s”\n"
+ msgstr "Ocurrió un error al abrir la pantalla de X Window System «%s»\n"
+ 
+-#: src/x11/meta-x11-display.c:1117
++#: src/x11/meta-x11-display.c:1123
+ #, c-format
+ msgid "Screen %d on display “%s” is invalid\n"
+ msgstr "La ventana %d en la pantalla «%s» no es válida\n"
diff -Nru mutter-3.30.2/debian/patches/wayland-output-Set-user-data-of-xdg_output-resource.patch mutter-3.30.2/debian/patches/wayland-output-Set-user-data-of-xdg_output-resource.patch
--- mutter-3.30.2/debian/patches/wayland-output-Set-user-data-of-xdg_output-resource.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/wayland-output-Set-user-data-of-xdg_output-resource.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,59 @@
+From: Olivier Fourdan <ofourdan@redhat.com>
+Date: Mon, 15 Apr 2019 14:55:45 +0200
+Subject: wayland/output: Set user data of xdg_output resource
+
+mutter would randomly crash in `send_xdg_output_events()` when changing
+the fractional scaling:
+
+  wl_resource_post_event ()
+  zxdg_output_v1_send_logical_size ()
+  send_xdg_output_events ()
+  wayland_output_update_for_output ()
+  meta_wayland_compositor_update_outputs ()
+  on_monitors_changed ()
+  g_closure_invoke ()
+  signal_emit_unlocked_R ()
+  g_signal_emit_valist ()
+  _signal_emit ()
+  meta_monitor_manager_notify_monitors_changed ()
+  meta_monitor_manager_rebuild ()
+
+This is because the xdg-output resource got freed but wasn't removed
+from the list of resources.
+
+Fix this by setting the user data of the xdg-output resource to the
+corresponding `MetaWaylandOutput` so that the xdg-output resource
+destructor can remove it from the list of resources.
+
+Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/538
+Origin: upstream, 3.32.1, commit:2c1a951b6e81ea583e9a83ce29343d7ffd5739d9
+Bug-Debian: https://bugs.debian.org/932428
+Bug-Debian: https://bugs.debian.org/932767
+Bug-Debian: https://bugs.debian.org/932781
+---
+ src/wayland/meta-wayland-outputs.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c
+index bd0a3b1..8017640 100644
+--- a/src/wayland/meta-wayland-outputs.c
++++ b/src/wayland/meta-wayland-outputs.c
+@@ -580,14 +580,14 @@ meta_xdg_output_manager_get_xdg_output (struct wl_client   *client,
+                                             wl_resource_get_version (resource),
+                                             id);
+ 
+-  wl_resource_set_implementation (xdg_output_resource,
+-                                  &meta_xdg_output_interface,
+-                                  NULL, meta_xdg_output_destructor);
+-
+   wayland_output = wl_resource_get_user_data (output);
+   if (!wayland_output)
+     return;
+ 
++  wl_resource_set_implementation (xdg_output_resource,
++                                  &meta_xdg_output_interface,
++                                  wayland_output, meta_xdg_output_destructor);
++
+   wayland_output->xdg_output_resources =
+     g_list_prepend (wayland_output->xdg_output_resources, xdg_output_resource);
+ 
diff -Nru mutter-3.30.2/debian/patches/wayland-seat-Use-g_free-to-cleanup-MetaWaylandSeat.patch mutter-3.30.2/debian/patches/wayland-seat-Use-g_free-to-cleanup-MetaWaylandSeat.patch
--- mutter-3.30.2/debian/patches/wayland-seat-Use-g_free-to-cleanup-MetaWaylandSeat.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/wayland-seat-Use-g_free-to-cleanup-MetaWaylandSeat.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,28 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Fri, 17 May 2019 19:56:31 +0000
+Subject: wayland-seat: Use g_free to cleanup MetaWaylandSeat
+
+MetaWaylandSeat is allocated using g_new0(), and thus we should use g_free() to
+destroy it.
+
+(cherry picked from commit 040578657309a515df4c73b51a068140ad477f03)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/581
+Origin: upstream, 3.30.3, commit:ccd5e9fa08c6c40671f93aeb7ef91881bc0918a3
+---
+ src/wayland/meta-wayland-seat.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c
+index 42af635..c572c83 100644
+--- a/src/wayland/meta-wayland-seat.c
++++ b/src/wayland/meta-wayland-seat.c
+@@ -266,7 +266,7 @@ meta_wayland_seat_free (MetaWaylandSeat *seat)
+   meta_wayland_gtk_text_input_destroy (seat->gtk_text_input);
+   meta_wayland_text_input_destroy (seat->text_input);
+ 
+-  g_slice_free (MetaWaylandSeat, seat);
++  g_free (seat);
+ }
+ 
+ static gboolean
diff -Nru mutter-3.30.2/debian/patches/window-actor-Set-actor-as-compositor-private-in-window-be.patch mutter-3.30.2/debian/patches/window-actor-Set-actor-as-compositor-private-in-window-be.patch
--- mutter-3.30.2/debian/patches/window-actor-Set-actor-as-compositor-private-in-window-be.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/window-actor-Set-actor-as-compositor-private-in-window-be.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,44 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Fri, 28 Jun 2019 11:18:22 +0200
+Subject: window-actor: Set actor as compositor private in window before the
+ surface
+
+In MetaWindowActor creation we're setting the compositor private (i.e. the
+window actor itself) of a window before creating the surface actor, and so
+passing to the it a window without its compositor side set.
+
+Since the surface actor might use the parent actor, set this before updating
+the surface.
+
+(cherry picked from commit 7776941b8950d6be71927b3fb575d66b43964310)
+
+Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/660
+Origin: upstream, 3.30.3, commit:ffa4279a968f17af410c32a9f55ff7f5c9e8d0c0
+---
+ src/compositor/meta-window-actor.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
+index df7b8d7..b367317 100644
+--- a/src/compositor/meta-window-actor.c
++++ b/src/compositor/meta-window-actor.c
+@@ -471,6 +471,9 @@ meta_window_actor_constructed (GObject *object)
+ 
+   priv->compositor = window->display->compositor;
+ 
++  /* Hang our compositor window state off the MetaWindow for fast retrieval */
++  meta_window_set_compositor_private (window, object);
++
+   meta_window_actor_update_surface (self);
+ 
+   meta_window_actor_update_opacity (self);
+@@ -1448,9 +1451,6 @@ meta_window_actor_new (MetaWindow *window)
+ 
+   meta_window_actor_sync_actor_geometry (self, priv->window->placed);
+ 
+-  /* Hang our compositor window state off the MetaWindow for fast retrieval */
+-  meta_window_set_compositor_private (window, G_OBJECT (self));
+-
+   if (window->layer == META_LAYER_OVERRIDE_REDIRECT)
+     window_group = compositor->top_window_group;
+   else
diff -Nru mutter-3.30.2/debian/patches/window-Emit-an-error-and-return-when-trying-to-activate-a.patch mutter-3.30.2/debian/patches/window-Emit-an-error-and-return-when-trying-to-activate-a.patch
--- mutter-3.30.2/debian/patches/window-Emit-an-error-and-return-when-trying-to-activate-a.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/window-Emit-an-error-and-return-when-trying-to-activate-a.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,37 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Fri, 3 May 2019 18:10:47 +0000
+Subject: window: Emit an error and return when trying to activate an
+ unmanaged
+
+If something (i.e. gnome-shell or an extension) tries to activate an unmanaged
+window, we should warn about this and avoid to perform further actions as this
+could lead to a crash of mutter, since the window has not valid flags (like
+workspace) set anymore at this stage.
+
+(cherry picked from commit a6fc656e917fd48b8708b8d9f4bf9f8b15581313)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/issues/580
+Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/564
+Origin: upstream, 3.30.3, commit:a9322c81af652f50b0c6fcce8e35d5c84948d68a
+---
+ src/core/window.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/src/core/window.c b/src/core/window.c
+index 78faf38..a584c1f 100644
+--- a/src/core/window.c
++++ b/src/core/window.c
+@@ -3639,6 +3639,13 @@ meta_window_activate_full (MetaWindow     *window,
+ {
+   MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
+   gboolean allow_workspace_switch;
++
++  if (window->unmanaging)
++    {
++      g_warning ("Trying to activate unmanaged window '%s'", window->desc);
++      return;
++    }
++
+   meta_topic (META_DEBUG_FOCUS,
+               "_NET_ACTIVE_WINDOW message sent for %s at time %u "
+               "by client type %u.\n",
diff -Nru mutter-3.30.2/debian/patches/window-x11-Accept-any-focusable-window-as-fallback-focus.patch mutter-3.30.2/debian/patches/window-x11-Accept-any-focusable-window-as-fallback-focus.patch
--- mutter-3.30.2/debian/patches/window-x11-Accept-any-focusable-window-as-fallback-focus.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/window-x11-Accept-any-focusable-window-as-fallback-focus.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,102 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Wed, 3 Jul 2019 11:15:36 +0200
+Subject: window-x11: Accept any focusable window as fallback focus
+
+As per commit f71151a5 we were ignoring WM_TAKE_FOCUS-only windows as focus
+targets, however this might end-up in an infinite loop if there are multiple
+non-input windows stacked.
+
+So, accept any focusable window as fallback focus target even if it's a
+take-focus one (that might not reply to the request).
+
+Added a stacking test to verify this.
+
+(cherry picked from commit c327b2df95ff9979dd22bca2e0d285e1b3ba0add)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/issues/660
+Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/669
+Origin: upstream, 3.30.3, commit:03d880ad2b3492f427db3ac31894b1836f66cba3
+---
+ src/Makefile-tests.am                              |  1 +
+ .../closed-transient-no-input-parents.metatest     | 46 ++++++++++++++++++++++
+ src/x11/window-x11.c                               |  2 +-
+ 3 files changed, 48 insertions(+), 1 deletion(-)
+ create mode 100644 src/tests/stacking/closed-transient-no-input-parents.metatest
+
+diff --git a/src/Makefile-tests.am b/src/Makefile-tests.am
+index 7c1dd60..195d1e4 100644
+--- a/src/Makefile-tests.am
++++ b/src/Makefile-tests.am
+@@ -19,6 +19,7 @@ dist_stacking_DATA =						\
+ 	$(srcdir)/tests/stacking/closed-transient-no-input-no-take-focus-parents.metatest	\
+ 	$(srcdir)/tests/stacking/closed-transient-no-input-parent.metatest	\
+ 	$(srcdir)/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest	\
++	$(srcdir)/tests/stacking/closed-transient-no-input-parents.metatest	\
+ 	$(srcdir)/tests/stacking/minimized.metatest 	\
+ 	$(srcdir)/tests/stacking/mixed-windows.metatest     \
+ 	$(srcdir)/tests/stacking/set-parent.metatest	\
+diff --git a/src/tests/stacking/closed-transient-no-input-parents.metatest b/src/tests/stacking/closed-transient-no-input-parents.metatest
+new file mode 100644
+index 0000000..e3ec2e8
+--- /dev/null
++++ b/src/tests/stacking/closed-transient-no-input-parents.metatest
+@@ -0,0 +1,46 @@
++new_client 0 x11
++create 0/1
++show 0/1
++
++new_client 1 x11
++create 1/1
++show 1/1
++
++create 1/2 csd
++set_parent 1/2 1
++accept_focus 1/2 false
++show 1/2
++
++create 1/3 csd
++set_parent 1/3 2
++accept_focus 1/3 false
++show 1/3
++
++create 1/4 csd
++set_parent 1/4 3
++accept_focus 1/4 false
++show 1/4
++
++create 1/5 csd
++set_parent 1/5 3
++show 1/5
++
++wait
++assert_focused 1/5
++assert_stacking 0/1 1/1 1/2 1/3 1/4 1/5
++
++destroy 1/5
++dispatch
++
++assert_focused none
++assert_stacking 0/1 1/1 1/2 1/3 1/4
++
++sleep 250
++assert_focused none
++assert_stacking 0/1 1/1 1/2 1/3 1/4
++
++destroy 1/3
++wait
++
++assert_focused none
++assert_stacking 0/1 1/1 1/2 1/4
+diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
+index 18a97f3..325235f 100644
+--- a/src/x11/window-x11.c
++++ b/src/x11/window-x11.c
+@@ -865,7 +865,7 @@ meta_window_x11_focus (MetaWindow *window,
+                       if (!focus_window)
+                         break;
+ 
+-                      if (focus_window->input)
++                      if (focus_window->input || focus_window->take_focus)
+                         break;
+ 
+                       if (focus_window->shaded && focus_window->frame)
diff -Nru mutter-3.30.2/debian/patches/window-x11-Add-lost-definition-for-TAKE_FOCUS_FALLBACK_DE.patch mutter-3.30.2/debian/patches/window-x11-Add-lost-definition-for-TAKE_FOCUS_FALLBACK_DE.patch
--- mutter-3.30.2/debian/patches/window-x11-Add-lost-definition-for-TAKE_FOCUS_FALLBACK_DE.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/window-x11-Add-lost-definition-for-TAKE_FOCUS_FALLBACK_DE.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,28 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Fri, 28 Jun 2019 20:14:27 +0200
+Subject: window-x11: Add lost definition for TAKE_FOCUS_FALLBACK_DELAY_MS
+
+In commit 8abd1b009 (cherry-pick to gnome-3-30 of commit f71151a5d) the
+definition of TAKE_FOCUS_FALLBACK_DELAY_MS was not properly merged.
+
+Include this back to fix the build failure.
+
+Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
+Origin: upstream, 3.30.3, commit:a51188f8d79e018425f2469b47c01f1ddde9227d
+---
+ src/x11/window-x11.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
+index d86d35f..360299c 100644
+--- a/src/x11/window-x11.c
++++ b/src/x11/window-x11.c
+@@ -55,6 +55,8 @@
+ #include "backends/meta-logical-monitor.h"
+ #include "backends/x11/meta-backend-x11.h"
+ 
++#define TAKE_FOCUS_FALLBACK_DELAY_MS 250
++
+ G_DEFINE_TYPE_WITH_PRIVATE (MetaWindowX11, meta_window_x11, META_TYPE_WINDOW)
+ 
+ static void
diff -Nru mutter-3.30.2/debian/patches/window-x11-Don-t-double-check-for-unmanaging-windows.patch mutter-3.30.2/debian/patches/window-x11-Don-t-double-check-for-unmanaging-windows.patch
--- mutter-3.30.2/debian/patches/window-x11-Don-t-double-check-for-unmanaging-windows.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/window-x11-Don-t-double-check-for-unmanaging-windows.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,32 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Mon, 1 Jul 2019 08:38:02 +0000
+Subject: window-x11: Don't double-check for unmanaging windows
+
+When looking for the best fallback focus window, we ignore it if it is in the
+unmanaging state, but meta_stack_get_default_focus_window() does this is check
+for us already.
+
+So, ignore the redundant test.
+
+(cherry picked from commit 9aee47daa984e5cc4a1ccefb3aacfbb2729cfbc1)
+
+Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/669
+Origin: upstream, 3.30.3, commit:bee55a27f4d78f2b5dd5c3a3141427fc6b2f8a6b
+---
+ src/x11/window-x11.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
+index 360299c..18a97f3 100644
+--- a/src/x11/window-x11.c
++++ b/src/x11/window-x11.c
+@@ -865,9 +865,6 @@ meta_window_x11_focus (MetaWindow *window,
+                       if (!focus_window)
+                         break;
+ 
+-                      if (focus_window->unmanaging)
+-                        continue;
+-
+                       if (focus_window->input)
+                         break;
+ 
diff -Nru mutter-3.30.2/debian/patches/window-x11-Focus-a-window-in-the-active-workspace-as-take.patch mutter-3.30.2/debian/patches/window-x11-Focus-a-window-in-the-active-workspace-as-take.patch
--- mutter-3.30.2/debian/patches/window-x11-Focus-a-window-in-the-active-workspace-as-take.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/window-x11-Focus-a-window-in-the-active-workspace-as-take.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,63 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Wed, 17 Jul 2019 01:13:48 +0200
+Subject: window-x11: Focus a window in the active workspace as take-focus
+ fallback
+
+Starting with commit 2db94e2e we try to focus a fallback default focus window
+if no take-focus window candidate gets the input focus when we request it and
+we limit the focus candidates to the current window's workspace.
+
+However, if the window is unmanaging, the workspace might be unset, and we could
+end up in deferencing a NULL pointer causing a crash.
+
+So, in case the window's workspace is unset, just use the currently active
+workspace for the display.
+
+(cherry picked from commit 5ca0ef078d39548edda1a97e9066d44aa8f38108)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/issues/687
+Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/688
+Origin: upstream, 3.30.3, commit:c05fe4ae98e3e0558b0a5bd76adbb254d5a2527f
+---
+ src/x11/window-x11.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
+index f323429..6acdbfc 100644
+--- a/src/x11/window-x11.c
++++ b/src/x11/window-x11.c
+@@ -846,15 +846,22 @@ meta_window_x11_maybe_focus_delayed (MetaWindow *window,
+ }
+ 
+ static void
+-maybe_focus_default_window (MetaWorkspace *workspace,
+-                            MetaWindow    *not_this_one,
+-                            guint32        timestamp)
++maybe_focus_default_window (MetaDisplay *display,
++                            MetaWindow  *not_this_one,
++                            guint32      timestamp)
+ {
++  MetaWorkspace *workspace;
++  MetaStack *stack = display->stack;
+   MetaStack *stack = workspace->display->stack;
+   g_autoptr (GList) focusable_windows = NULL;
+   g_autoptr (GQueue) focus_candidates = NULL;
+   GList *l;
+ 
++  if (not_this_one && not_this_one->workspace)
++    workspace = not_this_one->workspace;
++  else
++    workspace = display->workspace_manager->active_workspace;
++
+    /* Go through all the focusable windows and try to focus them
+     * in order, waiting for a delay. The first one that replies to
+     * the request (in case of take focus windows) changing the display
+@@ -949,7 +956,7 @@ meta_window_x11_focus (MetaWindow *window,
+ 
+                   meta_x11_display_focus_the_no_focus_window (x11_display,
+                                                               timestamp);
+-                  maybe_focus_default_window (window->workspace, window,
++                  maybe_focus_default_window (window->display, window,
+                                               timestamp);
+                 }
+             }
diff -Nru mutter-3.30.2/debian/patches/window-x11-Focus-the-default-window-with-delay-while-wait.patch mutter-3.30.2/debian/patches/window-x11-Focus-the-default-window-with-delay-while-wait.patch
--- mutter-3.30.2/debian/patches/window-x11-Focus-the-default-window-with-delay-while-wait.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/window-x11-Focus-the-default-window-with-delay-while-wait.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,233 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Wed, 14 Nov 2018 00:08:34 +0100
+Subject: window-x11: Focus the default window with delay while waiting for
+ take-focus
+
+When requesting to a take-focus window to acquire the input, the client may or
+may not respond with a SetInputFocus (this doesn't happen for no-input gtk
+windows in fact [to be fixed there too]), in such case we were unsetting the
+focus while waiting the reply.
+
+In case the client won't respond, we wait for a small delay (set to 250 ms) for
+the take-focus window to grab the input focus before setting it to the default
+window.
+
+Added a test for this behavior and for the case in which a window takes the
+focus meanwhile we're waiting to focus the default window.
+
+(cherry picked from commit f71151a5dd990d935f3fbb39451f9b41f640b625)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/merge_requests/307
+Origin: upstream, 3.30.3, commit:8abd1b00926534fb9a34638c89cbb41b37f0e078
+---
+ src/Makefile-tests.am                              |  1 +
+ ...parent-delayed-focus-default-cancelled.metatest | 36 ++++++++
+ .../closed-transient-no-input-parent.metatest      | 16 +++-
+ src/x11/window-x11.c                               | 98 +++++++++++++++++++++-
+ 4 files changed, 144 insertions(+), 7 deletions(-)
+ create mode 100644 src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest
+
+diff --git a/src/Makefile-tests.am b/src/Makefile-tests.am
+index e35ad91..7cfae23 100644
+--- a/src/Makefile-tests.am
++++ b/src/Makefile-tests.am
+@@ -18,6 +18,7 @@ dist_stacking_DATA =						\
+ 	$(srcdir)/closed-transient-no-input-no-take-focus-parent.metatest	\
+ 	$(srcdir)/closed-transient-no-input-no-take-focus-parents.metatest	\
+ 	$(srcdir)/closed-transient-no-input-parent.metatest	\
++	$(srcdir)/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest	\
+ 	$(srcdir)/tests/stacking/minimized.metatest 	\
+ 	$(srcdir)/tests/stacking/mixed-windows.metatest     \
+ 	$(srcdir)/tests/stacking/set-parent.metatest	\
+diff --git a/src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest b/src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest
+new file mode 100644
+index 0000000..38897e3
+--- /dev/null
++++ b/src/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest
+@@ -0,0 +1,36 @@
++new_client 2 x11
++create 2/1
++show 2/1
++
++new_client 1 x11
++create 1/1
++show 1/1
++
++create 1/2 csd
++set_parent 1/2 1
++accept_focus 1/2 false
++show 1/2
++
++create 1/3 csd
++set_parent 1/3 2
++show 1/3
++
++wait
++assert_focused 1/3
++assert_stacking 2/1 1/1 1/2 1/3
++
++destroy 1/3
++sleep 10
++
++assert_focused none
++assert_stacking 2/1 1/1 1/2
++
++activate 2/1
++wait
++
++assert_focused 2/1
++assert_stacking 1/1 1/2 2/1
++
++sleep 250
++assert_focused 2/1
++assert_stacking 1/1 1/2 2/1
+diff --git a/src/tests/stacking/closed-transient-no-input-parent.metatest b/src/tests/stacking/closed-transient-no-input-parent.metatest
+index 4cadb23..e0f1dc1 100644
+--- a/src/tests/stacking/closed-transient-no-input-parent.metatest
++++ b/src/tests/stacking/closed-transient-no-input-parent.metatest
+@@ -1,3 +1,7 @@
++new_client 2 x11
++create 2/1
++show 2/1
++
+ new_client 1 x11
+ create 1/1
+ show 1/1
+@@ -12,9 +16,15 @@ set_parent 1/3 2
+ show 1/3
+ 
+ wait
+-assert_stacking 1/1 1/2 1/3
++assert_focused 1/3
++assert_stacking 2/1 1/1 1/2 1/3
+ 
+ destroy 1/3
++dispatch
+ 
+-wait
+-assert_stacking 1/1 1/2
++assert_focused none
++assert_stacking 2/1 1/1 1/2
++
++sleep 250
++assert_focused 1/1
++assert_stacking 2/1 1/1 1/2
+diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
+index 4b27892..d86d35f 100644
+--- a/src/x11/window-x11.c
++++ b/src/x11/window-x11.c
+@@ -734,6 +734,66 @@ request_take_focus (MetaWindow *window,
+   send_icccm_message (window, display->x11_display->atom_WM_TAKE_FOCUS, timestamp);
+ }
+ 
++typedef struct
++{
++  MetaWindow *window;
++  guint32 timestamp;
++  guint timeout_id;
++  gulong unmanaged_id;
++  gulong focused_changed_id;
++} MetaWindowX11DelayedFocusData;
++
++static void
++meta_window_x11_delayed_focus_data_free (MetaWindowX11DelayedFocusData *data)
++{
++  g_signal_handler_disconnect (data->window, data->unmanaged_id);
++  g_signal_handler_disconnect (data->window->display, data->focused_changed_id);
++
++  if (data->timeout_id)
++    g_source_remove (data->timeout_id);
++
++  g_free (data);
++}
++
++static gboolean
++focus_window_delayed_timeout (gpointer user_data)
++{
++  MetaWindowX11DelayedFocusData *data = user_data;
++  MetaWindow *window = data->window;
++  guint32 timestamp = data->timestamp;
++
++  data->timeout_id = 0;
++  meta_window_x11_delayed_focus_data_free (data);
++
++  meta_window_focus (window, timestamp);
++
++  return G_SOURCE_REMOVE;
++}
++
++static void
++meta_window_x11_maybe_focus_delayed (MetaWindow *window,
++                                     guint32     timestamp)
++{
++  MetaWindowX11DelayedFocusData *data;
++
++  data = g_new0 (MetaWindowX11DelayedFocusData, 1);
++  data->window = window;
++  data->timestamp = timestamp;
++
++  data->unmanaged_id =
++    g_signal_connect_swapped (window, "unmanaged",
++                              G_CALLBACK (meta_window_x11_delayed_focus_data_free),
++                              data);
++
++  data->focused_changed_id =
++    g_signal_connect_swapped (window->display, "notify::focus-window",
++                              G_CALLBACK (meta_window_x11_delayed_focus_data_free),
++                              data);
++
++  data->timeout_id = g_timeout_add (TAKE_FOCUS_FALLBACK_DELAY_MS,
++                                    focus_window_delayed_timeout, data);
++}
++
+ static void
+ meta_window_x11_focus (MetaWindow *window,
+                        guint32     timestamp)
+@@ -783,13 +843,43 @@ meta_window_x11_focus (MetaWindow *window,
+                * Normally, we want to just leave the focus undisturbed until
+                * the window responds to WM_TAKE_FOCUS, but if we're unmanaging
+                * the current focus window we *need* to move the focus away, so
+-               * we focus the no_focus_window now (and set
+-               * display->focus_window to that) before sending WM_TAKE_FOCUS.
++               * we focus the no focus window before sending WM_TAKE_FOCUS,
++               * and eventually the default focus windwo excluding this one,
++               * if meanwhile we don't get any focus request.
+                */
+               if (window->display->focus_window != NULL &&
+                   window->display->focus_window->unmanaging)
+-                meta_x11_display_focus_the_no_focus_window (window->display->x11_display,
+-                                                            timestamp);
++                {
++                  MetaX11Display *x11_display = window->display->x11_display;
++                  MetaWindow *focus_window = window;
++                  MetaWorkspace *workspace = window->workspace;
++                  MetaStack *stack = workspace->display->stack;
++
++                  while (TRUE)
++                    {
++                      focus_window = meta_stack_get_default_focus_window (stack,
++                                                                          workspace,
++                                                                          focus_window);
++                      if (!focus_window)
++                        break;
++
++                      if (focus_window->unmanaging)
++                        continue;
++
++                      if (focus_window->input)
++                        break;
++
++                      if (focus_window->shaded && focus_window->frame)
++                        break;
++                    }
++
++                  meta_x11_display_focus_the_no_focus_window (x11_display,
++                                                              timestamp);
++
++                  if (focus_window)
++                    meta_window_x11_maybe_focus_delayed (focus_window,
++                                                         timestamp);
++                }
+             }
+ 
+           request_take_focus (window, timestamp);
diff -Nru mutter-3.30.2/debian/patches/window-x11-Remove-double-definition-of-MetaStack.patch mutter-3.30.2/debian/patches/window-x11-Remove-double-definition-of-MetaStack.patch
--- mutter-3.30.2/debian/patches/window-x11-Remove-double-definition-of-MetaStack.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/window-x11-Remove-double-definition-of-MetaStack.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,28 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Thu, 18 Jul 2019 11:33:55 +0200
+Subject: window-x11: Remove double definition of MetaStack
+
+In commit c05fe4ae9 we introduced a double definition of MetaStack due to a
+wrong cherry-pick conflict resolution.
+
+Fix this by removing the invalid duplicated line.
+
+Related to https://gitlab.gnome.org/GNOME/mutter/merge_requests/688
+
+Origin: upstream, 3.30.3, commit:2a81dc45e7474a4b48b6e3a4ce572a7795ad320d
+---
+ src/x11/window-x11.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
+index 6acdbfc..29bd645 100644
+--- a/src/x11/window-x11.c
++++ b/src/x11/window-x11.c
+@@ -852,7 +852,6 @@ maybe_focus_default_window (MetaDisplay *display,
+ {
+   MetaWorkspace *workspace;
+   MetaStack *stack = display->stack;
+-  MetaStack *stack = workspace->display->stack;
+   g_autoptr (GList) focusable_windows = NULL;
+   g_autoptr (GQueue) focus_candidates = NULL;
+   GList *l;
diff -Nru mutter-3.30.2/debian/patches/window-x11-Use-any-focusable-window-as-fallback-delayed-f.patch mutter-3.30.2/debian/patches/window-x11-Use-any-focusable-window-as-fallback-delayed-f.patch
--- mutter-3.30.2/debian/patches/window-x11-Use-any-focusable-window-as-fallback-delayed-f.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/window-x11-Use-any-focusable-window-as-fallback-delayed-f.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,374 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Wed, 3 Jul 2019 12:04:08 +0200
+Subject: window-x11: Use any focusable window as fallback delayed focus
+ window
+
+As per commit f71151a5 we focus an input window if no take-focus-window accepts
+it. This might lead to an infinite loop if there are various focusable but
+non-input windows in the stack.
+
+When the current focus window is unmanaging and we're trying to focus a
+WM_TAKE_FOCUS window, we intent to give the focus to the first focusable input
+window in the stack.
+
+However, if an application (such as the Java ones) only uses non-input
+WM_TAKE_FOCUS windows, are not requesting these ones to get the focus. This
+might lead to a state where no window is focused, or a wrong one is.
+
+So, instead of only focus the first eventually input window available, try to
+request to all the take-focus windows that are in the stack between the
+destroyed one and the first input one to acquire the input focus.
+Use a queue to keep track of those windows, that is passed around stealing
+ownership, while we protect for unmanaged queued windows.
+
+Also, reduce the default timeout value, as the previous one might lead to an
+excessive long wait.
+
+Added metatests verifying these situations.
+
+(cherry picked from commit 6d8293a422b08af97d3da985d49448db32d59248)
+
+Bug: https://gitlab.gnome.org/GNOME/mutter/issues/660
+Forwarded: https://gitlab.gnome.org/GNOME/mutter/merge_requests/669
+Origin: upstream, 3.30.3, commit:2a692a03287a5283d50152fd104f5e35bbbaab67
+---
+ src/Makefile-tests.am                              |   2 +
+ .../closed-transient-no-input-parent.metatest      |   2 +-
+ ...parents-queued-default-focus-destroyed.metatest |  43 ++++++++
+ .../closed-transient-no-input-parents.metatest     |   6 +-
+ ...osed-transient-only-take-focus-parents.metatest |  34 ++++++
+ src/x11/window-x11.c                               | 119 +++++++++++++++++----
+ 6 files changed, 179 insertions(+), 27 deletions(-)
+ create mode 100644 src/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest
+ create mode 100644 src/tests/stacking/closed-transient-only-take-focus-parents.metatest
+
+diff --git a/src/Makefile-tests.am b/src/Makefile-tests.am
+index 195d1e4..ff140d0 100644
+--- a/src/Makefile-tests.am
++++ b/src/Makefile-tests.am
+@@ -20,6 +20,8 @@ dist_stacking_DATA =						\
+ 	$(srcdir)/tests/stacking/closed-transient-no-input-parent.metatest	\
+ 	$(srcdir)/tests/stacking/closed-transient-no-input-parent-delayed-focus-default-cancelled.metatest	\
+ 	$(srcdir)/tests/stacking/closed-transient-no-input-parents.metatest	\
++	$(srcdir)/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest	\
++	$(srcdir)/tests/stacking/closed-transient-only-take-focus-parents.metatest	\
+ 	$(srcdir)/tests/stacking/minimized.metatest 	\
+ 	$(srcdir)/tests/stacking/mixed-windows.metatest     \
+ 	$(srcdir)/tests/stacking/set-parent.metatest	\
+diff --git a/src/tests/stacking/closed-transient-no-input-parent.metatest b/src/tests/stacking/closed-transient-no-input-parent.metatest
+index e0f1dc1..d0f3228 100644
+--- a/src/tests/stacking/closed-transient-no-input-parent.metatest
++++ b/src/tests/stacking/closed-transient-no-input-parent.metatest
+@@ -25,6 +25,6 @@ dispatch
+ assert_focused none
+ assert_stacking 2/1 1/1 1/2
+ 
+-sleep 250
++sleep 150
+ assert_focused 1/1
+ assert_stacking 2/1 1/1 1/2
+diff --git a/src/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest b/src/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest
+new file mode 100644
+index 0000000..49ecc51
+--- /dev/null
++++ b/src/tests/stacking/closed-transient-no-input-parents-queued-default-focus-destroyed.metatest
+@@ -0,0 +1,43 @@
++new_client 0 x11
++create 0/1
++show 0/1
++
++new_client 1 x11
++create 1/1
++show 1/1
++
++create 1/2 csd
++set_parent 1/2 1
++accept_focus 1/2 false
++show 1/2
++
++create 1/3 csd
++set_parent 1/3 2
++accept_focus 1/3 false
++show 1/3
++
++create 1/4 csd
++set_parent 1/4 3
++accept_focus 1/4 false
++show 1/4
++
++create 1/5 csd
++set_parent 1/5 3
++show 1/5
++
++wait
++assert_focused 1/5
++assert_stacking 0/1 1/1 1/2 1/3 1/4 1/5
++
++destroy 1/5
++dispatch
++
++assert_focused none
++assert_stacking 0/1 1/1 1/2 1/3 1/4
++
++destroy 1/2
++dispatch
++
++sleep 450
++assert_focused 1/1
++assert_stacking 0/1 1/1 1/3 1/4
+diff --git a/src/tests/stacking/closed-transient-no-input-parents.metatest b/src/tests/stacking/closed-transient-no-input-parents.metatest
+index e3ec2e8..ee99841 100644
+--- a/src/tests/stacking/closed-transient-no-input-parents.metatest
++++ b/src/tests/stacking/closed-transient-no-input-parents.metatest
+@@ -35,12 +35,12 @@ dispatch
+ assert_focused none
+ assert_stacking 0/1 1/1 1/2 1/3 1/4
+ 
+-sleep 250
+-assert_focused none
++sleep 600
++assert_focused 1/1
+ assert_stacking 0/1 1/1 1/2 1/3 1/4
+ 
+ destroy 1/3
+ wait
+ 
+-assert_focused none
++assert_focused 1/1
+ assert_stacking 0/1 1/1 1/2 1/4
+diff --git a/src/tests/stacking/closed-transient-only-take-focus-parents.metatest b/src/tests/stacking/closed-transient-only-take-focus-parents.metatest
+new file mode 100644
+index 0000000..8aa8670
+--- /dev/null
++++ b/src/tests/stacking/closed-transient-only-take-focus-parents.metatest
+@@ -0,0 +1,34 @@
++new_client 0 x11
++create 0/1
++show 0/1
++
++new_client 1 x11
++create 1/1
++accept_focus 1/1 false
++can_take_focus 1/1 true
++accept_take_focus 1/1 true
++show 1/1
++
++create 1/2 csd
++set_parent 1/2 1
++accept_focus 1/2 false
++can_take_focus 1/2 true
++accept_take_focus 1/2 true
++show 1/2
++
++create 1/3
++set_parent 1/3 2
++show 1/3
++
++assert_focused 1/3
++assert_stacking 0/1 1/1 1/2 1/3
++
++destroy 1/3
++wait
++
++assert_focused 1/2
++assert_stacking 0/1 1/1 1/2
++
++sleep 150
++assert_focused 1/2
++assert_stacking 0/1 1/1 1/2
+diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
+index 325235f..f323429 100644
+--- a/src/x11/window-x11.c
++++ b/src/x11/window-x11.c
+@@ -55,10 +55,15 @@
+ #include "backends/meta-logical-monitor.h"
+ #include "backends/x11/meta-backend-x11.h"
+ 
+-#define TAKE_FOCUS_FALLBACK_DELAY_MS 250
++#define TAKE_FOCUS_FALLBACK_DELAY_MS 150
+ 
+ G_DEFINE_TYPE_WITH_PRIVATE (MetaWindowX11, meta_window_x11, META_TYPE_WINDOW)
+ 
++static void
++meta_window_x11_maybe_focus_delayed (MetaWindow *window,
++                                     GQueue     *other_focus_candidates,
++                                     guint32     timestamp);
++
+ static void
+ meta_window_x11_init (MetaWindowX11 *window_x11)
+ {
+@@ -739,24 +744,60 @@ request_take_focus (MetaWindow *window,
+ typedef struct
+ {
+   MetaWindow *window;
++  GQueue *pending_focus_candidates;
+   guint32 timestamp;
+   guint timeout_id;
+   gulong unmanaged_id;
+   gulong focused_changed_id;
+ } MetaWindowX11DelayedFocusData;
+ 
++static void
++disconnect_pending_focus_window_signals (MetaWindow *window,
++                                         GQueue     *focus_candidates)
++{
++  g_signal_handlers_disconnect_by_func (window, g_queue_remove,
++                                        focus_candidates);
++}
++
+ static void
+ meta_window_x11_delayed_focus_data_free (MetaWindowX11DelayedFocusData *data)
+ {
+   g_signal_handler_disconnect (data->window, data->unmanaged_id);
+   g_signal_handler_disconnect (data->window->display, data->focused_changed_id);
+ 
++  if (data->pending_focus_candidates)
++    {
++      g_queue_foreach (data->pending_focus_candidates,
++                       (GFunc) disconnect_pending_focus_window_signals,
++                       data->pending_focus_candidates);
++      g_queue_free (data->pending_focus_candidates);
++    }
++
+   if (data->timeout_id)
+     g_source_remove (data->timeout_id);
+ 
+   g_free (data);
+ }
+ 
++static void
++focus_candidates_maybe_take_and_focus_next (GQueue  **focus_candidates_ptr,
++                                            guint32   timestamp)
++{
++  MetaWindow *focus_window;
++  GQueue *focus_candidates;
++
++  g_assert (*focus_candidates_ptr);
++
++  if (g_queue_is_empty (*focus_candidates_ptr))
++    return;
++
++  focus_candidates = g_steal_pointer (focus_candidates_ptr);
++  focus_window = g_queue_pop_head (focus_candidates);
++
++  disconnect_pending_focus_window_signals (focus_window, focus_candidates);
++  meta_window_x11_maybe_focus_delayed (focus_window, focus_candidates, timestamp);
++}
++
+ static gboolean
+ focus_window_delayed_timeout (gpointer user_data)
+ {
+@@ -764,6 +805,9 @@ focus_window_delayed_timeout (gpointer user_data)
+   MetaWindow *window = data->window;
+   guint32 timestamp = data->timestamp;
+ 
++  focus_candidates_maybe_take_and_focus_next (&data->pending_focus_candidates,
++                                              timestamp);
++
+   data->timeout_id = 0;
+   meta_window_x11_delayed_focus_data_free (data);
+ 
+@@ -774,6 +818,7 @@ focus_window_delayed_timeout (gpointer user_data)
+ 
+ static void
+ meta_window_x11_maybe_focus_delayed (MetaWindow *window,
++                                     GQueue     *other_focus_candidates,
+                                      guint32     timestamp)
+ {
+   MetaWindowX11DelayedFocusData *data;
+@@ -781,6 +826,10 @@ meta_window_x11_maybe_focus_delayed (MetaWindow *window,
+   data = g_new0 (MetaWindowX11DelayedFocusData, 1);
+   data->window = window;
+   data->timestamp = timestamp;
++  data->pending_focus_candidates = other_focus_candidates;
++
++  meta_topic (META_DEBUG_FOCUS,
++              "Requesting delayed focus to %s\n", window->desc);
+ 
+   data->unmanaged_id =
+     g_signal_connect_swapped (window, "unmanaged",
+@@ -796,6 +845,50 @@ meta_window_x11_maybe_focus_delayed (MetaWindow *window,
+                                     focus_window_delayed_timeout, data);
+ }
+ 
++static void
++maybe_focus_default_window (MetaWorkspace *workspace,
++                            MetaWindow    *not_this_one,
++                            guint32        timestamp)
++{
++  MetaStack *stack = workspace->display->stack;
++  g_autoptr (GList) focusable_windows = NULL;
++  g_autoptr (GQueue) focus_candidates = NULL;
++  GList *l;
++
++   /* Go through all the focusable windows and try to focus them
++    * in order, waiting for a delay. The first one that replies to
++    * the request (in case of take focus windows) changing the display
++    * focused window, will stop the chained requests.
++    */
++  focusable_windows =
++    meta_stack_get_default_focus_candidates (stack, workspace);
++  focus_candidates = g_queue_new ();
++
++  for (l = g_list_last (focusable_windows); l; l = l->prev)
++    {
++      MetaWindow *focus_window = l->data;
++
++      if (focus_window == not_this_one)
++        continue;
++
++      g_queue_push_tail (focus_candidates, focus_window);
++      g_signal_connect_swapped (focus_window, "unmanaged",
++                                G_CALLBACK (g_queue_remove),
++                                focus_candidates);
++
++      if (!META_IS_WINDOW_X11 (focus_window))
++        break;
++
++      if (focus_window->input)
++        break;
++
++      if (focus_window->shaded && focus_window->frame)
++        break;
++    }
++
++  focus_candidates_maybe_take_and_focus_next (&focus_candidates, timestamp);
++}
++
+ static void
+ meta_window_x11_focus (MetaWindow *window,
+                        guint32     timestamp)
+@@ -853,31 +946,11 @@ meta_window_x11_focus (MetaWindow *window,
+                   window->display->focus_window->unmanaging)
+                 {
+                   MetaX11Display *x11_display = window->display->x11_display;
+-                  MetaWindow *focus_window = window;
+-                  MetaWorkspace *workspace = window->workspace;
+-                  MetaStack *stack = workspace->display->stack;
+-
+-                  while (TRUE)
+-                    {
+-                      focus_window = meta_stack_get_default_focus_window (stack,
+-                                                                          workspace,
+-                                                                          focus_window);
+-                      if (!focus_window)
+-                        break;
+-
+-                      if (focus_window->input || focus_window->take_focus)
+-                        break;
+-
+-                      if (focus_window->shaded && focus_window->frame)
+-                        break;
+-                    }
+ 
+                   meta_x11_display_focus_the_no_focus_window (x11_display,
+                                                               timestamp);
+-
+-                  if (focus_window)
+-                    meta_window_x11_maybe_focus_delayed (focus_window,
+-                                                         timestamp);
++                  maybe_focus_default_window (window->workspace, window,
++                                              timestamp);
+                 }
+             }
+ 
diff -Nru mutter-3.30.2/debian/patches/workspace-Focus-only-ancestors-that-are-focusable.patch mutter-3.30.2/debian/patches/workspace-Focus-only-ancestors-that-are-focusable.patch
--- mutter-3.30.2/debian/patches/workspace-Focus-only-ancestors-that-are-focusable.patch	1970-01-01 01:00:00.000000000 +0100
+++ mutter-3.30.2/debian/patches/workspace-Focus-only-ancestors-that-are-focusable.patch	2019-08-18 19:51:33.000000000 +0100
@@ -0,0 +1,80 @@
+From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
+Date: Tue, 13 Nov 2018 08:31:52 +0100
+Subject: workspace: Focus only ancestors that are focusable
+
+When destroying a window that has a parent, we initially try to focus one of
+its ancestors. However if no ancestor can be focused, then we should instead
+focus the default focus window instead of trying to request focus for a window
+that can't get focus anyways.
+
+(cherry picked from commit eccc791f3b3451216f957e67fec47a73b65ed2b2)
+Bug: https://gitlab.gnome.org/GNOME/mutter/issues/308
+Origin: upstream, 3.30.3, commit:b95700dabc1e582e3757353850bb57f5d5b94aff
+---
+ src/core/workspace.c | 37 +++++++++++++++++++++++++++----------
+ 1 file changed, 27 insertions(+), 10 deletions(-)
+
+diff --git a/src/core/workspace.c b/src/core/workspace.c
+index e9b693e..ba146d6 100644
+--- a/src/core/workspace.c
++++ b/src/core/workspace.c
+@@ -86,6 +86,12 @@ typedef struct _MetaWorkspaceLogicalMonitorData
+   MetaRectangle logical_monitor_work_area;
+ } MetaWorkspaceLogicalMonitorData;
+ 
++typedef struct _MetaWorkspaceFocusableAncestorData
++{
++  MetaWorkspace *workspace;
++  MetaWindow *out_window;
++} MetaWorkspaceFocusableAncestorData;
++
+ static MetaWorkspaceLogicalMonitorData *
+ meta_workspace_get_logical_monitor_data (MetaWorkspace      *workspace,
+                                          MetaLogicalMonitor *logical_monitor)
+@@ -1327,13 +1333,20 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
+ }
+ 
+ static gboolean
+-record_ancestor (MetaWindow *window,
+-                 void       *data)
++find_focusable_ancestor (MetaWindow *window,
++                         gpointer    user_data)
+ {
+-  MetaWindow **result = data;
++  MetaWorkspaceFocusableAncestorData *data = user_data;
++
++  if (!window->unmanaging && (window->input || window->take_focus) &&
++      meta_window_located_on_workspace (window, data->workspace) &&
++      meta_window_showing_on_its_workspace (window))
++    {
++      data->out_window = window;
++      return FALSE;
++    }
+ 
+-  *result = window;
+-  return FALSE; /* quit with the first ancestor we find */
++  return TRUE;
+ }
+ 
+ /* Focus ancestor of not_this_one if there is one */
+@@ -1355,11 +1368,15 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
+   if (not_this_one)
+     {
+       MetaWindow *ancestor;
+-      ancestor = NULL;
+-      meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor);
+-      if (ancestor != NULL &&
+-          meta_window_located_on_workspace (ancestor, workspace) &&
+-          meta_window_showing_on_its_workspace (ancestor))
++      MetaWorkspaceFocusableAncestorData data;
++
++      data = (MetaWorkspaceFocusableAncestorData) {
++        .workspace = workspace,
++      };
++      meta_window_foreach_ancestor (not_this_one, find_focusable_ancestor, &data);
++      ancestor = data.out_window;
++
++      if (ancestor)
+         {
+           meta_topic (META_DEBUG_FOCUS,
+                       "Focusing %s, ancestor of %s\n",

Reply to: